Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright 2006-2016 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 com.consol.citrus.annotations;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import com.consol.citrus.Citrus;
import com.consol.citrus.CitrusContext;
import com.consol.citrus.GherkinTestActionRunner;
import com.consol.citrus.TestActionRunner;
import com.consol.citrus.TestCaseRunner;
import com.consol.citrus.context.TestContext;
import com.consol.citrus.exceptions.CitrusRuntimeException;
import com.consol.citrus.spi.BindToRegistry;
import com.consol.citrus.spi.ReferenceRegistry;
import com.consol.citrus.validation.MessageValidator;
import com.consol.citrus.validation.context.ValidationContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ReflectionUtils;
/**
* Dependency injection support for {@link CitrusFramework}, {@link CitrusResource} and {@link CitrusEndpoint} annotations.
*
* @author Christoph Deppisch
* @since 2.5
*/
public abstract class CitrusAnnotations {
/** Logger */
private static final Logger LOG = LoggerFactory.getLogger(CitrusAnnotations.class);
/**
* Prevent instantiation.
*/
private CitrusAnnotations() {
super();
}
/**
* Creates new Citrus instance and injects all supported components and endpoints to target object using annotations.
* @param target
*/
public static void injectAll(final Object target) {
injectAll(target, Citrus.newInstance());
}
/**
* Creates new Citrus test context and injects all supported components and endpoints to target object using annotations.
* @param target
*/
public static void injectAll(final Object target, final Citrus citrusFramework) {
injectAll(target, citrusFramework, citrusFramework.getCitrusContext().createTestContext());
}
/**
* Injects all supported components and endpoints to target object using annotations.
* @param target
*/
public static void injectAll(final Object target, final Citrus citrusFramework, final TestContext context) {
injectCitrusFramework(target, citrusFramework);
CitrusContext citrusContext = citrusFramework.getCitrusContext();
injectCitrusContext(target, citrusContext);
parseConfiguration(target, citrusContext);
injectEndpoints(target, context);
injectTestContext(target, context);
}
/**
* Reads all {@link CitrusEndpoint} and {@link CitrusEndpointConfig} related annotations on target object field declarations and
* injects proper endpoint instances.
*
* @param target
* @param context
*/
public static void injectEndpoints(final Object target, final TestContext context) {
CitrusEndpointAnnotations.injectEndpoints(target, context);
}
/**
* Inject Citrus framework instance to the test class fields with {@link CitrusFramework} annotation.
* @param testCase
* @param citrusFramework
*/
public static void injectCitrusFramework(final Object testCase, final Citrus citrusFramework) {
ReflectionUtils.doWithFields(testCase.getClass(), new ReflectionUtils.FieldCallback() {
@Override
public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
LOG.trace(String.format("Injecting Citrus framework instance on test class field '%s'", field.getName()));
ReflectionUtils.setField(field, testCase, citrusFramework);
}
}, new ReflectionUtils.FieldFilter() {
@Override
public boolean matches(Field field) {
if (field.isAnnotationPresent(CitrusFramework.class) &&
Citrus.class.isAssignableFrom(field.getType())) {
if (!field.isAccessible()) {
ReflectionUtils.makeAccessible(field);
}
return true;
}
return false;
}
});
}
/**
* Inject Citrus context instance to the test class fields with {@link CitrusResource} annotation.
* @param target
* @param context
*/
public static void injectCitrusContext(final Object target, final CitrusContext context) {
ReflectionUtils.doWithFields(target.getClass(), field -> {
LOG.trace(String.format("Injecting Citrus context instance on test class field '%s'", field.getName()));
ReflectionUtils.setField(field, target, context);
}, field -> {
if (field.isAnnotationPresent(CitrusResource.class) && CitrusContext.class.isAssignableFrom(field.getType())) {
if (!field.isAccessible()) {
ReflectionUtils.makeAccessible(field);
}
return true;
}
return false;
});
}
/**
* Inject test context instance to the test class fields with {@link CitrusResource} annotation.
* @param target
* @param context
*/
public static void injectTestContext(final Object target, final TestContext context) {
ReflectionUtils.doWithFields(target.getClass(), field -> {
Class> type = field.getType();
if (TestContext.class.isAssignableFrom(type)) {
LOG.trace(String.format("Injecting test context instance on test class field '%s'", field.getName()));
ReflectionUtils.setField(field, target, context);
} else {
throw new CitrusRuntimeException("Not able to provide a Citrus resource injection for type " + type);
}
}, field -> {
if (field.isAnnotationPresent(CitrusResource.class) && TestContext.class.isAssignableFrom(field.getType())) {
if (!field.isAccessible()) {
ReflectionUtils.makeAccessible(field);
}
return true;
}
return false;
});
}
/**
* Inject test runner instance to the test class fields with {@link CitrusResource} annotation.
* @param target
* @param runner
*/
public static void injectTestRunner(final Object target, final TestCaseRunner runner) {
ReflectionUtils.doWithFields(target.getClass(), field -> {
Class> type = field.getType();
if (TestCaseRunner.class.isAssignableFrom(type)) {
LOG.trace(String.format("Injecting test runner instance on test class field '%s'", field.getName()));
ReflectionUtils.setField(field, target, runner);
} else {
throw new CitrusRuntimeException("Not able to provide a Citrus resource injection for type " + type);
}
}, field -> {
if (field.isAnnotationPresent(CitrusResource.class) && TestCaseRunner.class.isAssignableFrom(field.getType())) {
if (!field.isAccessible()) {
ReflectionUtils.makeAccessible(field);
}
return true;
}
return false;
});
injectTestActionRunner(target, runner);
injectGherkinTestActionRunner(target, runner);
}
/**
* Inject test action runner instance to the test class fields with {@link CitrusResource} annotation.
* @param target
* @param runner
*/
private static void injectTestActionRunner(final Object target, final TestActionRunner runner) {
ReflectionUtils.doWithFields(target.getClass(), field -> {
Class> type = field.getType();
if (TestActionRunner.class.isAssignableFrom(type)) {
LOG.trace(String.format("Injecting test action runner instance on test class field '%s'", field.getName()));
ReflectionUtils.setField(field, target, runner);
} else {
throw new CitrusRuntimeException("Not able to provide a Citrus resource injection for type " + type);
}
}, field -> {
if (field.isAnnotationPresent(CitrusResource.class) && TestActionRunner.class.isAssignableFrom(field.getType())) {
if (!field.isAccessible()) {
ReflectionUtils.makeAccessible(field);
}
return true;
}
return false;
});
}
/**
* Inject test action runner instance to the test class fields with {@link CitrusResource} annotation.
* @param target
* @param runner
*/
private static void injectGherkinTestActionRunner(final Object target, final GherkinTestActionRunner runner) {
ReflectionUtils.doWithFields(target.getClass(), field -> {
Class> type = field.getType();
if (GherkinTestActionRunner.class.isAssignableFrom(type)) {
LOG.trace(String.format("Injecting test action runner instance on test class field '%s'", field.getName()));
ReflectionUtils.setField(field, target, runner);
} else {
throw new CitrusRuntimeException("Not able to provide a Citrus resource injection for type " + type);
}
}, field -> {
if (field.isAnnotationPresent(CitrusResource.class) && GherkinTestActionRunner.class.isAssignableFrom(field.getType())) {
if (!field.isAccessible()) {
ReflectionUtils.makeAccessible(field);
}
return true;
}
return false;
});
}
/**
* Parse given configuration class and bind annotated fields, methods to reference registry.
* @param configClass
* @param citrusContext
*/
public static void parseConfiguration(Class> configClass, CitrusContext citrusContext) {
try {
parseConfiguration(configClass.getConstructor().newInstance(), citrusContext);
} catch (InvocationTargetException | InstantiationException | IllegalAccessException | NoSuchMethodException e) {
throw new CitrusRuntimeException("Missing or non-accessible default constructor on custom configuration class", e);
}
}
/**
* Parse given configuration class and bind annotated fields, methods to reference registry.
* @param configuration
* @param citrusContext
*/
public static void parseConfiguration(Object configuration, CitrusContext citrusContext) {
Class> configClass = configuration.getClass();
if (configClass.isAnnotationPresent(CitrusConfiguration.class)) {
for (Class> type : configClass.getAnnotation(CitrusConfiguration.class).classes()) {
parseConfiguration(type, citrusContext);
}
}
Arrays.stream(configClass.getDeclaredMethods())
.filter(m -> m.getAnnotation(BindToRegistry.class) != null)
.forEach(m -> {
try {
String name = ReferenceRegistry.getName(m.getAnnotation(BindToRegistry.class), m.getName());
Object component = m.invoke(configuration);
citrusContext.getReferenceResolver().bind(name, component);
if (component instanceof MessageValidator) {
citrusContext.getMessageValidatorRegistry().addMessageValidator(name, (MessageValidator extends ValidationContext>) component);
}
} catch (IllegalAccessException | InvocationTargetException e) {
throw new CitrusRuntimeException("Failed to invoke configuration method", e);
}
});
Arrays.stream(configClass.getDeclaredFields())
.filter(f -> f.getAnnotation(BindToRegistry.class) != null)
.peek(ReflectionUtils::makeAccessible)
.forEach(f -> {
try {
String name = ReferenceRegistry.getName(f.getAnnotation(BindToRegistry.class), f.getName());
Object component = f.get(configuration);
citrusContext.getReferenceResolver().bind(name, component);
if (component instanceof MessageValidator) {
citrusContext.getMessageValidatorRegistry().addMessageValidator(name, (MessageValidator extends ValidationContext>) component);
}
} catch (IllegalAccessException e) {
throw new CitrusRuntimeException("Failed to access configuration field", e);
}
});
}
}