001// Copyright 2006, 2007, 2008, 2010, 2011, 2012 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
015package org.apache.tapestry5.ioc.test;
016
017import org.apache.tapestry5.commons.*;
018import org.apache.tapestry5.commons.services.*;
019import org.apache.tapestry5.ioc.AdvisorDef;
020import org.apache.tapestry5.ioc.AdvisorDef2;
021import org.apache.tapestry5.ioc.LoggerSource;
022import org.apache.tapestry5.ioc.OperationTracker;
023import org.apache.tapestry5.ioc.Registry;
024import org.apache.tapestry5.ioc.RegistryBuilder;
025import org.apache.tapestry5.ioc.ServiceBuilderResources;
026import org.apache.tapestry5.ioc.ServiceDecorator;
027import org.apache.tapestry5.ioc.ServiceResources;
028import org.apache.tapestry5.ioc.annotations.IntermediateType;
029import org.apache.tapestry5.ioc.def.*;
030import org.apache.tapestry5.ioc.services.MasterObjectProvider;
031import org.apache.tapestry5.ioc.services.PerthreadManager;
032import org.apache.tapestry5.ioc.services.SymbolSource;
033import org.apache.tapestry5.ioc.services.ThreadLocale;
034import org.apache.tapestry5.test.ioc.TestBase;
035import org.slf4j.Logger;
036
037import java.io.File;
038import java.lang.annotation.Annotation;
039import java.lang.reflect.Method;
040import java.net.URL;
041import java.util.Locale;
042
043import static java.lang.Thread.sleep;
044import static org.easymock.EasyMock.isA;
045
046/**
047 * Add factory and trainer methods for the public interfaces of Tapestry IOC.
048 *
049 * @deprecated In 5.4, with no replacement
050 */
051public class IOCTestCase extends TestBase
052{
053
054    /**
055     * Builds a Registry for the provided modules; caller should shutdown the Registry when done.
056     */
057    protected final Registry buildRegistry(Class... moduleClasses)
058    {
059        RegistryBuilder builder = new RegistryBuilder();
060
061        builder.add(moduleClasses);
062
063        return builder.build();
064    }
065
066    protected final Method findMethod(Class clazz, String methodName)
067    {
068        for (Method method : clazz.getMethods())
069        {
070            if (method.getName().equals(methodName))
071                return method;
072        }
073
074        throw new IllegalArgumentException(String.format("Class %s does not provide a method named '%s'.",
075                clazz.getName(), methodName));
076    }
077
078    protected final Method findMethod(Object subject, String methodName)
079    {
080        return findMethod(subject.getClass(), methodName);
081    }
082
083    protected final Method findMethod(String methodName)
084    {
085        return findMethod(this, methodName);
086    }
087
088    /**
089     * Combines a series of lines by forming a string with a line separator after each line.
090     */
091    protected final String join(String... lines)
092    {
093        StringBuilder result = new StringBuilder();
094
095        for (String line : lines)
096        {
097            result.append(line);
098            result.append('\n');
099        }
100
101        return result.toString();
102    }
103
104    protected final AnnotationProvider mockAnnotationProvider()
105    {
106        return newMock(AnnotationProvider.class);
107    }
108
109    @SuppressWarnings("unchecked")
110    protected final <T> Configuration<T> mockConfiguration()
111    {
112        return newMock(Configuration.class);
113    }
114
115    protected final ContributionDef mockContributionDef()
116    {
117        return newMock(ContributionDef.class);
118    }
119
120    protected final DecoratorDef mockDecoratorDef()
121    {
122        return newMock(DecoratorDef.class);
123    }
124
125    protected final DecoratorDef2 mockDecoratorDef2()
126    {
127        return newMock(DecoratorDef2.class);
128    }
129
130    protected final AdvisorDef mockAdvisorDef()
131    {
132        return newMock(AdvisorDef.class);
133    }
134
135    protected final AdvisorDef2 mockAdvisorDef2()
136    {
137        return newMock(AdvisorDef2.class);
138    }
139
140    protected final Location mockLocation()
141    {
142        return newMock(Location.class);
143    }
144
145    protected final Logger mockLogger()
146    {
147        return newMock(Logger.class);
148    }
149
150    protected final void stub_isDebugEnabled(Logger logger, boolean enabled)
151    {
152        expect(logger.isDebugEnabled()).andStubReturn(enabled);
153    }
154
155    @SuppressWarnings("unchecked")
156    protected final <K, V> MappedConfiguration<K, V> mockMappedConfiguration()
157    {
158        return newMock(MappedConfiguration.class);
159    }
160
161    protected final MessageFormatter mockMessageFormatter()
162    {
163        return newMock(MessageFormatter.class);
164    }
165
166    protected final Messages mockMessages()
167    {
168        return newMock(Messages.class);
169    }
170
171    protected final ModuleDef mockModuleDef()
172    {
173        return newMock(ModuleDef.class);
174    }
175
176    protected final ModuleDef2 mockModuleDef2()
177    {
178        return newMock(ModuleDef2.class);
179    }
180
181    protected final ObjectCreator mockObjectCreator()
182    {
183        return newMock(ObjectCreator.class);
184    }
185
186    protected final ObjectProvider mockObjectProvider()
187    {
188        return newMock(ObjectProvider.class);
189    }
190
191    @SuppressWarnings("unchecked")
192    protected final <T> OrderedConfiguration<T> mockOrderedConfiguration()
193    {
194        return newMock(OrderedConfiguration.class);
195    }
196
197    protected final Resource mockResource()
198    {
199        return newMock(Resource.class);
200    }
201
202    /**
203     * Frequently used as a placeholder for an arbitrary service (but its nice and simple).
204     */
205    protected final Runnable mockRunnable()
206    {
207        return newMock(Runnable.class);
208    }
209
210    protected final ServiceBuilderResources mockServiceBuilderResources()
211    {
212        return newMock(ServiceBuilderResources.class);
213    }
214
215    protected final ServiceDecorator mockServiceDecorator()
216    {
217        return newMock(ServiceDecorator.class);
218    }
219
220    protected final ServiceDef mockServiceDef()
221    {
222        return newMock(ServiceDef.class);
223    }
224
225    protected final ObjectLocator mockObjectLocator()
226    {
227        return newMock(ObjectLocator.class);
228    }
229
230    protected final ServiceResources mockServiceResources()
231    {
232        return newMock(ServiceResources.class);
233    }
234
235    protected final SymbolSource mockSymbolSource()
236    {
237        return newMock(SymbolSource.class);
238    }
239
240    protected final ThreadLocale mockThreadLocale()
241    {
242        return newMock(ThreadLocale.class);
243    }
244
245    protected final TypeCoercer mockTypeCoercer()
246    {
247        return newMock(TypeCoercer.class);
248    }
249
250    protected final void stub_contains(Messages messages, boolean contained)
251    {
252        expect(messages.contains(isA(String.class))).andStubReturn(contained);
253    }
254
255    protected <S, T> void train_coerce(TypeCoercer coercer, S input, Class<T> expectedType, T coercedValue)
256    {
257        expect(coercer.coerce(input, expectedType)).andReturn(coercedValue);
258    }
259
260    protected final void train_contains(Messages messages, String key, boolean result)
261    {
262        expect(messages.contains(key)).andReturn(result).atLeastOnce();
263    }
264
265    protected final void train_createInterceptor(ServiceDecorator decorator, Object coreObject, Object interceptor)
266    {
267        expect(decorator.createInterceptor(coreObject)).andReturn(interceptor);
268    }
269
270    protected final void train_createObject(ObjectCreator creator, Object service)
271    {
272        expect(creator.createObject()).andReturn(service);
273    }
274
275    protected final void train_expandSymbols(SymbolSource source, String input)
276    {
277        train_expandSymbols(source, input, input);
278    }
279
280    protected final void train_expandSymbols(SymbolSource source, String input, String expanded)
281    {
282        expect(source.expandSymbols(input)).andReturn(expanded);
283    }
284
285    protected final void train_forFile(Resource resource, String relativePath, Resource file)
286    {
287        expect(resource.forFile(relativePath)).andReturn(file);
288    }
289
290    protected final void train_forLocale(Resource base, Locale locale, Resource resource)
291    {
292        expect(base.forLocale(locale)).andReturn(resource);
293    }
294
295    /**
296     * Have to put the result before the varargs.
297     */
298    protected void train_format(MessageFormatter formatter, String result, Object... arguments)
299    {
300        expect(formatter.format(arguments)).andReturn(result);
301    }
302
303    protected final void train_get(Messages messages, String key, String message)
304    {
305        expect(messages.get(key)).andReturn(message).atLeastOnce();
306    }
307
308    protected final void train_getLocale(ThreadLocale threadLocale, Locale locale)
309    {
310        expect(threadLocale.getLocale()).andReturn(locale);
311    }
312
313    protected final void train_getLogger(LoggerSource source, String serviceId, Logger logger)
314    {
315        expect(source.getLogger(serviceId)).andReturn(logger).atLeastOnce();
316    }
317
318    protected final void train_getMessageFormatter(Messages messages, String key, MessageFormatter formatter)
319    {
320        expect(messages.getFormatter(key)).andReturn(formatter).atLeastOnce();
321    }
322
323    protected final void train_getPath(Resource r, String path)
324    {
325        expect(r.getPath()).andReturn(path).atLeastOnce();
326    }
327
328    protected final <T> void train_getService(ObjectLocator locator, Class<T> serviceInterface, T service)
329    {
330        expect(locator.getService(serviceInterface)).andReturn(service);
331    }
332
333    protected final <T> void train_getService(ObjectLocator locator, String serviceId, Class<T> serviceInterface,
334            T service)
335    {
336        expect(locator.getService(serviceId, serviceInterface)).andReturn(service);
337    }
338
339    protected final void train_getServiceId(ServiceDef def, String serviceId)
340    {
341        expect(def.getServiceId()).andReturn(serviceId).atLeastOnce();
342    }
343
344    protected final void train_getServiceId(ServiceResources resources, String serviceId)
345    {
346        expect(resources.getServiceId()).andReturn(serviceId).atLeastOnce();
347    }
348
349    protected final void train_getServiceInterface(ServiceDef def, Class serviceInterface)
350    {
351        expect(def.getServiceInterface()).andReturn(serviceInterface).atLeastOnce();
352    }
353
354    protected final void train_getServiceInterface(ServiceResources resources, Class serviceInterface)
355    {
356        expect(resources.getServiceInterface()).andReturn(serviceInterface).atLeastOnce();
357    }
358
359    protected final void train_getLogger(ServiceResources resources, Logger log)
360    {
361        expect(resources.getLogger()).andReturn(log).atLeastOnce();
362    }
363
364    protected final void train_isDebugEnabled(Logger log, boolean debugEnabled)
365    {
366        expect(log.isDebugEnabled()).andReturn(debugEnabled);
367    }
368
369    protected final void train_isTraceEnabled(Logger log, boolean traceEnabled)
370    {
371        expect(log.isTraceEnabled()).andReturn(traceEnabled);
372    }
373
374    protected final void train_matches(DecoratorDef decoratorDef, ServiceDef serviceDef, boolean matches)
375    {
376        expect(decoratorDef.matches(serviceDef)).andReturn(matches);
377    }
378
379    protected final void train_matches(AdvisorDef advisorDef, ServiceDef serviceDef, boolean matches)
380    {
381        expect(advisorDef.matches(serviceDef)).andReturn(matches);
382    }
383
384    protected final <T> void train_provide(ObjectProvider provider, Class<T> objectType,
385            AnnotationProvider annotationProvider, ObjectLocator locator, T object)
386    {
387        expect(provider.provide(objectType, annotationProvider, locator)).andReturn(object);
388    }
389
390    protected final void train_toURL(Resource resource, URL url)
391    {
392        expect(resource.toURL()).andReturn(url).atLeastOnce();
393    }
394
395    protected final <T extends Annotation> void train_getAnnotation(AnnotationProvider annotationProvider,
396            Class<T> annotationClass, T annotation)
397    {
398        expect(annotationProvider.getAnnotation(annotationClass)).andReturn(annotation);
399    }
400
401    protected final MasterObjectProvider mockMasterObjectProvider()
402    {
403        return newMock(MasterObjectProvider.class);
404    }
405
406    protected final void train_value(IntermediateType it, Class value)
407    {
408        expect(it.value()).andReturn(value);
409    }
410
411    protected final IntermediateType newIntermediateType()
412    {
413        return newMock(IntermediateType.class);
414    }
415
416    protected final PropertyAdapter mockPropertyAdapter()
417    {
418        return newMock(PropertyAdapter.class);
419    }
420
421    protected final ClassPropertyAdapter mockClassPropertyAdapter()
422    {
423        return newMock(ClassPropertyAdapter.class);
424    }
425
426    protected final PropertyAccess mockPropertyAccess()
427    {
428        return newMock(PropertyAccess.class);
429    }
430
431    protected final <T> void train_autobuild(ObjectLocator locator, Class<T> beanClass, T instance)
432    {
433        expect(locator.autobuild(beanClass)).andReturn(instance);
434    }
435
436    protected final PerthreadManager mockPerthreadManager()
437    {
438        return newMock(PerthreadManager.class);
439    }
440
441    protected final ServiceResources mockServiceResources(OperationTracker tracker)
442    {
443        ServiceResources resources = mockServiceResources();
444
445        train_getTracker(resources, tracker);
446
447        return resources;
448    }
449
450    protected final void train_getTracker(ServiceResources resources, OperationTracker tracker)
451    {
452        expect(resources.getTracker()).andReturn(tracker).atLeastOnce();
453    }
454
455    protected final ServiceBuilderResources mockServiceBuilderResources(OperationTracker tracker)
456    {
457        ServiceBuilderResources resources = mockServiceBuilderResources();
458
459        train_getTracker(resources, tracker);
460
461        return resources;
462    }
463
464    protected final void train_valueForSymbol(SymbolSource symbolSource, String symbolName, String value)
465    {
466        expect(symbolSource.valueForSymbol(symbolName)).andReturn(value).atLeastOnce();
467    }
468
469    /**
470     * Touches the file, changing the last modified time to the current time.
471     * Does not return until the last modified time for the file actually changes (how long that takes
472     * is JDK, OS and file system dependent).
473     */
474    protected final void touch(File f) throws Exception
475    {
476        long startModified = f.lastModified();
477
478        int index = 0;
479
480        while (true)
481        {
482            f.setLastModified(System.currentTimeMillis());
483
484            long newModified = f.lastModified();
485
486            if (newModified != startModified)
487                return;
488
489            // Sleep an ever increasing amount, to ensure that the filesystem
490            // catches the change to the file. The Ubuntu CI Server appears
491            // to need longer waits.
492
493            sleep(50 * (2 ^ index++));
494        }
495    }
496}