View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.apache.commons.proxy.factory.util;
19  
20  import java.lang.reflect.Method;
21  import java.lang.reflect.Modifier;
22  import java.util.Collection;
23  import java.util.HashMap;
24  import java.util.HashSet;
25  import java.util.Iterator;
26  import java.util.Map;
27  import java.util.Set;
28  
29  /**
30   * A useful superclass for {@link ProxyClassGenerator} implementations.
31   *
32   * @author James Carman
33   * @since 1.0
34   */
35  public abstract class AbstractProxyClassGenerator implements ProxyClassGenerator
36  {
37  //----------------------------------------------------------------------------------------------------------------------
38  // Static Methods
39  //----------------------------------------------------------------------------------------------------------------------
40  
41      /**
42       * Returns all methods that a proxy class must implement from the proxy interfaces.  This method makes sure there
43       * are no method signature clashes. For methods with the same signature (name and parameter types), the one
44       * encountered first will be returned in the result. Final methods are also excluded from the result.
45       *
46       * @param proxyClasses the interfaces the proxy class must implement
47       * @return all methods that the proxy class must implement
48       */
49      public static Method[] getImplementationMethods( Class[] proxyClasses )
50      {
51          final Map signatureMethodMap = new HashMap();
52          final Set finalizedSignatures = new HashSet();
53          for( int i = 0; i < proxyClasses.length; i++ )
54          {
55              Class proxyInterface = proxyClasses[i];
56              final Method[] methods = proxyInterface.getMethods();
57              for( int j = 0; j < methods.length; j++ )
58              {
59                  final MethodSignature signature = new MethodSignature( methods[j] );
60                  if( Modifier.isFinal( methods[j].getModifiers() ) )
61                  {
62                      finalizedSignatures.add( signature );
63                  }
64                  else if( !signatureMethodMap.containsKey( signature ) )
65                  {
66                      signatureMethodMap.put( signature, methods[j] );
67                  }
68              }
69          }
70          final Collection resultingMethods = signatureMethodMap.values();
71          for( Iterator i = finalizedSignatures.iterator(); i.hasNext(); )
72          {
73              MethodSignature signature = ( MethodSignature ) i.next();
74              resultingMethods.remove( signatureMethodMap.get( signature ) );
75          }
76          return ( Method[] ) resultingMethods.toArray( new Method[resultingMethods.size()] );
77      }
78  }
79