001: // Copyright 2006, 2007 The Apache Software Foundation
002: //
003: // Licensed under the Apache License, Version 2.0 (the "License");
004: // you may not use this file except in compliance with the License.
005: // You may obtain a copy of the License at
006: //
007: // http://www.apache.org/licenses/LICENSE-2.0
008: //
009: // Unless required by applicable law or agreed to in writing, software
010: // distributed under the License is distributed on an "AS IS" BASIS,
011: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012: // See the License for the specific language governing permissions and
013: // limitations under the License.
014:
015: package org.apache.tapestry.ioc.internal;
016:
017: import static org.apache.tapestry.ioc.internal.AbstractServiceCreator.findParameterizedTypeFromGenericType;
018: import static org.easymock.EasyMock.eq;
019: import static org.easymock.EasyMock.isA;
020:
021: import java.lang.reflect.Method;
022: import java.lang.reflect.Type;
023: import java.util.Collection;
024: import java.util.List;
025:
026: import org.apache.commons.logging.Log;
027: import org.apache.tapestry.ioc.AnnotationProvider;
028: import org.apache.tapestry.ioc.ObjectCreator;
029: import org.apache.tapestry.ioc.ServiceBuilderResources;
030: import org.testng.Assert;
031: import org.testng.annotations.Test;
032:
033: public class ServiceBuilderMethodInvokerTest extends
034: IOCInternalTestCase {
035: private static final String SERVICE_ID = "Fie";
036:
037: private static final String CREATOR_DESCRIPTION = "{CREATOR DESCRIPTION}";
038:
039: @Test
040: public void noargs_method() {
041: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
042: ServiceBuilderResources resources = mockServiceBuilderResources();
043: Log log = mockLog();
044:
045: fixture._fie = mockFieService();
046:
047: trainForConstructor(resources, log);
048:
049: train_getModuleBuilder(resources, fixture);
050:
051: train_isDebugEnabled(log, false);
052:
053: replay();
054:
055: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
056: CREATOR_DESCRIPTION,
057: findMethod(fixture, "build_noargs"));
058:
059: Object actual = sc.createObject();
060:
061: assertSame(actual, fixture._fie);
062:
063: verify();
064: }
065:
066: private void trainForConstructor(ServiceBuilderResources resources,
067: Log log) {
068: train_getServiceId(resources, SERVICE_ID);
069:
070: train_getServiceLog(resources, log);
071:
072: train_getServiceInterface(resources, FieService.class);
073: }
074:
075: @Test
076: public void method_with_args() {
077: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
078: Method method = findMethod(fixture, "build_args");
079: ServiceBuilderResources resources = mockServiceBuilderResources();
080:
081: Log log = mockLog();
082:
083: fixture._expectedServiceId = SERVICE_ID;
084: fixture._expectedServiceInterface = FieService.class;
085: fixture._expectedServiceResources = resources;
086: fixture._expectedLog = log;
087:
088: fixture._fie = mockFieService();
089:
090: trainForConstructor(resources, log);
091:
092: train_getModuleBuilder(resources, fixture);
093:
094: train_isDebugEnabled(log, true);
095:
096: log.debug(IOCMessages.invokingMethod(CREATOR_DESCRIPTION));
097:
098: replay();
099:
100: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
101: CREATOR_DESCRIPTION, method);
102:
103: Object actual = sc.createObject();
104:
105: assertSame(actual, fixture._fie);
106:
107: verify();
108: }
109:
110: @Test
111: public void inject_annotation_bypasses_resources() {
112: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
113: Method method = findMethod(fixture,
114: "build_with_forced_injection");
115: ServiceBuilderResources resources = mockServiceBuilderResources();
116:
117: Log log = mockLog();
118:
119: fixture._expectedString = "Injected";
120:
121: fixture._fie = mockFieService();
122:
123: trainForConstructor(resources, log);
124:
125: train_getModuleBuilder(resources, fixture);
126:
127: train_isDebugEnabled(log, true);
128:
129: log.debug(IOCMessages.invokingMethod(CREATOR_DESCRIPTION));
130:
131: // This simulates what the real stack does when it sees @Value("Injected")
132:
133: expect(
134: resources.getObject(eq(String.class),
135: isA(AnnotationProvider.class))).andReturn(
136: "Injected");
137:
138: replay();
139:
140: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
141: CREATOR_DESCRIPTION, method);
142:
143: Object actual = sc.createObject();
144:
145: assertSame(actual, fixture._fie);
146:
147: verify();
148: }
149:
150: @Test
151: public void injected_service_method() {
152: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
153: ServiceBuilderResources resources = mockServiceBuilderResources();
154: Log log = mockLog();
155:
156: fixture._fie = mockFieService();
157: fixture._expectedFoe = newFoe();
158:
159: trainForConstructor(resources, log);
160:
161: train_getModuleBuilder(resources, fixture);
162:
163: train_getService(resources, "Foe", FoeService.class,
164: fixture._expectedFoe);
165:
166: train_isDebugEnabled(log, false);
167:
168: replay();
169:
170: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
171: CREATOR_DESCRIPTION, findMethod(fixture,
172: "build_injected"));
173:
174: Object actual = sc.createObject();
175:
176: assertSame(actual, fixture._fie);
177:
178: verify();
179: }
180:
181: @SuppressWarnings("unchecked")
182: @Test
183: public void injected_ordered_collection() {
184: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
185: ServiceBuilderResources resources = mockServiceBuilderResources();
186: Log log = mockLog();
187:
188: fixture._fie = mockFieService();
189: List<Runnable> result = newMock(List.class);
190: fixture._expectedConfiguration = result;
191:
192: trainForConstructor(resources, log);
193:
194: train_getModuleBuilder(resources, fixture);
195:
196: expect(resources.getOrderedConfiguration(Runnable.class))
197: .andReturn(result);
198:
199: train_isDebugEnabled(log, false);
200:
201: replay();
202:
203: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
204: CREATOR_DESCRIPTION, findMethod(fixture,
205: "buildWithOrderedConfiguration"));
206:
207: Object actual = sc.createObject();
208:
209: assertSame(actual, fixture._fie);
210:
211: verify();
212:
213: }
214:
215: @SuppressWarnings("unchecked")
216: @Test
217: public void injected_unordered_collection() {
218: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
219: ServiceBuilderResources resources = mockServiceBuilderResources();
220: Log log = mockLog();
221:
222: fixture._fie = mockFieService();
223: Collection<Runnable> result = newMock(Collection.class);
224: fixture._expectedConfiguration = result;
225:
226: trainForConstructor(resources, log);
227:
228: train_getModuleBuilder(resources, fixture);
229:
230: expect(resources.getUnorderedConfiguration(Runnable.class))
231: .andReturn(result);
232:
233: train_isDebugEnabled(log, false);
234:
235: replay();
236:
237: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
238: CREATOR_DESCRIPTION, findMethod(fixture,
239: "buildWithUnorderedConfiguration"));
240:
241: Object actual = sc.createObject();
242:
243: assertSame(actual, fixture._fie);
244:
245: verify();
246: }
247:
248: private FoeService newFoe() {
249: return mockFoeService();
250: }
251:
252: @Test
253: public void builder_method_returns_null() {
254: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
255: ServiceBuilderResources resources = mockServiceBuilderResources();
256: Log log = mockLog();
257:
258: Method method = findMethod(fixture, "build_noargs");
259:
260: trainForConstructor(resources, log);
261:
262: train_getModuleBuilder(resources, fixture);
263:
264: train_isDebugEnabled(log, false);
265:
266: replay();
267:
268: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
269: CREATOR_DESCRIPTION, method);
270:
271: try {
272: sc.createObject();
273: unreachable();
274: } catch (RuntimeException ex) {
275: Assert.assertEquals(ex.getMessage(), "Builder method "
276: + CREATOR_DESCRIPTION
277: + " (for service 'Fie') returned null.");
278: }
279:
280: verify();
281: }
282:
283: @Test
284: public void builder_method_failed() {
285: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
286: ServiceBuilderResources resources = mockServiceBuilderResources();
287: Log log = mockLog();
288:
289: Method method = findMethod(fixture, "build_fail");
290:
291: trainForConstructor(resources, log);
292:
293: train_getModuleBuilder(resources, fixture);
294:
295: train_isDebugEnabled(log, false);
296:
297: replay();
298:
299: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
300: CREATOR_DESCRIPTION, method);
301:
302: try {
303: sc.createObject();
304: unreachable();
305: } catch (RuntimeException ex) {
306: assertEquals(ex.getMessage(),
307: "Error invoking service builder method "
308: + CREATOR_DESCRIPTION
309: + " (for service 'Fie'): Method failed.");
310:
311: Throwable cause = ex.getCause();
312:
313: assertEquals(cause.getMessage(), "Method failed.");
314: }
315:
316: verify();
317: }
318:
319: @Test
320: public void auto_dependency() {
321: ServiceBuilderMethodFixture fixture = new ServiceBuilderMethodFixture();
322: Method method = findMethod(fixture, "build_auto");
323:
324: ServiceBuilderResources resources = mockServiceBuilderResources();
325: Log log = mockLog();
326:
327: fixture._fie = mockFieService();
328: fixture._expectedFoe = mockFoeService();
329:
330: trainForConstructor(resources, log);
331:
332: train_getModuleBuilder(resources, fixture);
333:
334: expect(
335: resources.getObject(eq(FoeService.class),
336: isA(AnnotationProvider.class))).andReturn(
337: fixture._expectedFoe);
338:
339: train_isDebugEnabled(log, false);
340:
341: replay();
342:
343: ObjectCreator sc = new ServiceBuilderMethodInvoker(resources,
344: CREATOR_DESCRIPTION, method);
345:
346: Object actual = sc.createObject();
347:
348: verify();
349:
350: assertSame(actual, fixture._fie);
351: }
352:
353: protected final void train_getModuleBuilder(
354: ServiceBuilderResources resources, Object moduleBuilder) {
355: expect(resources.getModuleBuilder()).andReturn(moduleBuilder);
356: }
357:
358: @Test
359: public void parameterized_type_of_generic_parameter() {
360: Method m = findMethod(ServiceBuilderMethodFixture.class,
361: "methodWithParameterizedList");
362:
363: assertEquals(m.getParameterTypes()[0], List.class);
364: Type type = m.getGenericParameterTypes()[0];
365:
366: assertEquals(type.toString(),
367: "java.util.List<java.lang.Runnable>");
368: assertEquals(findParameterizedTypeFromGenericType(type),
369: Runnable.class);
370: }
371:
372: @Test
373: public void parameterized_type_of_nongeneric_parameter() {
374: Method m = findMethod(ServiceBuilderMethodFixture.class,
375: "methodWithList");
376:
377: assertEquals(m.getParameterTypes()[0], List.class);
378: Type type = m.getGenericParameterTypes()[0];
379:
380: assertEquals(type.toString(), "interface java.util.List");
381: assertEquals(findParameterizedTypeFromGenericType(type),
382: Object.class);
383: }
384:
385: @Test
386: public void parameterize_type_for_non_supported_type() {
387: Method m = findMethod(ServiceBuilderMethodFixture.class,
388: "methodWithWildcardList");
389:
390: assertEquals(m.getParameterTypes()[0], List.class);
391: Type type = m.getGenericParameterTypes()[0];
392:
393: try {
394: findParameterizedTypeFromGenericType(type);
395: unreachable();
396: } catch (IllegalArgumentException ex) {
397: assertEquals(ex.getMessage(), IOCMessages
398: .genericTypeNotSupported(type));
399: }
400: }
401:
402: private FoeService mockFoeService() {
403: return newMock(FoeService.class);
404: }
405:
406: private FieService mockFieService() {
407: return newMock(FieService.class);
408: }
409:
410: }
|