1 package org.apache.onami.test.handler;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
41
42
43
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
55
56 public List<Module> getModules()
57 {
58 return modules;
59 }
60
61
62
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 }