few changes to make prev. generic tests PASS
diff --git a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
index 618d4d1..e852f26 100644
--- a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
+++ b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
@@ -20,7 +20,6 @@
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
@@ -266,23 +265,23 @@
}
if (!typeDetected && valueNode.getNodeId() != NodeId.scalar) {
// only if there is no explicit TypeDescription
- Type[] arguments = property.getActualTypeArguments();
+ Class[] arguments = property.getActualTypeArguments();
if (arguments != null) {
// TODO check non Java HotSpot(TM) Server VM
// type safe (generic) collection may contain the
// proper class
if (valueNode.getNodeId() == NodeId.sequence) {
- Class t = (Class) arguments[0];
+ Class t = arguments[0];
SequenceNode snode = (SequenceNode) valueNode;
snode.setListType(t);
} else if (valueNode.getTag().equals(Tag.SET)) {
- Class t = (Class) arguments[0];
+ Class t = arguments[0];
MappingNode mnode = (MappingNode) valueNode;
mnode.setKeyType(t);
mnode.setUseClassConstructor(true);
} else if (valueNode.getNodeId() == NodeId.mapping) {
- Class ketType = (Class) arguments[0];
- Class valueType = (Class) arguments[1];
+ Class ketType = arguments[0];
+ Class valueType = arguments[1];
MappingNode mnode = (MappingNode) valueNode;
mnode.setKeyType(ketType);
mnode.setValueType(valueType);
diff --git a/src/main/java/org/yaml/snakeyaml/introspector/FieldProperty.java b/src/main/java/org/yaml/snakeyaml/introspector/FieldProperty.java
index 1eeffca..4978c67 100644
--- a/src/main/java/org/yaml/snakeyaml/introspector/FieldProperty.java
+++ b/src/main/java/org/yaml/snakeyaml/introspector/FieldProperty.java
@@ -16,16 +16,14 @@
package org.yaml.snakeyaml.introspector;
import java.lang.reflect.Field;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
import org.yaml.snakeyaml.error.YAMLException;
-public class FieldProperty extends Property {
+public class FieldProperty extends GenericProperty {
private final Field field;
public FieldProperty(Field field) {
- super(field.getName(), field.getType());
+ super(field.getName(), field.getType(), field.getGenericType());
this.field = field;
}
@@ -44,13 +42,4 @@
}
}
- @Override
- public Type[] getActualTypeArguments() {
- if (field.getGenericType() instanceof ParameterizedType) {
- ParameterizedType t = (ParameterizedType) field.getGenericType();
- return t.getActualTypeArguments();
- } else {
- return null;
- }
- }
}
\ No newline at end of file
diff --git a/src/main/java/org/yaml/snakeyaml/introspector/GenericProperty.java b/src/main/java/org/yaml/snakeyaml/introspector/GenericProperty.java
new file mode 100644
index 0000000..6695c15
--- /dev/null
+++ b/src/main/java/org/yaml/snakeyaml/introspector/GenericProperty.java
@@ -0,0 +1,47 @@
+package org.yaml.snakeyaml.introspector;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+
+abstract public class GenericProperty extends Property {
+
+ private Type genType;
+
+ public GenericProperty(String name, Class<?> aClass, Type aType) {
+ super(name, aClass);
+ genType = aType;
+ actualClassesChecked = aType == null;
+ }
+
+ private boolean actualClassesChecked;
+ private Class<?>[] actualClasses;
+
+ public Class<?>[] getActualTypeArguments() { // should we synchronize here ?
+ if (!actualClassesChecked) {
+ if (genType instanceof ParameterizedType) {
+ ParameterizedType parameterizedType = (ParameterizedType) genType;
+ Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
+ if (actualTypeArguments.length > 0) {
+ actualClasses = new Class<?>[actualTypeArguments.length];
+ for (int i = 0; i < actualTypeArguments.length; i++) {
+ if (actualTypeArguments[i] instanceof Class<?>) {
+ actualClasses[i] = (Class<?>) actualTypeArguments[i];
+ } else {
+ actualClasses = null;
+ break;
+ }
+ }
+ }
+ } else if (genType instanceof GenericArrayType) {
+ Type componentType = ((GenericArrayType) genType).getGenericComponentType();
+ if (componentType instanceof Class<?>) {
+ actualClasses = new Class<?>[] { (Class<?>) componentType };
+ }
+ }
+ actualClassesChecked = true;
+ }
+ return actualClasses;
+ }
+
+}
diff --git a/src/main/java/org/yaml/snakeyaml/introspector/MethodProperty.java b/src/main/java/org/yaml/snakeyaml/introspector/MethodProperty.java
index 165cb28..a8e518d 100644
--- a/src/main/java/org/yaml/snakeyaml/introspector/MethodProperty.java
+++ b/src/main/java/org/yaml/snakeyaml/introspector/MethodProperty.java
@@ -16,51 +16,23 @@
package org.yaml.snakeyaml.introspector;
import java.beans.PropertyDescriptor;
-import java.lang.reflect.ParameterizedType;
-import java.lang.reflect.Type;
-import java.lang.reflect.TypeVariable;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
import org.yaml.snakeyaml.error.YAMLException;
-public class MethodProperty extends Property {
+public class MethodProperty extends GenericProperty {
+
private final PropertyDescriptor property;
public MethodProperty(PropertyDescriptor property) {
- super(property.getName(), property.getPropertyType());
+ super(property.getName(), property.getPropertyType(), property.getReadMethod() == null ? null : property.getReadMethod().getGenericReturnType());
this.property = property;
}
-
+
@Override
public void set(Object object, Object value) throws Exception {
property.getWriteMethod().invoke(object, value);
}
- @SuppressWarnings("unchecked")
- @Override
- public Type[] getActualTypeArguments() {
- if (List.class.isAssignableFrom(property.getPropertyType())
- || Set.class.isAssignableFrom(property.getPropertyType())
- || Map.class.isAssignableFrom(property.getPropertyType())) {
- if (property.getReadMethod().getGenericReturnType() instanceof ParameterizedType) {
- ParameterizedType grt = (ParameterizedType) property.getReadMethod()
- .getGenericReturnType();
- Type[] result = grt.getActualTypeArguments();
- if (result[0] instanceof TypeVariable || result[0] instanceof ParameterizedType) {
- return null;
- } else {
- return result;
- }
- } else {
- return null;
- }
- } else {
- return null;
- }
- }
-
@Override
public Object get(Object object) {
try {
diff --git a/src/main/java/org/yaml/snakeyaml/introspector/Property.java b/src/main/java/org/yaml/snakeyaml/introspector/Property.java
index a247f38..ba51998 100644
--- a/src/main/java/org/yaml/snakeyaml/introspector/Property.java
+++ b/src/main/java/org/yaml/snakeyaml/introspector/Property.java
@@ -15,22 +15,22 @@
*/
package org.yaml.snakeyaml.introspector;
-import java.lang.reflect.Type;
public abstract class Property implements Comparable<Property> {
- private final String name;
- private final Class<? extends Object> type;
- public Property(String name, Class<? extends Object> type) {
+ private final String name;
+ private final Class<?> type;
+
+ public Property(String name, Class<?> type) {
this.name = name;
this.type = type;
}
- public Class<? extends Object> getType() {
+ public Class<?> getType() {
return type;
}
- public abstract Type[] getActualTypeArguments();
+ abstract public Class<?>[] getActualTypeArguments();
public String getName() {
return name;
diff --git a/src/main/java/org/yaml/snakeyaml/representer/Representer.java b/src/main/java/org/yaml/snakeyaml/representer/Representer.java
index dc049cd..2f53def 100644
--- a/src/main/java/org/yaml/snakeyaml/representer/Representer.java
+++ b/src/main/java/org/yaml/snakeyaml/representer/Representer.java
@@ -20,7 +20,6 @@
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
@@ -177,11 +176,11 @@
*/
@SuppressWarnings("unchecked")
protected void checkGlobalTag(Property property, Node node, Object object) {
- Type[] arguments = property.getActualTypeArguments();
+ Class<?>[] arguments = property.getActualTypeArguments();
if (arguments != null) {
if (node.getNodeId() == NodeId.sequence) {
// apply map tag where class is the same
- Class<? extends Object> t = (Class<? extends Object>) arguments[0];
+ Class<? extends Object> t = arguments[0];
SequenceNode snode = (SequenceNode) node;
List<Object> memberList = (List<Object>) object;
Iterator<Object> iter = memberList.iterator();
@@ -193,7 +192,7 @@
}
}
} else if (object instanceof Set) {
- Class t = (Class) arguments[0];
+ Class t = arguments[0];
MappingNode mnode = (MappingNode) node;
Iterator<NodeTuple> iter = mnode.getValue().iterator();
Set set = (Set) object;
@@ -205,8 +204,8 @@
}
}
} else if (node.getNodeId() == NodeId.mapping) {
- Class keyType = (Class) arguments[0];
- Class valueType = (Class) arguments[1];
+ Class keyType = arguments[0];
+ Class valueType = arguments[1];
MappingNode mnode = (MappingNode) node;
for (NodeTuple tuple : mnode.getValue()) {
resetTag(keyType, tuple.getKeyNode());