You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by cf...@apache.org on 2012/05/29 17:35:15 UTC

svn commit: r1343781 [14/17] - in /incubator/flex/trunk/modules: ./ thirdparty/velocity/ thirdparty/velocity/build/ thirdparty/velocity/build/lib/ thirdparty/velocity/build/xsl/ thirdparty/velocity/src/java/org/apache/velocity/anakia/ thirdparty/veloci...

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/ArrayIterator.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/ArrayIterator.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/ArrayIterator.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/ArrayIterator.java Tue May 29 15:35:01 2012
@@ -0,0 +1,114 @@
+package org.apache.velocity.util;
+
+/*
+ * Copyright 1999-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.lang.reflect.Array;
+
+
+/**
+ *  <p>
+ *  An Iterator wrapper for an Object[]. This will
+ *  allow us to deal with all array like structures
+ *  in a consistent manner.
+ *  </p>
+ *  <p>
+ *  WARNING : this class's operations are NOT synchronized.
+ *  It is meant to be used in a single thread, newly created
+ *  for each use in the #foreach() directive.
+ *  If this is used or shared, synchronize in the
+ *  next() method.
+ *  </p>
+ *
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
+ * @version $Id: ArrayIterator.java,v 1.6.8.1 2004/03/03 23:23:07 geirm Exp $
+ */
+public class ArrayIterator implements Iterator
+{
+    /**
+     * The objects to iterate.
+     */
+    private Object array;
+
+    /**
+     * The current position and size in the array.
+     */
+    private int pos;
+    private int size;
+
+    /**
+     * Creates a new iterator instance for the specified array.
+     *
+     * @param array The array for which an iterator is desired.
+     */
+    public ArrayIterator(Object array)
+    {
+        /*
+         * if this isn't an array, then throw.  Note that this is 
+         * for internal use - so this should never happen - if it does
+         *  we screwed up.
+         */
+         
+        if ( !array.getClass().isArray() )
+        {   
+            throw new IllegalArgumentException( 
+                "Programmer error : internal ArrayIterator invoked w/o array");
+        }
+            
+        this.array = array;
+        pos = 0;
+        size = Array.getLength( this.array );
+    }
+
+    /**
+     * Move to next element in the array.
+     *
+     * @return The next object in the array.
+     */
+    public Object next()
+    {
+        if (pos < size )
+            return Array.get( array, pos++);
+                
+        /*
+         *  we screwed up...
+         */
+         
+        throw new NoSuchElementException("No more elements: " + pos +
+                                         " / " + size);
+    }
+    
+    /**
+     * Check to see if there is another element in the array.
+     *
+     * @return Whether there is another element.
+     */
+    public boolean hasNext()
+    {
+        return (pos < size );
+    }
+
+    /**
+     * No op--merely added to satify the <code>Iterator</code> interface.
+     */
+    public void remove()
+    {
+        throw new UnsupportedOperationException();
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/ArrayIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/EnumerationIterator.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/EnumerationIterator.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/EnumerationIterator.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/EnumerationIterator.java Tue May 29 15:35:01 2012
@@ -0,0 +1,74 @@
+package org.apache.velocity.util;
+
+/*
+ * Copyright 1999-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Iterator;
+import java.util.Enumeration;
+
+/**
+ * An Iterator wrapper for an Enumeration.
+ *
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @version $Id: EnumerationIterator.java,v 1.1.14.1 2004/03/03 23:23:07 geirm Exp $
+ */
+public class EnumerationIterator implements Iterator
+{
+    /**
+     * The enumeration to iterate.
+     */
+    private Enumeration enum = null;
+
+    /**
+     * Creates a new iteratorwrapper instance for the specified 
+     * Enumeration.
+     *
+     * @param enum  The Enumeration to wrap.
+     */
+    public EnumerationIterator( Enumeration enum)
+    {
+        this.enum = enum;
+    }
+
+    /**
+     * Move to next element in the array.
+     *
+     * @return The next object in the array.
+     */
+    public Object next()
+    {
+        return enum.nextElement();
+    }
+    
+    /**
+     * Check to see if there is another element in the array.
+     *
+     * @return Whether there is another element.
+     */
+    public boolean hasNext()
+    {
+        return enum.hasMoreElements();
+    }
+
+    /**
+     *  Unimplemented.  No analogy in Enumeration
+     */
+    public void remove()
+    {
+        // not implemented
+    }
+   
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/EnumerationIterator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/SimplePool.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/SimplePool.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/SimplePool.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/SimplePool.java Tue May 29 15:35:01 2012
@@ -0,0 +1,126 @@
+package org.apache.velocity.util;
+
+/*
+ * Copyright 1999-2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Simple object pool. Based on ThreadPool and few other classes
+ *
+ * The pool will ignore overflow and return null if empty.
+ *
+ * @author Gal Shachor
+ * @author Costin
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @version $Id: SimplePool.java,v 1.2.14.1 2004/03/03 23:23:07 geirm Exp $
+ */
+public final class SimplePool  
+{
+    /*
+     * Where the objects are held.
+     */
+    private Object pool[];
+
+    /**
+     *  max amount of objects to be managed
+     *  set via CTOR
+     */
+    private int max;    
+    
+    /**
+     *  index of previous to next
+     *  free slot
+     */
+    private int current=-1;
+       
+    public SimplePool(int max) 
+    {
+        this.max = max;
+        pool = new Object[max];
+    } 
+
+    /**
+     * Add the object to the pool, silent nothing if the pool is full
+     */
+    public void put(Object o) 
+    {
+        int idx=-1;
+     
+        synchronized( this ) 
+        {
+            /*
+             *  if we aren't full
+             */
+
+            if( current < max - 1 )
+            {
+                /*
+                 *  then increment the 
+                 *  current index.
+                 */
+                idx = ++current;
+            }
+
+            if( idx >= 0 ) 
+            {
+                pool[idx] = o;
+            }
+        }
+    }
+
+    /**
+     * Get an object from the pool, null if the pool is empty.
+     */
+    public  Object get() 
+    {
+        int idx = -1;
+        
+        synchronized( this ) 
+        {
+            /*
+             *  if we have any in the pool
+             */
+            if( current >= 0 )
+            {
+                /*
+                 *  take one out, so to speak -
+                 *  separate the two operations
+                 *  to make it clear that you
+                 *  don't want idx = --current; :)
+                 */
+
+                idx = current;
+                current--;
+               
+                /*
+                 *  and since current was >= 0
+                 *  to get in here, idx must be as well
+                 *  so save the if() opration
+                 */
+
+                return pool[idx];
+            }
+        }
+        
+        return null;
+    }
+
+    /** Return the size of the pool
+     */
+    public int getMax() 
+    {
+        return max;
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/SimplePool.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/StringUtils.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/StringUtils.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/StringUtils.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/StringUtils.java Tue May 29 15:35:01 2012
@@ -0,0 +1,596 @@
+package org.apache.velocity.util;
+
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.io.FileReader;
+import java.io.ByteArrayOutputStream;
+import java.io.PrintWriter;
+
+import java.net.MalformedURLException;
+
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.Map;
+
+
+/**
+ * This class provides some methods for dynamically
+ * invoking methods in objects, and some string
+ * manipulation methods used by torque. The string
+ * methods will soon be moved into the turbine
+ * string utilities class.
+ *
+ *  @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ *  @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
+ *  @version $Id: StringUtils.java,v 1.16.8.1 2004/03/03 23:23:07 geirm Exp $
+ */
+public class StringUtils
+{
+    /**
+     * Line separator for the OS we are operating on.
+     */
+    private static final String EOL = System.getProperty("line.separator");
+    
+    /**
+     * Length of the line separator.
+     */
+    private static final int EOL_LENGTH = EOL.length();
+
+    /**
+     * Concatenates a list of objects as a String.
+     *
+     * @param list The list of objects to concatenate.
+     * @return     A text representation of the concatenated objects.
+     */
+    public String concat(List list)
+    {
+        StringBuffer sb = new StringBuffer();
+        int size = list.size();
+
+        for (int i = 0; i < size; i++)
+        {
+            sb.append(list.get(i).toString());
+        }
+        return sb.toString();
+    }
+
+    /**
+     * Return a package name as a relative path name
+     *
+     * @param String package name to convert to a directory.
+     * @return String directory path.
+     */
+    static public String getPackageAsPath(String pckge)
+    {
+        return pckge.replace( '.', File.separator.charAt(0) ) + File.separator;
+    }
+
+    /**
+     * <p>
+     * Remove underscores from a string and replaces first
+     * letters with capitals.  Other letters are changed to lower case. 
+     * </p>
+     *
+     * <p> 
+     * For example <code>foo_bar</code> becomes <code>FooBar</code>
+     * but <code>foo_barBar</code> becomes <code>FooBarbar</code>.
+     * </p>
+     *
+     * @param data string to remove underscores from.
+     * @return String 
+     * @deprecated Use the org.apache.commons.util.StringUtils class
+     * instead.  Using its firstLetterCaps() method in conjunction
+     * with a StringTokenizer will achieve the same result.
+     */
+    static public String removeUnderScores (String data)
+    {
+        String temp = null;
+        StringBuffer out = new StringBuffer();
+        temp = data;
+
+        StringTokenizer st = new StringTokenizer(temp, "_");
+       
+        while (st.hasMoreTokens())
+        {
+            String element = (String) st.nextElement();
+            out.append ( firstLetterCaps(element));
+        }
+
+        return out.toString();
+    }
+
+    /**
+     * <p> 
+     *  'Camels Hump' replacement of underscores.
+     * </p>
+     *
+     * <p> 
+     * Remove underscores from a string but leave the capitalization of the
+     * other letters unchanged.
+     * </p>
+     *
+     * <p> 
+     * For example <code>foo_barBar</code> becomes <code>FooBarBar</code>.
+     * </p>
+     *
+     * @param data string to hump
+     * @return String 
+     */
+    static public String removeAndHump (String data)
+    {
+        return removeAndHump(data,"_");
+    }
+
+    /**
+     * <p>
+     * 'Camels Hump' replacement.
+     * </p>
+     *
+     * <p> 
+     * Remove one string from another string but leave the capitalization of the
+     * other letters unchanged.
+     * </p>
+     *
+     * <p>
+     * For example, removing "_" from <code>foo_barBar</code> becomes <code>FooBarBar</code>.
+     * </p>
+     *
+     * @param data string to hump
+     * @param replaceThis string to be replaced
+     * @return String 
+     */
+    static public String removeAndHump (String data,String replaceThis)
+    {
+        String temp = null;
+        StringBuffer out = new StringBuffer();
+        temp = data;
+
+        StringTokenizer st = new StringTokenizer(temp, replaceThis);
+       
+        while (st.hasMoreTokens())
+        {
+            String element = (String) st.nextElement();
+            out.append ( capitalizeFirstLetter(element));
+        }//while
+        
+        return out.toString();
+    }
+
+    /**
+     * <p> 
+     *  Makes the first letter caps and the rest lowercase.
+     * </p>
+     *
+     * <p> 
+     *  For example <code>fooBar</code> becomes <code>Foobar</code>.
+     * </p>
+     *
+     * @param data capitalize this
+     * @return String
+     */
+    static public String firstLetterCaps ( String data )
+    {
+        String firstLetter = data.substring(0,1).toUpperCase();
+        String restLetters = data.substring(1).toLowerCase();
+        return firstLetter + restLetters;
+    }
+
+    /**
+     * <p> 
+     * Capitalize the first letter but leave the rest as they are. 
+     * </p>
+     *
+     * <p> 
+     *  For example <code>fooBar</code> becomes <code>FooBar</code>.
+     * </p>
+     *
+     * @param data capitalize this
+     * @return String
+     */
+    static public String capitalizeFirstLetter ( String data )
+    {
+        String firstLetter = data.substring(0,1).toUpperCase();
+        String restLetters = data.substring(1);
+        return firstLetter + restLetters;
+    }
+
+    /**
+     * Create a string array from a string separated by delim
+     *
+     * @param line the line to split
+     * @param delim the delimter to split by
+     * @return a string array of the split fields
+     */
+    public static String [] split(String line, String delim)
+    {
+        List list = new ArrayList();
+        StringTokenizer t = new StringTokenizer(line, delim);
+        while (t.hasMoreTokens())
+        {
+            list.add(t.nextToken());
+        }
+        return (String []) list.toArray(new String[list.size()]);
+    }
+
+    /**
+     * Chop i characters off the end of a string.
+     * This method assumes that any EOL characters in String s 
+     * and the platform EOL will be the same.
+     * A 2 character EOL will count as 1 character. 
+     *
+     * @param string String to chop.
+     * @param i Number of characters to chop.
+     * @return String with processed answer.
+     */
+    public static String chop(String s, int i)
+    {
+        return chop(s, i, EOL);
+    }
+
+    /**
+     * Chop i characters off the end of a string. 
+     * A 2 character EOL will count as 1 character. 
+     *
+     * @param string String to chop.
+     * @param i Number of characters to chop.
+     * @param eol A String representing the EOL (end of line).
+     * @return String with processed answer.
+     */
+    public static String chop(String s, int i, String eol)
+    {
+        if ( i == 0 || s == null || eol == null )
+        {
+           return s;
+        }
+
+        int length = s.length();
+
+        /*
+         * if it is a 2 char EOL and the string ends with
+         * it, nip it off.  The EOL in this case is treated like 1 character
+         */
+        if ( eol.length() == 2 && s.endsWith(eol ))
+        {
+            length -= 2;
+            i -= 1;
+        }
+
+        if ( i > 0)
+        {
+            length -= i;
+        }
+
+        if ( length < 0)
+        {
+            length = 0;
+        }
+
+        return s.substring( 0, length);
+    }
+
+    public static StringBuffer stringSubstitution( String argStr,
+                                                   Hashtable vars )
+    {
+        return stringSubstitution( argStr, (Map) vars );
+    }
+
+    /**
+     * Perform a series of substitutions. The substitions
+     * are performed by replacing $variable in the target
+     * string with the value of provided by the key "variable"
+     * in the provided hashtable.
+     *
+     * @param String target string
+     * @param Hashtable name/value pairs used for substitution
+     * @return String target string with replacements.
+     */
+    public static StringBuffer stringSubstitution(String argStr,
+            Map vars)
+    {
+        StringBuffer argBuf = new StringBuffer();
+
+        for (int cIdx = 0 ; cIdx < argStr.length();)
+        {
+            char ch = argStr.charAt(cIdx);
+
+            switch (ch)
+            {
+                case '$':
+                    StringBuffer nameBuf = new StringBuffer();
+                    for (++cIdx ; cIdx < argStr.length(); ++cIdx)
+                    {
+                        ch = argStr.charAt(cIdx);
+                        if (ch == '_' || Character.isLetterOrDigit(ch))
+                            nameBuf.append(ch);
+                        else
+                            break;
+                    }
+
+                    if (nameBuf.length() > 0)
+                    {
+                        String value =
+                                (String) vars.get(nameBuf.toString());
+
+                        if (value != null)
+                        {
+                            argBuf.append(value);
+                        }
+                    }
+                    break;
+
+                default:
+                    argBuf.append(ch);
+                    ++cIdx;
+                    break;
+            }
+        }
+
+        return argBuf;
+    }
+    
+    /**
+     * Read the contents of a file and place them in
+     * a string object.
+     *
+     * @param String path to file.
+     * @return String contents of the file.
+     */
+    public static String fileContentsToString(String file)
+    {
+        String contents = "";
+        
+        File f = new File(file);
+        
+        if (f.exists())
+        {
+            try
+            {
+                FileReader fr = new FileReader(f);
+                char[] template = new char[(int) f.length()];
+                fr.read(template);
+                contents = new String(template);
+            }
+            catch (Exception e)
+            {
+                System.out.println(e);
+                e.printStackTrace();
+            }
+        }
+        
+        return contents;
+    }
+    
+    /**
+     * Remove/collapse multiple newline characters.
+     *
+     * @param String string to collapse newlines in.
+     * @return String
+     */
+    public static String collapseNewlines(String argStr)
+    {
+        char last = argStr.charAt(0);
+        StringBuffer argBuf = new StringBuffer();
+
+        for (int cIdx = 0 ; cIdx < argStr.length(); cIdx++)
+        {
+            char ch = argStr.charAt(cIdx);
+            if (ch != '\n' || last != '\n')
+            {
+                argBuf.append(ch);
+                last = ch;
+            }
+        }
+
+        return argBuf.toString();
+    }
+
+    /**
+     * Remove/collapse multiple spaces.
+     *
+     * @param String string to remove multiple spaces from.
+     * @return String
+     */
+    public static String collapseSpaces(String argStr)
+    {
+        char last = argStr.charAt(0);
+        StringBuffer argBuf = new StringBuffer();
+
+        for (int cIdx = 0 ; cIdx < argStr.length(); cIdx++)
+        {
+            char ch = argStr.charAt(cIdx);
+            if (ch != ' ' || last != ' ')
+            {
+                argBuf.append(ch);
+                last = ch;
+            }
+        }
+
+        return argBuf.toString();
+    }
+
+    /**
+      * Replaces all instances of oldString with newString in line.
+      * Taken from the Jive forum package.
+      *
+      * @param String original string.
+      * @param String string in line to replace.
+      * @param String replace oldString with this.
+      * @return String string with replacements.
+      */
+    public static final String sub(String line, String oldString,
+            String newString)
+    {
+        int i = 0;
+        if ((i = line.indexOf(oldString, i)) >= 0)
+        {
+            char [] line2 = line.toCharArray();
+            char [] newString2 = newString.toCharArray();
+            int oLength = oldString.length();
+            StringBuffer buf = new StringBuffer(line2.length);
+            buf.append(line2, 0, i).append(newString2);
+            i += oLength;
+            int j = i;
+            while ((i = line.indexOf(oldString, i)) > 0)
+            {
+                buf.append(line2, j, i - j).append(newString2);
+                i += oLength;
+                j = i;
+            }
+            buf.append(line2, j, line2.length - j);
+            return buf.toString();
+        }
+        return line;
+    }
+    
+    /**
+     * Returns the output of printStackTrace as a String.
+     *
+     * @param e A Throwable.
+     * @return A String.
+     */
+    public static final String stackTrace(Throwable e)
+    {
+        String foo = null;
+        try
+        {
+            // And show the Error Screen.
+            ByteArrayOutputStream ostr = new ByteArrayOutputStream();
+            e.printStackTrace( new PrintWriter(ostr,true) );
+            foo = ostr.toString();
+        }
+        catch (Exception f)
+        {
+            // Do nothing.
+        }
+        return foo;
+    }
+
+    /**
+     * Return a context-relative path, beginning with a "/", that represents
+     * the canonical version of the specified path after ".." and "." elements
+     * are resolved out.  If the specified path attempts to go outside the
+     * boundaries of the current context (i.e. too many ".." path elements
+     * are present), return <code>null</code> instead.
+     *
+     * @param path Path to be normalized
+     * @return String normalized path
+     */
+    public static final String normalizePath(String path)
+    {
+        // Normalize the slashes and add leading slash if necessary
+        String normalized = path;
+        if (normalized.indexOf('\\') >= 0)
+        {
+            normalized = normalized.replace('\\', '/');
+        }
+
+        if (!normalized.startsWith("/"))
+        {
+            normalized = "/" + normalized;
+        }
+        
+        // Resolve occurrences of "//" in the normalized path
+        while (true)
+        {
+            int index = normalized.indexOf("//");
+            if (index < 0)
+                break;
+            normalized = normalized.substring(0, index) +
+            normalized.substring(index + 1);
+        }
+
+        // Resolve occurrences of "%20" in the normalized path
+        while (true)
+        {
+            int index = normalized.indexOf("%20");
+            if (index < 0)
+                break;
+            normalized = normalized.substring(0, index) + " " +
+            normalized.substring(index + 3);
+        }
+
+        // Resolve occurrences of "/./" in the normalized path
+        while (true)
+        {
+            int index = normalized.indexOf("/./");
+            if (index < 0)
+                break;
+            normalized = normalized.substring(0, index) +
+            normalized.substring(index + 2);
+        }
+
+        // Resolve occurrences of "/../" in the normalized path
+        while (true)
+        {
+            int index = normalized.indexOf("/../");
+            if (index < 0)
+                break;
+            if (index == 0)
+                return (null);  // Trying to go outside our context
+            int index2 = normalized.lastIndexOf('/', index - 1);
+            normalized = normalized.substring(0, index2) +
+            normalized.substring(index + 3);
+        }
+
+        // Return the normalized path that we have completed
+        return (normalized);
+    }
+
+    /**
+     * If state is true then return the trueString, else
+     * return the falseString.
+     *
+     * @param boolean 
+     * @param String trueString
+     * @param String falseString
+     */
+    public String select(boolean state, String trueString, String falseString)
+    {
+        if (state)
+        {
+            return trueString;
+        }            
+        else
+        {
+            return falseString;
+        }            
+    }            
+
+    /**
+     * Check to see if all the string objects passed
+     * in are empty.
+     *
+     * @param list A list of {@link java.lang.String} objects.
+     * @return     Whether all strings are empty.
+     */
+    public boolean allEmpty(List list)
+    {
+        int size = list.size();
+        
+        for (int i = 0; i < size; i++)
+        {
+            if (list.get(i) != null && list.get(i).toString().length() > 0)
+            {
+                return false;
+            }
+        }            
+        return true;
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/StringUtils.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/ClassMap.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/ClassMap.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/ClassMap.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/ClassMap.java Tue May 29 15:35:01 2012
@@ -0,0 +1,522 @@
+package org.apache.velocity.util.introspection;
+
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Map;
+import java.util.List;
+import java.util.Hashtable;
+
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+
+/**
+ * A cache of introspection information for a specific class instance.
+ * Keys {@link java.lang.Method} objects by a concatenation of the
+ * method name and the names of classes that make up the parameters.
+ *
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
+ * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @version $Id: ClassMap.java,v 1.20.8.1 2004/03/03 23:23:08 geirm Exp $
+ */
+public class ClassMap
+{
+    private static final class CacheMiss { }
+    private static final CacheMiss CACHE_MISS = new CacheMiss();
+    private static final Object OBJECT = new Object();
+
+    /** 
+     * Class passed into the constructor used to as
+     * the basis for the Method map.
+     */
+
+    private Class clazz;
+
+    /**
+     * Cache of Methods, or CACHE_MISS, keyed by method
+     * name and actual arguments used to find it.
+     */
+    private Map methodCache = new Hashtable();
+
+    private MethodMap methodMap = new MethodMap();
+
+    /**
+     * Standard constructor
+     */
+    public ClassMap( Class clazz)
+    {
+        this.clazz = clazz;
+        populateMethodCache();
+    }
+
+    private ClassMap()
+    {
+    }
+
+    /**
+     * @return the class object whose methods are cached by this map.
+     */
+     Class getCachedClass()
+     {
+         return clazz;
+     }
+    
+    /**
+     * Find a Method using the methodKey
+     * provided.
+     *
+     * Look in the methodMap for an entry.  If found,
+     * it'll either be a CACHE_MISS, in which case we
+     * simply give up, or it'll be a Method, in which
+     * case, we return it.
+     *
+     * If nothing is found, then we must actually go
+     * and introspect the method from the MethodMap.
+     */
+    public Method findMethod(String name, Object[] params)
+        throws MethodMap.AmbiguousException
+    {
+        String methodKey = makeMethodKey(name, params);
+        Object cacheEntry = methodCache.get( methodKey );
+
+        if (cacheEntry == CACHE_MISS)
+        {
+            return null;
+        }
+
+        if (cacheEntry == null)
+        {
+            try
+            {
+                cacheEntry = methodMap.find( name,
+                                             params );
+            }
+            catch( MethodMap.AmbiguousException ae )
+            {
+                /*
+                 *  that's a miss :)
+                 */
+
+                methodCache.put( methodKey,
+                                 CACHE_MISS );
+
+                throw ae;
+            }
+
+            if ( cacheEntry == null )
+            {
+                methodCache.put( methodKey,
+                                 CACHE_MISS );
+            }
+            else
+            {
+                methodCache.put( methodKey,
+                                 cacheEntry );
+            }
+        }
+
+        // Yes, this might just be null.
+        
+        return (Method) cacheEntry;
+    }
+    
+    /**
+     * Populate the Map of direct hits. These
+     * are taken from all the public methods
+     * that our class provides.
+     */
+    private void populateMethodCache()
+    {
+        StringBuffer methodKey;
+
+        /*
+         *  get all publicly accessible methods
+         */
+
+        Method[] methods = getAccessibleMethods(clazz);
+
+        /*
+         * map and cache them
+         */
+
+        for (int i = 0; i < methods.length; i++)
+        {
+            Method method = methods[i];
+
+            /*
+             *  now get the 'public method', the method declared by a 
+             *  public interface or class. (because the actual implementing
+             *  class may be a facade...
+             */
+
+            Method publicMethod = getPublicMethod( method );
+
+            /*
+             *  it is entirely possible that there is no public method for
+             *  the methods of this class (i.e. in the facade, a method
+             *  that isn't on any of the interfaces or superclass
+             *  in which case, ignore it.  Otherwise, map and cache
+             */
+
+            if ( publicMethod != null)
+            {
+                methodMap.add( publicMethod );
+                methodCache.put(  makeMethodKey( publicMethod), publicMethod);
+            }
+        }            
+    }
+
+    /**
+     * Make a methodKey for the given method using
+     * the concatenation of the name and the
+     * types of the method parameters.
+     */
+    private String makeMethodKey(Method method)
+    {
+        Class[] parameterTypes = method.getParameterTypes();
+        
+        StringBuffer methodKey = new StringBuffer(method.getName());
+        
+        for (int j = 0; j < parameterTypes.length; j++)
+        {
+            /*
+             * If the argument type is primitive then we want
+             * to convert our primitive type signature to the 
+             * corresponding Object type so introspection for
+             * methods with primitive types will work correctly.
+             */
+            if (parameterTypes[j].isPrimitive())
+            {
+                if (parameterTypes[j].equals(Boolean.TYPE))
+                    methodKey.append("java.lang.Boolean");
+                else if (parameterTypes[j].equals(Byte.TYPE))
+                    methodKey.append("java.lang.Byte");
+                else if (parameterTypes[j].equals(Character.TYPE))
+                    methodKey.append("java.lang.Character");
+                else if (parameterTypes[j].equals(Double.TYPE))
+                    methodKey.append("java.lang.Double");
+                else if (parameterTypes[j].equals(Float.TYPE))
+                    methodKey.append("java.lang.Float");
+                else if (parameterTypes[j].equals(Integer.TYPE))
+                    methodKey.append("java.lang.Integer");
+                else if (parameterTypes[j].equals(Long.TYPE))
+                    methodKey.append("java.lang.Long");
+                else if (parameterTypes[j].equals(Short.TYPE))
+                    methodKey.append("java.lang.Short");
+            }                
+            else
+            {
+                methodKey.append(parameterTypes[j].getName());
+            }
+        }            
+        
+        return methodKey.toString();
+    }
+
+    private static String makeMethodKey(String method, Object[] params)
+    {
+        StringBuffer methodKey = new StringBuffer().append(method);
+
+        for (int j = 0; j < params.length; j++)
+        {
+            Object arg = params[j];
+
+            if (arg == null)
+            {
+                arg = OBJECT;
+            }
+
+            methodKey.append(arg.getClass().getName());
+        }
+        
+        return methodKey.toString();
+    }
+
+    /**
+     * Retrieves public methods for a class. In case the class is not
+     * public, retrieves methods with same signature as its public methods
+     * from public superclasses and interfaces (if they exist). Basically
+     * upcasts every method to the nearest acccessible method.
+     */
+    private static Method[] getAccessibleMethods(Class clazz)
+    {
+        Method[] methods = clazz.getMethods();
+        
+        /*
+         *  Short circuit for the (hopefully) majority of cases where the
+         *  clazz is public
+         */
+        
+        if (Modifier.isPublic(clazz.getModifiers()))
+        {
+            return methods;
+        }
+
+        /*
+         *  No luck - the class is not public, so we're going the longer way.
+         */
+
+        MethodInfo[] methodInfos = new MethodInfo[methods.length];
+
+        for(int i = methods.length; i-- > 0; )
+        {
+            methodInfos[i] = new MethodInfo(methods[i]);
+        }
+
+        int upcastCount = getAccessibleMethods(clazz, methodInfos, 0);
+
+        /*
+         *  Reallocate array in case some method had no accessible counterpart.
+         */
+
+        if(upcastCount < methods.length)
+        {
+            methods = new Method[upcastCount];
+        }
+
+        int j = 0;
+        for(int i = 0; i < methodInfos.length; ++i)
+        {
+            MethodInfo methodInfo = methodInfos[i];
+            if(methodInfo.upcast)
+            {
+                methods[j++] = methodInfo.method;
+            }
+        }
+        return methods;
+    }
+
+    /**
+     *  Recursively finds a match for each method, starting with the class, and then
+     *  searching the superclass and interfaces.
+     *
+     *  @param clazz Class to check
+     *  @param methodInfos array of methods we are searching to match
+     *  @param upcastCount current number of methods we have matched
+     *  @return count of matched methods
+     */
+    private static int getAccessibleMethods( Class clazz, MethodInfo[] methodInfos, int upcastCount)
+    {
+        int l = methodInfos.length;
+        
+        /*
+         *  if this class is public, then check each of the currently
+         *  'non-upcasted' methods to see if we have a match
+         */
+
+        if( Modifier.isPublic(clazz.getModifiers()) )
+        {
+            for(int i = 0; i < l && upcastCount < l; ++i)
+            {
+                try
+                {
+                    MethodInfo methodInfo = methodInfos[i];
+
+                    if(!methodInfo.upcast)
+                    {
+                        methodInfo.tryUpcasting(clazz);
+                        upcastCount++;
+                    }
+                }
+                catch(NoSuchMethodException e)
+                {
+                    /*
+                     *  Intentionally ignored - it means
+                     *  it wasn't found in the current class
+                     */
+                }
+            }
+
+            /*
+             *  Short circuit if all methods were upcast
+             */
+
+            if(upcastCount == l)
+            {
+                return upcastCount;
+            }
+        }
+
+        /*
+         *   Examine superclass
+         */
+
+        Class superclazz = clazz.getSuperclass();
+
+        if(superclazz != null)
+        {
+            upcastCount = getAccessibleMethods(superclazz , methodInfos, upcastCount);
+
+            /*
+             *  Short circuit if all methods were upcast
+             */
+
+            if(upcastCount == l)
+            {
+                return upcastCount;
+            }
+        }
+
+        /*
+         *  Examine interfaces. Note we do it even if superclazz == null.
+         *  This is redundant as currently java.lang.Object does not implement
+         *  any interfaces, however nothing guarantees it will not in future.
+         */
+
+        Class[] interfaces = clazz.getInterfaces();
+
+        for(int i = interfaces.length; i-- > 0; )
+        {
+            upcastCount = getAccessibleMethods(interfaces[i], methodInfos, upcastCount);
+
+            /*
+             *  Short circuit if all methods were upcast
+             */
+
+            if(upcastCount == l)
+            {
+                return upcastCount;
+            }
+        }
+
+        return upcastCount;
+    }
+    
+    /**
+     *  For a given method, retrieves its publicly accessible counterpart. 
+     *  This method will look for a method with same name
+     *  and signature declared in a public superclass or implemented interface of this 
+     *  method's declaring class. This counterpart method is publicly callable.
+     *
+     *  @param method a method whose publicly callable counterpart is requested.
+     *  @return the publicly callable counterpart method. Note that if the parameter
+     *  method is itself declared by a public class, this method is an identity
+     *  function.
+     */
+    public static Method getPublicMethod(Method method)
+    {
+        Class clazz = method.getDeclaringClass();
+        
+        /*
+         *   Short circuit for (hopefully the majority of) cases where the declaring
+         *   class is public.
+         */
+
+        if((clazz.getModifiers() & Modifier.PUBLIC) != 0)
+        {
+            return method;
+        }
+
+        return getPublicMethod(clazz, method.getName(), method.getParameterTypes());
+    }
+
+    /**
+     *  Looks up the method with specified name and signature in the first public
+     *  superclass or implemented interface of the class. 
+     * 
+     *  @param class the class whose method is sought
+     *  @param name the name of the method
+     *  @param paramTypes the classes of method parameters
+     */
+    private static Method getPublicMethod(Class clazz, String name, Class[] paramTypes)
+    {
+        /*
+         *  if this class is public, then try to get it
+         */
+
+        if((clazz.getModifiers() & Modifier.PUBLIC) != 0)
+        {
+            try
+            {
+                return clazz.getMethod(name, paramTypes);
+            }
+            catch(NoSuchMethodException e)
+            {
+                /*
+                 *  If the class does not have the method, then neither its
+                 *  superclass nor any of its interfaces has it so quickly return
+                 *  null.
+                 */
+                 return null;
+            }
+        }
+
+        /*
+         *  try the superclass
+         */
+
+ 
+        Class superclazz = clazz.getSuperclass();
+
+        if ( superclazz != null )
+        {
+            Method superclazzMethod = getPublicMethod(superclazz, name, paramTypes);
+            
+            if(superclazzMethod != null)
+            {
+                return superclazzMethod;
+            }
+        }
+
+        /*
+         *  and interfaces
+         */
+
+        Class[] interfaces = clazz.getInterfaces();
+
+        for(int i = 0; i < interfaces.length; ++i)
+        {
+            Method interfaceMethod = getPublicMethod(interfaces[i], name, paramTypes);
+            
+            if(interfaceMethod != null)
+            {
+                return interfaceMethod;
+            }
+        }
+
+        return null;
+    }
+
+    /**
+     *  Used for the iterative discovery process for public methods.
+     */
+    private static final class MethodInfo
+    {
+        Method method;
+        String name;
+        Class[] parameterTypes;
+        boolean upcast;
+        
+        MethodInfo(Method method)
+        {
+            this.method = null;
+            name = method.getName();
+            parameterTypes = method.getParameterTypes();
+            upcast = false;
+        }
+        
+        void tryUpcasting(Class clazz)
+            throws NoSuchMethodException
+        {
+            method = clazz.getMethod(name, parameterTypes);
+            name = null;
+            parameterTypes = null;
+            upcast = true;
+        }
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/ClassMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectionCacheData.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectionCacheData.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectionCacheData.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectionCacheData.java Tue May 29 15:35:01 2012
@@ -0,0 +1,40 @@
+package org.apache.velocity.util.introspection;
+
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ *  Holds information for node-local context data introspection
+ *  information.
+ *
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @version $Id: IntrospectionCacheData.java,v 1.3.14.1 2004/03/03 23:23:08 geirm Exp $
+ */
+public class IntrospectionCacheData
+{
+    /**  
+     *  Object to pair with class - currently either a Method or 
+     *  AbstractExecutor. It can be used in any way the using node
+     *  wishes. 
+     */
+    public Object thingy;
+    
+    /*
+     *  Class of context data object associated with the introspection
+     *  information
+     */
+    public Class  contextData;
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectionCacheData.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Introspector.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Introspector.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Introspector.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Introspector.java Tue May 29 15:35:01 2012
@@ -0,0 +1,136 @@
+package org.apache.velocity.util.introspection;
+
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Map;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import java.lang.reflect.Method;
+
+import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.runtime.RuntimeLogger;
+
+/**
+ * This basic function of this class is to return a Method
+ * object for a particular class given the name of a method
+ * and the parameters to the method in the form of an Object[]
+ *
+ * The first time the Introspector sees a 
+ * class it creates a class method map for the
+ * class in question. Basically the class method map
+ * is a Hastable where Method objects are keyed by a
+ * concatenation of the method name and the names of
+ * classes that make up the parameters.
+ *
+ * For example, a method with the following signature:
+ *
+ * public void method(String a, StringBuffer b)
+ *
+ * would be mapped by the key:
+ *
+ * "method" + "java.lang.String" + "java.lang.StringBuffer"
+ *
+ * This mapping is performed for all the methods in a class
+ * and stored for 
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
+ * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
+ * @author <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
+ * @version $Id: Introspector.java,v 1.21.4.1 2004/03/03 23:23:08 geirm Exp $
+ */
+public class Introspector extends IntrospectorBase
+{
+    /**
+     *  define a public string so that it can be looked for
+     *  if interested
+     */
+     
+    public final static String CACHEDUMP_MSG = 
+        "Introspector : detected classloader change. Dumping cache.";
+
+    /**
+     *  our engine runtime services
+     */
+    private RuntimeLogger rlog = null;
+
+    /**
+     *  Recieves our RuntimeServices object
+     */
+    public Introspector(RuntimeLogger logger)
+    {
+        this.rlog = logger;
+    }
+   
+    /**
+     * Gets the method defined by <code>name</code> and
+     * <code>params</code> for the Class <code>c</code>.
+     *
+     * @param c Class in which the method search is taking place
+     * @param name Name of the method being searched for
+     * @param params An array of Objects (not Classes) that describe the
+     *               the parameters
+     *
+     * @return The desired Method object.
+     */
+    public Method getMethod(Class c, String name, Object[] params)
+        throws Exception
+    {
+        /*
+         *  just delegate to the base class
+         */
+
+        try
+        {
+            return super.getMethod( c, name, params );
+        }
+        catch( MethodMap.AmbiguousException ae )
+        {
+            /*
+             *  whoops.  Ambiguous.  Make a nice log message and return null...
+             */
+
+            String msg = "Introspection Error : Ambiguous method invocation "
+                + name + "( ";
+
+            for (int i = 0; i < params.length; i++)
+            {
+                if ( i > 0)
+                    msg = msg + ", ";
+                
+                msg = msg + params[i].getClass().getName();
+            }
+            
+            msg = msg + ") for class " + c;
+            
+            rlog.error( msg );
+        }
+
+        return null;
+    }
+
+    /**
+     * Clears the classmap and classname
+     * caches, and logs that we did so
+     */
+    protected void clearCache()
+    {
+        super.clearCache();
+        rlog.info( CACHEDUMP_MSG );
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Introspector.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectorBase.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectorBase.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectorBase.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectorBase.java Tue May 29 15:35:01 2012
@@ -0,0 +1,152 @@
+package org.apache.velocity.util.introspection;
+
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Map;
+import java.util.Set;
+import java.util.HashMap;
+import java.util.HashSet;
+
+import java.lang.reflect.Method;
+
+/**
+ * This basic function of this class is to return a Method
+ * object for a particular class given the name of a method
+ * and the parameters to the method in the form of an Object[]
+ *
+ * The first time the Introspector sees a 
+ * class it creates a class method map for the
+ * class in question. Basically the class method map
+ * is a Hastable where Method objects are keyed by a
+ * concatenation of the method name and the names of
+ * classes that make up the parameters.
+ *
+ * For example, a method with the following signature:
+ *
+ * public void method(String a, StringBuffer b)
+ *
+ * would be mapped by the key:
+ *
+ * "method" + "java.lang.String" + "java.lang.StringBuffer"
+ *
+ * This mapping is performed for all the methods in a class
+ * and stored for 
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
+ * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
+ * @author <a href="mailto:paulo.gaspar@krankikom.de">Paulo Gaspar</a>
+ * @version $Id: IntrospectorBase.java,v 1.2.8.1 2004/03/03 23:23:08 geirm Exp $
+ */
+public class IntrospectorBase
+{   
+    /**
+     * Holds the method maps for the classes we know about, keyed by
+     * Class object.
+     */ 
+    protected  Map classMethodMaps = new HashMap();
+    
+    /**
+     * Holds the qualified class names for the classes
+     * we hold in the classMethodMaps hash
+     */
+    protected Set cachedClassNames = new HashSet();
+   
+    /**
+     * Gets the method defined by <code>name</code> and
+     * <code>params</code> for the Class <code>c</code>.
+     *
+     * @param c Class in which the method search is taking place
+     * @param name Name of the method being searched for
+     * @param params An array of Objects (not Classes) that describe the
+     *               the parameters
+     *
+     * @return The desired Method object.
+     */
+    public Method getMethod(Class c, String name, Object[] params)
+        throws Exception
+    {
+        if (c == null)
+        {
+            throw new Exception ( 
+                "Introspector.getMethod(): Class method key was null: " + name );
+        }                
+
+        ClassMap classMap = null;
+        
+        synchronized(classMethodMaps)
+        {
+            classMap = (ClassMap)classMethodMaps.get(c);
+          
+            /*
+             *  if we don't have this, check to see if we have it
+             *  by name.  if so, then we have a classloader change
+             *  so dump our caches.
+             */
+             
+            if (classMap == null)
+            {                
+                if ( cachedClassNames.contains( c.getName() ))
+                {
+                    /*
+                     * we have a map for a class with same name, but not
+                     * this class we are looking at.  This implies a 
+                     * classloader change, so dump
+                     */
+                    clearCache();                    
+                }
+                 
+                classMap = createClassMap(c);
+            }
+        }
+        
+        return classMap.findMethod(name, params);
+    }
+
+    /**
+     * Creates a class map for specific class and registers it in the
+     * cache.  Also adds the qualified name to the name->class map
+     * for later Classloader change detection.
+     */
+    protected ClassMap createClassMap(Class c)
+    {        
+        ClassMap classMap = new ClassMap( c );        
+        classMethodMaps.put(c, classMap);
+        cachedClassNames.add( c.getName() );
+
+        return classMap;
+    }
+
+    /**
+     * Clears the classmap and classname
+     * caches
+     */
+    protected void clearCache()
+    {
+        /*
+         *  since we are synchronizing on this
+         *  object, we have to clear it rather than
+         *  just dump it.
+         */            
+        classMethodMaps.clear();
+        
+        /*
+         * for speed, we can just make a new one
+         * and let the old one be GC'd
+         */
+        cachedClassNames = new HashSet();
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/IntrospectorBase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/MethodMap.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/MethodMap.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/MethodMap.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/MethodMap.java Tue May 29 15:35:01 2012
@@ -0,0 +1,467 @@
+package org.apache.velocity.util.introspection;
+
+/*
+ * Copyright 2001,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Hashtable;
+
+import java.lang.reflect.Method;
+
+/**
+ *
+ * @author <a href="mailto:jvanzyl@apache.org">Jason van Zyl</a>
+ * @author <a href="mailto:bob@werken.com">Bob McWhirter</a>
+ * @author <a href="mailto:Christoph.Reck@dlr.de">Christoph Reck</a>
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @author <a href="mailto:szegedia@freemail.hu">Attila Szegedi</a>
+ * @version $Id: MethodMap.java,v 1.15.4.1 2004/03/03 23:23:08 geirm Exp $
+ */
+public class MethodMap
+{
+    private static final int MORE_SPECIFIC = 0;
+    private static final int LESS_SPECIFIC = 1;
+    private static final int INCOMPARABLE = 2;
+
+    /**
+     * Keep track of all methods with the same name.
+     */
+    Map methodByNameMap = new Hashtable();
+
+    /**
+     * Add a method to a list of methods by name.
+     * For a particular class we are keeping track
+     * of all the methods with the same name.
+     */
+    public void add(Method method)
+    {
+        String methodName = method.getName();
+
+        List l = get( methodName );
+
+        if ( l == null)
+        {
+            l = new ArrayList();
+            methodByNameMap.put(methodName, l);
+        }
+
+        l.add(method);
+
+        return;
+    }
+
+    /**
+     * Return a list of methods with the same name.
+     *
+     * @param String key
+     * @return List list of methods
+     */
+    public List get(String key)
+    {
+        return (List) methodByNameMap.get(key);
+    }
+
+    /**
+     *  <p>
+     *  Find a method.  Attempts to find the
+     *  most specific applicable method using the
+     *  algorithm described in the JLS section
+     *  15.12.2 (with the exception that it can't
+     *  distinguish a primitive type argument from
+     *  an object type argument, since in reflection
+     *  primitive type arguments are represented by
+     *  their object counterparts, so for an argument of
+     *  type (say) java.lang.Integer, it will not be able
+     *  to decide between a method that takes int and a
+     *  method that takes java.lang.Integer as a parameter.
+     *  </p>
+     *
+     *  <p>
+     *  This turns out to be a relatively rare case
+     *  where this is needed - however, functionality
+     *  like this is needed.
+     *  </p>
+     *
+     *  @param methodName name of method
+     *  @param args the actual arguments with which the method is called
+     *  @return the most specific applicable method, or null if no
+     *  method is applicable.
+     *  @throws AmbiguousException if there is more than one maximally
+     *  specific applicable method
+     */
+    public Method find(String methodName, Object[] args)
+        throws AmbiguousException
+    {
+        List methodList = get(methodName);
+
+        if (methodList == null)
+        {
+            return null;
+        }
+
+        int l = args.length;
+        Class[] classes = new Class[l];
+
+        for(int i = 0; i < l; ++i)
+        {
+            Object arg = args[i];
+
+            /*
+             * if we are careful down below, a null argument goes in there
+             * so we can know that the null was passed to the method
+             */
+            classes[i] =
+                    arg == null ? null : arg.getClass();
+        }
+
+        return getMostSpecific(methodList, classes);
+    }
+
+    /**
+     *  simple distinguishable exception, used when
+     *  we run across ambiguous overloading
+     */
+    public static class AmbiguousException extends Exception
+    {
+    }
+
+
+    private static Method getMostSpecific(List methods, Class[] classes)
+        throws AmbiguousException
+    {
+        LinkedList applicables = getApplicables(methods, classes);
+
+        if(applicables.isEmpty())
+        {
+            return null;
+        }
+
+        if(applicables.size() == 1)
+        {
+            return (Method)applicables.getFirst();
+        }
+
+        /*
+         * This list will contain the maximally specific methods. Hopefully at
+         * the end of the below loop, the list will contain exactly one method,
+         * (the most specific method) otherwise we have ambiguity.
+         */
+
+        LinkedList maximals = new LinkedList();
+
+        for (Iterator applicable = applicables.iterator();
+             applicable.hasNext();)
+        {
+            Method app = (Method) applicable.next();
+            Class[] appArgs = app.getParameterTypes();
+            boolean lessSpecific = false;
+
+            for (Iterator maximal = maximals.iterator();
+                 !lessSpecific && maximal.hasNext();)
+            {
+                Method max = (Method) maximal.next();
+
+                switch(moreSpecific(appArgs, max.getParameterTypes()))
+                {
+                    case MORE_SPECIFIC:
+                    {
+                        /*
+                         * This method is more specific than the previously
+                         * known maximally specific, so remove the old maximum.
+                         */
+
+                        maximal.remove();
+                        break;
+                    }
+
+                    case LESS_SPECIFIC:
+                    {
+                        /*
+                         * This method is less specific than some of the
+                         * currently known maximally specific methods, so we
+                         * won't add it into the set of maximally specific
+                         * methods
+                         */
+
+                        lessSpecific = true;
+                        break;
+                    }
+                }
+            }
+
+            if(!lessSpecific)
+            {
+                maximals.addLast(app);
+            }
+        }
+
+        if(maximals.size() > 1)
+        {
+            // We have more than one maximally specific method
+            throw new AmbiguousException();
+        }
+
+        return (Method)maximals.getFirst();
+    }
+
+    /**
+     * Determines which method signature (represented by a class array) is more
+     * specific. This defines a partial ordering on the method signatures.
+     * @param c1 first signature to compare
+     * @param c2 second signature to compare
+     * @return MORE_SPECIFIC if c1 is more specific than c2, LESS_SPECIFIC if
+     * c1 is less specific than c2, INCOMPARABLE if they are incomparable.
+     */
+    private static int moreSpecific(Class[] c1, Class[] c2)
+    {
+        boolean c1MoreSpecific = false;
+        boolean c2MoreSpecific = false;
+
+        for(int i = 0; i < c1.length; ++i)
+        {
+            if(c1[i] != c2[i])
+            {
+                c1MoreSpecific =
+                    c1MoreSpecific ||
+                    isStrictMethodInvocationConvertible(c2[i], c1[i]);
+                c2MoreSpecific =
+                    c2MoreSpecific ||
+                    isStrictMethodInvocationConvertible(c1[i], c2[i]);
+            }
+        }
+
+        if(c1MoreSpecific)
+        {
+            if(c2MoreSpecific)
+            {
+                /*
+                 *  Incomparable due to cross-assignable arguments (i.e.
+                 * foo(String, Object) vs. foo(Object, String))
+                 */
+
+                return INCOMPARABLE;
+            }
+
+            return MORE_SPECIFIC;
+        }
+
+        if(c2MoreSpecific)
+        {
+            return LESS_SPECIFIC;
+        }
+
+        /*
+         * Incomparable due to non-related arguments (i.e.
+         * foo(Runnable) vs. foo(Serializable))
+         */
+
+        return INCOMPARABLE;
+    }
+
+    /**
+     * Returns all methods that are applicable to actual argument types.
+     * @param methods list of all candidate methods
+     * @param classes the actual types of the arguments
+     * @return a list that contains only applicable methods (number of
+     * formal and actual arguments matches, and argument types are assignable
+     * to formal types through a method invocation conversion).
+     */
+    private static LinkedList getApplicables(List methods, Class[] classes)
+    {
+        LinkedList list = new LinkedList();
+
+        for (Iterator imethod = methods.iterator(); imethod.hasNext();)
+        {
+            Method method = (Method) imethod.next();
+
+            if(isApplicable(method, classes))
+            {
+                list.add(method);
+            }
+
+        }
+        return list;
+    }
+
+    /**
+     * Returns true if the supplied method is applicable to actual
+     * argument types.
+     */
+    private static boolean isApplicable(Method method, Class[] classes)
+    {
+        Class[] methodArgs = method.getParameterTypes();
+
+        if(methodArgs.length != classes.length)
+        {
+            return false;
+        }
+
+        for(int i = 0; i < classes.length; ++i)
+        {
+            if(!isMethodInvocationConvertible(methodArgs[i], classes[i]))
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Determines whether a type represented by a class object is
+     * convertible to another type represented by a class object using a
+     * method invocation conversion, treating object types of primitive
+     * types as if they were primitive types (that is, a Boolean actual
+     * parameter type matches boolean primitive formal type). This behavior
+     * is because this method is used to determine applicable methods for
+     * an actual parameter list, and primitive types are represented by
+     * their object duals in reflective method calls.
+     *
+     * @param formal the formal parameter type to which the actual
+     * parameter type should be convertible
+     * @param actual the actual parameter type.
+     * @return true if either formal type is assignable from actual type,
+     * or formal is a primitive type and actual is its corresponding object
+     * type or an object type of a primitive type that can be converted to
+     * the formal type.
+     */
+    private static boolean isMethodInvocationConvertible(Class formal,
+                                                         Class actual)
+    {
+        /*
+         * if it's a null, it means the arg was null
+         */
+        if (actual == null && !formal.isPrimitive())
+        {
+            return true;
+        }
+
+        /*
+         *  Check for identity or widening reference conversion
+         */
+
+        if (actual != null && formal.isAssignableFrom(actual))
+        {
+            return true;
+        }
+
+        /*
+         * Check for boxing with widening primitive conversion. Note that
+         * actual parameters are never primitives.
+         */
+
+        if (formal.isPrimitive())
+        {
+            if(formal == Boolean.TYPE && actual == Boolean.class)
+                return true;
+            if(formal == Character.TYPE && actual == Character.class)
+                return true;
+            if(formal == Byte.TYPE && actual == Byte.class)
+                return true;
+            if(formal == Short.TYPE &&
+               (actual == Short.class || actual == Byte.class))
+                return true;
+            if(formal == Integer.TYPE &&
+               (actual == Integer.class || actual == Short.class ||
+                actual == Byte.class))
+                return true;
+            if(formal == Long.TYPE &&
+               (actual == Long.class || actual == Integer.class ||
+                actual == Short.class || actual == Byte.class))
+                return true;
+            if(formal == Float.TYPE &&
+               (actual == Float.class || actual == Long.class ||
+                actual == Integer.class || actual == Short.class ||
+                actual == Byte.class))
+                return true;
+            if(formal == Double.TYPE &&
+               (actual == Double.class || actual == Float.class ||
+                actual == Long.class || actual == Integer.class ||
+                actual == Short.class || actual == Byte.class))
+                return true;
+        }
+
+        return false;
+    }
+
+    /**
+     * Determines whether a type represented by a class object is
+     * convertible to another type represented by a class object using a
+     * method invocation conversion, without matching object and primitive
+     * types. This method is used to determine the more specific type when
+     * comparing signatures of methods.
+     *
+     * @param formal the formal parameter type to which the actual
+     * parameter type should be convertible
+     * @param actual the actual parameter type.
+     * @return true if either formal type is assignable from actual type,
+     * or formal and actual are both primitive types and actual can be
+     * subject to widening conversion to formal.
+     */
+    private static boolean isStrictMethodInvocationConvertible(Class formal,
+                                                               Class actual)
+    {
+        /*
+         * we shouldn't get a null into, but if so
+         */
+        if (actual == null && !formal.isPrimitive())
+        {
+            return true;
+        }
+
+        /*
+         *  Check for identity or widening reference conversion
+         */
+
+        if(formal.isAssignableFrom(actual))
+        {
+            return true;
+        }
+
+        /*
+         *  Check for widening primitive conversion.
+         */
+
+        if(formal.isPrimitive())
+        {
+            if(formal == Short.TYPE && (actual == Byte.TYPE))
+                return true;
+            if(formal == Integer.TYPE &&
+               (actual == Short.TYPE || actual == Byte.TYPE))
+                return true;
+            if(formal == Long.TYPE &&
+               (actual == Integer.TYPE || actual == Short.TYPE ||
+                actual == Byte.TYPE))
+                return true;
+            if(formal == Float.TYPE &&
+               (actual == Long.TYPE || actual == Integer.TYPE ||
+                actual == Short.TYPE || actual == Byte.TYPE))
+                return true;
+            if(formal == Double.TYPE &&
+               (actual == Float.TYPE || actual == Long.TYPE ||
+                actual == Integer.TYPE || actual == Short.TYPE ||
+                actual == Byte.TYPE))
+                return true;
+        }
+        return false;
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/MethodMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Uberspect.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Uberspect.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Uberspect.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Uberspect.java Tue May 29 15:35:01 2012
@@ -0,0 +1,57 @@
+package org.apache.velocity.util.introspection;
+
+/*
+ * Copyright 2002,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.velocity.runtime.RuntimeLogger;
+
+import java.util.Iterator;
+import java.lang.reflect.Method;
+
+/**
+ * 'Federated' introspection/reflection interface to allow the introspection
+ *  behavior in Velocity to be customized.
+ *
+ * @author <a href="mailto:geirm@apache.org">Geir Magusson Jr.</a>
+ * @version $Id: Uberspect.java,v 1.1.4.1 2004/03/03 23:23:08 geirm Exp $
+ */
+public interface Uberspect
+{
+    /**
+     *  Initializer - will be called before use
+     */
+    public void init() throws Exception;
+
+    /**
+     *  To support iteratives - #foreach()
+     */
+    public Iterator getIterator(Object obj, Info info) throws Exception;
+
+    /**
+     *  Returns a general method, corresponding to $foo.bar( $woogie )
+     */
+    public VelMethod getMethod(Object obj, String method, Object[] args, Info info) throws Exception;
+
+    /**
+     * Property getter - returns VelPropertyGet appropos for #set($foo = $bar.woogie)
+     */
+    public VelPropertyGet getPropertyGet(Object obj, String identifier, Info info) throws Exception;
+
+    /**
+     * Property setter - returns VelPropertySet appropos for #set($foo.bar = "geir")
+     */
+    public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info info) throws Exception;
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/Uberspect.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/UberspectImpl.java
URL: http://svn.apache.org/viewvc/incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/UberspectImpl.java?rev=1343781&view=auto
==============================================================================
--- incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/UberspectImpl.java (added)
+++ incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/UberspectImpl.java Tue May 29 15:35:01 2012
@@ -0,0 +1,366 @@
+package org.apache.velocity.util.introspection;
+
+/*
+ * Copyright 2002,2004 The Apache Software Foundation.
+ * 
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import org.apache.velocity.util.ArrayIterator;
+import org.apache.velocity.util.EnumerationIterator;
+import org.apache.velocity.runtime.RuntimeServices;
+import org.apache.velocity.runtime.RuntimeLogger;
+import org.apache.velocity.runtime.parser.node.AbstractExecutor;
+import org.apache.velocity.runtime.parser.node.PropertyExecutor;
+import org.apache.velocity.runtime.parser.node.GetExecutor;
+import org.apache.velocity.runtime.parser.node.BooleanPropertyExecutor;
+
+import java.lang.reflect.Method;
+import java.util.Iterator;
+import java.util.Collection;
+import java.util.Map;
+import java.util.Enumeration;
+import java.util.ArrayList;
+
+/**
+ *  Implementation of Uberspect to provide the default introspective
+ *  functionality of Velocity
+ *
+ * @author <a href="mailto:geirm@optonline.net">Geir Magnusson Jr.</a>
+ * @version $Id: UberspectImpl.java,v 1.2.4.1 2004/03/03 23:23:08 geirm Exp $
+ */
+public class UberspectImpl implements Uberspect, UberspectLoggable
+{
+    /**
+     *  Our runtime logger.
+     */
+    private RuntimeLogger rlog;
+
+    /**
+     *  the default Velocity introspector
+     */
+    private static Introspector introspector;
+
+    /**
+     *  init - does nothing - we need to have setRuntimeLogger
+     *  called before getting our introspector, as the default
+     *  vel introspector depends upon it.
+     */
+    public void init()
+        throws Exception
+    {
+    }
+
+    /**
+     *  Sets the runtime logger - this must be called before anything
+     *  else besides init() as to get the logger.  Makes the pull
+     *  model appealing...
+     */
+    public void setRuntimeLogger(RuntimeLogger runtimeLogger)
+    {
+        rlog = runtimeLogger;
+        introspector = new Introspector(rlog);
+    }
+
+    /**
+     *  To support iteratives - #foreach()
+     */
+    public Iterator getIterator(Object obj, Info i)
+            throws Exception
+    {
+        if (obj.getClass().isArray())
+        {
+            return new ArrayIterator(obj);
+        }
+        else if (obj instanceof Collection)
+        {
+            return ((Collection) obj).iterator();
+        }
+        else if (obj instanceof Map)
+        {
+            return ((Map) obj).values().iterator();
+        }
+        else if (obj instanceof Iterator)
+        {
+            rlog.warn ("Warning! The iterative "
+                          + " is an Iterator in the #foreach() loop at ["
+                          + i.getLine() + "," + i.getColumn() + "]"
+                          + " in template " + i.getTemplateName()
+                          + ". Because it's not resetable,"
+                          + " if used in more than once, this may lead to"
+                          + " unexpected results.");
+
+            return ((Iterator) obj);
+        }
+        else if (obj instanceof Enumeration)
+        {
+            rlog.warn ("Warning! The iterative "
+                          + " is an Enumeration in the #foreach() loop at ["
+                          + i.getLine() + "," + i.getColumn() + "]"
+                          + " in template " + i.getTemplateName()
+                          + ". Because it's not resetable,"
+                          + " if used in more than once, this may lead to"
+                          + " unexpected results.");
+
+            return new EnumerationIterator((Enumeration) obj);
+        }
+
+        /*  we have no clue what this is  */
+        rlog.warn ("Could not determine type of iterator in "
+                      +  "#foreach loop "
+                      + " at [" + i.getLine() + "," + i.getColumn() + "]"
+                      + " in template " + i.getTemplateName() );
+
+        return null;
+    }
+
+    /**
+     *  Method
+     */
+    public VelMethod getMethod(Object obj, String methodName, Object[] args, Info i)
+            throws Exception
+    {
+        if (obj == null)
+            return null;
+
+        Method m = introspector.getMethod(obj.getClass(), methodName, args);
+
+        return (m != null) ? new VelMethodImpl(m) : null;
+    }
+
+    /**
+     * Property  getter
+     */
+    public VelPropertyGet getPropertyGet(Object obj, String identifier, Info i)
+            throws Exception
+    {
+        AbstractExecutor executor;
+
+        Class claz = obj.getClass();
+
+        /*
+         *  first try for a getFoo() type of property
+         *  (also getfoo() )
+         */
+
+        executor = new PropertyExecutor(rlog,introspector, claz, identifier);
+
+        /*
+         *  if that didn't work, look for get("foo")
+         */
+
+        if (executor.isAlive() == false)
+        {
+            executor = new GetExecutor(rlog, introspector, claz, identifier);
+        }
+
+        /*
+         *  finally, look for boolean isFoo()
+         */
+
+        if( executor.isAlive() == false)
+        {
+            executor = new BooleanPropertyExecutor(rlog, introspector, claz, identifier);
+        }
+
+        return (executor != null) ? new VelGetterImpl(executor) : null;
+    }
+
+    /**
+     * Property setter
+     */
+    public VelPropertySet getPropertySet(Object obj, String identifier, Object arg, Info i)
+            throws Exception
+    {
+        Class claz = obj.getClass();
+
+        VelPropertySet vs = null;
+        VelMethod vm = null;
+        try
+        {
+            /*
+             *  first, we introspect for the set<identifier> setter method
+             */
+
+            Object[] params = {arg};
+
+            try
+            {
+                vm = getMethod(obj, "set" + identifier, params, i);
+
+                if (vm == null)
+                {
+                   throw new NoSuchMethodException();
+                }
+            }
+            catch(NoSuchMethodException nsme2)
+            {
+                StringBuffer sb = new StringBuffer("set");
+                sb.append(identifier);
+
+                if (Character.isLowerCase( sb.charAt(3)))
+                {
+                    sb.setCharAt(3, Character.toUpperCase(sb.charAt(3)));
+                }
+                else
+                {
+                    sb.setCharAt(3, Character.toLowerCase(sb.charAt(3)));
+                }
+
+                vm = getMethod(obj, sb.toString(), params, i);
+
+                if (vm == null)
+                {
+                   throw new NoSuchMethodException();
+                }
+            }
+        }
+        catch (NoSuchMethodException nsme)
+        {
+            /*
+             *  right now, we only support the Map interface
+             */
+
+            if (Map.class.isAssignableFrom(claz))
+            {
+                Object[] params = {new Object(), new Object()};
+
+                vm = getMethod(obj, "put", params, i);
+
+                if (vm!=null)
+                    return new VelSetterImpl(vm, identifier);
+            }
+       }
+
+       return (vm!=null) ?  new VelSetterImpl(vm) : null;
+    }
+
+    /**
+     *  Implementation of VelMethod
+     */
+    public class VelMethodImpl implements VelMethod
+    {
+        Method method = null;
+
+        public VelMethodImpl(Method m)
+        {
+            method = m;
+        }
+
+        private VelMethodImpl()
+        {
+        }
+
+        public Object invoke(Object o, Object[] params)
+            throws Exception
+        {
+            return method.invoke(o, params);
+        }
+
+        public boolean isCacheable()
+        {
+            return true;
+        }
+
+        public String getMethodName()
+        {
+            return method.getName();
+        }
+
+        public Class getReturnType()
+        {
+            return method.getReturnType();
+        }
+    }
+
+    public class VelGetterImpl implements VelPropertyGet
+    {
+        AbstractExecutor ae = null;
+
+        public VelGetterImpl(AbstractExecutor exec)
+        {
+            ae = exec;
+        }
+
+        private VelGetterImpl()
+        {
+        }
+
+        public Object invoke(Object o)
+            throws Exception
+        {
+            return ae.execute(o);
+        }
+
+        public boolean isCacheable()
+        {
+            return true;
+        }
+
+        public String getMethodName()
+        {
+            return ae.getMethod().getName();
+        }
+
+    }
+
+    public class VelSetterImpl implements VelPropertySet
+    {
+        VelMethod vm = null;
+        String putKey = null;
+
+        public VelSetterImpl(VelMethod velmethod)
+        {
+            this.vm = velmethod;
+        }
+
+        public VelSetterImpl(VelMethod velmethod, String key)
+        {
+            this.vm = velmethod;
+            putKey = key;
+        }
+
+        private VelSetterImpl()
+        {
+        }
+
+        public Object invoke(Object o, Object value)
+            throws Exception
+        {
+            ArrayList al = new ArrayList();
+
+            if (putKey != null)
+            {
+                al.add(putKey);
+                al.add(value);
+            }
+            else
+            {
+                al.add(value);
+            }
+
+            return vm.invoke(o,al.toArray());
+        }
+
+        public boolean isCacheable()
+        {
+            return true;
+        }
+
+        public String getMethodName()
+        {
+            return vm.getMethodName();
+        }
+
+    }
+}

Propchange: incubator/flex/trunk/modules/thirdparty/velocity/src/java/org/apache/velocity/util/introspection/UberspectImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native