forked from gscokart/jbehave-core
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
JBEHAVE-900 Honor order in @UsingSteps instances
- Loading branch information
Jonas Olsson
authored and
Jonas Olsson
committed
Apr 13, 2013
1 parent
946a651
commit 4ee794d
Showing
4 changed files
with
312 additions
and
143 deletions.
There are no files selected for viewing
227 changes: 127 additions & 100 deletions
227
jbehave-core/src/main/java/org/jbehave/core/configuration/AnnotationFinder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,100 +1,127 @@ | ||
package org.jbehave.core.configuration; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Method; | ||
import java.util.ArrayList; | ||
import java.util.HashSet; | ||
import java.util.List; | ||
import java.util.Set; | ||
|
||
import org.apache.commons.lang.StringUtils; | ||
|
||
/** | ||
* Helper class to find and retrieve annotated values | ||
* | ||
* @author Cristiano Gavião | ||
* @author Brian Repko | ||
* @author Mauro Talevi | ||
*/ | ||
public class AnnotationFinder { | ||
|
||
private final Class<?> annotatedClass; | ||
|
||
public AnnotationFinder(Class<?> annotatedClass) { | ||
this.annotatedClass = annotatedClass; | ||
} | ||
|
||
public <A extends Annotation> boolean isAnnotationPresent(Class<A> annotationClass) { | ||
return getAnnotation(annotationClass) != null; | ||
} | ||
|
||
public <A extends Annotation> boolean isAnnotationValuePresent(Class<A> annotationClass, String memberName) { | ||
Annotation annotation = getAnnotation(annotationClass); | ||
return annotation != null && getAnnotationValue(annotation, memberName) != null; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public <T, A extends Annotation> T getAnnotatedValue(Class<A> annotationClass, Class<T> memberType, | ||
String memberName) { | ||
Annotation annotation = getAnnotation(annotationClass); | ||
if (annotation != null) { | ||
return (T) getAnnotationValue(annotation, memberName); | ||
} | ||
throw new AnnotationRequired(annotatedClass, annotationClass); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public <T, A extends Annotation> List<T> getAnnotatedValues(Class<A> annotationClass, Class<T> type, | ||
String memberName) { | ||
Set<T> set = new HashSet<T>(); | ||
if (!isAnnotationPresent(annotationClass)) { | ||
return new ArrayList<T>(set); | ||
} | ||
Object[] values = getAnnotatedValue(annotationClass, Object[].class, memberName); | ||
for (Object value : values) { | ||
set.add((T) value); | ||
} | ||
boolean inheritValues = true; | ||
String inheritMemberName = createInheritMemberName(memberName); | ||
if (isAnnotationValuePresent(annotationClass, inheritMemberName)) { | ||
inheritValues = getAnnotatedValue(annotationClass, boolean.class, inheritMemberName); | ||
} | ||
if (inheritValues) { | ||
Class<?> superClass = annotatedClass.getSuperclass(); | ||
if (superClass != null && superClass != Object.class) { | ||
set.addAll(new AnnotationFinder(superClass).getAnnotatedValues(annotationClass, type, memberName)); | ||
} | ||
} | ||
return new ArrayList<T>(set); | ||
} | ||
|
||
/** | ||
* Creates the inherit member name by prefixing "inherit" to the capitalized | ||
* member name. | ||
* | ||
* @param memberName | ||
* @return The inherit member name | ||
*/ | ||
protected String createInheritMemberName(String memberName) { | ||
return "inherit" + StringUtils.capitalize(memberName); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public <T, A extends Annotation> List<Class<T>> getAnnotatedClasses(Class<A> annotationClass, Class<T> type, | ||
String memberName) { | ||
return (List<Class<T>>) getAnnotatedValues(annotationClass, type.getClass(), memberName); | ||
} | ||
|
||
protected <A extends Annotation> Annotation getAnnotation(Class<A> annotationClass) { | ||
return annotatedClass.getAnnotation(annotationClass); | ||
} | ||
|
||
protected Object getAnnotationValue(Annotation annotation, String attributeName) { | ||
try { | ||
Method method = annotation.annotationType().getDeclaredMethod(attributeName, new Class[0]); | ||
return method.invoke(annotation); | ||
} catch (Exception e) { | ||
return null; | ||
} | ||
} | ||
} | ||
package org.jbehave.core.configuration; | ||
|
||
import java.lang.annotation.Annotation; | ||
import java.lang.reflect.Method; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
|
||
import org.apache.commons.lang.StringUtils; | ||
|
||
/** | ||
* Helper class to find and retrieve annotated values | ||
* | ||
* @author Cristiano Gavião | ||
* @author Brian Repko | ||
* @author Mauro Talevi | ||
*/ | ||
public class AnnotationFinder | ||
{ | ||
|
||
private final Class<?> annotatedClass; | ||
|
||
public AnnotationFinder(Class<?> annotatedClass) | ||
{ | ||
this.annotatedClass = annotatedClass; | ||
} | ||
|
||
public <A extends Annotation> boolean isAnnotationPresent( | ||
Class<A> annotationClass) | ||
{ | ||
return getAnnotation(annotationClass) != null; | ||
} | ||
|
||
public <A extends Annotation> boolean isAnnotationValuePresent( | ||
Class<A> annotationClass, String memberName) | ||
{ | ||
Annotation annotation = getAnnotation(annotationClass); | ||
return annotation != null | ||
&& getAnnotationValue(annotation, memberName) != null; | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public <T, A extends Annotation> T getAnnotatedValue( | ||
Class<A> annotationClass, Class<T> memberType, String memberName) | ||
{ | ||
Annotation annotation = getAnnotation(annotationClass); | ||
if (annotation != null) | ||
{ | ||
return (T) getAnnotationValue(annotation, memberName); | ||
} | ||
throw new AnnotationRequired(annotatedClass, annotationClass); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public <T, A extends Annotation> List<T> getAnnotatedValues( | ||
Class<A> annotationClass, Class<T> type, String memberName) | ||
{ | ||
List<T> list = new LinkedList<T>(); | ||
if (!isAnnotationPresent(annotationClass)) | ||
{ | ||
return list; | ||
} | ||
Object[] values = getAnnotatedValue(annotationClass, Object[].class, | ||
memberName); | ||
for (Object value : values) | ||
{ | ||
list.add((T) value); | ||
} | ||
boolean inheritValues = true; | ||
String inheritMemberName = createInheritMemberName(memberName); | ||
if (isAnnotationValuePresent(annotationClass, inheritMemberName)) | ||
{ | ||
inheritValues = getAnnotatedValue(annotationClass, boolean.class, | ||
inheritMemberName); | ||
} | ||
if (inheritValues) | ||
{ | ||
Class<?> superClass = annotatedClass.getSuperclass(); | ||
if (superClass != null && superClass != Object.class) | ||
{ | ||
list.addAll(new AnnotationFinder(superClass) | ||
.getAnnotatedValues(annotationClass, type, memberName)); | ||
} | ||
} | ||
return list; | ||
} | ||
|
||
/** | ||
* Creates the inherit member name by prefixing "inherit" to the capitalized | ||
* member name. | ||
* | ||
* @param memberName | ||
* @return The inherit member name | ||
*/ | ||
protected String createInheritMemberName(String memberName) | ||
{ | ||
return "inherit" + StringUtils.capitalize(memberName); | ||
} | ||
|
||
@SuppressWarnings("unchecked") | ||
public <T, A extends Annotation> List<Class<T>> getAnnotatedClasses( | ||
Class<A> annotationClass, Class<T> type, String memberName) | ||
{ | ||
return (List<Class<T>>) getAnnotatedValues(annotationClass, | ||
type.getClass(), memberName); | ||
} | ||
|
||
protected <A extends Annotation> Annotation getAnnotation( | ||
Class<A> annotationClass) | ||
{ | ||
return annotatedClass.getAnnotation(annotationClass); | ||
} | ||
|
||
protected Object getAnnotationValue(Annotation annotation, | ||
String attributeName) | ||
{ | ||
try | ||
{ | ||
Method method = annotation.annotationType().getDeclaredMethod( | ||
attributeName, new Class[0]); | ||
return method.invoke(annotation); | ||
} | ||
catch (Exception e) | ||
{ | ||
return null; | ||
} | ||
} | ||
} |
97 changes: 54 additions & 43 deletions
97
jbehave-core/src/main/java/org/jbehave/core/steps/InstanceStepsFactory.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,43 +1,54 @@ | ||
package org.jbehave.core.steps; | ||
|
||
import java.util.ArrayList; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.jbehave.core.configuration.Configuration; | ||
|
||
import static java.util.Arrays.asList; | ||
|
||
/** | ||
* An {@link InjectableStepsFactory} that is provided Object instances. | ||
*/ | ||
public class InstanceStepsFactory extends AbstractStepsFactory { | ||
|
||
private final Map<Class<?>,Object> stepsInstances = new HashMap<Class<?>, Object>(); | ||
|
||
public InstanceStepsFactory(Configuration configuration, Object... stepsInstances) { | ||
this(configuration, asList(stepsInstances)); | ||
} | ||
|
||
public InstanceStepsFactory(Configuration configuration, List<Object> stepsInstances) { | ||
super(configuration); | ||
for (Object instance : stepsInstances) { | ||
this.stepsInstances.put(instance.getClass(), instance); | ||
} | ||
} | ||
|
||
@Override | ||
protected List<Class<?>> stepsTypes() { | ||
return new ArrayList<Class<?>>(stepsInstances.keySet()); | ||
} | ||
|
||
public Object createInstanceOfType(Class<?> type) { | ||
Object instance = stepsInstances.get(type); | ||
if ( instance == null ){ | ||
throw new StepsInstanceNotFound(type, this); | ||
} | ||
return instance; | ||
} | ||
|
||
} | ||
package org.jbehave.core.steps; | ||
|
||
import static java.util.Arrays.asList; | ||
|
||
import java.util.HashMap; | ||
import java.util.LinkedList; | ||
import java.util.List; | ||
import java.util.Map; | ||
|
||
import org.jbehave.core.configuration.Configuration; | ||
|
||
/** | ||
* An {@link InjectableStepsFactory} that is provided Object instances. | ||
*/ | ||
public class InstanceStepsFactory extends AbstractStepsFactory | ||
{ | ||
|
||
private final List<Class<?>> stepsTypes = new LinkedList<Class<?>>(); | ||
private final Map<Class<?>, Object> stepsInstances = new HashMap<Class<?>, Object>(); | ||
|
||
public InstanceStepsFactory(Configuration configuration, | ||
Object... stepsInstances) | ||
{ | ||
this(configuration, asList(stepsInstances)); | ||
} | ||
|
||
public InstanceStepsFactory(Configuration configuration, | ||
List<Object> stepsInstances) | ||
{ | ||
super(configuration); | ||
for (Object instance : stepsInstances) | ||
{ | ||
this.stepsTypes.add(instance.getClass()); | ||
this.stepsInstances.put(instance.getClass(), instance); | ||
} | ||
} | ||
|
||
@Override | ||
protected List<Class<?>> stepsTypes() | ||
{ | ||
return stepsTypes; | ||
} | ||
|
||
public Object createInstanceOfType(Class<?> type) | ||
{ | ||
Object instance = stepsInstances.get(type); | ||
if (instance == null) | ||
{ | ||
throw new StepsInstanceNotFound(type, this); | ||
} | ||
return instance; | ||
} | ||
|
||
} |
Oops, something went wrong.