Revision: 1057
http://stripes.svn.sourceforge.net/stripes/?rev=1057&view=rev
Author: bengunter
Date: 2009-02-26 06:48:17 +0000 (Thu, 26 Feb 2009)
Log Message:
-----------
STS-614: Added a type parameter to ObjectPostProcessor interface to indicate
the type it processes. This can still be overridden using @TargetTypes, but
this will often make things easier on developers.
Modified Paths:
--------------
trunk/stripes/src/net/sourceforge/stripes/controller/DefaultObjectFactory.java
trunk/stripes/src/net/sourceforge/stripes/controller/ObjectPostProcessor.java
trunk/tests/src/net/sourceforge/stripes/controller/ObjectFactoryTests.java
Modified:
trunk/stripes/src/net/sourceforge/stripes/controller/DefaultObjectFactory.java
===================================================================
---
trunk/stripes/src/net/sourceforge/stripes/controller/DefaultObjectFactory.java
2009-02-26 06:14:38 UTC (rev 1056)
+++
trunk/stripes/src/net/sourceforge/stripes/controller/DefaultObjectFactory.java
2009-02-26 06:48:17 UTC (rev 1057)
@@ -16,7 +16,9 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Type;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@@ -34,6 +36,7 @@
import net.sourceforge.stripes.config.TargetTypes;
import net.sourceforge.stripes.exception.StripesRuntimeException;
import net.sourceforge.stripes.util.Log;
+import net.sourceforge.stripes.util.ReflectUtil;
import net.sourceforge.stripes.util.TypeHandlerCache;
/**
@@ -45,6 +48,7 @@
* @author Ben Gunter
* @since Stripes 1.5.1
*/
+...@suppresswarnings("unchecked")
public class DefaultObjectFactory implements ObjectFactory {
/**
* An implementation of {...@link ConstructorWrapper} that calls back to
@@ -124,16 +128,30 @@
postProcessors = new TypeHandlerCache<List<ObjectPostProcessor>>();
}
+ // Determine target types from type arguments
+ List<Class<?>> targetTypes = new ArrayList<Class<?>>();
+ Type[] typeArguments =
ReflectUtil.getActualTypeArguments(postProcessor.getClass(),
+ ObjectPostProcessor.class);
+ if ((typeArguments != null) && (typeArguments.length == 1)
+ && !typeArguments[0].equals(Object.class)) {
+ if (typeArguments[0] instanceof Class) {
+ targetTypes.add((Class<?>) typeArguments[0]);
+ }
+ else {
+ log.warn("Type parameter for non-abstract post-processor [",
postProcessor
+ .getClass().getName(), "] is not a class.");
+ }
+ }
+
// Determine target types from annotation; if no annotation then
process everything
TargetTypes annotation =
postProcessor.getClass().getAnnotation(TargetTypes.class);
- Class<?>[] targetTypes;
- if (annotation == null) {
- targetTypes = new Class<?>[] { Object.class };
- }
- else {
- targetTypes = annotation.value();
- }
+ if (annotation != null)
+ targetTypes.addAll(Arrays.asList(annotation.value()));
+ // Default to Object
+ if (targetTypes.isEmpty())
+ targetTypes.add(Object.class);
+
// Register post-processor for each target type
for (Class<?> targetType : targetTypes) {
List<ObjectPostProcessor> list =
postProcessors.getHandler(targetType);
@@ -177,7 +195,6 @@
* @throws InstantiationException if no implementation type has been
configured
* @throws IllegalAccessException if thrown by the JVM during class
instantiation
*/
- @SuppressWarnings("unchecked")
public <T> T newInterfaceInstance(Class<T> interfaceType) throws
InstantiationException,
IllegalAccessException {
Class impl = getImplementingClass(interfaceType);
@@ -308,7 +325,7 @@
List<ObjectPostProcessor> list =
postProcessors.getHandler(object.getClass());
if (list != null) {
for (ObjectPostProcessor postProcessor : list) {
- object = postProcessor.postProcess(object);
+ object = (T) postProcessor.postProcess(object);
}
}
}
Modified:
trunk/stripes/src/net/sourceforge/stripes/controller/ObjectPostProcessor.java
===================================================================
---
trunk/stripes/src/net/sourceforge/stripes/controller/ObjectPostProcessor.java
2009-02-26 06:14:38 UTC (rev 1056)
+++
trunk/stripes/src/net/sourceforge/stripes/controller/ObjectPostProcessor.java
2009-02-26 06:48:17 UTC (rev 1057)
@@ -21,7 +21,7 @@
*
* @author Ben Gunter
*/
-public interface ObjectPostProcessor {
+public interface ObjectPostProcessor<T> {
/**
* Do whatever post-processing is necessary on the object and return it.
It is not absolutely
* required that this method return exactly the same object that was
passed to it, but it is
@@ -30,5 +30,5 @@
* @param object The object to be processed.
* @return The object that was passed in.
*/
- <T> T postProcess(T object);
+ T postProcess(T object);
}
Modified:
trunk/tests/src/net/sourceforge/stripes/controller/ObjectFactoryTests.java
===================================================================
--- trunk/tests/src/net/sourceforge/stripes/controller/ObjectFactoryTests.java
2009-02-26 06:14:38 UTC (rev 1056)
+++ trunk/tests/src/net/sourceforge/stripes/controller/ObjectFactoryTests.java
2009-02-26 06:48:17 UTC (rev 1057)
@@ -25,7 +25,6 @@
import java.util.concurrent.atomic.AtomicInteger;
import net.sourceforge.stripes.StripesTestFixture;
-import net.sourceforge.stripes.config.TargetTypes;
import net.sourceforge.stripes.controller.ObjectFactory.ConstructorWrapper;
import net.sourceforge.stripes.exception.StripesRuntimeException;
import net.sourceforge.stripes.util.Log;
@@ -182,12 +181,10 @@
@Test(groups = "fast")
public void classPostProcessor() {
final String prefix = "Stripey!";
- @TargetTypes(String.class)
- class MyObjectPostProcessor implements ObjectPostProcessor {
- @SuppressWarnings("unchecked")
- public <T> T postProcess(T object) {
+ class MyObjectPostProcessor implements ObjectPostProcessor<String> {
+ public String postProcess(String object) {
log.debug("Altering '", object, "'");
- return (T) (prefix + object);
+ return (prefix + object);
}
}
@@ -218,12 +215,10 @@
@Test(groups = "fast")
public void interfacePostProcessor() {
final String prefix = "Stripey!";
- @TargetTypes(CharSequence.class)
- class MyObjectPostProcessor implements ObjectPostProcessor {
- @SuppressWarnings("unchecked")
- public <T> T postProcess(T object) {
+ class MyObjectPostProcessor implements
ObjectPostProcessor<CharSequence> {
+ public CharSequence postProcess(CharSequence object) {
log.debug("Altering '", object, "'");
- return (T) (prefix + object);
+ return (prefix + object);
}
}
@@ -259,14 +254,11 @@
@Test(groups = "fast")
public void multipleSequentialPostProcessors() {
final AtomicInteger counter = new AtomicInteger(0);
- @TargetTypes(StringBuilder.class)
- class MyObjectPostProcessor implements ObjectPostProcessor {
- @SuppressWarnings("unchecked")
- public <T> T postProcess(T object) {
+ class MyObjectPostProcessor implements
ObjectPostProcessor<StringBuilder> {
+ public StringBuilder postProcess(StringBuilder object) {
log.debug("Altering '", object, "'");
- return (T) ((StringBuilder) object).append("Touched by
").append(
- this.toString().replaceAll(".*@", "")).append("
(counter=").append(
- counter.addAndGet(1)).append(") ... ");
+ return object.append("Touched by
").append(this.toString().replaceAll(".*@", ""))
+ .append("
(counter=").append(counter.addAndGet(1)).append(") ... ");
}
}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Open Source Business Conference (OSBC), March 24-25, 2009, San Francisco, CA
-OSBC tackles the biggest issue in open source: Open Sourcing the Enterprise
-Strategies to boost innovation and cut costs with open source participation
-Receive a $600 discount off the registration fee with the source code: SFAD
http://p.sf.net/sfu/XcvMzF8H
_______________________________________________
Stripes-development mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/stripes-development