aboutsummaryrefslogtreecommitdiff
path: root/src/main
diff options
context:
space:
mode:
authormaslovalex <alexander.maslov@gmail.com>2022-08-15 23:00:01 +0300
committermaslovalex <alexander.maslov@gmail.com>2022-08-15 23:31:08 +0300
commite9e009441956f981b593c70cad912186d29a3a6b (patch)
treeb00ff5efe02727e27179dc36ed8dde76af7a8fa4 /src/main
parent607672097f3aeec3357488881440c730900b06b6 (diff)
downloadsnakeyaml-e9e009441956f981b593c70cad912186d29a3a6b.tar.gz
improve newInstance process
instead of InstantiationException return fake Object to indicate that newInstance didn't create any objects.
Diffstat (limited to 'src/main')
-rw-r--r--src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java89
-rw-r--r--src/main/java/org/yaml/snakeyaml/constructor/Constructor.java25
2 files changed, 65 insertions, 49 deletions
diff --git a/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java b/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java
index a9ad9cd4..02239222 100644
--- a/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java
+++ b/src/main/java/org/yaml/snakeyaml/constructor/BaseConstructor.java
@@ -49,6 +49,12 @@ import java.util.TreeMap;
import java.util.TreeSet;
public abstract class BaseConstructor {
+
+ /**
+ * An instance returned by newInstance methods when instantiation has not been performed.
+ */
+ protected static final Object NOT_INSTANTIATED_OBJECT = new Object();
+
/**
* It maps the node kind to the the Construct implementation. When the
* runtime class is known then the implicit tag is ignored.
@@ -298,71 +304,80 @@ public abstract class BaseConstructor {
// >>>> NEW instance
protected Object newInstance(Node node) {
- try {
- return newInstance(Object.class, node);
- } catch (InstantiationException e) {
- throw new YAMLException(e);
- }
+ return newInstance(Object.class, node);
}
- final protected Object newInstance(Class<?> ancestor, Node node) throws InstantiationException {
+ final protected Object newInstance(Class<?> ancestor, Node node) {
return newInstance(ancestor, node, true);
}
- protected Object newInstance(Class<?> ancestor, Node node, boolean tryDefault)
- throws InstantiationException {
- final Class<? extends Object> type = node.getType();
- if (typeDefinitions.containsKey(type)) {
- TypeDescription td = typeDefinitions.get(type);
- final Object instance = td.newInstance(node);
- if (instance != null) {
- return instance;
+ /**
+ * Tries to create a new object for the node.
+ *
+ * @param ancestor expected ancestor of the {@code node.getType()}
+ * @param node for which to create a corresponding java object
+ * @param tryDefault should default constructor to be tried when there is no corresponding
+ * {@code TypeDescription} or {@code TypeDescription.newInstance(node)} returns {@code null}.
+ *
+ * @return - a new object created for {@code node.getType()} by using corresponding
+ * TypeDescription.newInstance or default constructor.
+ * - {@code NOT_INSTANTIATED_OBJECT} in case no object has been created
+ */
+ protected Object newInstance(Class<?> ancestor, Node node, boolean tryDefault) {
+ try {
+ final Class<? extends Object> type = node.getType();
+ if (typeDefinitions.containsKey(type)) {
+ TypeDescription td = typeDefinitions.get(type);
+ final Object instance = td.newInstance(node);
+ if (instance != null) {
+ return instance;
+ }
}
- }
- if (tryDefault) {
- /*
- * Removed <code> have InstantiationException in case of abstract
- * type
- */
- if (ancestor.isAssignableFrom(type) && !Modifier.isAbstract(type.getModifiers())) {
- try {
+
+ if (tryDefault) {
+ /*
+ * Removed <code> have InstantiationException in case of
+ * abstract type
+ */
+ if (ancestor.isAssignableFrom(type) && !Modifier.isAbstract(type.getModifiers())) {
java.lang.reflect.Constructor<?> c = type.getDeclaredConstructor();
c.setAccessible(true);
return c.newInstance();
- } catch (NoSuchMethodException e) {
- throw new InstantiationException("NoSuchMethodException:"
- + e.getLocalizedMessage());
- } catch (Exception e) {
- throw new YAMLException(e);
}
}
+ } catch (Exception e) {
+ throw new YAMLException(e);
}
- throw new InstantiationException();
+
+ return NOT_INSTANTIATED_OBJECT;
}
@SuppressWarnings("unchecked")
protected Set<Object> newSet(CollectionNode<?> node) {
- try {
- return (Set<Object>) newInstance(Set.class, node);
- } catch (InstantiationException e) {
+ Object instance = newInstance(Set.class, node);
+ if (instance != NOT_INSTANTIATED_OBJECT) {
+ return (Set<Object>) instance;
+ } else {
return createDefaultSet(node.getValue().size());
}
}
@SuppressWarnings("unchecked")
protected List<Object> newList(SequenceNode node) {
- try {
- return (List<Object>) newInstance(List.class, node);
- } catch (InstantiationException e) {
+ Object instance = newInstance(List.class, node);
+ if (instance != NOT_INSTANTIATED_OBJECT) {
+ return (List<Object>) instance;
+ } else {
return createDefaultList(node.getValue().size());
}
}
@SuppressWarnings("unchecked")
protected Map<Object, Object> newMap(MappingNode node) {
- try {
- return (Map<Object, Object>) newInstance(Map.class, node);
- } catch (InstantiationException e) {
+ Object instance = newInstance(Map.class, node);
+ if (instance != NOT_INSTANTIATED_OBJECT) {
+ return (Map<Object, Object>) instance;
+ } else {
return createDefaultMap(node.getValue().size());
}
}
diff --git a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
index ee887dcd..56263463 100644
--- a/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
+++ b/src/main/java/org/yaml/snakeyaml/constructor/Constructor.java
@@ -172,10 +172,15 @@ public class Constructor extends SafeConstructor {
}
} else {
Object obj = Constructor.this.newInstance(mnode);
- if (node.isTwoStepsConstruction()) {
- return obj;
+ if (obj != NOT_INSTANTIATED_OBJECT) {
+ if (node.isTwoStepsConstruction()) {
+ return obj;
+ } else {
+ return constructJavaBean2ndStep(mnode, obj);
+ }
} else {
- return constructJavaBean2ndStep(mnode, obj);
+ throw new ConstructorException(null, null, "Can't create an instance for " + mnode.getTag(),
+ node.getStartMark());
}
}
}
@@ -356,9 +361,10 @@ public class Constructor extends SafeConstructor {
ScalarNode node = (ScalarNode) nnode;
Class<?> type = node.getType();
- try {
- return newInstance(type, node, false);
- } catch (InstantiationException e1) {
+ // In case there is TypeDefinition for the 'type'
+ Object instance = newInstance(type, node, false);
+ if (instance != NOT_INSTANTIATED_OBJECT) {
+ return instance;
}
Object result;
@@ -384,12 +390,7 @@ public class Constructor extends SafeConstructor {
}
Object argument;
if (javaConstructor == null) {
- try {
- return newInstance(type, node, false);
- } catch (InstantiationException ie) {
- throw new YAMLException("No single argument constructor found for " + type
- + " : " + ie.getMessage());
- }
+ throw new YAMLException("No single argument constructor found for " + type);
} else if (oneArgCount == 1) {
argument = constructStandardJavaInstance(javaConstructor.getParameterTypes()[0],
node);