View Javadoc

1   /*
2    *    Copyright 2012 The 99 Software Foundation
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.nnsoft.guice.junice.handler;
17  
18  import java.lang.reflect.Method;
19  import java.lang.reflect.Modifier;
20  import java.util.ArrayList;
21  import java.util.List;
22  
23  import org.apache.commons.logging.Log;
24  import org.apache.commons.logging.LogFactory;
25  import org.nnsoft.guice.junice.annotation.GuiceProvidedModules;
26  import org.nnsoft.guice.junice.reflection.ClassVisitor;
27  import org.nnsoft.guice.junice.reflection.HandleException;
28  import org.nnsoft.guice.junice.reflection.MethodHandler;
29  
30  import com.google.inject.Module;
31  import com.google.inject.TypeLiteral;
32  import com.google.inject.internal.MoreTypes;
33  
34  /**
35   * Handler class to handle all {@link GuiceProvidedModules} annotations.
36   * 
37   * @see ClassVisitor
38   * @see GuiceProvidedModules
39   * @author Marco Speranza
40   * @version $Id: GuiceProviderHandler.java 000 2009-12-01 00:00:00Z marco.speranza79 $
41   */
42  public final class GuiceProvidedModuleHandler implements MethodHandler<GuiceProvidedModules> {
43  
44      private static Log logger = LogFactory.getLog(GuiceProvidedModuleHandler.class);
45  
46      final private List<Module> modules = new ArrayList<Module>();
47  
48      /**
49       * @return the guiceProviderModuleRegistry
50       */
51      public List<Module> getModules() {
52          return this.modules;
53      }
54  
55      /**
56       * {@inheritDoc}
57       */
58      @SuppressWarnings("unchecked")
59      public void handle(GuiceProvidedModules annotation, Method method) throws HandleException {
60          final Class<?> returnType = method.getReturnType();
61  
62          if (logger.isDebugEnabled()) {
63              logger.debug("  Found " 
64                      + GuiceProvidedModules.class.getSimpleName()
65                      + " annotated method, checking if return type '"
66                      + returnType.getName()
67                      + "' is one of (''|''|'')...");
68          }
69  
70          if (!Modifier.isPublic(method.getModifiers())
71                  || !Modifier.isStatic(method.getModifiers())) {
72              throw new HandleException("Impossible to invoke method: "
73                      + method
74                      + ", it has to be static and public");
75          }
76  
77          final Class<?> type = method.getDeclaringClass();
78  
79          try {
80              if (Module.class.isAssignableFrom(returnType)) {
81                  this.modules.add((Module) method.invoke(type));
82              } else if (MoreTypes
83                      .getRawType(new TypeLiteral<Iterable<Module>>() {}.getType())
84                      .isAssignableFrom(returnType)) {
85                  this.addModules((Iterable<Module>) method.invoke(type));
86              } else if (MoreTypes
87                      .getRawType(new TypeLiteral<Module[]>() {}.getType())
88                      .isAssignableFrom(returnType)) {
89                  this.addModules((Module[]) method.invoke(type));
90              }
91          } catch (Exception e) {
92              throw new HandleException("Error invoking method: "
93                      + method
94                      + "please make sure it is static and public", e);
95          }
96  
97          if (logger.isDebugEnabled()) {
98              logger.debug("  Invoked method: "
99                      + method.toGenericString());
100         }
101     }
102 
103     private void addModules(Iterable<Module> modules) {
104         for (Module module : modules) {
105             this.modules.add(module);
106         }
107     }
108 
109     private void addModules(Module... modules) {
110         for (Module module : modules) {
111             this.modules.add(module);
112         }
113     }
114 
115 }