    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}