mirror of https://github.com/apache/activemq.git
AMQ-4011: IntrospectionSupport does not use java bean propery editors which are not thread safe, cause leaks, and are jvm global causing issues for other apps.
git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@1387025 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
fef7f54a17
commit
1802116df8
|
@ -18,7 +18,12 @@ package org.apache.activemq.util;
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
import java.beans.PropertyEditorSupport;
|
||||||
|
|
||||||
@Deprecated
|
/**
|
||||||
|
* Used by xbean to set booleans.
|
||||||
|
* <p/>
|
||||||
|
* <b>Important: </b> Do not use this for other purposes than xbean, as property editors
|
||||||
|
* are not thread safe, and they are slow to use.
|
||||||
|
*/
|
||||||
public class BooleanEditor extends PropertyEditorSupport {
|
public class BooleanEditor extends PropertyEditorSupport {
|
||||||
|
|
||||||
public String getJavaInitializationString() {
|
public String getJavaInitializationString() {
|
||||||
|
|
|
@ -16,12 +16,9 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.util;
|
package org.apache.activemq.util;
|
||||||
|
|
||||||
import java.beans.PropertyEditor;
|
|
||||||
import java.beans.PropertyEditorManager;
|
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -34,34 +31,13 @@ import java.util.Set;
|
||||||
import javax.net.ssl.SSLServerSocket;
|
import javax.net.ssl.SSLServerSocket;
|
||||||
|
|
||||||
import org.apache.activemq.command.ActiveMQDestination;
|
import org.apache.activemq.command.ActiveMQDestination;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
public final class IntrospectionSupport {
|
public final class IntrospectionSupport {
|
||||||
|
|
||||||
static {
|
|
||||||
// Add Spring and ActiveMQ specific property editors
|
|
||||||
String[] additionalPath = new String[] {
|
|
||||||
"org.springframework.beans.propertyeditors",
|
|
||||||
"org.apache.activemq.util" };
|
|
||||||
synchronized (PropertyEditorManager.class) {
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
list.addAll(Arrays.asList(PropertyEditorManager.getEditorSearchPath()));
|
|
||||||
|
|
||||||
if (!list.contains(additionalPath[0])) {
|
private static final Logger LOG = LoggerFactory.getLogger(IntrospectionSupport.class);
|
||||||
list.add(additionalPath[0]);
|
|
||||||
}
|
|
||||||
if (!list.contains(additionalPath[1])) {
|
|
||||||
list.add(additionalPath[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
String[] newSearchPath = list.toArray(new String[list.size()]);
|
|
||||||
try {
|
|
||||||
PropertyEditorManager.setEditorSearchPath(newSearchPath);
|
|
||||||
} catch(java.security.AccessControlException ignore) {
|
|
||||||
// we might be in an applet...
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private IntrospectionSupport() {
|
private IntrospectionSupport() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +62,7 @@ public final class IntrospectionSupport {
|
||||||
String name = method.getName();
|
String name = method.getName();
|
||||||
Class type = method.getReturnType();
|
Class type = method.getReturnType();
|
||||||
Class params[] = method.getParameterTypes();
|
Class params[] = method.getParameterTypes();
|
||||||
if ((name.startsWith("is") || name.startsWith("get")) && params.length == 0 && type != null && isSettableType(type)) {
|
if ((name.startsWith("is") || name.startsWith("get")) && params.length == 0 && type != null) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
@ -208,33 +184,75 @@ public final class IntrospectionSupport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Object convert(Object value, Class type) {
|
private static Object convert(Object value, Class to) {
|
||||||
|
if (value == null) {
|
||||||
|
// lets avoid NullPointerException when converting to boolean for null values
|
||||||
|
if (boolean.class.isAssignableFrom(to)) {
|
||||||
|
return Boolean.FALSE;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// eager same instance type test to avoid the overhead of invoking the type converter
|
||||||
|
// if already same type
|
||||||
|
if (to.isAssignableFrom(value.getClass())) {
|
||||||
|
return to.cast(value);
|
||||||
|
}
|
||||||
|
|
||||||
// special for String[] as we do not want to use a PropertyEditor for that
|
// special for String[] as we do not want to use a PropertyEditor for that
|
||||||
if (type.isAssignableFrom(String[].class)) {
|
if (to.isAssignableFrom(String[].class)) {
|
||||||
return StringArrayConverter.convertToStringArray(value);
|
return StringArrayConverter.convertToStringArray(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyEditor editor = PropertyEditorManager.findEditor(type);
|
// special for String to List<ActiveMQDestination> as we do not want to use a PropertyEditor for that
|
||||||
if (editor != null) {
|
if (value.getClass().equals(String.class) && to.equals(List.class)) {
|
||||||
editor.setAsText(value.toString());
|
Object answer = StringToListOfActiveMQDestinationConverter.convertToActiveMQDestination(value);
|
||||||
return editor.getValue();
|
if (answer != null) {
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeConversionSupport.Converter converter = TypeConversionSupport.lookupConverter(value.getClass(), to);
|
||||||
|
if (converter != null) {
|
||||||
|
return converter.convert(value);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot convert from " + value.getClass()
|
||||||
|
+ " to " + to + " with value " + value);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String convertToString(Object value, Class type) {
|
public static String convertToString(Object value, Class to) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// already a String
|
||||||
|
if (value instanceof String) {
|
||||||
|
return (String) value;
|
||||||
|
}
|
||||||
|
|
||||||
// special for String[] as we do not want to use a PropertyEditor for that
|
// special for String[] as we do not want to use a PropertyEditor for that
|
||||||
if (value != null && value.getClass().isAssignableFrom(String[].class)) {
|
if (String[].class.isInstance(value)) {
|
||||||
String[] array = (String[]) value;
|
String[] array = (String[]) value;
|
||||||
return StringArrayConverter.convertToString(array);
|
return StringArrayConverter.convertToString(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
PropertyEditor editor = PropertyEditorManager.findEditor(type);
|
// special for String to List<ActiveMQDestination> as we do not want to use a PropertyEditor for that
|
||||||
if (editor != null) {
|
if (List.class.isInstance(value)) {
|
||||||
editor.setValue(value);
|
// if the list is a ActiveMQDestination, then return a comma list
|
||||||
return editor.getAsText();
|
String answer = StringToListOfActiveMQDestinationConverter.convertFromActiveMQDestination(value);
|
||||||
|
if (answer != null) {
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeConversionSupport.Converter converter = TypeConversionSupport.lookupConverter(value.getClass(), String.class);
|
||||||
|
if (converter != null) {
|
||||||
|
return (String) converter.convert(value);
|
||||||
|
} else {
|
||||||
|
throw new IllegalArgumentException("Cannot convert from " + value.getClass()
|
||||||
|
+ " to " + to + " with value " + value);
|
||||||
}
|
}
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Method findSetterMethod(Class clazz, String name) {
|
private static Method findSetterMethod(Class clazz, String name) {
|
||||||
|
@ -251,19 +269,6 @@ public final class IntrospectionSupport {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isSettableType(Class clazz) {
|
|
||||||
// special for String[]
|
|
||||||
if (clazz.isAssignableFrom(String[].class)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PropertyEditorManager.findEditor(clazz) != null) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String toString(Object target) {
|
public static String toString(Object target) {
|
||||||
return toString(target, Object.class, null);
|
return toString(target, Object.class, null);
|
||||||
}
|
}
|
||||||
|
@ -349,7 +354,7 @@ public final class IntrospectionSupport {
|
||||||
}
|
}
|
||||||
map.put(field.getName(), o);
|
map.put(field.getName(), o);
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
e.printStackTrace();
|
LOG.debug("Error getting field " + field + " on class " + startClass + ". This exception is ignored.", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
/**
|
|
||||||
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
||||||
* contributor license agreements. See the NOTICE file distributed with
|
|
||||||
* this work for additional information regarding copyright ownership.
|
|
||||||
* The ASF licenses this file to You 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.apache.activemq.util;
|
|
||||||
|
|
||||||
import java.beans.PropertyEditorSupport;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
|
|
||||||
import org.apache.activemq.command.ActiveMQDestination;
|
|
||||||
import org.springframework.util.StringUtils;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Used to serialize lists of ActiveMQDestinations.
|
|
||||||
* @see org.apache.activemq.util.IntrospectionSupport
|
|
||||||
*/
|
|
||||||
@Deprecated
|
|
||||||
public class ListEditor extends PropertyEditorSupport {
|
|
||||||
|
|
||||||
public static final String DEFAULT_SEPARATOR = ",";
|
|
||||||
|
|
||||||
public String getAsText() {
|
|
||||||
return getValue().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
|
||||||
text = text.substring(1, text.length() - 1);
|
|
||||||
String[] array = StringUtils.delimitedListToStringArray(text, ListEditor.DEFAULT_SEPARATOR, null);
|
|
||||||
ArrayList<ActiveMQDestination> list = new ArrayList<ActiveMQDestination>();
|
|
||||||
for (String item : array) {
|
|
||||||
list.add(ActiveMQDestination.createDestination(item.trim(), ActiveMQDestination.QUEUE_TYPE));
|
|
||||||
}
|
|
||||||
setValue(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -21,10 +21,14 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Used by xbean to set integers.
|
||||||
|
* <p/>
|
||||||
|
* <b>Important: </b> Do not use this for other purposes than xbean, as property editors
|
||||||
|
* are not thread safe, and they are slow to use.
|
||||||
|
* <p/>
|
||||||
* Converts string values like "20 Mb", "1024kb", and "1g" to int values in
|
* Converts string values like "20 Mb", "1024kb", and "1g" to int values in
|
||||||
* bytes.
|
* bytes.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public class MemoryIntPropertyEditor extends PropertyEditorSupport {
|
public class MemoryIntPropertyEditor extends PropertyEditorSupport {
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,14 @@ import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Used by xbean to set longs.
|
||||||
|
* <p/>
|
||||||
|
* <b>Important: </b> Do not use this for other purposes than xbean, as property editors
|
||||||
|
* are not thread safe, and they are slow to use.
|
||||||
|
* <p/>
|
||||||
* Converts string values like "20 Mb", "1024kb", and "1g" to long values in
|
* Converts string values like "20 Mb", "1024kb", and "1g" to long values in
|
||||||
* bytes.
|
* bytes.
|
||||||
*/
|
*/
|
||||||
@Deprecated
|
|
||||||
public class MemoryPropertyEditor extends PropertyEditorSupport {
|
public class MemoryPropertyEditor extends PropertyEditorSupport {
|
||||||
public void setAsText(String text) throws IllegalArgumentException {
|
public void setAsText(String text) throws IllegalArgumentException {
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
/**
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You 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.apache.activemq.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.activemq.command.ActiveMQDestination;
|
||||||
|
import org.springframework.util.StringUtils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Special converter for String -> List<ActiveMQDestination> to be used instead of a
|
||||||
|
* {@link java.beans.PropertyEditor} which otherwise causes
|
||||||
|
* memory leaks as the JDK {@link java.beans.PropertyEditorManager}
|
||||||
|
* is a static class and has strong references to classes, causing
|
||||||
|
* problems in hot-deployment environments.
|
||||||
|
*/
|
||||||
|
public class StringToListOfActiveMQDestinationConverter {
|
||||||
|
|
||||||
|
public static List<ActiveMQDestination> convertToActiveMQDestination(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// text must be enclosed with []
|
||||||
|
|
||||||
|
String text = value.toString();
|
||||||
|
if (text.startsWith("[") && text.endsWith("]")) {
|
||||||
|
text = text.substring(1, text.length() - 1);
|
||||||
|
String[] array = StringUtils.delimitedListToStringArray(text, ",", null);
|
||||||
|
|
||||||
|
List<ActiveMQDestination> list = new ArrayList<ActiveMQDestination>();
|
||||||
|
for (String item : array) {
|
||||||
|
list.add(ActiveMQDestination.createDestination(item.trim(), ActiveMQDestination.QUEUE_TYPE));
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String convertFromActiveMQDestination(Object value) {
|
||||||
|
if (value == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder("[");
|
||||||
|
if (value instanceof List) {
|
||||||
|
List list = (List) value;
|
||||||
|
for (int i = 0; i < list.size(); i++) {
|
||||||
|
Object e = list.get(i);
|
||||||
|
if (e instanceof ActiveMQDestination) {
|
||||||
|
ActiveMQDestination destination = (ActiveMQDestination) e;
|
||||||
|
sb.append(destination);
|
||||||
|
if (i < list.size() - 1) {
|
||||||
|
sb.append(", ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sb.append("]");
|
||||||
|
|
||||||
|
if (sb.length() > 2) {
|
||||||
|
return sb.toString();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,12 +16,17 @@
|
||||||
*/
|
*/
|
||||||
package org.apache.activemq.util;
|
package org.apache.activemq.util;
|
||||||
|
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.apache.activemq.command.ActiveMQDestination;
|
import org.apache.activemq.command.ActiveMQDestination;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type conversion support for ActiveMQ.
|
||||||
|
*/
|
||||||
public final class TypeConversionSupport {
|
public final class TypeConversionSupport {
|
||||||
|
|
||||||
private static class ConversionKey {
|
private static class ConversionKey {
|
||||||
|
@ -45,7 +50,7 @@ public final class TypeConversionSupport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Converter {
|
public interface Converter {
|
||||||
Object convert(Object value);
|
Object convert(Object value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,16 +143,25 @@ public final class TypeConversionSupport {
|
||||||
return ActiveMQDestination.createDestination((String)value, ActiveMQDestination.QUEUE_TYPE);
|
return ActiveMQDestination.createDestination((String)value, ActiveMQDestination.QUEUE_TYPE);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
CONVERSION_MAP.put(new ConversionKey(String.class, URI.class), new Converter() {
|
||||||
|
public Object convert(Object value) {
|
||||||
|
String text = value.toString();
|
||||||
|
try {
|
||||||
|
return new URI(text);
|
||||||
|
} catch (URISyntaxException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private TypeConversionSupport() {
|
private TypeConversionSupport() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Object convert(Object value, Class type) {
|
public static Object convert(Object value, Class to) {
|
||||||
|
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
// lets avoid NullPointerException when converting to boolean for null values
|
// lets avoid NullPointerException when converting to boolean for null values
|
||||||
if (boolean.class.isAssignableFrom(type)) {
|
if (boolean.class.isAssignableFrom(to)) {
|
||||||
return Boolean.FALSE;
|
return Boolean.FALSE;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -155,12 +169,12 @@ public final class TypeConversionSupport {
|
||||||
|
|
||||||
// eager same instance type test to avoid the overhead of invoking the type converter
|
// eager same instance type test to avoid the overhead of invoking the type converter
|
||||||
// if already same type
|
// if already same type
|
||||||
if (type.isInstance(value)) {
|
if (to.isInstance(value)) {
|
||||||
return type.cast(value);
|
return to.cast(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// lookup converter
|
// lookup converter
|
||||||
Converter c = CONVERSION_MAP.get(new ConversionKey(value.getClass(), type));
|
Converter c = lookupConverter(value.getClass(), to);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
return c.convert(value);
|
return c.convert(value);
|
||||||
} else {
|
} else {
|
||||||
|
@ -168,4 +182,42 @@ public final class TypeConversionSupport {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Converter lookupConverter(Class from, Class to) {
|
||||||
|
// use wrapped type for primitives
|
||||||
|
if (from.isPrimitive()) {
|
||||||
|
from = convertPrimitiveTypeToWrapperType(from);
|
||||||
|
}
|
||||||
|
if (to.isPrimitive()) {
|
||||||
|
to = convertPrimitiveTypeToWrapperType(to);
|
||||||
|
}
|
||||||
|
|
||||||
|
return CONVERSION_MAP.get(new ConversionKey(from, to));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts primitive types such as int to its wrapper type like
|
||||||
|
* {@link Integer}
|
||||||
|
*/
|
||||||
|
private static Class<?> convertPrimitiveTypeToWrapperType(Class<?> type) {
|
||||||
|
Class<?> rc = type;
|
||||||
|
if (type.isPrimitive()) {
|
||||||
|
if (type == int.class) {
|
||||||
|
rc = Integer.class;
|
||||||
|
} else if (type == long.class) {
|
||||||
|
rc = Long.class;
|
||||||
|
} else if (type == double.class) {
|
||||||
|
rc = Double.class;
|
||||||
|
} else if (type == float.class) {
|
||||||
|
rc = Float.class;
|
||||||
|
} else if (type == short.class) {
|
||||||
|
rc = Short.class;
|
||||||
|
} else if (type == byte.class) {
|
||||||
|
rc = Byte.class;
|
||||||
|
} else if (type == boolean.class) {
|
||||||
|
rc = Boolean.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,6 +52,7 @@ public class ReflectionSupportTest extends TestCase {
|
||||||
map.put("favorites", favoritesString);
|
map.put("favorites", favoritesString);
|
||||||
map.put("nonFavorites", nonFavoritesString);
|
map.put("nonFavorites", nonFavoritesString);
|
||||||
map.put("others", null);
|
map.put("others", null);
|
||||||
|
map.put("systems", "windows,mac");
|
||||||
|
|
||||||
IntrospectionSupport.setProperties(pojo, map);
|
IntrospectionSupport.setProperties(pojo, map);
|
||||||
|
|
||||||
|
@ -62,6 +63,8 @@ public class ReflectionSupportTest extends TestCase {
|
||||||
assertEquals(favorites, pojo.getFavorites());
|
assertEquals(favorites, pojo.getFavorites());
|
||||||
assertEquals(nonFavorites, pojo.getNonFavorites());
|
assertEquals(nonFavorites, pojo.getNonFavorites());
|
||||||
assertNull(pojo.getOthers());
|
assertNull(pojo.getOthers());
|
||||||
|
assertEquals("windows", pojo.getSystems()[0]);
|
||||||
|
assertEquals("mac", pojo.getSystems()[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testGetProperties() {
|
public void testGetProperties() {
|
||||||
|
@ -72,6 +75,7 @@ public class ReflectionSupportTest extends TestCase {
|
||||||
pojo.setFavorites(favorites);
|
pojo.setFavorites(favorites);
|
||||||
pojo.setNonFavorites(nonFavorites);
|
pojo.setNonFavorites(nonFavorites);
|
||||||
pojo.setOthers(null);
|
pojo.setOthers(null);
|
||||||
|
pojo.setSystems(new String[]{"windows", "mac"});
|
||||||
|
|
||||||
Properties props = new Properties();
|
Properties props = new Properties();
|
||||||
|
|
||||||
|
@ -79,10 +83,11 @@ public class ReflectionSupportTest extends TestCase {
|
||||||
|
|
||||||
assertEquals("Dejan", props.get("name"));
|
assertEquals("Dejan", props.get("name"));
|
||||||
assertEquals("31", props.get("age"));
|
assertEquals("31", props.get("age"));
|
||||||
assertEquals("True", props.get("enabled"));
|
assertEquals("true", props.get("enabled"));
|
||||||
assertEquals(favoritesString, props.get("favorites"));
|
assertEquals(favoritesString, props.get("favorites"));
|
||||||
assertEquals(nonFavoritesString, props.get("nonFavorites"));
|
assertEquals(nonFavoritesString, props.get("nonFavorites"));
|
||||||
assertNull(props.get("others"));
|
assertNull(props.get("others"));
|
||||||
|
assertEquals("windows,mac", props.get("systems"));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSetBoolean() {
|
public void testSetBoolean() {
|
||||||
|
|
|
@ -31,6 +31,7 @@ public class SimplePojo {
|
||||||
List<ActiveMQDestination> favorites = new ArrayList<ActiveMQDestination>();
|
List<ActiveMQDestination> favorites = new ArrayList<ActiveMQDestination>();
|
||||||
List<ActiveMQDestination> nonFavorites = new ArrayList<ActiveMQDestination>();
|
List<ActiveMQDestination> nonFavorites = new ArrayList<ActiveMQDestination>();
|
||||||
List<ActiveMQDestination> others = new ArrayList<ActiveMQDestination>();
|
List<ActiveMQDestination> others = new ArrayList<ActiveMQDestination>();
|
||||||
|
String[] systems;
|
||||||
|
|
||||||
public int getAge() {
|
public int getAge() {
|
||||||
return age;
|
return age;
|
||||||
|
@ -74,5 +75,10 @@ public class SimplePojo {
|
||||||
public void setOthers(List<ActiveMQDestination> others) {
|
public void setOthers(List<ActiveMQDestination> others) {
|
||||||
this.others = others;
|
this.others = others;
|
||||||
}
|
}
|
||||||
|
public String[] getSystems() {
|
||||||
|
return systems;
|
||||||
|
}
|
||||||
|
public void setSystems(String[] systems) {
|
||||||
|
this.systems = systems;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue