View Javadoc

1   package org.apache.onami.test.handler;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import static java.lang.String.format;
23  
24  import java.lang.reflect.Method;
25  import java.lang.reflect.Modifier;
26  import java.util.ArrayList;
27  import java.util.List;
28  import java.util.logging.Level;
29  import java.util.logging.Logger;
30  
31  import org.apache.onami.test.annotation.GuiceProvidedModules;
32  import org.apache.onami.test.reflection.HandleException;
33  import org.apache.onami.test.reflection.MethodHandler;
34  
35  import com.google.inject.Module;
36  import com.google.inject.TypeLiteral;
37  import com.google.inject.internal.MoreTypes;
38  
39  /**
40   * Handler class to handle all {@link GuiceProvidedModules} annotations.
41   *
42   * @see org.apache.onami.test.reflection.ClassVisitor
43   * @see GuiceProvidedModules
44   */
45  public final class GuiceProvidedModuleHandler
46      implements MethodHandler<GuiceProvidedModules>
47  {
48  
49      private static final Logger LOGGER = Logger.getLogger( GuiceProvidedModuleHandler.class.getName() );
50  
51      private final List<Module> modules = new ArrayList<Module>();
52  
53      /**
54       * @return the guiceProviderModuleRegistry
55       */
56      public List<Module> getModules()
57      {
58          return modules;
59      }
60  
61      /**
62       * {@inheritDoc}
63       */
64      @SuppressWarnings( "unchecked" )
65      public void handle( GuiceProvidedModules annotation, Method method )
66          throws HandleException
67      {
68          final Class<?> returnType = method.getReturnType();
69  
70          if ( LOGGER.isLoggable( Level.FINER ) )
71          {
72              LOGGER.finer( format( "  Found %s annotated method, checking if return type '%s' is one of ( %s | Iterable<%s> | %s[] )",
73                                    GuiceProvidedModules.class.getSimpleName(),
74                                    returnType.getName(),
75                                    Module.class.getName(),
76                                    Module.class.getName(),
77                                    Module.class.getName() ) );
78          }
79  
80          if ( !Modifier.isPublic( method.getModifiers() ) || !Modifier.isStatic( method.getModifiers() ) )
81          {
82              throw new HandleException( "Impossible to invoke method: " + method + ", it has to be static and public" );
83          }
84  
85          final Class<?> type = method.getDeclaringClass();
86  
87          try
88          {
89              if ( Module.class.isAssignableFrom( returnType ) )
90              {
91                  modules.add( (Module) method.invoke( type ) );
92              }
93              else if ( MoreTypes.getRawType( new TypeLiteral<Iterable<Module>>()
94              {
95              }.getType() ).isAssignableFrom( returnType ) )
96              {
97                  addModules( (Iterable<Module>) method.invoke( type ) );
98              }
99              else if ( MoreTypes.getRawType( new TypeLiteral<Module[]>()
100             {
101             }.getType() ).isAssignableFrom( returnType ) )
102             {
103                 addModules( (Module[]) method.invoke( type ) );
104             }
105             else
106             {
107                 throw new ClassCastException( format( "  Incompatible return type: %s.\nThe return type must be one of ( %s | Iterable<%s> | %s[] )",
108                                                       returnType.getName(),
109                                                       Module.class.getName(),
110                                                       Module.class.getName(),
111                                                       Module.class.getName() ) );
112             }
113 
114             if ( LOGGER.isLoggable( Level.FINER ) )
115             {
116                 LOGGER.finer( "  Invoked method: " + method.toGenericString() );
117             }
118         }
119         catch ( Exception e )
120         {
121             throw new HandleException( e );
122         }
123     }
124 
125     private void addModules( Iterable<Module> modules )
126     {
127         for ( Module module : modules )
128         {
129             this.modules.add( module );
130         }
131     }
132 
133     private void addModules( Module... modules )
134     {
135         for ( Module module : modules )
136         {
137             this.modules.add( module );
138         }
139     }
140 }