You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by dj...@apache.org on 2009/10/05 20:54:56 UTC

svn commit: r821961 [23/30] - in /geronimo/sandbox/djencks/osgi/framework: ./ buildsupport/ buildsupport/car-maven-plugin/ buildsupport/car-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/car/ buildsupport/geronimo-maven-plugin/src/main/jav...

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/DAG.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/DAG.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/DAG.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/DAG.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,266 @@
+package org.apache.geronimo.system.plugin.plexus.util.dag;
+
+/*
+ * Copyright The Codehaus 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.Serializable;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * DAG = Directed Acyclic Graph
+ *
+ * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
+ * @version $Id: DAG.java 8010 2009-01-07 12:59:50Z vsiveton $
+ * @todo this class should be reanmed from DAG to Dag
+ */
+public class DAG implements Cloneable, Serializable
+{
+    //------------------------------------------------------------
+    //Fields
+    //------------------------------------------------------------
+    /**
+     * Nodes will be kept in two data strucures at the same time
+     * for faster processing
+     */
+    /**
+     * Maps vertex's label to vertex
+     */
+    private Map vertexMap = new HashMap();
+
+    /**
+     * Conatin list of all verticies
+     */
+    private List vertexList = new ArrayList();
+
+    // ------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------
+
+    /**
+     *
+     */
+    public DAG()
+    {
+        super();
+    }
+
+    // ------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------
+
+    /**
+     * @return
+     */
+    public List getVerticies()
+    {
+        return vertexList;
+    }
+
+
+    public Set getLabels()
+    {
+        final Set retValue = vertexMap.keySet();
+
+        return retValue;
+    }
+
+    // ------------------------------------------------------------
+    // Implementation
+    // ------------------------------------------------------------
+
+    /**
+     * Adds vertex to DAG. If vertex of given label alredy exist in DAG
+     * no vertex is added
+     *
+     * @param label The lable of the Vertex
+     * @return New vertex if vertext of given label was not presenst in the DAG
+     *         or exising vertex if vertex of given labale was alredy added to DAG
+     */
+    public Vertex addVertex( final String label )
+    {
+        Vertex retValue = null;
+
+        // check if vertex is alredy in DAG
+        if ( vertexMap.containsKey( label ) )
+        {
+            retValue = ( Vertex ) vertexMap.get( label );
+        }
+        else
+        {
+            retValue = new Vertex( label );
+
+            vertexMap.put( label, retValue );
+
+            vertexList.add( retValue );
+        }
+
+        return retValue;
+    }
+
+    public void addEdge( final String from, final String to ) throws CycleDetectedException
+    {
+        final Vertex v1 = addVertex( from );
+
+        final Vertex v2 = addVertex( to );
+
+        addEdge( v1, v2 );
+    }
+
+    public void addEdge( final Vertex from, final Vertex to ) throws CycleDetectedException
+    {
+
+        from.addEdgeTo( to );
+
+        to.addEdgeFrom( from );
+
+        final List cycle = CycleDetector.introducesCycle( to );
+
+        if ( cycle != null )
+        {
+            // remove edge which introduced cycle
+
+            removeEdge( from, to );
+
+            final String msg = "Edge between '" + from + "' and '" + to + "' introduces to cycle in the graph";
+
+            throw new CycleDetectedException( msg, cycle );
+        }
+    }
+
+
+    public void removeEdge( final String from, final String to )
+    {
+        final Vertex v1 = addVertex( from );
+
+        final Vertex v2 = addVertex( to );
+
+        removeEdge( v1, v2 );
+    }
+
+    public void removeEdge( final Vertex from, final Vertex to )
+    {
+        from.removeEdgeTo( to );
+
+        to.removeEdgeFrom( from );
+    }
+
+
+    public Vertex getVertex( final String label )
+    {
+        final Vertex retValue = ( Vertex ) vertexMap.get( label );
+
+        return retValue;
+    }
+
+    public boolean hasEdge( final String label1, final String label2 )
+    {
+        final Vertex v1 = getVertex( label1 );
+
+        final Vertex v2 = getVertex( label2 );
+
+        final boolean retValue = v1.getChildren().contains( v2 );
+
+        return retValue;
+
+    }
+
+    /**
+     * @param label
+     * @return
+     */
+    public List getChildLabels( final String label )
+    {
+        final Vertex vertex = getVertex( label );
+
+        return vertex.getChildLabels();
+    }
+
+    /**
+     * @param label
+     * @return
+     */
+    public List getParentLabels( final String label )
+    {
+        final Vertex vertex = getVertex( label );
+
+        return vertex.getParentLabels();
+    }
+
+
+    /**
+     * @see java.lang.Object#clone()
+     */
+    public Object clone() throws CloneNotSupportedException
+    {
+        // this is what's failing..
+        final Object retValue = super.clone();
+
+        return retValue;
+    }
+
+
+    /**
+     * Indicates if there is at least one edge leading to or from vertex of given label
+     *
+     * @return <code>true</true> if this vertex is connected with other vertex,<code>false</code> otherwise
+     */
+    public boolean isConnected( final String label )
+    {
+        final Vertex vertex = getVertex( label );
+
+        final boolean retValue = vertex.isConnected();
+
+        return retValue;
+
+    }
+
+
+    /**
+     * Return the list of labels of successor in order decided by topological sort
+     *
+     * @param label The label of the vertex whose predessors are serched
+     *
+     * @return The list of labels. Returned list contains also
+     *         the label passed as parameter to this method. This label should
+     *         always be the last item in the list.
+     */
+    public List getSuccessorLabels( final String label )
+    {
+        final Vertex vertex = getVertex( label );
+
+        final List retValue;
+
+        //optimization.
+        if ( vertex.isLeaf() )
+        {
+            retValue = new ArrayList( 1 );
+
+            retValue.add( label );
+        }
+        else
+        {
+            retValue = TopologicalSorter.sort( vertex );
+        }
+
+        return retValue;
+    }
+
+
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/DAG.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/DAG.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/DAG.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/TopologicalSorter.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/TopologicalSorter.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/TopologicalSorter.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/TopologicalSorter.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,122 @@
+package org.apache.geronimo.system.plugin.plexus.util.dag;
+
+/*
+ * Copyright The Codehaus 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.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
+ * @version $Id: TopologicalSorter.java 8010 2009-01-07 12:59:50Z vsiveton $
+ */
+public class TopologicalSorter
+{
+
+    private final static Integer NOT_VISTITED = new Integer( 0 );
+
+    private final static Integer VISITING = new Integer( 1 );
+
+    private final static Integer VISITED = new Integer( 2 );
+
+    /**
+     * @param graph
+     * @return List of String (vertex labels)
+     */
+
+    public static List sort( final DAG graph )
+    {
+        return dfs( graph );
+    }
+
+    public static List sort( final Vertex vertex )
+    {
+        // we need to use addFirst method so we will use LinkedList explicitly
+        final LinkedList retValue = new LinkedList();
+
+        final Map vertexStateMap = new HashMap();
+
+        dfsVisit( vertex, vertexStateMap, retValue );
+
+        return retValue;
+    }
+
+
+    private static List dfs( final DAG graph )
+    {
+        final List verticies = graph.getVerticies();
+
+        // we need to use addFirst method so we will use LinkedList explicitly
+        final LinkedList retValue = new LinkedList();
+
+        final Map vertexStateMap = new HashMap();
+
+        for ( final Iterator iter = verticies.iterator(); iter.hasNext(); )
+        {
+            final Vertex vertex = ( Vertex ) iter.next();
+
+            if ( isNotVisited( vertex, vertexStateMap ) )
+            {
+                dfsVisit( vertex, vertexStateMap, retValue );
+            }
+        }
+
+        return retValue;
+    }
+
+    /**
+     * @param vertex
+     * @param vertexStateMap
+     * @return
+     */
+    private static boolean isNotVisited( final Vertex vertex, final Map vertexStateMap )
+    {
+        if ( !vertexStateMap.containsKey( vertex ) )
+        {
+            return true;
+        }
+        final Integer state = ( Integer ) vertexStateMap.get( vertex );
+
+        return NOT_VISTITED.equals( state );
+    }
+
+
+    private static void dfsVisit( final Vertex vertex, final Map vertexStateMap, final LinkedList list )
+    {
+        vertexStateMap.put( vertex, VISITING );
+
+        final List verticies = vertex.getChildren();
+
+        for ( final Iterator iter = verticies.iterator(); iter.hasNext(); )
+        {
+            final Vertex v = ( Vertex ) iter.next();
+
+            if ( isNotVisited( v, vertexStateMap ) )
+            {
+                dfsVisit( v, vertexStateMap, list );
+            }
+        }
+
+        vertexStateMap.put( vertex, VISITED );
+
+        list.add( vertex.getLabel() );
+    }
+
+}
+

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/TopologicalSorter.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/TopologicalSorter.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/TopologicalSorter.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/Vertex.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/Vertex.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/Vertex.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/Vertex.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,204 @@
+package org.apache.geronimo.system.plugin.plexus.util.dag;
+
+/*
+ * Copyright The Codehaus 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.Serializable;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author <a href="michal.maczka@dimatics.com">Michal Maczka</a>
+ * @version $Id: Vertex.java 8010 2009-01-07 12:59:50Z vsiveton $
+ */
+public class Vertex implements Cloneable, Serializable
+{
+    //------------------------------------------------------------
+    //Fields
+    //------------------------------------------------------------
+    private String label = null;
+
+    List children = new ArrayList();
+
+    List parents = new ArrayList();
+
+
+    // ------------------------------------------------------------
+    // Constructors
+    // ------------------------------------------------------------
+
+    /**
+     *
+     */
+    public Vertex( final String label )
+    {
+        this.label = label;
+    }
+
+    // ------------------------------------------------------------
+    // Accessors
+    // ------------------------------------------------------------
+
+
+    /**
+     * @return
+     */
+    public String getLabel()
+    {
+        return label;
+    }
+
+    /**
+     * @param vertex
+     */
+    public void addEdgeTo( final Vertex vertex )
+    {
+        children.add( vertex );
+    }
+
+
+    /**
+     * @param vertex
+     */
+    public void removeEdgeTo( final Vertex vertex )
+    {
+        children.remove( vertex );
+    }
+
+
+    /**
+     * @param vertex
+     */
+    public void addEdgeFrom( final Vertex vertex )
+    {
+        parents.add( vertex );
+    }
+
+    public void removeEdgeFrom( final Vertex vertex )
+    {
+
+        parents.remove( vertex );
+
+    }
+
+
+    public List getChildren()
+    {
+        return children;
+    }
+
+
+    /**
+     * Get the labels used by the most direct children.
+     *
+     * @return the labels used by the most direct children.
+     */
+    public List getChildLabels()
+    {
+        final List retValue = new ArrayList( children.size() );
+
+        for ( final Iterator iter = children.iterator(); iter.hasNext(); )
+        {
+            final Vertex vertex = ( Vertex ) iter.next();
+
+            retValue.add( vertex.getLabel() );
+        }
+        return retValue;
+    }
+
+
+    /**
+     * Get the list the most direct ancestors (parents).
+     *
+     * @return list of parents
+     */
+    public List getParents()
+    {
+        return parents;
+    }
+
+
+    /**
+     * Get the labels used by the most direct ancestors (parents).
+     *
+     * @return the labels used parents
+     */
+    public List getParentLabels()
+    {
+        final List retValue = new ArrayList( parents.size() );
+
+        for ( final Iterator iter = parents.iterator(); iter.hasNext(); )
+        {
+            final Vertex vertex = ( Vertex ) iter.next();
+
+            retValue.add( vertex.getLabel() );
+        }
+        return retValue;
+    }
+
+
+    /**
+     * Indicates if given vertex has no child
+     *
+     * @return <code>true</true> if this vertex has no child, <code>false</code> otherwise
+     */
+    public boolean isLeaf()
+    {
+        return children.size() == 0;
+    }
+
+
+    /**
+     * Indicates if given vertex has no parent
+     *
+     * @return <code>true</true> if this vertex has no parent, <code>false</code> otherwise
+     */
+    public boolean isRoot()
+    {
+        return parents.size() == 0;
+    }
+
+
+    /**
+     * Indicates if there is at least one edee leading to or from given vertex
+     *
+     * @return <code>true</true> if this vertex is connected with other vertex,<code>false</code> otherwise
+     */
+    public boolean isConnected()
+    {
+        return isRoot() || isLeaf();
+    }
+
+
+    public Object clone() throws CloneNotSupportedException
+    {
+        // this is what's failing..
+        final Object retValue = super.clone();
+
+        return retValue;
+    }
+
+    public String toString()
+    {
+        return "Vertex{" +
+               "label='" + label + "'" +
+               "}";
+    }
+
+
+}
+

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/Vertex.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/Vertex.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/dag/Vertex.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ClassMap.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ClassMap.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ClassMap.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ClassMap.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,519 @@
+package org.apache.geronimo.system.plugin.plexus.util.introspection;
+
+/*
+ * Copyright The Codehaus 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.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.util.Hashtable;
+import java.util.Map;
+
+/**
+ * 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 8010 2009-01-07 12:59:50Z vsiveton $
+ */
+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();
+    }
+
+    /**
+     * @return the class object whose methods are cached by this map.
+     */
+    Class getCachedClass()
+    {
+        return clazz;
+    }
+
+    /**
+     * Find a Method using the methodKey
+     * provided.
+     * <p/>
+     * 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.
+     * <p/>
+     * 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: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ClassMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ClassMap.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ClassMap.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/MethodMap.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/MethodMap.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/MethodMap.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/MethodMap.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,464 @@
+package org.apache.geronimo.system.plugin.plexus.util.introspection;
+
+/*
+ * Copyright The Codehaus 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.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @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 8010 2009-01-07 12:59:50Z vsiveton $
+ */
+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 key The name of the method.
+     * @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: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/MethodMap.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/MethodMap.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/MethodMap.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ReflectionValueExtractor.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ReflectionValueExtractor.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ReflectionValueExtractor.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ReflectionValueExtractor.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,248 @@
+package org.apache.geronimo.system.plugin.plexus.util.introspection;
+
+/*
+ * Copyright The Codehaus 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.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Arrays;
+import java.util.List;
+import java.util.WeakHashMap;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import org.apache.geronimo.system.plugin.plexus.util.StringUtils;
+
+/**
+ * <p>Using simple dotted expressions to extract the values from an Object instance,
+ * For example we might want to extract a value like: <code>project.build.sourceDirectory</code></p>
+ *
+ * <p>The implementation supports indexed, nested and mapped properties similar to the JSP way.</p>
+ *
+ * @author <a href="mailto:jason@maven.org">Jason van Zyl </a>
+ * @author <a href="mailto:vincent.siveton@gmail.com">Vincent Siveton</a>
+ * @version $Id: ReflectionValueExtractor.java 8010 2009-01-07 12:59:50Z vsiveton $
+ * @see <a href="http://struts.apache.org/1.x/struts-taglib/indexedprops.html">http://struts.apache.org/1.x/struts-taglib/indexedprops.html</a>
+ */
+public class ReflectionValueExtractor
+{
+    private static final Class[] CLASS_ARGS = new Class[0];
+
+    private static final Object[] OBJECT_ARGS = new Object[0];
+
+    /**
+     * Use a WeakHashMap here, so the keys (Class objects) can be garbage collected.
+     * This approach prevents permgen space overflows due to retention of discarded
+     * classloaders.
+     */
+    private static final Map classMaps = new WeakHashMap();
+
+    /**
+     * Indexed properties pattern, ie <code>(\\w+)\\[(\\d+)\\]</code>
+     */
+    private static final Pattern INDEXED_PROPS = Pattern.compile( "(\\w+)\\[(\\d+)\\]" );
+
+    /**
+     * Indexed properties pattern, ie <code>(\\w+)\\((.+)\\)</code>
+     */
+    private static final Pattern MAPPED_PROPS = Pattern.compile( "(\\w+)\\((.+)\\)" );
+
+    private ReflectionValueExtractor()
+    {
+    }
+
+    /**
+     * <p>The implementation supports indexed, nested and mapped properties.</p>
+     *
+     * <ul>
+     * <li>nested properties should be defined by a dot, i.e. "user.address.street"</li>
+     * <li>indexed properties (java.util.List or array instance) should be contains <code>(\\w+)\\[(\\d+)\\]</code>
+     * pattern, i.e. "user.addresses[1].street"</li>
+     * <li>mapped properties should be contains <code>(\\w+)\\((.+)\\)</code> pattern, i.e. "user.addresses(myAddress).street"</li>
+     * <ul>
+     *
+     * @param expression not null expression
+     * @param root not null object
+     * @return the object defined by the expression
+     * @throws Exception if any
+     */
+    public static Object evaluate( String expression, Object root )
+        throws Exception
+    {
+        return evaluate( expression, root, true );
+    }
+
+    /**
+     * <p>The implementation supports indexed, nested and mapped properties.</p>
+     *
+     * <ul>
+     * <li>nested properties should be defined by a dot, i.e. "user.address.street"</li>
+     * <li>indexed properties (java.util.List or array instance) should be contains <code>(\\w+)\\[(\\d+)\\]</code>
+     * pattern, i.e. "user.addresses[1].street"</li>
+     * <li>mapped properties should be contains <code>(\\w+)\\((.+)\\)</code> pattern, i.e. "user.addresses(myAddress).street"</li>
+     * <ul>
+     *
+     * @param expression not null expression
+     * @param root not null object
+     * @return the object defined by the expression
+     * @throws Exception if any
+     */
+    // TODO: don't throw Exception
+    public static Object evaluate( String expression, Object root, boolean trimRootToken )
+        throws Exception
+    {
+        // if the root token refers to the supplied root object parameter, remove it.
+        if ( trimRootToken )
+        {
+            expression = expression.substring( expression.indexOf( '.' ) + 1 );
+        }
+
+        Object value = root;
+
+        // ----------------------------------------------------------------------
+        // Walk the dots and retrieve the ultimate value desired from the
+        // MavenProject instance.
+        // ----------------------------------------------------------------------
+
+        StringTokenizer parser = new StringTokenizer( expression, "." );
+
+        while ( parser.hasMoreTokens() )
+        {
+            // if we have nothing, stop now
+            if ( value == null )
+            {
+                return null;
+            }
+
+            String token = parser.nextToken();
+
+            ClassMap classMap = getClassMap( value.getClass() );
+
+            Method method;
+            Object[] localParams = OBJECT_ARGS;
+
+            // do we have an indexed property?
+            Matcher matcher = INDEXED_PROPS.matcher( token );
+            if ( matcher.find() )
+            {
+                String methodBase = StringUtils.capitalizeFirstLetter( matcher.group( 1 ) );
+                String methodName = "get" + methodBase;
+                method = classMap.findMethod( methodName, CLASS_ARGS );
+                value = method.invoke( value, OBJECT_ARGS );
+                classMap = getClassMap( value.getClass() );
+
+                if ( classMap.getCachedClass().isArray() )
+                {
+                    value = Arrays.asList( (Object[]) value );
+                    classMap = getClassMap( value.getClass() );
+                }
+
+                if ( value instanceof List )
+                {
+                    // use get method on List interface
+                    localParams = new Object[1];
+                    localParams[0] = Integer.valueOf( matcher.group( 2 ) );
+                    method = classMap.findMethod( "get", localParams );
+                }
+                else
+                {
+                    throw new Exception( "The token '" + token
+                        + "' refers to a java.util.List or an array, but the value seems is an instance of '"
+                        + value.getClass() + "'." );
+                }
+            }
+            else
+            {
+                // do we have a mapped property?
+                matcher = MAPPED_PROPS.matcher( token );
+                if ( matcher.find() )
+                {
+                    String methodBase = StringUtils.capitalizeFirstLetter( matcher.group( 1 ) );
+                    String methodName = "get" + methodBase;
+                    method = classMap.findMethod( methodName, CLASS_ARGS );
+                    value = method.invoke( value, OBJECT_ARGS );
+                    classMap = getClassMap( value.getClass() );
+
+                    if ( value instanceof Map )
+                    {
+                        // use get method on List interface
+                        localParams = new Object[1];
+                        localParams[0] = matcher.group( 2 );
+                        method = classMap.findMethod( "get", localParams );
+                    }
+                    else
+                    {
+                        throw new Exception( "The token '" + token
+                            + "' refers to a java.util.Map, but the value seems is an instance of '"
+                            + value.getClass() + "'." );
+                    }
+                }
+                else
+                {
+                    String methodBase = StringUtils.capitalizeFirstLetter( token );
+                    String methodName = "get" + methodBase;
+                    method = classMap.findMethod( methodName, CLASS_ARGS );
+
+                    if ( method == null )
+                    {
+                        // perhaps this is a boolean property??
+                        methodName = "is" + methodBase;
+
+                        method = classMap.findMethod( methodName, CLASS_ARGS );
+                    }
+                }
+            }
+
+            if ( method == null )
+            {
+                return null;
+            }
+
+            try
+            {
+                value = method.invoke( value, localParams );
+            }
+            catch ( InvocationTargetException e )
+            {
+                // catch array index issues gracefully, otherwise release
+                if ( e.getCause() instanceof IndexOutOfBoundsException )
+                {
+                    return null;
+                }
+
+                throw e;
+            }
+        }
+
+        return value;
+    }
+
+    private static ClassMap getClassMap( Class clazz )
+    {
+        ClassMap classMap = (ClassMap) classMaps.get( clazz );
+
+        if ( classMap == null )
+        {
+            classMap = new ClassMap( clazz );
+
+            classMaps.put( clazz, classMap );
+        }
+
+        return classMap;
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ReflectionValueExtractor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ReflectionValueExtractor.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/introspection/ReflectionValueExtractor.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/FileInputStreamFacade.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/FileInputStreamFacade.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/FileInputStreamFacade.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/FileInputStreamFacade.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,43 @@
+package org.apache.geronimo.system.plugin.plexus.util.io;
+
+/*
+ * Copyright The Codehaus 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.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * Implementation of {@link InputStreamFacade} for files.
+ */
+public class FileInputStreamFacade implements InputStreamFacade {
+    private final File file;
+
+    /**
+     * Creates a new instance.
+     */
+    public FileInputStreamFacade( File file )
+    {
+        this.file = file;
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return new FileInputStream( file );
+    }
+
+
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/FileInputStreamFacade.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/FileInputStreamFacade.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/FileInputStreamFacade.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/InputStreamFacade.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/InputStreamFacade.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/InputStreamFacade.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/InputStreamFacade.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,33 @@
+package org.apache.geronimo.system.plugin.plexus.util.io;
+
+/*
+ * Copyright The Codehaus 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.IOException;
+import java.io.InputStream;
+
+/**
+ * Interface of a wrapper for input streams. This facade is used
+ * by methods, which are being implemented for files, URL's, or
+ * input streams.
+ */
+public interface InputStreamFacade {
+    /**
+     * Retrieves the actual {@link InputStream}. The caller must assume,
+     * that this method may be invoked only once.
+     */
+    InputStream getInputStream() throws IOException;
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/InputStreamFacade.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/InputStreamFacade.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/InputStreamFacade.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/RawInputStreamFacade.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/RawInputStreamFacade.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/RawInputStreamFacade.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/RawInputStreamFacade.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,39 @@
+package org.apache.geronimo.system.plugin.plexus.util.io;
+
+/*
+ * Copyright The Codehaus 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.IOException;
+import java.io.InputStream;
+
+/**
+ * Implementation of {@link InputStreamFacade} for raw input streams.
+ */
+public class RawInputStreamFacade implements InputStreamFacade {
+    final InputStream stream;
+
+    /**
+     * Creates a new instance.
+     */
+    public RawInputStreamFacade( InputStream stream )
+    {
+        this.stream = stream;
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return stream;
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/RawInputStreamFacade.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/RawInputStreamFacade.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/RawInputStreamFacade.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/URLInputStreamFacade.java
URL: http://svn.apache.org/viewvc/geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/URLInputStreamFacade.java?rev=821961&view=auto
==============================================================================
--- geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/URLInputStreamFacade.java (added)
+++ geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/URLInputStreamFacade.java Mon Oct  5 18:54:50 2009
@@ -0,0 +1,40 @@
+package org.apache.geronimo.system.plugin.plexus.util.io;
+
+/*
+ * Copyright The Codehaus 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.IOException;
+import java.io.InputStream;
+import java.net.URL;
+
+/**
+ * Implementation of {@link InputStreamFacade} for URL's.
+ */
+public class URLInputStreamFacade implements InputStreamFacade {
+    private final URL url;
+
+    /**
+     * Creates a new instance.
+     */
+    public URLInputStreamFacade( URL url )
+    {
+        this.url = url;
+    }
+
+    public InputStream getInputStream() throws IOException {
+        return url.openStream();
+    }
+}

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/URLInputStreamFacade.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/URLInputStreamFacade.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/sandbox/djencks/osgi/framework/modules/geronimo-plugin/src/main/java/org/apache/geronimo/system/plugin/plexus/util/io/URLInputStreamFacade.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain