org.jboss.arquillian.drone.impl.InjectionPoints Maven / Gradle / Ivy
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2011, Red Hat Middleware LLC, and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* 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.jboss.arquillian.drone.impl;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.jboss.arquillian.container.test.api.OperateOnDeployment;
import org.jboss.arquillian.drone.api.annotation.Drone;
import org.jboss.arquillian.drone.api.annotation.lifecycle.ClassLifecycle;
import org.jboss.arquillian.drone.api.annotation.lifecycle.MethodLifecycle;
import org.jboss.arquillian.drone.spi.DroneContext;
import org.jboss.arquillian.drone.spi.DronePoint;
import org.jboss.arquillian.drone.spi.deployment.DeploymentNameKey;
// FIXME make this class not static and do the API a better way
final class InjectionPoints {
private InjectionPoints() {
}
static Set> allInClass(DroneContext context, Class> cls) {
List> dronePoints = new ArrayList>();
dronePoints.addAll(fieldsInClass(context, cls).values());
for (DronePoint>[] methodDronePoints : parametersInClass(context, cls).values()) {
for (DronePoint> dronePoint : methodDronePoints) {
if (dronePoint == null) {
continue;
}
dronePoints.add(dronePoint);
}
}
// We want no duplicates
return new HashSet>(dronePoints);
}
static Map> fieldsInClass(DroneContext context, Class> cls) {
Map> injectionPoints = new HashMap>();
List fields = SecurityActions.getFieldsWithAnnotation(cls, Drone.class);
for (Field field : fields) {
DronePoint> dronePoint = resolveInjectionPoint(context, field);
injectionPoints.put(field, dronePoint);
}
return injectionPoints;
}
static Map[]> parametersInClass(DroneContext context, Class> cls) {
Map[]> mergedInjectionPoints = new HashMap[]>();
Method[] methods = cls.getMethods();
for (Method method : methods) {
DronePoint>[] dronePoints = parametersInMethod(context, method);
mergedInjectionPoints.put(method, dronePoints);
}
return mergedInjectionPoints;
}
static DronePoint>[] parametersInMethod(DroneContext context, Method method) {
Class>[] parameters = method.getParameterTypes();
Map droneParameters = SecurityActions.getParametersWithAnnotation(method, Drone.class);
DronePoint>[] dronePoints = new DronePoint>[parameters.length];
for (int i = 0; i < parameters.length; i++) {
if (!droneParameters.containsKey(i)) {
dronePoints[i] = null;
continue;
}
Annotation[] parameterAnnotations = droneParameters.get(i);
Class> droneType = parameters[i];
DronePoint> dronePoint = resolveInjectionPoint(context, droneType, parameterAnnotations);
dronePoints[i] = dronePoint;
}
return dronePoints;
}
static DronePoint> resolveInjectionPoint(DroneContext context, Field field) {
Class> droneType = field.getType();
Annotation[] annotations = SecurityActions.getAnnotations(field);
return createInjectionPoint(context, droneType, annotations, DronePoint.Lifecycle.CLASS);
}
static DronePoint resolveInjectionPoint(DroneContext context, Class droneType,
Annotation[] parameterAnnotations) {
return createInjectionPoint(context, droneType, parameterAnnotations, DronePoint.Lifecycle.METHOD);
}
// We can't instantiate class with wildcard generic parameter directly, so we delegate it through parameter
static DronePoint createInjectionPoint(DroneContext context, Class droneType,
Annotation[] annotations,
DronePoint.Lifecycle defaultLifecycle) {
Class extends Annotation> scopeAnnotation = SecurityActions.getScope(annotations);
OperateOnDeployment operateOnDeployment = SecurityActions.findAnnotation(annotations,
OperateOnDeployment.class);
DronePoint.Lifecycle lifecycle = scopeForAnnotation(scopeAnnotation, operateOnDeployment, defaultLifecycle);
DronePoint dronePoint = new DronePointImpl(droneType, lifecycle, annotations);
// We register the drone point into context immediately
context.get(dronePoint);
if (lifecycle == DronePoint.Lifecycle.DEPLOYMENT) {
String deployment = operateOnDeployment.value();
context.get(dronePoint).setMetadata(DeploymentNameKey.class, deployment);
}
return dronePoint;
}
static DronePoint.Lifecycle scopeForAnnotation(Class extends Annotation> annotation,
OperateOnDeployment deployment,
DronePoint.Lifecycle defaultLifecycle) {
if (annotation == ClassLifecycle.class) {
return DronePoint.Lifecycle.CLASS;
} else if (annotation == MethodLifecycle.class) {
return DronePoint.Lifecycle.METHOD;
} else {
if (deployment != null) {
return DronePoint.Lifecycle.DEPLOYMENT;
} else {
return defaultLifecycle;
}
}
}
}