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 java.lang.reflect.Field;
23 import java.lang.reflect.Method;
24 import java.lang.reflect.Modifier;
25 import java.util.HashMap;
26 import java.util.Map.Entry;
27 import java.util.logging.Level;
28 import java.util.logging.Logger;
29
30 import org.apache.onami.test.annotation.Mock;
31 import org.apache.onami.test.mock.MockEngine;
32 import org.apache.onami.test.reflection.FieldHandler;
33 import org.apache.onami.test.reflection.HandleException;
34
35
36
37
38
39
40
41 public final class MockHandler
42 implements FieldHandler<Mock>
43 {
44
45 private static final Logger LOGGER = Logger.getLogger( MockHandler.class.getName() );
46
47 private final HashMap<Field, Object> mockedObjects = new HashMap<Field, Object>( 1 );
48
49
50
51
52
53
54
55 public HashMap<Field, Object> getMockedObject( MockEngine engine )
56 {
57 createMockedObjectBymockFramekork( engine );
58 return mockedObjects;
59 }
60
61 private void createMockedObjectBymockFramekork( MockEngine engine )
62 {
63 for ( Entry<Field, Object> entry : mockedObjects.entrySet() )
64 {
65 if ( entry.getValue() instanceof Class<?> )
66 {
67 Field field = entry.getKey();
68 Mock mock = field.getAnnotation( Mock.class );
69 mockedObjects.put( entry.getKey(), engine.createMock( (Class<?>) entry.getValue(), mock.type() ) );
70 }
71 }
72 }
73
74
75
76
77
78
79
80
81 @SuppressWarnings( "unchecked" )
82 public void handle( final Mock annotation, final Field element )
83 throws HandleException
84 {
85 final Class<? super Object> type = (Class<? super Object>) element.getDeclaringClass();
86
87 if ( LOGGER.isLoggable( Level.FINER ) )
88 {
89 LOGGER.finer( " Found annotated field: " + element );
90 }
91 if ( annotation.providedBy().length() > 0 )
92 {
93 Class<?> providedClass = type;
94 if ( annotation.providerClass() != Object.class )
95 {
96 providedClass = annotation.providerClass();
97 }
98 try
99 {
100 Method method = providedClass.getMethod( annotation.providedBy() );
101
102 if ( !element.getType().isAssignableFrom( method.getReturnType() ) )
103 {
104 throw new HandleException( "Impossible to mock %s due to compatibility type, method provider %s#%s returns %s",
105 element.getDeclaringClass().getName(),
106 providedClass.getName(),
107 annotation.providedBy(),
108 method.getReturnType().getName() );
109 }
110 try
111 {
112 Object mocked = getMockProviderForType( element.getType(), method, type );
113 mockedObjects.put( element, mocked );
114 }
115 catch ( Throwable t )
116 {
117 throw new HandleException( "Impossible to mock %s, method provider %s#%s raised an error: %s",
118 element.getDeclaringClass().getName(),
119 providedClass.getName(),
120 annotation.providedBy(),
121 t );
122 }
123 }
124 catch ( SecurityException e )
125 {
126 throw new HandleException( "Impossible to mock %s, impossible to access to method provider %s#%s: %s",
127 element.getDeclaringClass().getName(),
128 providedClass.getName(),
129 annotation.providedBy(),
130 e );
131 }
132 catch ( NoSuchMethodException e )
133 {
134 throw new HandleException( "Impossible to mock %s, the method provider %s#%s doesn't exist.",
135 element.getDeclaringClass().getName(),
136 providedClass.getName(),
137 annotation.providedBy() );
138 }
139 }
140 else
141 {
142 mockedObjects.put( element, element.getType() );
143 }
144 }
145
146 @SuppressWarnings( "unchecked" )
147 private <T> T getMockProviderForType( T t, Method method, Class<?> cls )
148 throws HandleException
149 {
150 if ( method.getReturnType() == t )
151 {
152 try
153 {
154 if ( LOGGER.isLoggable( Level.FINER ) )
155 {
156 LOGGER.finer( " ...invoke Provider method for Mock: " + method.getName() );
157 }
158 if ( !Modifier.isPublic( method.getModifiers() ) || !Modifier.isStatic( method.getModifiers() ) )
159 {
160 throw new HandleException( "Impossible to invoke method %s#%s. The method shuld be 'static public %s %s()",
161 cls.getName(),
162 method.getName(),
163 method.getReturnType().getName(),
164 method.getName() );
165 }
166
167 return (T) method.invoke( cls );
168 }
169 catch ( Exception e )
170 {
171 throw new RuntimeException( e );
172 }
173 }
174 throw new HandleException( "The method: %s should return type %s", method, t );
175 }
176
177 }