diff options
author | maslovalex <alexander.maslov@gmail.com> | 2022-08-15 23:00:01 +0300 |
---|---|---|
committer | maslovalex <alexander.maslov@gmail.com> | 2022-08-15 23:31:08 +0300 |
commit | e9e009441956f981b593c70cad912186d29a3a6b (patch) | |
tree | b00ff5efe02727e27179dc36ed8dde76af7a8fa4 /src/main | |
parent | 607672097f3aeec3357488881440c730900b06b6 (diff) | |
download | snakeyaml-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.java | 89 | ||||
-rw-r--r-- | src/main/java/org/yaml/snakeyaml/constructor/Constructor.java | 25 |
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); |