Merge "Removed unused dependency."
authorRobert Varga <nite@hq.sk>
Mon, 4 May 2015 12:05:13 +0000 (12:05 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 4 May 2015 12:05:13 +0000 (12:05 +0000)
55 files changed:
benchmarks/src/main/java/org/opendaylight/yangtools/yang/data/impl/tree/BenchmarkModel.java
benchmarks/src/main/java/org/opendaylight/yangtools/yang/data/impl/tree/InMemoryDataTreeBenchmark.java
code-generator/binding-generator-impl/src/main/java/org/opendaylight/yangtools/sal/binding/generator/impl/BindingGeneratorImpl.java
common/util/src/main/java/org/opendaylight/yangtools/util/ClassLoaderUtils.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QName.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QNameModule.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/SimpleDateFormatUtil.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeCandidateNodes.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/schema/tree/DataTreeCandidates.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/SchemaTracker.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlDocumentUtils.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/leafref/LeafRefValidatation.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/InstanceIdToCompositeNodes.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/NormalizedNodeResult.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ResultAlreadySetException.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/SchemaUtils.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/ToNormalizedNodeParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/AugmentationNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/BaseDispatcherParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ChoiceNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ContainerNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ExtensibleParser.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetEntryNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/LeafSetNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListEntryNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ListNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/MapNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/OrderedListNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/UnkeyedListNodeBaseParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/AugmentationNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ChoiceNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ContainerNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/DomToNormalizedNodeParserFactory.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/LeafSetEntryNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/ListEntryNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapEntryNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/MapNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/OrderedListNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListEntryNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/parser/UnkeyedListNodeDomParser.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractModifiedNodeBasedCandidateNode.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractReadyIterator.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/InMemoryDataTreeModification.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/MinMaxElementsValidation.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModifiedNode.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlStreamUtilsTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/NormalizedDataBuilderTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/dom/serializer/NormalizedNodeXmlTranslationTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ConcurrentTreeModificationTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/ModificationMetadataTreeTest.java
yang/yang-data-impl/src/test/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/StoreTreeNodesTest.java
yang/yang-data-operations/src/test/java/org/opendaylight/yangtools/yang/data/operations/YangDataOperationsTest.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/stmt/rfc6020/effective/AnyXmlEffectiveStatementImpl.java

index e8cf728b459b5352ed41b9f7f8222cfeb5d2336f..3acdfb2525e47f5de101c3ae90de49dc5c1d5a08 100644 (file)
@@ -1,3 +1,10 @@
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
 package org.opendaylight.yangtools.yang.data.impl.tree;
 
 import java.io.InputStream;
@@ -10,7 +17,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
 
 /**
- * @author Lukas Sedlak <lsedlak@cisco.com>
+ * @author Lukas Sedlak &lt;lsedlak@cisco.com&gt;
  */
 public class BenchmarkModel {
 
index 4cf95a73acb889b5ef9f066661f85c33ba63452b..4e22bd15d84c4284e0f86b846ebb5805a8df9102 100644 (file)
@@ -31,7 +31,7 @@ import org.openjdk.jmh.runner.options.OptionsBuilder;
  *
  * JMH is used for microbenchmarking.
  *
- * @author Lukas Sedlak <lsedlak@cisco.com>
+ * @author Lukas Sedlak &lt;lsedlak@cisco.com&gt;
  *
  * @see <a href="http://openjdk.java.net/projects/code-tools/jmh/">JMH</a>
  */
index 66f3bc042408f6a475a772aa41ef78541aabbbab..15b818e43ddbb9754eb159349c8ed63ca3831ce4 100644 (file)
@@ -38,6 +38,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import org.opendaylight.yangtools.sal.binding.generator.impl.YangTemplate;
 import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.binding.generator.util.BindingTypes;
 import org.opendaylight.yangtools.binding.generator.util.ReferencedTypeImpl;
index 6f84ef81ff8a115adcec1f4aae5e14044014844d..44dfc4526e6f596ca42e1a08e5fcd5a67939ff68 100644 (file)
@@ -12,7 +12,6 @@ import static com.google.common.base.Preconditions.checkNotNull;
 import com.google.common.base.Joiner;
 import com.google.common.base.Preconditions;
 import com.google.common.base.Supplier;
-
 import java.lang.reflect.Constructor;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.ParameterizedType;
@@ -20,7 +19,6 @@ import java.lang.reflect.Type;
 import java.util.Arrays;
 import java.util.List;
 import java.util.concurrent.Callable;
-
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -104,16 +102,19 @@ public final class ClassLoaderUtils {
         if ("char[]".equals(name)) {
             return char[].class;
         }
+        return loadClass0(cls,name);
+    }
 
+    private static Class<?> loadClass0(final ClassLoader cls, final String name) throws ClassNotFoundException {
         try {
             return cls.loadClass(name);
-        } catch (ClassNotFoundException e) {
-            String[] components = name.split("\\.");
-            String potentialOuter;
-            int length = components.length;
-            if (length > 2 && (potentialOuter = components[length - 2]) != null && Character.isUpperCase(potentialOuter.charAt(0))) {
-                String outerName = Joiner.on(".").join(Arrays.asList(components).subList(0, length - 1));
-                String innerName = outerName + "$" + components[length-1];
+        } catch (final ClassNotFoundException e) {
+            final String[] components = name.split("\\.");
+
+            if (isInnerClass(components)) {
+                final int length = components.length;
+                final String outerName = Joiner.on(".").join(Arrays.asList(components).subList(0, length - 1));
+                final String innerName = outerName + "$" + components[length-1];
                 return cls.loadClass(innerName);
             } else {
                 throw e;
@@ -121,6 +122,18 @@ public final class ClassLoaderUtils {
         }
     }
 
+    private static boolean isInnerClass(final String[] components) {
+        final int length = components.length;
+        if(length < 2) {
+            return false;
+        }
+        final String potentialOuter = components[length - 2];
+        if(potentialOuter == null) {
+            return false;
+        }
+        return Character.isUpperCase(potentialOuter.charAt(0));
+    }
+
     public static Class<?> loadClassWithTCCL(final String name) throws ClassNotFoundException {
         return loadClass(Thread.currentThread().getContextClassLoader(), name);
     }
@@ -128,7 +141,7 @@ public final class ClassLoaderUtils {
     public static Class<?> tryToLoadClassWithTCCL(final String fullyQualifiedName) {
         try {
             return loadClassWithTCCL(fullyQualifiedName);
-        } catch (ClassNotFoundException e) {
+        } catch (final ClassNotFoundException e) {
             LOG.debug("Failed to load class {}", fullyQualifiedName, e);
             return null;
         }
@@ -156,7 +169,7 @@ public final class ClassLoaderUtils {
         Preconditions.checkNotNull(subclass);
         Preconditions.checkNotNull(genericType);
 
-        for (Type type : subclass.getGenericInterfaces()) {
+        for (final Type type : subclass.getGenericInterfaces()) {
             if (type instanceof ParameterizedType && genericType.equals(((ParameterizedType) type).getRawType())) {
                 return (ParameterizedType) type;
             }
index bfdfdadc80d8721372e829c7b226eb58627e5cf1..9d8a5e8e43c6f92a7516f89bc6bc828ecb54c43d 100644 (file)
@@ -109,7 +109,7 @@ public final class QName implements Immutable, Serializable, Comparable<QName> {
             throw new IllegalArgumentException("Parameter 'localName' must be a non-empty string.");
         }
 
-        for (char c : ILLEGAL_CHARACTERS) {
+        for (final char c : ILLEGAL_CHARACTERS) {
             if (localName.indexOf(c) != -1) {
                 throw new IllegalArgumentException(String.format(
                         "Parameter 'localName':'%s' contains illegal character '%s'", localName, c));
@@ -121,20 +121,20 @@ public final class QName implements Immutable, Serializable, Comparable<QName> {
     public static QName create(final String input) {
         Matcher matcher = QNAME_PATTERN_FULL.matcher(input);
         if (matcher.matches()) {
-            String namespace = matcher.group(1);
-            String revision = matcher.group(2);
-            String localName = matcher.group(3);
+            final String namespace = matcher.group(1);
+            final String revision = matcher.group(2);
+            final String localName = matcher.group(3);
             return create(namespace, revision, localName);
         }
         matcher = QNAME_PATTERN_NO_REVISION.matcher(input);
         if (matcher.matches()) {
-            URI namespace = URI.create(matcher.group(1));
-            String localName = matcher.group(2);
+            final URI namespace = URI.create(matcher.group(1));
+            final String localName = matcher.group(2);
             return new QName(namespace, localName);
         }
         matcher = QNAME_PATTERN_NO_NAMESPACE_NO_REVISION.matcher(input);
         if (matcher.matches()) {
-            String localName = matcher.group(1);
+            final String localName = matcher.group(1);
             return new QName((URI) null, localName);
         }
         throw new IllegalArgumentException("Invalid input:" + input);
@@ -273,8 +273,7 @@ public final class QName implements Immutable, Serializable, Comparable<QName> {
      *             <code>revision</code> is not according to format
      *             <code>YYYY-mm-dd</code>.
      */
-    public static QName create(final String namespace, final String revision, final String localName)
-            throws IllegalArgumentException {
+    public static QName create(final String namespace, final String revision, final String localName) {
         final URI namespaceUri = parseNamespace(namespace);
         final Date revisionDate = parseRevision(revision);
         return create(namespaceUri, revisionDate, localName);
@@ -283,7 +282,7 @@ public final class QName implements Immutable, Serializable, Comparable<QName> {
     private static URI parseNamespace(final String namespace) {
         try {
             return new URI(namespace);
-        } catch (URISyntaxException ue) {
+        } catch (final URISyntaxException ue) {
             throw new IllegalArgumentException(String.format("Namespace '%s' is not a valid URI", namespace), ue);
         }
     }
@@ -301,13 +300,13 @@ public final class QName implements Immutable, Serializable, Comparable<QName> {
      * @throws IllegalArgumentException
      *             If <code>namespace</code> is not valid URI.
      */
-    public static QName create(final String namespace, final String localName) throws IllegalArgumentException {
+    public static QName create(final String namespace, final String localName) {
         return create(parseNamespace(namespace), null, localName);
     }
 
     @Override
     public String toString() {
-        StringBuilder sb = new StringBuilder();
+        final StringBuilder sb = new StringBuilder();
         if (getNamespace() != null) {
             sb.append(QNAME_LEFT_PARENTHESIS + getNamespace());
 
index cd6c0e9ef855f74ae7dac5ea26314312ad2a7d22..def8da86cbeeec77689b50f44c0493456a172b9f 100644 (file)
@@ -12,6 +12,7 @@ import java.io.Serializable;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Date;
+import java.util.Objects;
 import org.opendaylight.yangtools.concepts.Immutable;
 import org.opendaylight.yangtools.objcache.ObjectCache;
 import org.opendaylight.yangtools.objcache.ObjectCacheFactory;
@@ -114,18 +115,10 @@ public final class QNameModule implements Immutable, Serializable {
             return false;
         }
         final QNameModule other = (QNameModule) obj;
-        if (revision == null) {
-            if (other.revision != null) {
-                return false;
-            }
-        } else if (!revision.equals(other.revision)) {
+        if (!Objects.equals(revision, other.revision)) {
             return false;
         }
-        if (namespace == null) {
-            if (other.namespace != null) {
-                return false;
-            }
-        } else if (!namespace.equals(other.namespace)) {
+        if (!Objects.equals(namespace, other.namespace)) {
             return false;
         }
         return true;
@@ -157,7 +150,7 @@ public final class QNameModule implements Immutable, Serializable {
         try {
             compositeURI = new URI(namespace.getScheme(), namespace.getUserInfo(), namespace.getHost(),
                     namespace.getPort(), namespace.getPath(), query, namespace.getFragment());
-        } catch (URISyntaxException e) {
+        } catch (final URISyntaxException e) {
             LOG.error("", e);
         }
         return compositeURI;
index 303ef4f2e06f3c17e13c9de02a648a2e44e49816..9d11685a6df77193a0b2229b20e1916c99530879 100644 (file)
@@ -17,16 +17,16 @@ public final class SimpleDateFormatUtil {
     private static final String REVISION_SIMPLE_DATE = "yyyy-MM-dd";
     private static final String DEFAULT_DATE = "1970-01-01";
 
-    public static Date DEFAULT_DATE_REV;
-    public static Date DEFAULT_DATE_IMP;
+    public static final Date DEFAULT_DATE_REV;
+    public static final Date DEFAULT_DATE_IMP;
 
     static {
-        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(REVISION_SIMPLE_DATE);
+        final SimpleDateFormat simpleDateFormat = new SimpleDateFormat(REVISION_SIMPLE_DATE);
 
         try {
             DEFAULT_DATE_REV = simpleDateFormat.parse(DEFAULT_DATE);
             DEFAULT_DATE_IMP = simpleDateFormat.parse(DEFAULT_DATE);
-        } catch (ParseException e) {
+        } catch (final ParseException e) {
             throw new ExceptionInInitializerError(e);
         }
     }
@@ -43,7 +43,7 @@ public final class SimpleDateFormatUtil {
         }
 
         @Override
-        public void set(SimpleDateFormat value) {
+        public void set(final SimpleDateFormat value) {
             throw new UnsupportedOperationException();
         }
 
index 44f24c2a70f8548327f49e3c6c797bea6efe6ce9..e1636ae77e8707baccc837e5f721ad78cbc30a55 100644 (file)
@@ -8,6 +8,9 @@
 package org.opendaylight.yangtools.yang.data.api.schema.tree;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Iterator;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 @Beta
@@ -19,4 +22,66 @@ public final class DataTreeCandidateNodes {
     public static DataTreeCandidateNode fromNormalizedNode(final NormalizedNode<?, ?> node) {
         return new NormalizedNodeDataTreeCandidateNode(node);
     }
+
+    public static void applyToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
+        switch (node.getModificationType()) {
+        case DELETE:
+            cursor.delete(node.getIdentifier());
+            break;
+        case SUBTREE_MODIFIED:
+            cursor.enter(node.getIdentifier());
+            NodeIterator iterator = new NodeIterator(null, node.getChildNodes().iterator());
+            do {
+                iterator = iterator.next(cursor);
+            } while (iterator != null);
+            break;
+        case UNMODIFIED:
+            // No-op
+            break;
+        case WRITE:
+            cursor.write(node.getIdentifier(), node.getDataAfter().get());
+            break;
+        default:
+            throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+        }
+    }
+
+    private static final class NodeIterator {
+        private final Iterator<DataTreeCandidateNode> iterator;
+        private final NodeIterator parent;
+
+        NodeIterator(final NodeIterator parent, final Iterator<DataTreeCandidateNode> iterator) {
+            this.parent = Preconditions.checkNotNull(parent);
+            this.iterator = Preconditions.checkNotNull(iterator);
+        }
+
+        NodeIterator next(final DataTreeModificationCursor cursor) {
+            while (iterator.hasNext()) {
+                final DataTreeCandidateNode node = iterator.next();
+                switch (node.getModificationType()) {
+                case DELETE:
+                    cursor.delete(node.getIdentifier());
+                    break;
+                case SUBTREE_MODIFIED:
+                    final Collection<DataTreeCandidateNode> children = node.getChildNodes();
+                    if (!children.isEmpty()) {
+                        cursor.enter(node.getIdentifier());
+                        return new NodeIterator(this, children.iterator());
+                    }
+                    break;
+                case UNMODIFIED:
+                    // No-op
+                    break;
+                case WRITE:
+                    cursor.write(node.getIdentifier(), node.getDataAfter().get());
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+                }
+            }
+
+            cursor.exit();
+            return parent;
+        }
+    }
 }
index 99256397b0e9197f9cb156060c8c03fb7b76278f..1b242918ddd15799dec0b977040bf717bb860d5a 100644 (file)
@@ -8,6 +8,8 @@
 package org.opendaylight.yangtools.yang.data.api.schema.tree;
 
 import com.google.common.annotations.Beta;
+import com.google.common.base.Preconditions;
+import java.util.Iterator;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.slf4j.Logger;
@@ -31,17 +33,20 @@ public final class DataTreeCandidates {
         return new DefaultDataTreeCandidate(rootPath, new NormalizedNodeDataTreeCandidateNode(node));
     }
 
+    public static void applyToCursor(final DataTreeModificationCursor cursor, final DataTreeCandidate candidate) {
+        DataTreeCandidateNodes.applyToCursor(cursor, candidate.getRootNode());
+    }
+
     public static void applyToModification(final DataTreeModification modification, final DataTreeCandidate candidate) {
         if (modification instanceof CursorAwareDataTreeModification) {
             try (DataTreeModificationCursor cursor = ((CursorAwareDataTreeModification) modification).createCursor(candidate.getRootPath())) {
-                applyNode(cursor, candidate.getRootNode());
+                applyToCursor(cursor, candidate);
             }
-        } else {
-            applyNode(modification, candidate.getRootPath(), candidate.getRootNode());
+            return;
         }
-    }
 
-    private static void applyNode(final DataTreeModification modification, final YangInstanceIdentifier path, final DataTreeCandidateNode node) {
+        final DataTreeCandidateNode node = candidate.getRootNode();
+        final YangInstanceIdentifier path = candidate.getRootPath();
         switch (node.getModificationType()) {
         case DELETE:
             modification.delete(path);
@@ -49,9 +54,11 @@ public final class DataTreeCandidates {
             break;
         case SUBTREE_MODIFIED:
             LOG.debug("Modification {} modified path {}", modification, path);
-            for (DataTreeCandidateNode child : node.getChildNodes()) {
-                applyNode(modification, path.node(child.getIdentifier()), child);
-            }
+
+            NodeIterator iterator = new NodeIterator(null, path, node.getChildNodes().iterator());
+            do {
+                iterator = iterator.next(modification);
+            } while (iterator != null);
             break;
         case UNMODIFIED:
             LOG.debug("Modification {} unmodified path {}", modification, path);
@@ -66,26 +73,44 @@ public final class DataTreeCandidates {
         }
     }
 
-    private static void applyNode(final DataTreeModificationCursor cursor, final DataTreeCandidateNode node) {
-        switch (node.getModificationType()) {
-        case DELETE:
-            cursor.delete(node.getIdentifier());
-            break;
-        case SUBTREE_MODIFIED:
-            cursor.enter(node.getIdentifier());
-            for (DataTreeCandidateNode child : node.getChildNodes()) {
-                applyNode(cursor, child);
+    private static final class NodeIterator {
+        private final Iterator<DataTreeCandidateNode> iterator;
+        private final YangInstanceIdentifier path;
+        private final NodeIterator parent;
+
+        public NodeIterator(final NodeIterator parent, final YangInstanceIdentifier path, final Iterator<DataTreeCandidateNode> iterator) {
+            this.iterator = Preconditions.checkNotNull(iterator);
+            this.parent = Preconditions.checkNotNull(parent);
+            this.path = Preconditions.checkNotNull(path);
+        }
+
+        NodeIterator next(final DataTreeModification modification) {
+            while (iterator.hasNext()) {
+                final DataTreeCandidateNode node = iterator.next();
+                final YangInstanceIdentifier child = path.node(node.getIdentifier());
+
+                switch (node.getModificationType()) {
+                case DELETE:
+                    modification.delete(child);
+                    LOG.debug("Modification {} deleted path {}", modification, child);
+                    break;
+                case SUBTREE_MODIFIED:
+                    LOG.debug("Modification {} modified path {}", modification, child);
+                    return new NodeIterator(this, child, node.getChildNodes().iterator());
+                case UNMODIFIED:
+                    LOG.debug("Modification {} unmodified path {}", modification, child);
+                    // No-op
+                    break;
+                case WRITE:
+                    modification.write(child, node.getDataAfter().get());
+                    LOG.debug("Modification {} written path {}", modification, child);
+                    break;
+                default:
+                    throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+                }
             }
-            cursor.exit();
-            break;
-        case UNMODIFIED:
-            // No-op
-            break;
-        case WRITE:
-            cursor.write(node.getIdentifier(), node.getDataAfter().get());
-            break;
-        default:
-            throw new IllegalArgumentException("Unsupported modification " + node.getModificationType());
+
+            return parent;
         }
     }
 }
index 7ff31d693507d5eb04e6da5477c875d4917cd746..5c02d7eb396352a079c4dfd2416674530aec9d4b 100644 (file)
@@ -91,15 +91,15 @@ public final class SchemaTracker {
         root = (DataNodeContainer) current;
     }
 
-    private Optional<SchemaNode> tryFindGroupings(final SchemaContext ctx, final QName qname) {
+    private static Optional<SchemaNode> tryFindGroupings(final SchemaContext ctx, final QName qname) {
         return Optional.<SchemaNode> fromNullable(Iterables.find(ctx.getGroupings(), new SchemaNodePredicate(qname), null));
     }
 
-    private Optional<SchemaNode> tryFindRpc(final SchemaContext ctx, final QName qname) {
+    private static Optional<SchemaNode> tryFindRpc(final SchemaContext ctx, final QName qname) {
         return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getOperations(), new SchemaNodePredicate(qname), null));
     }
 
-    private Optional<SchemaNode> tryFindNotification(final SchemaContext ctx, final QName qname) {
+    private static Optional<SchemaNode> tryFindNotification(final SchemaContext ctx, final QName qname) {
         return Optional.<SchemaNode>fromNullable(Iterables.find(ctx.getNotifications(), new SchemaNodePredicate(qname), null));
     }
 
@@ -155,7 +155,7 @@ public final class SchemaTracker {
         return schema;
     }
 
-    private SchemaNode findChildInCases(final ChoiceSchemaNode parent, final QName qname) {
+    private static SchemaNode findChildInCases(final ChoiceSchemaNode parent, final QName qname) {
         DataSchemaNode schema = null;
         for(final ChoiceCaseNode caze : parent.getCases()) {
             final DataSchemaNode potential = caze.getDataChildByName(qname);
@@ -167,7 +167,7 @@ public final class SchemaTracker {
         return schema;
     }
 
-    private SchemaNode findCaseByChild(final ChoiceSchemaNode parent, final QName qname) {
+    private static SchemaNode findCaseByChild(final ChoiceSchemaNode parent, final QName qname) {
         DataSchemaNode schema = null;
         for(final ChoiceCaseNode caze : parent.getCases()) {
             final DataSchemaNode potential = caze.getDataChildByName(qname);
index a4812c7316c81593bcf8869bc7919e448d6e26b7..19122a00cb18ffdfedfa38f1bcc2d6545b96876b 100644 (file)
@@ -23,15 +23,12 @@ import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.w3c.dom.Attr;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
 
 public final class XmlDocumentUtils {
     public static final QName OPERATION_ATTRIBUTE_QNAME = QName.create(SchemaContext.NAME, "operation");
-    private static final Logger LOG = LoggerFactory.getLogger(XmlDocumentUtils.class);
 
     private XmlDocumentUtils() {
         throw new UnsupportedOperationException("Utility class should not be instantiated");
index 42006157e59916fc5071c588df53176a5beaf901..c8bf9ccc99f5d29b9e8a8a40c350c24389b6e87a 100644 (file)
@@ -144,7 +144,7 @@ public class LeafRefValidatation {
 
     }
 
-    private LeafRefContext getReferencingCtxChild(
+    private static LeafRefContext getReferencingCtxChild(
             final LeafRefContext referencingCtx, final DataTreeCandidateNode childNode) {
 
         LeafRefContext childReferencingCtx = null;
@@ -167,7 +167,7 @@ public class LeafRefValidatation {
         return childReferencingCtx;
     }
 
-    private LeafRefContext getReferencedByCtxChild(
+    private static LeafRefContext getReferencedByCtxChild(
             final LeafRefContext referencedByCtx, final DataTreeCandidateNode childNode) {
 
         LeafRefContext childReferencedByCtx = null;
@@ -318,7 +318,7 @@ public class LeafRefValidatation {
         // FIXME if(node instance of UnkeyedListNode ...
     }
 
-    private LeafRefContext findReferencingCtxUnderChoice(
+    private static LeafRefContext findReferencingCtxUnderChoice(
             final LeafRefContext referencingCtx, final QName qname) {
 
         final Map<QName, LeafRefContext> referencingChilds = referencingCtx
@@ -335,7 +335,7 @@ public class LeafRefValidatation {
         return null;
     }
 
-    private LeafRefContext findReferencedByCtxUnderChoice(
+    private static LeafRefContext findReferencedByCtxUnderChoice(
             final LeafRefContext referencedByCtx, final QName qname) {
 
         final Map<QName, LeafRefContext> referencedByChilds = referencedByCtx
@@ -436,14 +436,13 @@ public class LeafRefValidatation {
         validatedLeafRefCtx.add(referencedByCtx);
     }
 
-    private StringBuilder createInvalidTargetMessage(final NormalizedNode<?, ?> leaf,
+    private static StringBuilder createInvalidTargetMessage(final NormalizedNode<?, ?> leaf,
             final HashSet<?> leafRefTargetNodeValues, final LeafRefContext leafRefContext,
             final Object leafRefsValue) {
         final StringBuilder sb = new StringBuilder();
         sb.append("Invalid leafref value [");
         sb.append(leafRefsValue);
-        sb.append("]");
-        sb.append(" allowed values ");
+        sb.append("] allowed values ");
         sb.append(leafRefTargetNodeValues);
         sb.append(" by validation of leafref TARGET node: ");
         sb.append(leaf.getNodeType());
@@ -458,13 +457,16 @@ public class LeafRefValidatation {
             final LeafRefContext referencingCtx, final ModificationType modificationType,
             final YangInstanceIdentifier current) {
 
-        final StringBuilder header_log = new StringBuilder();
+        final StringBuilder headerLog = new StringBuilder();
         final StringBuilder log = new StringBuilder();
 
-        header_log.append("Operation [" + modificationType
-                + "] validate data of LEAFREF node: name["
-                + referencingCtx.getNodeName() + "] = value["
-                + leaf.getValue() + "]");
+        headerLog.append("Operation [");
+        headerLog.append(modificationType);
+        headerLog.append("] validate data of LEAFREF node: name[");
+        headerLog.append(referencingCtx.getNodeName());
+        headerLog.append("] = value[");
+        headerLog.append(leaf.getValue());
+        headerLog.append(']');
 
         final HashSet<Object> values = new HashSet<>();
         final LeafRefPath targetPath = referencingCtx.getAbsoluteLeafRefTargetPath();
@@ -479,25 +481,25 @@ public class LeafRefValidatation {
                     referencingCtx, values);
             errorsMessages.add(sb.toString());
 
-            header_log.append(" -> FAILED");
+            headerLog.append(" -> FAILED");
             log.append(sb.toString());
         } else {
-            header_log.append(" -> OK");
+            headerLog.append(" -> OK");
         }
 
-        LOG.debug(header_log.toString());
-        if (!log.toString().equals(""))
+        LOG.debug(headerLog.toString());
+        if (log.length() != 0) {
             LOG.debug(log.toString());
+        }
     }
 
-    private StringBuilder createInvalidLeafRefMessage(
+    private static StringBuilder createInvalidLeafRefMessage(
             final NormalizedNode<?, ?> leaf, final LeafRefContext referencingCtx,
             final Set<?> values) {
         final StringBuilder sb = new StringBuilder();
         sb.append("Invalid leafref value [");
         sb.append(leaf.getValue());
-        sb.append("]");
-        sb.append(" allowed values ");
+        sb.append("] allowed values ");
         sb.append(values);
         sb.append(" of LEAFREF node: ");
         sb.append(leaf.getNodeType());
@@ -615,8 +617,7 @@ public class LeafRefValidatation {
         }
     }
 
-    private Iterable<ChoiceNode> getChoiceNodes(
-            final DataContainerNode<?> dataContainerNode) {
+    private static Iterable<ChoiceNode> getChoiceNodes(final DataContainerNode<?> dataContainerNode) {
 
         final LinkedList<ChoiceNode> choiceNodes = new LinkedList<ChoiceNode>();
 
@@ -630,7 +631,7 @@ public class LeafRefValidatation {
         return choiceNodes;
     }
 
-    private boolean isMatchingPredicate(final MapEntryNode mapEntryNode,
+    private static boolean isMatchingPredicate(final MapEntryNode mapEntryNode,
             final Map<QName, Set<?>> allowedKeyValues) {
 
         final NodeIdentifierWithPredicates identifier = mapEntryNode.getIdentifier();
@@ -671,7 +672,7 @@ public class LeafRefValidatation {
         return values;
     }
 
-    private Optional<NormalizedNode<?, ?>> findParentNode(
+    private static Optional<NormalizedNode<?, ?>> findParentNode(
             final Optional<NormalizedNode<?, ?>> root, final YangInstanceIdentifier path) {
         Optional<NormalizedNode<?, ?>> currentNode = root;
         final Iterator<PathArgument> pathIterator = path.getPathArguments()
@@ -688,12 +689,11 @@ public class LeafRefValidatation {
         return Optional.absent();
     }
 
-    private Iterable<QNameWithPredicate> nextLevel(
-            final Iterable<QNameWithPredicate> path) {
+    private static Iterable<QNameWithPredicate> nextLevel(final Iterable<QNameWithPredicate> path) {
         return Iterables.skip(path, 1);
     }
 
-    private PathArgument toPathArgument(final QName qName) {
+    private static PathArgument toPathArgument(final QName qName) {
         return YangInstanceIdentifier.of(qName).getLastPathArgument();
     }
 }
index 28e8d892f0dba1a9cdf9b0670d5964d4d4a30856..69618f5128b6a05f63bb68b1db2becfab28d4fb0 100644 (file)
@@ -9,7 +9,6 @@ package org.opendaylight.yangtools.yang.data.impl.schema;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
-
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableMap;
@@ -110,7 +109,6 @@ abstract class InstanceIdToCompositeNodes<T extends YangInstanceIdentifier.PathA
         return childOp;
     }
 
-    @SuppressWarnings("rawtypes")
     protected abstract NormalizedNodeContainerBuilder<?, ?, ?, ?> createBuilder(final YangInstanceIdentifier.PathArgument compositeNode);
 
     static abstract class DataContainerNormalizationOperation<T extends YangInstanceIdentifier.PathArgument> extends
index 76b28e93aaad9a7775068b3a37e383cdf9738ac1..47723fd788f00ed91ce4f499fcd245e258e27be8 100644 (file)
@@ -7,7 +7,6 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema;
 
-import com.google.common.base.Preconditions;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
@@ -33,7 +32,9 @@ public class NormalizedNodeResult {
     }
 
     void setResult(final NormalizedNode<?, ?> result) {
-        Preconditions.checkState(!this.finished, "Result was already set.");
+        if (finished) {
+            throw new ResultAlreadySetException("Normalized Node result was already set.", this.result);
+        }
         this.finished = true;
         this.result = result;
     }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ResultAlreadySetException.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/ResultAlreadySetException.java
new file mode 100644 (file)
index 0000000..f066f29
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema;
+
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class ResultAlreadySetException extends IllegalStateException {
+    private static final long serialVersionUID = 1L;
+    private final NormalizedNode<?, ?> resultData;
+
+    public ResultAlreadySetException(final String message, final NormalizedNode<?, ?> resultData) {
+        this(message, resultData, null);
+    }
+
+    public ResultAlreadySetException(final String message, final NormalizedNode<?, ?> resultData, final Throwable cause) {
+        super(message, cause);
+        this.resultData = resultData;
+    }
+
+    public NormalizedNode<?, ?> getResultData() {
+        return resultData;
+    }
+}
index a5c5148548418596d13c1ef26543aa89c527aff4..755a228c91ff11fcf0ca4bb6264eb26406c28a5a 100644 (file)
@@ -23,7 +23,6 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
 import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
@@ -34,6 +33,7 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 public final class SchemaUtils {
 
     private SchemaUtils() {
+        throw new UnsupportedOperationException();
     }
 
     /**
index a300cc07d41f88b83daa6d3dcbdc386ba353132d..04c4ed8f7388e34db8a588237e9a37ae85b86718 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform;
 
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 
 /**
@@ -33,5 +34,6 @@ public interface ToNormalizedNodeParser<E, N extends NormalizedNode<?, ?>, S> {
      * @param schema
      * @return NormalizedNode as a result of parsing list of E elements with schema S
      */
+    @Nullable
     N parse(Iterable<E> xmlDom, S schema);
 }
index 7c3938fe088d92bc3bb6076bfa039cb9720e8102..bd7853a5dd028ea337c840f50f491e1a971f0056 100644 (file)
@@ -26,7 +26,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
  * @param <E> type of elements to be parsed
  */
 public abstract class AugmentationNodeBaseParser<E> extends
-        BaseDispatcherParser<E,AugmentationNode, AugmentationSchema> {
+        BaseDispatcherParser<E, YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode, AugmentationSchema> {
+
+    public AugmentationNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> buildingStrategy) {
+        super(buildingStrategy);
+    }
+
+    public AugmentationNodeBaseParser() {}
 
     @Override
     protected final DataContainerNodeBuilder<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> getBuilder(final AugmentationSchema schema) {
index a594e5d763a8dbe51c8a33fd03d808b97d605d97..9d52ba4b1534ff31bca0f34d7424d75e6c18e6a5 100644 (file)
@@ -14,30 +14,42 @@ import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.AttributesBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
 import org.opendaylight.yangtools.yang.model.api.ChoiceSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.opendaylight.yangtools.yang.model.util.EffectiveAugmentationSchema;
 
 /**
  * Abstract(base) Parser for DataContainerNodes e.g. ContainerNode, AugmentationNode.
  */
-public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
-        implements ToNormalizedNodeParser<E, N, S> {
+public abstract class BaseDispatcherParser<E, P extends YangInstanceIdentifier.PathArgument, N extends DataContainerNode<P>, S>
+        implements ExtensibleParser<P, E, N, S> {
+
+    private final BuildingStrategy<P, N> buildingStrategy;
+
+    public BaseDispatcherParser(final BuildingStrategy<P, N> buildingStrategy) {
+        this.buildingStrategy = buildingStrategy;
+    }
+
+    public BaseDispatcherParser() {
+        this.buildingStrategy = new SimpleBuildingStrategy<>();
+    }
 
     /**
      *
      * @param schema
      * @return New(empty) instance of a builder to build node identified by schema.
      */
-    protected abstract DataContainerNodeBuilder<?, N> getBuilder(S schema);
+    protected abstract DataContainerNodeBuilder<P, N> getBuilder(S schema);
 
     /**
      *
@@ -88,12 +100,19 @@ public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
      */
     protected abstract NodeParserDispatcher<E> getDispatcher();
 
+    /**
+     * can return null only if you override ParsingStrategy and explicitely return null
+     * @param elements
+     * @param schema
+     * @return
+     */
+    @Nullable
     @Override
     public N parse(final Iterable<E> elements, final S schema) {
 
         checkAtLeastOneNode(schema, elements);
 
-        DataContainerNodeBuilder<?, N> containerBuilder = getBuilder(schema);
+        DataContainerNodeBuilder<P, N> containerBuilder = getBuilder(schema);
 
         // Map child nodes to QName
         LinkedListMultimap<QName, E> mappedChildElements = mapChildElements(elements);
@@ -106,6 +125,36 @@ public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
         Map<QName, ChoiceSchemaNode> mappedChoiceChildNodes = mapChildElementsFromChoices(schema);
         LinkedListMultimap<ChoiceSchemaNode, E> choicesToElements = LinkedListMultimap.create();
 
+        Map<QName, String> attributes = getAttributes(elements.iterator().next());
+        if (containerBuilder instanceof AttributesBuilder) {
+            final int size = Iterables.size(elements);
+            Preconditions.checkArgument(size == 1, "Unexpected number of elements: %s, should be 1 for: %s",
+                    size, schema);
+            ((AttributesBuilder<?>) containerBuilder).withAttributes(attributes);
+        }
+
+        //parse keys first
+        if (schema instanceof ListSchemaNode) {
+            for (QName qname : ((ListSchemaNode) schema).getKeyDefinition()) {
+                if(mappedChildElements.get(qname.withoutRevision()).isEmpty()) {
+                    continue;
+                }
+
+                DataSchemaNode childSchema = getSchemaForChild(schema, qname);
+                List<E> childrenForQName = mappedChildElements.removeAll(qname.withoutRevision());
+
+
+                DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChildNode = getDispatcher()
+                        .dispatchChildElement(childSchema, childrenForQName);
+                if (optionalChildNode != null) {
+                    containerBuilder.withChild(optionalChildNode);
+                }
+            }
+        }
+
+        //stage attribues for strategy before going deeper in the recursion
+        buildingStrategy.prepareAttributes(attributes, containerBuilder);
+
         // process Child nodes
         for (QName childPartialQName : mappedChildElements.keySet()) {
             DataSchemaNode childSchema = getSchemaForChild(schema, childPartialQName);
@@ -125,32 +174,39 @@ public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
                 choicesToElements.putAll(choiceSchema, childrenForQName);
                 // Regular child nodes
             } else {
-                DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> builtChildNode = getDispatcher()
+                DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChildNode = getDispatcher()
                         .dispatchChildElement(childSchema, childrenForQName);
-                containerBuilder.withChild(builtChildNode);
+                if (optionalChildNode != null) {
+                    containerBuilder.withChild(optionalChildNode);
+                }
             }
         }
 
         // TODO ordering is not preserved for choice and augment elements
         for (ChoiceSchemaNode choiceSchema : choicesToElements.keySet()) {
-            containerBuilder.withChild(getDispatcher().dispatchChildElement(choiceSchema,
-                    choicesToElements.get(choiceSchema)));
+            DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChild = getDispatcher()
+                    .dispatchChildElement(choiceSchema, choicesToElements.get(choiceSchema));
+            if (optionalChild != null) {
+                containerBuilder.withChild(optionalChild);
+            }
         }
 
         for (AugmentationSchema augmentSchema : augmentsToElements.keySet()) {
             Set<DataSchemaNode> realChildSchemas = getRealSchemasForAugment(schema, augmentSchema);
             EffectiveAugmentationSchema augSchemaProxy = new EffectiveAugmentationSchema(augmentSchema, realChildSchemas);
-            containerBuilder.withChild(getDispatcher().dispatchChildElement(augSchemaProxy, augmentsToElements.get(augmentSchema)));
+            DataContainerChild<? extends YangInstanceIdentifier.PathArgument, ?> optionalChild = getDispatcher()
+                    .dispatchChildElement(augSchemaProxy, augmentsToElements.get(augmentSchema));
+            if (optionalChild != null) {
+                containerBuilder.withChild(optionalChild);
+            }
         }
 
-        if (containerBuilder instanceof AttributesBuilder) {
-            final int size = Iterables.size(elements);
-            Preconditions.checkArgument(size == 1, "Unexpected number of elements: %s, should be 1 for: %s",
-                    size, schema);
-            ((AttributesBuilder<?>) containerBuilder).withAttributes(getAttributes(elements.iterator().next()));
-        }
+        return buildingStrategy.build(containerBuilder);
+    }
 
-        return containerBuilder.build();
+    @Override
+    public BuildingStrategy<P, N> getBuildingStrategy() {
+        return buildingStrategy;
     }
 
     protected Map<QName, String> getAttributes(final E e) {
@@ -161,7 +217,7 @@ public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
         return true;
     }
 
-    private boolean isMarkedAs(final Map<QName, ?> mappedAugmentChildNodes, final QName qName) {
+    private static boolean isMarkedAs(final Map<QName, ?> mappedAugmentChildNodes, final QName qName) {
         return mappedAugmentChildNodes.containsKey(qName);
     }
 
@@ -175,4 +231,16 @@ public abstract class BaseDispatcherParser<E, N extends DataContainerNode<?>, S>
         Preconditions.checkArgument(!Iterables.isEmpty(childNodes),
                 "Node detected 0 times, should be at least 1, identified by: %s, found: %s", schema, childNodes);
     }
+
+    public static class SimpleBuildingStrategy<P extends YangInstanceIdentifier.PathArgument, N extends DataContainerNode<P>> implements BuildingStrategy<P, N> {
+        @Override
+        public N build(final NormalizedNodeBuilder<P, ?, N> builder) {
+            return builder.build();
+        }
+
+        @Override
+        public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<P, ?, N> containerBuilder) {
+            // NOOP
+        }
+    }
 }
index a82f71685ad642e578b54fdc6d846a5409e9dbe0..371c59c3556c5df5ff3016d6d2f6f440ebd25cf9 100644 (file)
@@ -28,7 +28,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
  *
  * @param <E> type of elements to be parsed
  */
-public abstract class ChoiceNodeBaseParser<E> extends BaseDispatcherParser<E, ChoiceNode, ChoiceSchemaNode> {
+public abstract class ChoiceNodeBaseParser<E> extends BaseDispatcherParser<E, YangInstanceIdentifier.NodeIdentifier, ChoiceNode, ChoiceSchemaNode> {
+
+    protected ChoiceNodeBaseParser() {}
+
+    protected ChoiceNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ChoiceNode> buildingStrategy) {
+        super(buildingStrategy);
+    }
 
     @Override
     protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ChoiceNode> getBuilder(
index f7cca88155f52cfe18a504ce8a5e4b0849ffef4b..99801cf3a1195f664a2ac84d75c1bf37493730c4 100644 (file)
@@ -27,7 +27,13 @@ import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
  * @param <E> type of elements to be parsed
  */
 public abstract class ContainerNodeBaseParser<E> extends
-        BaseDispatcherParser<E, ContainerNode, ContainerSchemaNode> {
+        BaseDispatcherParser<E, YangInstanceIdentifier.NodeIdentifier, ContainerNode, ContainerSchemaNode> {
+
+    public ContainerNodeBaseParser() {}
+
+    public ContainerNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ContainerNode> buildingStrategy) {
+        super(buildingStrategy);
+    }
 
     @Override
     protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode> getBuilder(
@@ -63,4 +69,5 @@ public abstract class ContainerNodeBaseParser<E> extends
 
     @Override
     protected abstract Map<QName, String> getAttributes(E e);
+
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ExtensibleParser.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/transform/base/parser/ExtensibleParser.java
new file mode 100644 (file)
index 0000000..e2b5ec7
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
+
+import java.util.Map;
+import javax.annotation.Nullable;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+
+/**
+ * Extensible parser allows its subclasses to customize the building process of normalized nodes
+ *
+ * @param <P>
+ * @param <E>
+ * @param <N>
+ * @param <S>
+ */
+public interface ExtensibleParser<P extends YangInstanceIdentifier.PathArgument, E, N extends NormalizedNode<P, ?>, S>
+        extends ToNormalizedNodeParser<E, N, S> {
+
+    /**
+     * Provide building strategy
+     */
+    BuildingStrategy<P, N> getBuildingStrategy();
+
+    /**
+     * Building strategy serves as a set of hooks into the parsing process.
+     *
+     * @param <P>
+     * @param <N>
+     */
+    interface BuildingStrategy<P extends YangInstanceIdentifier.PathArgument, N extends NormalizedNode<P, ?>> {
+
+        /**
+         * Build normalized node from its builder
+         *
+         * @param builder filled builder for node
+         * @return built normalized node or null if the node should not be built
+         */
+        @Nullable N build(NormalizedNodeBuilder<P, ?, N> builder);
+
+        /**
+         * Hook for subclasses to handle attributes associated with current node. This is called before the build method
+         * and allows subclasses to react to node's attributes e.g. modification operation
+         *
+         * @param attributes attributes for node
+         * @param containerBuilder builder created for node. Can be modified according to attributes e.g. remove attribute
+         */
+        void prepareAttributes(Map<QName, String> attributes, NormalizedNodeBuilder<P, ?, N> containerBuilder);
+    }
+}
index 4056d1da18512ddad3a32629ff1ea74d8856b262..f5dc67e1a322e8772d74456eca9f08ab3c162597 100644 (file)
@@ -7,27 +7,36 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
 import java.util.Map;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
 /**
  * Abstract(base) parser for LeafNodes, parses elements of type E.
  *
  * @param <E> type of elements to be parsed
  */
-public abstract class LeafNodeBaseParser<E> implements
-        ToNormalizedNodeParser<E, LeafNode<?>, LeafSchemaNode> {
+public abstract class LeafNodeBaseParser<E> implements ExtensibleParser<NodeIdentifier, E, LeafNode<?>, LeafSchemaNode> {
+
+    private final BuildingStrategy<NodeIdentifier, LeafNode<?>> buildingStrategy;
+
+    public LeafNodeBaseParser() {
+        buildingStrategy = new SimpleLeafBuildingStrategy();
+    }
 
+    public LeafNodeBaseParser(final BuildingStrategy<NodeIdentifier, LeafNode<?>> buildingStrategy) {
+        this.buildingStrategy = buildingStrategy;
+    }
+
+    @SuppressWarnings("unchecked")
     @Override
     public final LeafNode<?> parse(Iterable<E> elements, LeafSchemaNode schema) {
         final int size = Iterables.size(elements);
@@ -36,11 +45,13 @@ public abstract class LeafNodeBaseParser<E> implements
         final E e = elements.iterator().next();
         Object value = parseLeaf(e, schema);
 
-        NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier,Object,LeafNode<Object>> leafBuilder = Builders.leafBuilder(schema);
+        NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeIdentifier, Object, LeafNode<Object>> leafBuilder =
+                Builders.leafBuilder(schema);
 
         leafBuilder.withAttributes(getAttributes(e));
 
-        return leafBuilder.withValue(value).build();
+        final BuildingStrategy rawBuildingStrat = buildingStrategy;
+        return (LeafNode<?>) rawBuildingStrat.build(leafBuilder.withValue(value));
     }
 
     /**
@@ -59,4 +70,21 @@ public abstract class LeafNodeBaseParser<E> implements
      * @return attributes mapped to QNames
      */
     protected abstract Map<QName, String> getAttributes(E e);
+
+    @Override
+    public BuildingStrategy<NodeIdentifier, LeafNode<?>> getBuildingStrategy() {
+        return buildingStrategy;
+    }
+
+    public static class SimpleLeafBuildingStrategy implements BuildingStrategy<NodeIdentifier, LeafNode<?>> {
+        @Override
+        public LeafNode<?> build(final NormalizedNodeBuilder<NodeIdentifier, ?, LeafNode<?>> builder) {
+            return builder.build();
+        }
+
+        @Override
+        public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<NodeIdentifier, ?, LeafNode<?>> containerBuilder) {
+            // NOOP
+        }
+    }
 }
index 526cdf8615452893ccc3201a0cfdd1c26ea02eb0..7006c269ad0a4597a16f9b856659113202886662 100644 (file)
@@ -7,29 +7,38 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Iterables;
 import java.util.Map;
-
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Iterables;
-
 /**
  * Abstract(base) parser for LeafSetEntryNodes, parses elements of type E.
  *
  * @param <E> type of elements to be parsed
  */
-public abstract class LeafSetEntryNodeBaseParser<E> implements
-        ToNormalizedNodeParser<E, LeafSetEntryNode<?>, LeafListSchemaNode> {
+public abstract class LeafSetEntryNodeBaseParser<E> implements ExtensibleParser<YangInstanceIdentifier.NodeWithValue, E, LeafSetEntryNode<?>, LeafListSchemaNode> {
+
+    private final BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> buildingStrategy;
+
+    public LeafSetEntryNodeBaseParser() {
+        buildingStrategy = new SimpleLeafSetEntryBuildingStrategy();
+    }
 
+    public LeafSetEntryNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> buildingStrategy) {
+        this.buildingStrategy = buildingStrategy;
+    }
+
+    @SuppressWarnings("unchecked")
     @Override
-    public final LeafSetEntryNode<Object> parse(Iterable<E> elements, LeafListSchemaNode schema) {
+    public final LeafSetEntryNode<?> parse(Iterable<E> elements, LeafListSchemaNode schema) {
         final int size = Iterables.size(elements);
         Preconditions.checkArgument(size == 1, "Xml elements mapped to leaf node illegal count: %s", size);
 
@@ -39,8 +48,15 @@ public abstract class LeafSetEntryNodeBaseParser<E> implements
         NormalizedNodeAttrBuilder<YangInstanceIdentifier.NodeWithValue, Object, LeafSetEntryNode<Object>> leafEntryBuilder = Builders
                 .leafSetEntryBuilder(schema);
         leafEntryBuilder.withAttributes(getAttributes(e));
+        leafEntryBuilder.withValue(value);
+
+        final BuildingStrategy rawBuildingStrat = buildingStrategy;
+        return (LeafSetEntryNode<?>) rawBuildingStrat.build(leafEntryBuilder);
+    }
 
-        return leafEntryBuilder.withValue(value).build();
+    @Override
+    public BuildingStrategy<NodeWithValue, LeafSetEntryNode<?>> getBuildingStrategy() {
+        return buildingStrategy;
     }
 
     /**
@@ -60,4 +76,15 @@ public abstract class LeafSetEntryNodeBaseParser<E> implements
      */
     protected abstract Map<QName, String> getAttributes(E e);
 
+    public static class SimpleLeafSetEntryBuildingStrategy implements BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> {
+
+        @Override
+        public LeafSetEntryNode<?> build(final NormalizedNodeBuilder<NodeWithValue, ?, LeafSetEntryNode<?>> builder) {
+            return builder.build();
+        }
+
+        @Override
+        public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<NodeWithValue, ?, LeafSetEntryNode<?>> containerBuilder) {
+        }
+    }
 }
index 4cdae37f3554f18f13d4f99872f3235f7839c310..3669cba16bad8c5e99aaabaa8feafe62df7d2d2b 100644 (file)
@@ -8,7 +8,6 @@
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
 
 import java.util.Collections;
-
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
index dfa34abcc7d6881bb2ba696deb4c7e62202556c1..cd0b478ec0a4c6c53903c5d21a4f12014d3249c2 100644 (file)
@@ -10,6 +10,7 @@ package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
 import java.util.Map;
 import java.util.Set;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
@@ -24,8 +25,15 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
  * @param <E>
  *            type of elements to be parsed
  */
-public abstract class ListEntryNodeBaseParser<E, N extends DataContainerNode<?>> extends
-        BaseDispatcherParser<E, N, ListSchemaNode> {
+public abstract class ListEntryNodeBaseParser<P extends YangInstanceIdentifier.PathArgument, E, N extends DataContainerNode<P>> extends
+        BaseDispatcherParser<E, P, N, ListSchemaNode> {
+
+    public ListEntryNodeBaseParser(final BuildingStrategy<P, N> buildingStrategy) {
+        super(buildingStrategy);
+    }
+
+    public ListEntryNodeBaseParser() {
+    }
 
     @Override
     protected final Set<DataSchemaNode> getRealSchemasForAugment(final ListSchemaNode schema, final AugmentationSchema augmentSchema) {
index 67c97a767d042c56956fae92d2fa684b19293612..f8bc9c120b274b99948d9aa9de5ea73bfadaf7a1 100644 (file)
@@ -8,9 +8,12 @@
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
 
 import java.util.Collections;
+import java.util.Map;
+import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 
@@ -21,17 +24,32 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
  *            type of elements to be parsed
  */
 public abstract class ListNodeBaseParser<E, N extends NormalizedNode<?, ?>, O extends NormalizedNode<YangInstanceIdentifier.NodeIdentifier, ?>, S extends ListSchemaNode>
-        implements ToNormalizedNodeParser<E, O, S> {
+        implements ExtensibleParser<YangInstanceIdentifier.NodeIdentifier, E, O, S> {
+
+    private final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> buildingStrategy;
+
+    public ListNodeBaseParser() {
+        buildingStrategy = new SimpleListNodeBuildingStrategy<>();
+    }
+
+    public ListNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> buildingStrategy) {
+        this.buildingStrategy = buildingStrategy;
+    }
 
     @Override
-    public final O parse(Iterable<E> childNodes, S schema) {
+    public O parse(Iterable<E> childNodes, S schema) {
         CollectionNodeBuilder<N, O> listBuilder = provideBuilder(schema);
+
+        buildingStrategy.prepareAttributes(Collections.<QName, String>emptyMap(), listBuilder);
+
         for (E childNode : childNodes) {
             N listChild = getListEntryNodeParser().parse(Collections.singletonList(childNode), schema);
-            listBuilder.withChild(listChild);
+            if (listChild != null) {
+                listBuilder.withChild(listChild);
+            }
         }
 
-        return listBuilder.build();
+        return buildingStrategy.build(listBuilder);
     }
 
     /**
@@ -46,4 +64,21 @@ public abstract class ListNodeBaseParser<E, N extends NormalizedNode<?, ?>, O ex
      * @return prepares builder which will contain entries of list according to concrete list type
      */
     protected abstract CollectionNodeBuilder<N, O> provideBuilder(S schema);
+
+    @Override
+    public BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> getBuildingStrategy() {
+        return buildingStrategy;
+    }
+
+    public static class SimpleListNodeBuildingStrategy<O extends NormalizedNode<YangInstanceIdentifier.NodeIdentifier, ?>> implements BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, O> {
+        @Override
+        public O build(final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, O> builder) {
+            return builder.build();
+        }
+
+        @Override
+        public void prepareAttributes(final Map<QName, String> attributes, final NormalizedNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ?, O> containerBuilder) {
+            // NOOP
+        }
+    }
 }
index a57a694e126668684bf9310804aa0f50aea7f062..805634046554609a8b3ca5e9b0f3d1c9019a6932 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
 
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -21,6 +22,13 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
  */
 public abstract class MapNodeBaseParser<E> extends ListNodeBaseParser<E, MapEntryNode, MapNode, ListSchemaNode> {
 
+    public MapNodeBaseParser() {
+    }
+
+    public MapNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, MapNode> buildingStrategy) {
+        super(buildingStrategy);
+    }
+
     protected CollectionNodeBuilder<MapEntryNode, MapNode> provideBuilder(ListSchemaNode schema) {
         return Builders.mapBuilder(schema);
     }
index 6278accb61656b4ccad44924f31418d9e425e6d1..a2ca255ce8b0ac7aee2772b8da0f86e9d18cd0cd 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser;
 
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
@@ -21,8 +22,17 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
  */
 public abstract class OrderedListNodeBaseParser<E> extends
         ListNodeBaseParser<E, MapEntryNode, OrderedMapNode, ListSchemaNode> {
+
+    public OrderedListNodeBaseParser() {
+    }
+
+    public OrderedListNodeBaseParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, OrderedMapNode> buildingStrategy) {
+        super(buildingStrategy);
+    }
+
     @Override
     protected CollectionNodeBuilder<MapEntryNode, OrderedMapNode> provideBuilder(ListSchemaNode schema) {
         return Builders.orderedMapBuilder(schema);
     }
+
 }
index 14d47890cf8ab66510e8915e927003ba0df539c8..73e7f3905292b4b54fa9a98707bdfc0aa218fd47 100644 (file)
@@ -22,6 +22,14 @@ import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
  */
 public abstract class UnkeyedListNodeBaseParser<E> extends
         ListNodeBaseParser<E, UnkeyedListEntryNode, UnkeyedListNode, ListSchemaNode> {
+
+    public UnkeyedListNodeBaseParser(final BuildingStrategy<NodeIdentifier, UnkeyedListNode> buildingStrategy) {
+        super(buildingStrategy);
+    }
+
+    public UnkeyedListNodeBaseParser() {
+    }
+
     @Override
     protected CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> provideBuilder(ListSchemaNode schema) {
         CollectionNodeBuilder<UnkeyedListEntryNode, UnkeyedListNode> listBuilder = Builders.unkeyedListBuilder();
index 73167f407a522232c3c105311ef26c2e5c1b9055..3fed808ad9814280b2c38f520fc5e70bdbfc457e 100644 (file)
@@ -7,15 +7,16 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.LinkedListMultimap;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.AugmentationNodeBaseParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.LinkedListMultimap;
-
 final class AugmentationNodeDomParser extends AugmentationNodeBaseParser<Element> {
 
     private final NodeParserDispatcher<Element> dispatcher;
@@ -31,6 +32,13 @@ final class AugmentationNodeDomParser extends AugmentationNodeBaseParser<Element
         this.strictParsing = strictParsing;
     }
 
+    public AugmentationNodeDomParser(final BuildingStrategy<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> buildingStrategy,
+                                     final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+        super(buildingStrategy);
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+        this.strictParsing = strictParsing;
+    }
+
     @Override
     protected LinkedListMultimap<QName, Element> mapChildElements(Iterable<Element> elements) {
         return DomUtils.mapChildElements(elements);
index 97e8a6171cdaaf0d82c1031247c181385fcbb0d6..2c2ccc6ad7aaf46a578412c78092e3ebcd62d28a 100644 (file)
@@ -7,25 +7,31 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.LinkedListMultimap;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ChoiceNodeBaseParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.LinkedListMultimap;
-
 final class ChoiceNodeDomParser extends ChoiceNodeBaseParser<Element> {
 
     private final NodeParserDispatcher<Element> dispatcher;
 
-    ChoiceNodeDomParser(NodeParserDispatcher<Element> dispatcher) {
+    ChoiceNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
+        this.dispatcher = Preconditions.checkNotNull(dispatcher);
+    }
+
+    ChoiceNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ChoiceNode> buildingStrategy) {
+        super(buildingStrategy);
         this.dispatcher = Preconditions.checkNotNull(dispatcher);
     }
 
     @Override
-    protected LinkedListMultimap<QName, Element> mapChildElements(Iterable<Element> xml) {
+    protected LinkedListMultimap<QName, Element> mapChildElements(final Iterable<Element> xml) {
         return DomUtils.mapChildElements(xml);
     }
 
@@ -33,4 +39,5 @@ final class ChoiceNodeDomParser extends ChoiceNodeBaseParser<Element> {
     protected NodeParserDispatcher<Element> getDispatcher() {
         return dispatcher;
     }
+
 }
index ed4f2772ed453d83430deeac6525b871091583bc..397df436a5feefef5d5ac07378efab8450f162a9 100644 (file)
@@ -7,17 +7,17 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import com.google.common.base.Preconditions;
+import com.google.common.collect.LinkedListMultimap;
 import java.util.Map;
-
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ContainerNodeBaseParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Preconditions;
-import com.google.common.collect.LinkedListMultimap;
-
 final class ContainerNodeDomParser extends ContainerNodeBaseParser<Element> {
 
     private final NodeParserDispatcher<Element> dispatcher;
@@ -25,10 +25,16 @@ final class ContainerNodeDomParser extends ContainerNodeBaseParser<Element> {
 
     ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
         this.dispatcher = Preconditions.checkNotNull(dispatcher);
-        this.strictParsing = super.strictParsing();
+        strictParsing = super.strictParsing();
+    }
+
+    public ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+        this.dispatcher = dispatcher;
+        this.strictParsing = strictParsing;
     }
 
-    ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final boolean strictParsing) {
+    ContainerNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, ContainerNode> parsingStrategy, final boolean strictParsing) {
+        super(parsingStrategy);
         this.dispatcher = Preconditions.checkNotNull(dispatcher);
         this.strictParsing = strictParsing;
     }
index 8e6381748ef856c7963739b0caf01a164795d64b..b86289a7be4ba4e30e39bf606dffd82f5cae3351 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
@@ -22,6 +23,11 @@ import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParserFactory;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.BaseDispatcherParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ExtensibleParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafNodeBaseParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafSetEntryNodeBaseParser;
+import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ListNodeBaseParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
 import org.opendaylight.yangtools.yang.model.api.AnyXmlSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
@@ -34,6 +40,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.w3c.dom.Element;
 
 public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeParserFactory<Element> {
+
     private final AugmentationNodeDomParser augmentationNodeParser;
     private final ChoiceNodeDomParser choiceNodeParser;
     private final ContainerNodeDomParser containerNodeParser;
@@ -67,6 +74,31 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP
         augmentationNodeParser = new AugmentationNodeDomParser(dispatcher, strictParsing);
     }
 
+    private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider, final SchemaContext schema,
+                                             final BuildingStrategyProvider buildingStratProvider, final boolean strictParsing) {
+        leafNodeParser = new LeafNodeDomParser(codecProvider, schema, buildingStratProvider.forLeaf());
+        leafSetEntryNodeParser = new LeafSetEntryNodeDomParser(codecProvider, schema, buildingStratProvider.forLeafSetEntry());
+
+        // no buildingStrategy for Augment (no use case for now)
+        leafSetNodeParser = new LeafSetNodeDomParser(leafSetEntryNodeParser);
+        // no buildingStrategy for anyXml (probably not necessary)
+        anyXmlNodeParser = new AnyXmlDomParser();
+
+        final NodeParserDispatcher<Element> dispatcher = new NodeParserDispatcher.BaseNodeParserDispatcher<Element>(this) {
+
+        };
+
+        containerNodeParser = new ContainerNodeDomParser(dispatcher, buildingStratProvider.forContainer(), strictParsing);
+        mapEntryNodeParser = new MapEntryNodeDomParser(dispatcher, buildingStratProvider.forMapEntry(), strictParsing);
+        mapNodeParser = new MapNodeDomParser(mapEntryNodeParser, buildingStratProvider.forMap());
+        orderedListNodeParser = new OrderedListNodeDomParser(mapEntryNodeParser, buildingStratProvider.forOrderedList());
+        unkeyedListEntryNodeParser = new UnkeyedListEntryNodeDomParser(buildingStratProvider.forUnkeyedListEntry(), dispatcher);
+        unkeyedListNodeParser = new UnkeyedListNodeDomParser(buildingStratProvider.forUnkeyedList(), unkeyedListEntryNodeParser);
+        choiceNodeParser = new ChoiceNodeDomParser(dispatcher, buildingStratProvider.forChoice());
+        // no buildingStrategy for Augment (no use case for now)
+        augmentationNodeParser = new AugmentationNodeDomParser(buildingStratProvider.forAugmentation(), dispatcher, strictParsing);
+    }
+
     @Deprecated
     private DomToNormalizedNodeParserFactory(final XmlCodecProvider codecProvider) {
         leafNodeParser = new LeafNodeDomParser(codecProvider);
@@ -96,6 +128,17 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP
         return new DomToNormalizedNodeParserFactory(codecProvider, schema, true);
     }
 
+    public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema,
+                                                               final BuildingStrategyProvider buildingStratProvider) {
+        return new DomToNormalizedNodeParserFactory(codecProvider, schema, buildingStratProvider, true);
+    }
+
+    public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider, final SchemaContext schema,
+                                                               final BuildingStrategyProvider buildingStratProvider,
+                                                               final boolean strictParsing) {
+        return new DomToNormalizedNodeParserFactory(codecProvider, schema, buildingStratProvider, strictParsing);
+    }
+
     @Deprecated
     public static DomToNormalizedNodeParserFactory getInstance(final XmlCodecProvider codecProvider) {
         return new DomToNormalizedNodeParserFactory(codecProvider);
@@ -160,4 +203,50 @@ public final class DomToNormalizedNodeParserFactory implements ToNormalizedNodeP
     public ToNormalizedNodeParser<Element, AnyXmlNode, AnyXmlSchemaNode> getAnyXmlNodeParser() {
         return anyXmlNodeParser;
     }
+
+    /**
+     * Base provider of building strategies used for customizing parsing process
+     */
+    public static abstract class BuildingStrategyProvider {
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,LeafNode<?>> forLeaf() {
+            return new LeafNodeBaseParser.SimpleLeafBuildingStrategy();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeWithValue,LeafSetEntryNode<?>> forLeafSetEntry() {
+            return new LeafSetEntryNodeBaseParser.SimpleLeafSetEntryBuildingStrategy();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,ContainerNode> forContainer() {
+            return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifierWithPredicates,MapEntryNode> forMapEntry() {
+            return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,MapNode> forMap() {
+            return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,OrderedMapNode> forOrderedList() {
+            return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,UnkeyedListEntryNode> forUnkeyedListEntry() {
+            return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,UnkeyedListNode> forUnkeyedList() {
+            return new ListNodeBaseParser.SimpleListNodeBuildingStrategy<>();
+        }
+
+        protected ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.NodeIdentifier,ChoiceNode> forChoice() {
+            return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+        }
+
+        public ExtensibleParser.BuildingStrategy<YangInstanceIdentifier.AugmentationIdentifier, AugmentationNode> forAugmentation() {
+            return new BaseDispatcherParser.SimpleBuildingStrategy<>();
+        }
+    }
 }
index 2e8ab87bd749d0134ee6ad68f9cf058d2e263bb7..25b57ccf083f91c5531c97e437f89226768d187e 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import com.google.common.base.Preconditions;
 import java.util.Map;
-
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafNodeBaseParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
@@ -17,8 +19,6 @@ import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Preconditions;
-
 final class LeafNodeDomParser extends LeafNodeBaseParser<Element> {
 
     private final XmlCodecProvider codecProvider;
@@ -29,6 +29,12 @@ final class LeafNodeDomParser extends LeafNodeBaseParser<Element> {
         this.codecProvider = Preconditions.checkNotNull(codecProvider);
     }
 
+    LeafNodeDomParser(XmlCodecProvider codecProvider, final SchemaContext schema, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, LeafNode<?>> strategy) {
+        super(strategy);
+        this.ctx = schema;
+        this.codecProvider = Preconditions.checkNotNull(codecProvider);
+    }
+
     @Deprecated
     LeafNodeDomParser(XmlCodecProvider codecProvider) {
         this(codecProvider, null);
@@ -43,4 +49,5 @@ final class LeafNodeDomParser extends LeafNodeBaseParser<Element> {
     protected Map<QName, String> getAttributes(Element element) {
         return DomUtils.toAttributes(element.getAttributes());
     }
+
 }
index 0458cd5d106644cac40ed247956a640385fe9d8f..decf9013371a37003805a2381110761e6ca9e9f9 100644 (file)
@@ -7,9 +7,11 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import com.google.common.base.Preconditions;
 import java.util.Map;
-
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
 import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlCodecProvider;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.LeafSetEntryNodeBaseParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
@@ -17,15 +19,19 @@ import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 import org.w3c.dom.Element;
 
-import com.google.common.base.Preconditions;
-
 final class LeafSetEntryNodeDomParser extends LeafSetEntryNodeBaseParser<Element> {
 
     private final XmlCodecProvider codecProvider;
     private final SchemaContext ctx;
 
-    LeafSetEntryNodeDomParser(XmlCodecProvider codecProvider, final SchemaContext schema) {
-        ctx = schema;
+    LeafSetEntryNodeDomParser(final XmlCodecProvider codecProvider, final SchemaContext schema) {
+        this.ctx = schema;
+        this.codecProvider = Preconditions.checkNotNull(codecProvider);
+    }
+
+    LeafSetEntryNodeDomParser(final XmlCodecProvider codecProvider, final SchemaContext schema, final  BuildingStrategy<YangInstanceIdentifier.NodeWithValue, LeafSetEntryNode<?>> strategy) {
+        super(strategy);
+        this.ctx = schema;
         this.codecProvider = Preconditions.checkNotNull(codecProvider);
     }
 
@@ -43,4 +49,5 @@ final class LeafSetEntryNodeDomParser extends LeafSetEntryNodeBaseParser<Element
     protected Map<QName, String> getAttributes(Element element) {
         return DomUtils.toAttributes(element.getAttributes());
     }
+
 }
index 92496d79f7bcb5c8af6d3818c7ccb0a03b8c237d..90aca17fd84a1192a0d4e0af499e0649f35e0982 100644 (file)
@@ -11,13 +11,14 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.LinkedListMultimap;
 import java.util.Map;
 import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.ListEntryNodeBaseParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.NodeParserDispatcher;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.DomUtils;
 import org.w3c.dom.Element;
 
-abstract class ListEntryNodeDomParser<N extends DataContainerNode<?>> extends ListEntryNodeBaseParser<Element, N> {
+abstract class ListEntryNodeDomParser<P extends YangInstanceIdentifier.PathArgument, N extends DataContainerNode<P>> extends ListEntryNodeBaseParser<P, Element, N> {
 
     private final NodeParserDispatcher<Element> dispatcher;
 
@@ -25,6 +26,11 @@ abstract class ListEntryNodeDomParser<N extends DataContainerNode<?>> extends Li
         this.dispatcher = Preconditions.checkNotNull(dispatcher);
     }
 
+    ListEntryNodeDomParser(final BuildingStrategy<P, N> buildingStrategy, final NodeParserDispatcher<Element> dispatcher) {
+        super(buildingStrategy);
+        this.dispatcher = dispatcher;
+    }
+
     @Override
     protected LinkedListMultimap<QName, Element> mapChildElements(Iterable<Element> elements) {
         return DomUtils.mapChildElementsForSingletonNode(elements.iterator().next());
index a6c467c22224159dcb4120bf84233752bb18f13a..05a086476cfa9216338fe7f0f4eabbe3426aded3 100644 (file)
@@ -15,12 +15,14 @@ import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.No
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.w3c.dom.Element;
 
-final class MapEntryNodeDomParser extends ListEntryNodeDomParser<MapEntryNode> {
+final class MapEntryNodeDomParser extends ListEntryNodeDomParser<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> {
 
     private final boolean strictParsing;
 
     MapEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
         super(dispatcher);
+        // TODO strict parsing attribute should be injected into superclass via a constructor
+        // WIth current approach (getter) we have to call super.strictParsing in constructor and cannot reuse constructors
         this.strictParsing = super.strictParsing();
     }
 
@@ -29,6 +31,12 @@ final class MapEntryNodeDomParser extends ListEntryNodeDomParser<MapEntryNode> {
         this.strictParsing = strictParsing;
     }
 
+    MapEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> strategy,
+                          final boolean strictParsing) {
+        super(strategy, dispatcher);
+        this.strictParsing = strictParsing;
+    }
+
     @Override
     protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode> getBuilder(
             ListSchemaNode schema) {
index 748564fdd1c6a3493112b3390259622caf6b3390..0f1c822ae101f29590906c58f31c208539c60189 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.MapNodeBaseParser;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
@@ -17,7 +19,12 @@ final class MapNodeDomParser extends MapNodeBaseParser<Element> {
 
     private final MapEntryNodeDomParser mapEntryParser;
 
-    MapNodeDomParser(MapEntryNodeDomParser mapEntryParser) {
+    MapNodeDomParser(final MapEntryNodeDomParser mapEntryParser) {
+        this.mapEntryParser = mapEntryParser;
+    }
+
+    MapNodeDomParser(MapEntryNodeDomParser mapEntryParser, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, MapNode> strategy) {
+        super(strategy);
         this.mapEntryParser = mapEntryParser;
     }
 
@@ -25,4 +32,5 @@ final class MapNodeDomParser extends MapNodeBaseParser<Element> {
     protected ToNormalizedNodeParser<Element, MapEntryNode, ListSchemaNode> getListEntryNodeParser() {
         return mapEntryParser;
     }
+
 }
index 787bff8856b7c2ec2bcebd5301a7056ba72c19e4..920c30f3421be8de7eb4055b38eab951351034b8 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.OrderedListNodeBaseParser;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
@@ -17,7 +19,12 @@ final class OrderedListNodeDomParser extends OrderedListNodeBaseParser<Element>
 
     private final MapEntryNodeDomParser mapEntryNodeParser;
 
-    OrderedListNodeDomParser(MapEntryNodeDomParser mapEntryNodeParser) {
+    OrderedListNodeDomParser(final MapEntryNodeDomParser mapEntryNodeParser) {
+        this.mapEntryNodeParser = mapEntryNodeParser;
+    }
+
+    OrderedListNodeDomParser(MapEntryNodeDomParser mapEntryNodeParser, final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, OrderedMapNode> strategy) {
+        super(strategy);
         this.mapEntryNodeParser = mapEntryNodeParser;
     }
 
@@ -25,4 +32,5 @@ final class OrderedListNodeDomParser extends OrderedListNodeBaseParser<Element>
     protected ToNormalizedNodeParser<Element, MapEntryNode, ListSchemaNode> getListEntryNodeParser() {
         return mapEntryNodeParser;
     }
+
 }
index 781f06cb71ac917efb7061bb51952842edb8fc54..79d478fb47692b5746d13bbedfce1114a61f070c 100644 (file)
@@ -16,12 +16,16 @@ import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.No
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
 import org.w3c.dom.Element;
 
-final class UnkeyedListEntryNodeDomParser extends ListEntryNodeDomParser<UnkeyedListEntryNode> {
+final class UnkeyedListEntryNodeDomParser extends ListEntryNodeDomParser<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode> {
 
     UnkeyedListEntryNodeDomParser(final NodeParserDispatcher<Element> dispatcher) {
         super(dispatcher);
     }
 
+    UnkeyedListEntryNodeDomParser(final BuildingStrategy<NodeIdentifier, UnkeyedListEntryNode> buildingStrategy, final NodeParserDispatcher<Element> dispatcher) {
+        super(buildingStrategy, dispatcher);
+    }
+
     @Override
     protected final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, UnkeyedListEntryNode> getBuilder(
             ListSchemaNode schema) {
index 15eed32a2df5f6bfb4faab65279bd7e8cf9c103e..21ec64e5a527509257246c6f5c3f8762edd18840 100644 (file)
@@ -7,7 +7,9 @@
  */
 package org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser;
 
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.ToNormalizedNodeParser;
 import org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser.UnkeyedListNodeBaseParser;
 import org.opendaylight.yangtools.yang.model.api.ListSchemaNode;
@@ -21,8 +23,14 @@ final class UnkeyedListNodeDomParser extends UnkeyedListNodeBaseParser<Element>
         this.unkeyedListEntryNodeParser = unkeyedListEntryNodeParser;
     }
 
+    UnkeyedListNodeDomParser(final BuildingStrategy<YangInstanceIdentifier.NodeIdentifier, UnkeyedListNode> buildingStrategy, final UnkeyedListEntryNodeDomParser unkeyedListEntryNodeParser) {
+        super(buildingStrategy);
+        this.unkeyedListEntryNodeParser = unkeyedListEntryNodeParser;
+    }
+
     @Override
     protected ToNormalizedNodeParser<Element, UnkeyedListEntryNode, ListSchemaNode> getListEntryNodeParser() {
         return unkeyedListEntryNodeParser;
     }
+
 }
index 93e0e671eda7e72ac8a4d73efa53f4ebb2e39fd4..6c947843ccd57f989891a1442f0a81767934651d 100644 (file)
@@ -118,7 +118,7 @@ abstract class AbstractModifiedNodeBasedCandidateNode implements DataTreeCandida
         return Verify.verifyNotNull(mod.getModificationType(), "Node %s does not have resolved modification type", mod);
     }
 
-    private Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
+    private static Optional<NormalizedNode<?, ?>> optionalData(final TreeNode meta) {
         if (meta != null) {
             return Optional.<NormalizedNode<?,?>>of(meta.getData());
         } else {
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractReadyIterator.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/schema/tree/AbstractReadyIterator.java
new file mode 100644 (file)
index 0000000..5591192
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.yangtools.yang.data.impl.schema.tree;
+
+import com.google.common.base.Preconditions;
+import java.util.Collection;
+import java.util.Iterator;
+
+abstract class AbstractReadyIterator {
+    final Iterator<ModifiedNode> children;
+    final ModifiedNode node;
+
+    private AbstractReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children) {
+        this.children = Preconditions.checkNotNull(children);
+        this.node = Preconditions.checkNotNull(node);
+    }
+
+    static AbstractReadyIterator create(final ModifiedNode root) {
+        return new RootReadyIterator(root, root.getChildren().iterator());
+    }
+
+    final AbstractReadyIterator process() {
+        // Walk all child nodes and remove any children which have not
+        // been modified. If a child
+        while (children.hasNext()) {
+            final ModifiedNode child = children.next();
+            final Collection<ModifiedNode> grandChildren = child.getChildren();
+            if (grandChildren.isEmpty()) {
+                child.seal();
+                if (child.getOperation() == LogicalOperation.NONE) {
+                    children.remove();
+                }
+            } else {
+                return new NestedReadyIterator(this, child, grandChildren.iterator());
+            }
+        }
+
+        node.seal();
+
+        // Remove from parent if we have one and this is a no-op
+        if (node.getOperation() == LogicalOperation.NONE) {
+            removeFromParent();
+        }
+        return getParent();
+    }
+
+    abstract AbstractReadyIterator getParent();
+    abstract void removeFromParent();
+
+    private static final class NestedReadyIterator extends AbstractReadyIterator {
+        private final AbstractReadyIterator parent;
+
+        private NestedReadyIterator(final AbstractReadyIterator parent, final ModifiedNode node, final Iterator<ModifiedNode> children) {
+            super(node, children);
+            this.parent = Preconditions.checkNotNull(parent);
+        }
+
+        @Override
+        AbstractReadyIterator getParent() {
+            return parent;
+        }
+
+        @Override
+        void removeFromParent() {
+            parent.children.remove();
+        }
+    }
+
+    private static final class RootReadyIterator extends AbstractReadyIterator {
+        private RootReadyIterator(final ModifiedNode node, final Iterator<ModifiedNode> children) {
+            super(node, children);
+        }
+
+        @Override
+        AbstractReadyIterator getParent() {
+            return null;
+        }
+
+        @Override
+        void removeFromParent() {
+            // No-op, since root node cannot be removed
+        }
+    }
+
+}
\ No newline at end of file
index 2dda1b3f654fc38527d6849b674e6315f6540bad..f86c71249bc53b20f2b3a5586cc16b49302c58cb 100644 (file)
@@ -148,7 +148,7 @@ final class InMemoryDataTreeModification implements DataTreeModification {
         ModifiedNode modification = rootNode;
 
         int i = 1;
-        for(PathArgument pathArg : path.getPathArguments()) {
+        for (PathArgument pathArg : path.getPathArguments()) {
             Optional<ModificationApplyOperation> potential = operation.getChild(pathArg);
             if (!potential.isPresent()) {
                 throw new IllegalArgumentException(String.format("Child %s is not present in schema tree.",
@@ -163,14 +163,6 @@ final class InMemoryDataTreeModification implements DataTreeModification {
         return OperationWithModification.from(operation, modification);
     }
 
-    @Override
-    public void ready() {
-        final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
-        Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
-
-        rootNode.seal();
-    }
-
     private void checkSealed() {
         Preconditions.checkState(sealed == 0, "Data Tree is sealed. No further modifications allowed.");
     }
@@ -248,4 +240,16 @@ final class InMemoryDataTreeModification implements DataTreeModification {
             applyNode(cursor, child);
         }
     }
+
+    @Override
+    public void ready() {
+        final boolean wasRunning = UPDATER.compareAndSet(this, 0, 1);
+        Preconditions.checkState(wasRunning, "Attempted to seal an already-sealed Data Tree.");
+
+        AbstractReadyIterator current = AbstractReadyIterator.create(rootNode);
+        do {
+            current = current.process();
+        } while (current != null);
+    }
+
 }
index 306d9c8581233362e07ec61f27500a5680548e85..525ff55612146323284be99d4017a32a95c515ba 100644 (file)
@@ -37,7 +37,7 @@ final class MinMaxElementsValidation extends SchemaAwareApplyOperation {
         this.maxElements = maxElements;
     }
 
-    static final SchemaAwareApplyOperation from(final SchemaAwareApplyOperation delegate, final DataSchemaNode schema) {
+    static SchemaAwareApplyOperation from(final SchemaAwareApplyOperation delegate, final DataSchemaNode schema) {
         final ConstraintDefinition constraints = schema.getConstraints();
         if (constraints == null || (constraints.getMinElements() == null && constraints.getMaxElements() == null)) {
             return delegate;
@@ -46,6 +46,22 @@ final class MinMaxElementsValidation extends SchemaAwareApplyOperation {
 
     }
 
+    private static int findChildrenBefore(final Optional<TreeNode> current) {
+        if (current.isPresent()) {
+            return numOfChildrenFromValue(current.get().getData());
+        } else {
+            return 0;
+        }
+    }
+
+    private static int findChildrenAfter(final ModifiedNode modification) {
+        if (modification.getWrittenValue() != null) {
+            return numOfChildrenFromValue(modification.getWrittenValue());
+        } else {
+            return 0;
+        }
+    }
+
     private void checkMinMaxElements(final YangInstanceIdentifier path, final NodeModification nodeMod,
             final Optional<TreeNode> current) throws DataValidationFailedException {
         if (!(nodeMod instanceof ModifiedNode)) {
@@ -53,19 +69,10 @@ final class MinMaxElementsValidation extends SchemaAwareApplyOperation {
             return;
         }
         final ModifiedNode modification = (ModifiedNode) nodeMod;
-        final int childrenBefore;
-        if (current.isPresent()) {
-            childrenBefore = numOfChildrenFromValue(current.get().getData());
-        } else {
-            childrenBefore = 0;
-        }
 
-        final int childrenAfter;
-        if (modification.getWrittenValue() != null) {
-            childrenAfter = numOfChildrenFromValue(modification.getWrittenValue());
-        } else {
-            childrenAfter = 0;
-        }
+        final int childrenBefore = findChildrenBefore(current);
+
+        final int childrenAfter = findChildrenAfter(modification);
 
         final int childrenTotal = childrenBefore + childrenAfter + numOfChildrenFromChildMods(modification, current);
         if (minElements != null && minElements > childrenTotal) {
index dbb1f419207553fff84da39f3bf5cea54e21634e..cdd5de01db4fda3a67df0404b7dddc8c7032a958 100644 (file)
@@ -13,7 +13,6 @@ import com.google.common.base.Predicate;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import javax.annotation.Nonnull;
@@ -233,24 +232,11 @@ final class ModifiedNode extends NodeModification implements StoreTreeNode<Modif
     }
 
     /**
-     * Seal the modification node and prune any children which has not been
-     * modified.
+     * Seal the modification node.
      */
     void seal() {
         clearSnapshot();
 
-        // Walk all child nodes and remove any children which have not
-        // been modified.
-        final Iterator<ModifiedNode> it = children.values().iterator();
-        while (it.hasNext()) {
-            final ModifiedNode child = it.next();
-            child.seal();
-
-            if (child.operation == LogicalOperation.NONE) {
-                it.remove();
-            }
-        }
-
         // A TOUCH node without any children is a no-op
         if (operation == LogicalOperation.TOUCH && children.isEmpty()) {
             updateOperationType(LogicalOperation.NONE);
index 817afccc6a6cf1a8dd790b8f74065c3c9dcf320c..a95366ae15f7ac14d6d7f3cf9f1ae0fdbd8900df 100644 (file)
@@ -11,7 +11,6 @@ package org.opendaylight.yangtools.yang.data.impl.codec.xml;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
-
 import com.google.common.base.Optional;
 import com.google.common.collect.Maps;
 import java.io.ByteArrayOutputStream;
@@ -143,7 +142,7 @@ public class XmlStreamUtilsTest {
         return targetBaseType;
     }
 
-    private Map<String, String> mapPrefixed(final Iterable<Map.Entry<URI, String>> prefixes) {
+    private static Map<String, String> mapPrefixed(final Iterable<Map.Entry<URI, String>> prefixes) {
         final Map<String, String> mappedPrefixes = Maps.newHashMap();
         for (final Map.Entry<URI, String> prefix : prefixes) {
             mappedPrefixes.put(prefix.getKey().toString(), prefix.getValue());
@@ -151,9 +150,8 @@ public class XmlStreamUtilsTest {
         return mappedPrefixes;
     }
 
-    private QName getAttrQName(final String namespace, final String revision, final String localName, final Optional<String> prefix) {
-
-        if(prefix.isPresent()) {
+    private static QName getAttrQName(final String namespace, final String revision, final String localName, final Optional<String> prefix) {
+        if (prefix.isPresent()) {
             final QName moduleQName = QName.create(namespace, revision, "module");
             final QNameModule module = QNameModule.create(moduleQName.getNamespace(), moduleQName.getRevision());
             return QName.create(module, localName);
@@ -179,7 +177,7 @@ public class XmlStreamUtilsTest {
         return null;
     }
 
-    private LeafrefTypeDefinition findLeafrefType(final LeafSchemaNode schemaNode) {
+    private static LeafrefTypeDefinition findLeafrefType(final LeafSchemaNode schemaNode) {
         final TypeDefinition<?> type = schemaNode.getType();
         if (type instanceof LeafrefTypeDefinition) {
             return (LeafrefTypeDefinition)type;
index 9c69016e19c4a086dd2496be4523fcf9b0d02b1b..71440c23a9c7cc774fba8140a9b60315204c89ec 100644 (file)
@@ -185,7 +185,7 @@ public class NormalizedDataBuilderTest {
         // .build());
     }
 
-    private AugmentationSchema getAugmentationSchemaForChild(final ContainerSchemaNode containerNode, final QName qName) {
+    private static AugmentationSchema getAugmentationSchemaForChild(final ContainerSchemaNode containerNode, final QName qName) {
         for (AugmentationSchema augmentationSchema : containerNode.getAvailableAugmentations()) {
             if (augmentationSchema.getDataChildByName(qName) != null) {
                 return augmentationSchema;
@@ -194,16 +194,16 @@ public class NormalizedDataBuilderTest {
         throw new IllegalStateException("Unable to find child augmentation in " + containerNode);
     }
 
-    private YangInstanceIdentifier.NodeWithValue getNodeWithValueIdentifier(final String localName, final Object value) {
+    private static YangInstanceIdentifier.NodeWithValue getNodeWithValueIdentifier(final String localName, final Object value) {
         return new YangInstanceIdentifier.NodeWithValue(getQName(localName), value);
     }
 
-    private QName getQName(final String localName) {
+    private static QName getQName(final String localName) {
         String namespace = "namespace";
         return new QName(URI.create(namespace), localName);
     }
 
-    private YangInstanceIdentifier.NodeIdentifier getNodeIdentifier(final String localName) {
+    private static YangInstanceIdentifier.NodeIdentifier getNodeIdentifier(final String localName) {
         return new YangInstanceIdentifier.NodeIdentifier(getQName(localName));
     }
 
index 30a9db0fbf55146b7af82b1b8b5f39076a7a5f8b..63962eb91096120c9d083b0ea165937d15202406 100644 (file)
@@ -278,7 +278,7 @@ public class NormalizedNodeXmlTranslationTest {
         XML_FACTORY.setProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES, false);
     }
 
-    private void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
+    private static void writeNormalizedNode(final NormalizedNode<?, ?> normalized, final DOMResult result, final SchemaPath schemaPath, final SchemaContext context)
             throws IOException, XMLStreamException {
         NormalizedNodeWriter normalizedNodeWriter = null;
         NormalizedNodeStreamWriter normalizedNodeStreamWriter = null;
@@ -304,7 +304,7 @@ public class NormalizedNodeXmlTranslationTest {
         }
     }
 
-    private Document loadDocument(final String xmlPath) throws Exception {
+    private static Document loadDocument(final String xmlPath) throws IOException, SAXException {
         final InputStream resourceAsStream = NormalizedDataBuilderTest.class.getResourceAsStream(xmlPath);
 
         final Document currentConfigElement = readXmlToDocument(resourceAsStream);
@@ -323,7 +323,7 @@ public class NormalizedNodeXmlTranslationTest {
         BUILDERFACTORY = factory;
     }
 
-    private Document readXmlToDocument(final InputStream xmlContent) throws IOException, SAXException {
+    private static Document readXmlToDocument(final InputStream xmlContent) throws IOException, SAXException {
         final DocumentBuilder dBuilder;
         try {
             dBuilder = BUILDERFACTORY.newDocumentBuilder();
index 6812122eb494701ffb446bac29e83eac45778533..fade79591311dec54e80f4d7ebbaaf628e8f48c2 100644 (file)
@@ -60,7 +60,7 @@ public class ConcurrentTreeModificationTest {
         inMemoryDataTree.setSchemaContext(schemaContext);
     }
 
-    private ContainerNode createFooTestContainerNode() {
+    private static ContainerNode createFooTestContainerNode() {
         return ImmutableContainerNodeBuilder
                 .create()
                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
@@ -69,7 +69,7 @@ public class ConcurrentTreeModificationTest {
                                 .withChild(FOO_NODE).build()).build();
     }
 
-    private ContainerNode createBarTestContainerNode() {
+    private static ContainerNode createBarTestContainerNode() {
         return ImmutableContainerNodeBuilder
                 .create()
                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
index 2896675c156a0ddc5c2be0612d140dad75ed9c26..294bd9323c50042cd237e6e9efed5147327e47c7 100644 (file)
@@ -15,7 +15,7 @@ import static org.junit.Assert.assertTrue;
 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
 import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
-
+import com.google.common.base.Optional;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -32,13 +32,6 @@ import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
 
-import com.google.common.base.Optional;
-
-
-
-
-
-
 /**
  *
  * Schema structure of document is
@@ -133,7 +126,7 @@ public class ModificationMetadataTreeTest {
 
     }
 
-    private ContainerNode createTestContainer() {
+    private static ContainerNode createTestContainer() {
         return ImmutableContainerNodeBuilder
                 .create()
                 .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME))
index 20b35b34698e0fcdb6b010d21ab20a9338f35cee..54dff7c1bd9c874b9d96ee92a247041654e00c3d 100644 (file)
@@ -78,7 +78,7 @@ public class StoreTreeNodesTest {
 
     }
 
-    private ContainerNode createTestContainer() {
+    private static ContainerNode createTestContainer() {
         return ImmutableContainerNodeBuilder
                 .create()
                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME))
index f05db1e5da95e06c6c40afc4acf67d1020467368..2fd5694c011f1b96ce066ae767fcadf917bb2000 100644 (file)
@@ -178,7 +178,7 @@ public class YangDataOperationsTest {
         Document currentConfigElement = readXmlToDocument(resourceAsStream);
         Preconditions.checkNotNull(currentConfigElement);
 
-        return Optional.of(DomToNormalizedNodeParserFactory.getInstance(DomUtils.defaultValueCodecProvider(), schema).getContainerNodeParser().parse(
+        return Optional.fromNullable(DomToNormalizedNodeParserFactory.getInstance(DomUtils.defaultValueCodecProvider(), schema).getContainerNodeParser().parse(
                 Collections.singletonList(currentConfigElement.getDocumentElement()), containerNode));
     }
 
index 07e503e76b4a35888d5a26d783e515114eb64ea4..b2f469cb1bb4384d8ea62a5df9bbd003dedeb859 100644 (file)
@@ -131,32 +131,58 @@ public class AnyXmlEffectiveStatementImpl extends
         return result;
     }
 
+    private boolean checkQname(AnyXmlEffectiveStatementImpl other) {
+      if (qname == null) {
+        if (other.qname != null) {
+          return false;
+        }
+      } else if (!qname.equals(other.qname)) {
+        return false;
+      }
+      return true;
+    }
+
+    private boolean checkPath(AnyXmlEffectiveStatementImpl other) {
+      if (path == null) {
+        if (other.path != null) {
+            return false;
+        }
+      } else if (!path.equals(other.path)) {
+        return false;
+      }
+      return true;
+    }
+
+    private boolean checkObject(final Object obj) {
+      if (obj == null) {
+        return false;
+      }
+      if (getClass() != obj.getClass()) {
+        return false;
+      }
+      return true;
+    }
+
     @Override
     public boolean equals(final Object obj) {
         if (this == obj) {
             return true;
         }
-        if (obj == null) {
-            return false;
-        }
-        if (getClass() != obj.getClass()) {
-            return false;
+
+        if (!checkObject(obj)) {
+          return false;
         }
+
         AnyXmlEffectiveStatementImpl other = (AnyXmlEffectiveStatementImpl) obj;
-        if (qname == null) {
-            if (other.qname != null) {
-                return false;
-            }
-        } else if (!qname.equals(other.qname)) {
+
+        if (!checkQname(other)) {
             return false;
         }
-        if (path == null) {
-            if (other.path != null) {
-                return false;
-            }
-        } else if (!path.equals(other.path)) {
+
+        if (!checkPath(other)) {
             return false;
         }
+
         return true;
     }
 
@@ -171,4 +197,4 @@ public class AnyXmlEffectiveStatementImpl extends
         return sb.toString();
     }
 
-}
\ No newline at end of file
+}