mirror of
https://github.com/apache/struts.git
synced 2026-08-11 01:27:14 +00:00
WW-4210 Adds support for defining converter via class instead of string
This commit is contained in:
@@ -14,4 +14,13 @@ public interface TypeConverterCreator {
|
||||
*/
|
||||
TypeConverter createTypeConverter(String className) throws Exception;
|
||||
|
||||
/**
|
||||
* Creates {@link TypeConverter} from given class
|
||||
*
|
||||
* @param clazz convert class
|
||||
* @return instance of {@link TypeConverter}
|
||||
* @throws Exception when cannot create/cast to {@link TypeConverter}
|
||||
*/
|
||||
TypeConverter createTypeConverter(Class<?> clazz) throws Exception;
|
||||
|
||||
}
|
||||
|
||||
+25
-6
@@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.opensymphony.xwork2.conversion.annotations;
|
||||
|
||||
import com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
@@ -77,11 +79,17 @@ import java.lang.annotation.Target;
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>converter</td>
|
||||
* <td>either this or value</td>
|
||||
* <td>DEPRECATED: either this or value</td>
|
||||
* <td> </td>
|
||||
* <td>The class name of the TypeConverter to be used as converter.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>converterClass</td>
|
||||
* <td>either this or value</td>
|
||||
* <td> </td>
|
||||
* <td>The class of the TypeConverter to be used as converter. XWorkBasicConverter by default.</td>
|
||||
* </tr>
|
||||
* <tr>
|
||||
* <td>value</td>
|
||||
* <td>either converter or this</td>
|
||||
* <td> </td>
|
||||
@@ -106,27 +114,27 @@ import java.lang.annotation.Target;
|
||||
*
|
||||
* private HashMap keyValues = null;
|
||||
*
|
||||
* @TypeConversion(type = ConversionType.APPLICATION, converter = "com.opensymphony.xwork2.util.XWorkBasicConverter")
|
||||
* @TypeConversion(type = ConversionType.APPLICATION)
|
||||
* public void setConvertInt( String convertInt ) {
|
||||
* this.convertInt = convertInt;
|
||||
* }
|
||||
*
|
||||
* @TypeConversion(converter = "com.opensymphony.xwork2.util.XWorkBasicConverter")
|
||||
* @TypeConversion(converterClass = XWorkBasicConverter.class)
|
||||
* public void setConvertDouble( String convertDouble ) {
|
||||
* this.convertDouble = convertDouble;
|
||||
* }
|
||||
*
|
||||
* @TypeConversion(rule = ConversionRule.COLLECTION, converter = "java.util.String")
|
||||
* @TypeConversion(rule = ConversionRule.COLLECTION, converterClass = String.class)
|
||||
* public void setUsers( List users ) {
|
||||
* this.users = users;
|
||||
* }
|
||||
*
|
||||
* @TypeConversion(rule = ConversionRule.MAP, converter = "java.math.BigInteger")
|
||||
* @TypeConversion(rule = ConversionRule.MAP, converterClass = BigInteger.class)
|
||||
* public void setKeyValues( HashMap keyValues ) {
|
||||
* this.keyValues = keyValues;
|
||||
* }
|
||||
*
|
||||
* @TypeConversion(type = ConversionType.APPLICATION, property = "java.util.Date", converter = "com.opensymphony.xwork2.util.XWorkBasicConverter")
|
||||
* @TypeConversion(type = ConversionType.APPLICATION, property = "java.util.Date", converterClass = XWorkBasicConverter.class)
|
||||
* public String execute() throws Exception {
|
||||
* return SUCCESS;
|
||||
* }
|
||||
@@ -175,9 +183,20 @@ public @interface TypeConversion {
|
||||
* Note: This can not be used with ConversionRule.KEY_PROPERTY!
|
||||
*
|
||||
* @return class of the TypeConverter to be used as converter
|
||||
* @deprecated user {@link #converterClass()} instead
|
||||
*/
|
||||
@Deprecated
|
||||
String converter() default "";
|
||||
|
||||
/**
|
||||
* The class of the TypeConverter to be used as converter.
|
||||
*
|
||||
* Note: This can not be used with ConversionRule.KEY_PROPERTY!
|
||||
*
|
||||
* @return class of the TypeConverter to be used as converter
|
||||
*/
|
||||
Class<?> converterClass() default XWorkBasicConverter.class;
|
||||
|
||||
/**
|
||||
* If used with ConversionRule.KEY_PROPERTY specify a value here!
|
||||
*
|
||||
|
||||
+28
-8
@@ -8,6 +8,7 @@ import com.opensymphony.xwork2.conversion.annotations.ConversionRule;
|
||||
import com.opensymphony.xwork2.conversion.annotations.ConversionType;
|
||||
import com.opensymphony.xwork2.conversion.annotations.TypeConversion;
|
||||
import com.opensymphony.xwork2.inject.Inject;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@@ -34,28 +35,43 @@ public class DefaultConversionAnnotationProcessor implements ConversionAnnotatio
|
||||
}
|
||||
|
||||
public void process(Map<String, Object> mapping, TypeConversion tc, String key) {
|
||||
LOG.debug("TypeConversion [{}] with key: [{}]", tc.converter(), key);
|
||||
LOG.debug("TypeConversion [{}/{}] with key: [{}]", tc.converter(), tc.converterClass(), key);
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (tc.type() == ConversionType.APPLICATION) {
|
||||
converterHolder.addDefaultMapping(key, converterCreator.createTypeConverter(tc.converter()));
|
||||
if (StringUtils.isNoneEmpty(tc.converter())) {
|
||||
converterHolder.addDefaultMapping(key, converterCreator.createTypeConverter(tc.converter()));
|
||||
} else {
|
||||
converterHolder.addDefaultMapping(key, converterCreator.createTypeConverter(tc.converterClass()));
|
||||
}
|
||||
} else {
|
||||
if (tc.rule() == ConversionRule.KEY_PROPERTY || tc.rule() == ConversionRule.CREATE_IF_NULL) {
|
||||
mapping.put(key, tc.value());
|
||||
}
|
||||
//for properties of classes
|
||||
else if (tc.rule() != ConversionRule.ELEMENT || tc.rule() == ConversionRule.KEY || tc.rule() == ConversionRule.COLLECTION) {
|
||||
mapping.put(key, converterCreator.createTypeConverter(tc.converter()));
|
||||
if (StringUtils.isNoneEmpty(tc.converter())) {
|
||||
mapping.put(key, converterCreator.createTypeConverter(tc.converter()));
|
||||
} else {
|
||||
mapping.put(key, converterCreator.createTypeConverter(tc.converterClass()));
|
||||
}
|
||||
}
|
||||
//for keys of Maps
|
||||
else if (tc.rule() == ConversionRule.KEY) {
|
||||
Class converterClass = Thread.currentThread().getContextClassLoader().loadClass(tc.converter());
|
||||
Class<?> converterClass;
|
||||
if (StringUtils.isNoneEmpty(tc.converter())) {
|
||||
converterClass = Thread.currentThread().getContextClassLoader().loadClass(tc.converter());
|
||||
//check if the converter is a type converter if it is one
|
||||
//then just put it in the map as is. Otherwise
|
||||
//put a value in for the type converter of the class
|
||||
} else {
|
||||
converterClass = tc.converterClass();
|
||||
}
|
||||
|
||||
LOG.debug("Converter class: [{}]", converterClass);
|
||||
//check if the converter is a type converter if it is one
|
||||
//then just put it in the map as is. Otherwise
|
||||
//put a value in for the type converter of the class
|
||||
|
||||
if (converterClass.isAssignableFrom(TypeConverter.class)) {
|
||||
mapping.put(key, converterCreator.createTypeConverter(tc.converter()));
|
||||
} else {
|
||||
@@ -65,7 +81,11 @@ public class DefaultConversionAnnotationProcessor implements ConversionAnnotatio
|
||||
}
|
||||
//elements(values) of maps / lists
|
||||
else {
|
||||
mapping.put(key, Thread.currentThread().getContextClassLoader().loadClass(tc.converter()));
|
||||
if (StringUtils.isNoneEmpty(tc.converter())) {
|
||||
mapping.put(key, Thread.currentThread().getContextClassLoader().loadClass(tc.converter()));
|
||||
} else {
|
||||
mapping.put(key, tc.converterClass());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
+9
-1
@@ -19,8 +19,16 @@ public class DefaultTypeConverterCreator implements TypeConverterCreator {
|
||||
}
|
||||
|
||||
public TypeConverter createTypeConverter(String className) throws Exception {
|
||||
// type converters are used across users
|
||||
Object obj = objectFactory.buildBean(className, null);
|
||||
return getTypeConverter(obj);
|
||||
}
|
||||
|
||||
public TypeConverter createTypeConverter(Class<?> clazz) throws Exception {
|
||||
Object obj = objectFactory.buildBean(clazz, null);
|
||||
return getTypeConverter(obj);
|
||||
}
|
||||
|
||||
protected TypeConverter getTypeConverter(Object obj) {
|
||||
if (obj instanceof TypeConverter) {
|
||||
return (TypeConverter) obj;
|
||||
|
||||
|
||||
@@ -487,9 +487,9 @@ public class XWorkConverter extends DefaultTypeConverter {
|
||||
}
|
||||
if (LOG.isDebugEnabled()) {
|
||||
if (StringUtils.isEmpty(tc.key())) {
|
||||
LOG.debug("WARNING! key of @TypeConversion [{}] applied to [{}] is empty!", tc.converter(), clazz.getName());
|
||||
LOG.debug("WARNING! key of @TypeConversion [{}/{}] applied to [{}] is empty!", tc.converter(), tc.converterClass(), clazz.getName());
|
||||
} else {
|
||||
LOG.debug("TypeConversion [{}] with key: [{}]", tc.converter(), tc.key());
|
||||
LOG.debug("TypeConversion [{}/{}] with key: [{}]", tc.converter(), tc.converterClass(), tc.key());
|
||||
}
|
||||
}
|
||||
annotationProcessor.process(mapping, tc, tc.key());
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.opensymphony.xwork2.conversion.annotations.ConversionRule;
|
||||
import com.opensymphony.xwork2.conversion.annotations.ConversionType;
|
||||
import com.opensymphony.xwork2.conversion.annotations.TypeConversion;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
@@ -49,7 +50,7 @@ public class ConversionTestAction implements Action {
|
||||
return convertInt;
|
||||
}
|
||||
|
||||
@TypeConversion(type = ConversionType.APPLICATION, converter = "com.opensymphony.xwork2.util.XWorkBasicConverter")
|
||||
@TypeConversion(type = ConversionType.APPLICATION)
|
||||
public void setConvertInt( String convertInt ) {
|
||||
this.convertInt = convertInt;
|
||||
}
|
||||
@@ -67,7 +68,7 @@ public class ConversionTestAction implements Action {
|
||||
return users;
|
||||
}
|
||||
|
||||
@TypeConversion(rule = ConversionRule.COLLECTION, converter = "java.lang.String")
|
||||
@TypeConversion(rule = ConversionRule.COLLECTION, converterClass = String.class)
|
||||
public void setUsers( List users ) {
|
||||
this.users = users;
|
||||
}
|
||||
@@ -76,7 +77,7 @@ public class ConversionTestAction implements Action {
|
||||
return keyValues;
|
||||
}
|
||||
|
||||
@TypeConversion(rule = ConversionRule.MAP, converter = "java.math.BigInteger")
|
||||
@TypeConversion(rule = ConversionRule.MAP, converterClass = BigInteger.class)
|
||||
public void setKeyValues( HashMap keyValues ) {
|
||||
this.keyValues = keyValues;
|
||||
}
|
||||
@@ -90,7 +91,7 @@ public class ConversionTestAction implements Action {
|
||||
* Application level exceptions should be handled by returning
|
||||
* an error value, such as Action.ERROR.
|
||||
*/
|
||||
@TypeConversion(type = ConversionType.APPLICATION, key = "java.util.Date", converter = "com.opensymphony.xwork2.util.XWorkBasicConverter")
|
||||
@TypeConversion(type = ConversionType.APPLICATION, key = "java.util.Date")
|
||||
public String execute() throws Exception {
|
||||
return SUCCESS;
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ package com.opensymphony.xwork2.test;
|
||||
|
||||
import com.opensymphony.xwork2.conversion.annotations.Conversion;
|
||||
import com.opensymphony.xwork2.conversion.annotations.TypeConversion;
|
||||
import com.opensymphony.xwork2.conversion.impl.FooBarConverter;
|
||||
import com.opensymphony.xwork2.util.Bar;
|
||||
import com.opensymphony.xwork2.validator.annotations.RequiredFieldValidator;
|
||||
import com.opensymphony.xwork2.validator.annotations.RequiredStringValidator;
|
||||
@@ -29,15 +30,12 @@ import com.opensymphony.xwork2.validator.annotations.Validation;
|
||||
* @author Mark Woon
|
||||
* @author Rainer Hermanns
|
||||
*/
|
||||
@Validation()
|
||||
@Conversion()
|
||||
public interface AnnotationDataAware {
|
||||
|
||||
void setBarObj(Bar b);
|
||||
|
||||
@TypeConversion(
|
||||
converter = "com.opensymphony.xwork2.conversion.impl.FooBarConverter"
|
||||
)
|
||||
@TypeConversion(converterClass = FooBarConverter.class)
|
||||
Bar getBarObj();
|
||||
|
||||
@RequiredFieldValidator(message = "You must enter a value for data.")
|
||||
|
||||
@@ -18,6 +18,7 @@ package com.opensymphony.xwork2.test;
|
||||
import com.opensymphony.xwork2.AnnotatedTestBean;
|
||||
import com.opensymphony.xwork2.conversion.annotations.Conversion;
|
||||
import com.opensymphony.xwork2.conversion.annotations.TypeConversion;
|
||||
import com.opensymphony.xwork2.conversion.impl.FooBarConverter;
|
||||
import com.opensymphony.xwork2.util.Bar;
|
||||
import com.opensymphony.xwork2.util.Cat;
|
||||
|
||||
@@ -56,9 +57,7 @@ public class AnnotationTestBean2 extends AnnotatedTestBean implements Annotation
|
||||
return cat;
|
||||
}
|
||||
|
||||
@TypeConversion(
|
||||
key = "cat", converter = "com.opensymphony.xwork2.conversion.impl.FooBarConverter"
|
||||
)
|
||||
@TypeConversion(key = "cat", converterClass = FooBarConverter.class)
|
||||
public void setCat(Cat cat) {
|
||||
this.cat = cat;
|
||||
}
|
||||
|
||||
@@ -82,12 +82,12 @@ public class AnnotationUser implements AnnotationUserMarker {
|
||||
}
|
||||
|
||||
@KeyProperty( value = "name")
|
||||
@TypeConversion( converter = "java.lang.String", rule = ConversionRule.COLLECTION)
|
||||
@TypeConversion(converterClass = String.class, rule = ConversionRule.COLLECTION)
|
||||
public List getList() {
|
||||
return list;
|
||||
}
|
||||
|
||||
@TypeConversion( converter = "java.lang.String", rule = ConversionRule.MAP)
|
||||
@TypeConversion(converterClass = String.class, rule = ConversionRule.MAP)
|
||||
public void setMap(Map m) {
|
||||
map = m;
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import java.util.List;
|
||||
conversions={
|
||||
@TypeConversion(type=ConversionType.APPLICATION,
|
||||
key="com.opensymphony.xwork2.test.annotations.Address",
|
||||
converter="com.opensymphony.xwork2.test.annotations.AddressTypeConverter"),
|
||||
converterClass=AddressTypeConverter.class),
|
||||
@TypeConversion(type=ConversionType.APPLICATION,
|
||||
key="com.opensymphony.xwork2.test.annotations.Person",
|
||||
converter="com.opensymphony.xwork2.test.annotations.PersonTypeConverter")})
|
||||
converterClass=PersonTypeConverter.class)})
|
||||
public class PersonAction {
|
||||
List<Person> users;
|
||||
private List<Address> address;
|
||||
|
||||
@@ -50,9 +50,7 @@ public class AnnotatedCat {
|
||||
this.kittens = kittens;
|
||||
}
|
||||
|
||||
@TypeConversion(
|
||||
key = "kittens", converter = "com.opensymphony.xwork2.util.Cat"
|
||||
)
|
||||
@TypeConversion(key = "kittens", converterClass = Cat.class)
|
||||
public List getKittens() {
|
||||
return kittens;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user