001// Copyright 2006, 2007, 2008, 2009, 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.junit; 016 017import java.lang.reflect.InvocationTargetException; 018import java.lang.reflect.Method; 019import java.lang.reflect.Modifier; 020import java.util.ArrayList; 021import java.util.Collections; 022import java.util.List; 023 024import org.apache.tapestry5.ioc.RegistryBuilder; 025import org.junit.runners.model.InitializationError; 026 027/** 028 * Helper class used by the {@link TapestryIOCJUnit4ClassRunner} to manage the test registry 029 */ 030public class TestRegistryManager { 031 private final Registry annotation; 032 private final List<Method> moduleDefFactories; 033 034 private org.apache.tapestry5.ioc.Registry registry; 035 036 public TestRegistryManager(Class<?> type) throws InitializationError { 037 super(); 038 039 Registry annotation = type.getAnnotation(Registry.class); 040 if (annotation == null) { 041 throw new InitializationError(type.getName() + " does not specify a @Registry"); 042 } 043 044 this.annotation = annotation; 045 this.moduleDefFactories = findModuleDefFactories(type); 046 } 047 048 protected List<Method> findModuleDefFactories(Class<?> type) throws InitializationError { 049 List<Method> factoryMethods = new ArrayList<Method>(); 050 for (Method method : type.getMethods()) { 051 if (method.getAnnotation(ModuleDef.class) != null) { 052 validateModuleDefMethod(method); 053 factoryMethods.add(method); 054 } 055 } 056 return factoryMethods.isEmpty() ? Collections.<Method> emptyList() : factoryMethods; 057 } 058 059 protected void validateModuleDefMethod(Method method) throws InitializationError { 060 int modifiers = method.getModifiers(); 061 if (method.getParameterTypes().length != 0 062 || !Modifier.isStatic(modifiers) 063 || !Modifier.isPublic(modifiers)) { 064 065 throw new InitializationError( 066 String.format("@ModuleDef method %s must be public static and accept no arguments", 067 method.getName())); 068 } 069 if (!org.apache.tapestry5.ioc.def.ModuleDef.class.isAssignableFrom(method.getReturnType())) { 070 throw new InitializationError( 071 String.format("@ModuleDef method %s return type %s is not valid", 072 method.getName(), method.getReturnType().getName())); 073 } 074 } 075 076 /** 077 * Get the existing registry or create one if required. 078 * @return The test Registry 079 * @throws Exception 080 */ 081 public org.apache.tapestry5.ioc.Registry getOrCreateRegistry() throws Exception { 082 if (registry == null) { 083 RegistryBuilder builder = new RegistryBuilder(); 084 if (annotation.modules() != null) { 085 builder.add(annotation.modules()); 086 } 087 for (Method moduleDefFactory : moduleDefFactories) { 088 try { 089 org.apache.tapestry5.ioc.def.ModuleDef moduleDef = 090 (org.apache.tapestry5.ioc.def.ModuleDef) moduleDefFactory.invoke(null); 091 092 builder.add(moduleDef); 093 } catch (InvocationTargetException e) { 094 if (e.getTargetException() instanceof Exception) { 095 throw (Exception) e.getTargetException(); 096 } 097 throw e; 098 } 099 } 100 registry = builder.build(); 101 registry.performRegistryStartup(); 102 } 103 return registry; 104 } 105 106 /** 107 * Notify that the current test method has completed 108 */ 109 public void afterTestMethod() { 110 if (annotation.shutdown() == RegistryShutdownType.AFTER_METHOD) { 111 shutdownRegistry(); 112 } 113 } 114 115 /** 116 * Notify that the current test class has completed 117 */ 118 public void afterTestClass() { 119 if (annotation.shutdown() == RegistryShutdownType.AFTER_CLASS) { 120 shutdownRegistry(); 121 } 122 } 123 124 protected void shutdownRegistry() { 125 try { 126 registry.shutdown(); 127 } finally { 128 registry = null; 129 } 130 } 131}