
org.spockframework.tapestry.TapestryInterceptor Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of spock-tapestry Show documentation
Show all versions of spock-tapestry Show documentation
Spock's Tapestry Module provides support for testing Tapestry 5 based applications.
/*
* Copyright 2009 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 org.spockframework.tapestry;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import org.apache.tapestry5.ioc.AnnotationProvider;
import org.apache.tapestry5.ioc.Registry;
import org.apache.tapestry5.ioc.RegistryBuilder;
import org.apache.tapestry5.ioc.annotations.Autobuild;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.ioc.annotations.InjectService;
import org.spockframework.runtime.extension.AbstractMethodInterceptor;
import org.spockframework.runtime.extension.IMethodInvocation;
import org.spockframework.runtime.model.FieldInfo;
import org.spockframework.runtime.model.SpecInfo;
import org.spockframework.util.ReflectionUtil;
import spock.lang.Shared;
import spock.lang.Specification;
/**
* Controls creation, startup and shutdown of the Tapestry container,
* and injects specifications with Tapestry-provided objects.
*
* @author Peter Niederwieser
*/
public class TapestryInterceptor extends AbstractMethodInterceptor {
private final SpecInfo spec;
private final Set> modules;
private Registry registry;
public TapestryInterceptor(SpecInfo spec, Set> modules) {
this.spec = spec;
this.modules = modules;
}
@Override
public void interceptSharedInitializerMethod(IMethodInvocation invocation) throws Throwable {
runBeforeRegistryCreatedMethods((Specification) invocation.getSharedInstance());
createAndStartupRegistry();
injectServices(invocation.getSharedInstance(), true);
invocation.proceed();
}
@Override
public void interceptCleanupSpecMethod(IMethodInvocation invocation) throws Throwable {
try {
invocation.proceed();
} finally {
shutdownRegistry();
}
}
@Override
public void interceptInitializerMethod(IMethodInvocation invocation) throws Throwable {
injectServices(invocation.getInstance(), false);
invocation.proceed();
}
private void runBeforeRegistryCreatedMethods(Specification spec) {
Object returnValue;
for (Method method : findAllBeforeRegistryCreatedMethods()) {
returnValue = ReflectionUtil.invokeMethod(spec, method);
// Return values of a type other than Registry are silently ignored.
// This avoids problems in case the method unintentionally returns a
// value (which is common due to Groovy's implicit return).
if (returnValue instanceof Registry)
registry = (Registry) returnValue;
}
}
private void createAndStartupRegistry() {
if (registry != null) return;
RegistryBuilder builder = new RegistryBuilder();
builder.add(ExtensionModule.class);
for (Class> module : modules) builder.add(module);
registry = builder.build();
registry.performRegistryStartup();
}
private List findAllBeforeRegistryCreatedMethods() {
List methods = new ArrayList();
for (SpecInfo curr : spec.getSpecsTopToBottom()) {
Method method = ReflectionUtil.getDeclaredMethodByName(curr.getReflection(), "beforeRegistryCreated");
if (method != null) {
method.setAccessible(true);
methods.add(method);
}
}
return methods;
}
private void injectServices(Object target, boolean sharedFields) throws IllegalAccessException {
for (final FieldInfo field : spec.getAllFields()) {
Field rawField = field.getReflection();
if ((rawField.isAnnotationPresent(Inject.class)
|| ReflectionUtil.isAnnotationPresent(rawField, "javax.inject.Inject")
|| rawField.isAnnotationPresent(Autobuild.class))
&& rawField.isAnnotationPresent(Shared.class) == sharedFields) {
Object value = registry.getObject(rawField.getType(), createAnnotationProvider(field));
rawField.setAccessible(true);
rawField.set(target, value);
} else if (rawField.isAnnotationPresent(InjectService.class)) {
String serviceName = rawField.getAnnotation(InjectService.class).value();
Object value = registry.getService(serviceName, rawField.getType());
rawField.setAccessible(true);
rawField.set(target, value);
}
}
}
private AnnotationProvider createAnnotationProvider(final FieldInfo field) {
return new AnnotationProvider() {
public T getAnnotation(Class annotationClass) {
return field.getAnnotation(annotationClass);
}
};
}
private void shutdownRegistry() {
if (registry != null)
registry.shutdown();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy