/* * Copyright 2006 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package jdave.runner; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collection; import java.util.List; import jdave.Specification; /** * @author Joni Freeman * @author Pekka Enberg */ public abstract class Context { private final Class<? extends Specification<?>> specType; private final Class<?> contextType; public Context(final Class<? extends Specification<?>> specType, final Class<?> contextType) { this.specType = specType; this.contextType = contextType; } public String getName() { return contextType.getSimpleName(); } protected abstract Behavior newBehavior(Method method, Class<? extends Specification<?>> specType, Class<?> contextType); void run(final ISpecVisitor callback) { for (final Method method : ClassMemberSorter.getMethods(contextType)) { if (isBehavior(method)) { callback.onBehavior(newBehavior(method, specType, contextType)); } } } private boolean isBehavior(final Method method) { return newIntrospection().isBehavior(method); } public boolean isContextClass() { return newIntrospection().isContextClass(specType, contextType); } private ISpecIntrospection newIntrospection() { try { Class<?> clazz = specType; do { final Collection<Class<?>> types = typesOf(clazz); for (final Class<?> type : types) { if (hasStrategy(type)) { return type.getAnnotation(IntrospectionStrategy.class).value() .newInstance(); } } } while ((clazz = clazz.getSuperclass()) != null); } catch (final Exception e) { throw new RuntimeException(e); } return new DefaultSpecIntrospection(); } private Collection<Class<?>> typesOf(final Class<?> clazz) { final List<Class<?>> types = new ArrayList<Class<?>>(); types.add(clazz); final Class<?>[] interfaces = clazz.getInterfaces(); for (final Class<?> anInterface : interfaces) { types.add(anInterface); } return types; } boolean hasStrategy(final Class<?> type) { return type.isAnnotationPresent(IntrospectionStrategy.class); } }