Merge "BUG-1344: Implemented getOriginal() for DataSchemaNode."
authorTony Tkacik <ttkacik@cisco.com>
Tue, 15 Jul 2014 09:13:38 +0000 (09:13 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 15 Jul 2014 09:13:38 +0000 (09:13 +0000)
common/features/src/main/resources/features.xml
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/RpcError.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/RpcResult.java
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/RpcResultBuilder.java [new file with mode: 0644]
yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/RpcResultBuilderTest.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/InstanceIdentifierForXmlCodec.java
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/RandomPrefix.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlStreamUtils.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlUtils.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/test/java/org/opendaylight/yangtools/yang/data/impl/NodeUtilsTest.java

index 968990aaa916dfb49232d522e8fbb80fce5e8e09..6782698c32dd34aef65e8774ae9c0e0487ef557f 100644 (file)
@@ -11,7 +11,7 @@
 
     <feature name='yangtools-all' version='${project.version}'>
         <feature version='${project.version}'>yangtools-models</feature>
-        <feature version='${project.version}'>yangtools-binding</feature>
+        <feature version='${project.version}'>yangtools-data-binding</feature>
         <feature version='${project.version}'>yangtools-common</feature>
         <feature version='${project.version}'>yangtools-concepts</feature>
         <feature version='${project.version}'>yangtools-binding-generator</feature>
         <bundle>mvn:org.opendaylight.yangtools.model/ietf-topology/${ietf.topology.version}</bundle>
        </feature>
 
-    <feature name='yangtools-binding' version='${project.version}'>
+    <feature name='yangtools-data-binding' version='${project.version}'>
         <feature version='${project.version}'>yangtools-concepts</feature>
+        <feature version='${project.version}'>yangtools-binding</feature>
         <bundle>mvn:org.opendaylight.yangtools.thirdparty/antlr4-runtime-osgi-nohead/${antlr4.version}</bundle>
         <bundle>mvn:commons-io/commons-io/${commons.io.version}</bundle>
-        <bundle>mvn:org.opendaylight.yangtools/yang-binding/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-data-api/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-data-impl/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-data-json/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-parser-api/${project.version}</bundle>
     </feature>
 
+    <feature name='yangtools-binding' version='${project.version}'>
+        <feature version='${project.version}'>yangtools-concepts</feature>
+        <bundle>mvn:com.google.guava/guava/${guava.version}</bundle>
+        <bundle>mvn:org.opendaylight.yangtools/yang-binding/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.yangtools/util/${project.version}</bundle>
+    </feature>
+
     <feature name='yangtools-concepts' version='${project.version}'>
         <bundle>mvn:org.opendaylight.yangtools/concepts/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/yang-common/${project.version}</bundle>
-        <bundle>wrap:mvn:com.google.guava/guava/${guava.version}</bundle>
-        <bundle>wrap:mvn:org.eclipse.xtend/org.eclipse.xtend.lib/${xtend.version}</bundle>
-        <bundle>wrap:mvn:org.eclipse.xtext/org.eclipse.xtext.xbase.lib/${xtend.version}</bundle>
+        <bundle>mvn:com.google.guava/guava/${guava.version}</bundle>
     </feature>
     <feature name="yangtools-common" version='${project.version}'>
         <bundle>mvn:org.opendaylight.yangtools/util/${project.version}</bundle>
@@ -55,7 +60,7 @@
         <bundle>mvn:org.opendaylight.yangtools/object-cache-noop/${project.version}</bundle>
     </feature>
     <feature name='yangtools-binding-generator' version='${project.version}'>
-        <feature version='${project.version}'>yangtools-binding</feature>
+        <feature version='${project.version}'>yangtools-data-binding</feature>
         <bundle>mvn:org.javassist/javassist/${javassist.version}</bundle>
         <bundle>mvn:org.apache.commons/commons-lang3/${commons.lang3.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/binding-generator-api/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/binding-generator-util/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/binding-model-api/${project.version}</bundle>
         <bundle>mvn:org.opendaylight.yangtools/binding-type-provider/${project.version}</bundle>
-
+        <bundle>wrap:mvn:org.eclipse.xtend/org.eclipse.xtend.lib/${xtend.version}</bundle>
+        <bundle>wrap:mvn:org.eclipse.xtext/org.eclipse.xtext.xbase.lib/${xtend.version}</bundle>
+        <bundle>mvn:org.opendaylight.yangtools/yang-model-api/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.yangtools/yang-model-util/${project.version}</bundle>
+        <bundle>mvn:org.opendaylight.yangtools/yang-parser-api/${project.version}</bundle>
     </feature>
 
 </features>
index d207791f2a64a68ff2aca14a5f4660427f3ed0ef..809ea857220cd8e81448e002b57500257e2553b1 100644 (file)
 package org.opendaylight.yangtools.yang.common;
 
 /**
- *
- * Representation of Error in YANG enabled system.
- *
- * Which may be send / received by YANG modeled / enabled systems.
+ * Representation of an error.
  *
  */
 public interface RpcError {
 
+    public enum ErrorSeverity {
+        ERROR,
+        WARNING
+    }
+
+    public enum ErrorType {
+        /**
+         * Indicates an error occurred during transport of data, eg over the network.
+         */
+        TRANSPORT,
+
+        /**
+         * Indicates an error occurred during a remote procedure call.
+         */
+        RPC,
+
+        /**
+         * Indicates an error at a protocol layer, eg if invalid data was passed by the caller.
+         */
+        PROTOCOL,
+
+        /**
+         * Indicates an error occurred during internal processing.
+         */
+        APPLICATION
+    }
+
     /**
+     * Returns the error severity, as determined by the application reporting the error.
      *
-     * Returns error severity, as determined by component reporting the error.
-     *
-     * @return error severity
+     * @return an {@link ErrorSeverity} enum.
      */
     ErrorSeverity getSeverity();
 
     /**
-     *
-     * Returns a string identifying the error condition.
-     *
-     * @return string identifying the error condition.
+     * Returns a short string that identifies the general type of error condition.
+     * <p>
+     * The following outlines suggested values as defined by netconf (<a href="https://tools.ietf.org/html/rfc6241#page-89">RFC 6241</a>):
+     * <pre>
+     *    access_denied
+     *    bad_attribute
+     *    bad_element
+     *    data_exists
+     *    data_missing
+     *    in_use
+     *    invalid_value
+     *    lock_denied
+     *    malformed_message
+     *    missing_attribute
+     *    missing_element
+     *    operation_failed
+     *    operation_not_supported
+     *    resource_denied
+     *    rollback_failed
+     *    too_big
+     *    unknown_attribute
+     *    unknown_element
+     *    unknown_namespace
+     * </pre>
+     * @return a string if available or null otherwise.
      */
     String getTag();
 
     /**
+     * Returns a short string that identifies the specific type of error condition as
+     * determined by the application reporting the error.
      *
-     * Returns a string identifying the data-model-specific or
-     * implementation-specific error condition, if one exists. This element will
-     * not be present if no appropriate application error-tag can be associated
-     * with a particular error condition. If a data-model-specific and an
-     * implementation-specific error-app-tag both exist, then the
-     * data-model-specific value MUST be used by the reporter.
-     *
-     * @return Returns a string identifying the data-model-specific or
-     *         implementation-specific error condition, or null if does not
-     *         exists.
+     * @return a string if available or null otherwise.
      */
     String getApplicationTag();
 
     /**
-     *
      * Returns a string suitable for human display that describes the error
-     * condition. This element will not be present if no appropriate message is
-     * provided for a particular error condition.
+     * condition.
      *
-     * @return returns an error description for human display.
+     * @return a message string.
      */
     String getMessage();
 
     /**
      *
-     * Contains protocol- or data-model-specific error content. This value may
-     * be not be present if no such error content is provided for a particular
-     * error condition.
-     *
-     * The list in Appendix A defines any mandatory error-info content for each
-     * error. After any protocol-mandated content, a data model definition MAY
-     * mandate that certain application-layer error information be included in
-     * the error-info container.
-     *
-     * An implementation MAY include additional information to provide extended
-     * and/or implementation- specific debugging information.
+     * Returns a string containing additional information to provide extended
+     * and/or implementation-specific debugging information.
      *
-     * @return
+     * @return a string if available or null otherwise.
      */
     String getInfo();
 
     /**
      *
-     * Return a cause if available.
+     * Returns an exception cause.
      *
-     * @return cause of this error, if error was triggered by exception.
+     * @return a Throwable if the error was triggered by exception, null otherwise.
      */
     Throwable getCause();
 
     /**
-     * Returns the conceptual layer that on which the error occurred.
+     * Returns the conceptual layer at which the error occurred.
      *
-     * @return the conceptual layer that on which the error occurred.
+     * @return an {@link ErrorType} enum.
      */
     ErrorType getErrorType();
-
-    public enum ErrorSeverity {
-        ERROR, WARNING,
-    }
-
-    public enum ErrorType {
-        TRANSPORT, RPC, PROTOCOL, APPLICATION
-    }
 }
index 4cc40822336ac7c50bb64de9edffc64e70984458..1aed5df711c8d0490d317517bcd888d169f78e30 100644 (file)
@@ -10,36 +10,29 @@ package org.opendaylight.yangtools.yang.common;
 import java.util.Collection;
 
 /**
+ * Represents a general result of a call, request, or operation.
  *
- * Result of call to YANG enabled system.
- *
- *
- * @param <T> Return type
+ * @param <T> the result value type
  */
 public interface RpcResult<T> {
 
     /**
-     * True if processing of request was successful
+     * Returns whether or not processing of the call was successful.
      *
-     * @return true if processing was successful.
+     * @return true if processing was successful, false otherwise.
      */
     boolean isSuccessful();
 
     /**
-     *
-     * Returns result of call or null if no result is available.
-     *
-     * @return result of call or null if no result is available.
-     *
+     * Returns the value result of the call or null if no result is available.
      */
     T getResult();
 
     /**
+     * Returns a set of errors and warnings which occurred during processing
+     * the call.
      *
-     * Returns set of errors and warnings which occured during processing
-     * the request.
-     *
-     * @return
+     * @return a Collection of {@link RpcError}
      */
     Collection<RpcError> getErrors();
 }
diff --git a/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/RpcResultBuilder.java b/yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/RpcResultBuilder.java
new file mode 100644 (file)
index 0000000..7b1b3dc
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2014 Brocade Communications 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.common;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+
+/**
+ * A builder for creating RpcResult instances.
+ *
+ * @author Thomas Pantelis
+ *
+ * @param <T> the result value type
+ */
+public class RpcResultBuilder<T> {
+
+    private static class RpcResultImpl<T> implements RpcResult<T> {
+
+        private final Collection<RpcError> errors;
+        private final T result;
+        private final boolean successful;
+
+        RpcResultImpl( boolean successful, T result,
+                       Collection<RpcError> errors ) {
+            this.successful = successful;
+            this.result = result;
+            this.errors = errors;
+        }
+
+        @Override
+        public Collection<RpcError> getErrors() {
+            return errors;
+        }
+
+        @Override
+        public T getResult() {
+            return result;
+        }
+
+        @Override
+        public boolean isSuccessful() {
+            return successful;
+        }
+
+        @Override
+        public String toString(){
+            return "RpcResult [successful=" + successful + ", result="
+                    + result + ", errors=" + errors + "]";
+        }
+    }
+
+    private static class RpcErrorImpl implements RpcError {
+
+        private final String applicationTag;
+        private final String tag;
+        private final String info;
+        private final ErrorSeverity severity;
+        private final String message;
+        private final ErrorType errorType;
+        private final Throwable cause;
+
+        RpcErrorImpl( ErrorSeverity severity, ErrorType errorType,
+                String tag, String message, String applicationTag, String info,
+                Throwable cause ) {
+            this.severity = severity;
+            this.errorType = errorType;
+            this.tag = tag;
+            this.message = message;
+            this.applicationTag = applicationTag;
+            this.info = info;
+            this.cause = cause;
+        }
+
+        @Override
+        public String getApplicationTag() {
+            return applicationTag;
+        }
+
+        @Override
+        public String getTag() {
+            return tag;
+        }
+
+        @Override
+        public String getInfo() {
+            return info;
+        }
+
+        @Override
+        public ErrorSeverity getSeverity() {
+            return severity;
+        }
+
+        @Override
+        public String getMessage(){
+            return message;
+        }
+
+        @Override
+        public ErrorType getErrorType() {
+            return errorType;
+        }
+
+        @Override
+        public Throwable getCause() {
+            return cause;
+        }
+
+        @Override
+        public String toString(){
+            return "RpcError [message=" + message + ", severity="
+                    + severity + ", errorType=" + errorType + ", tag=" + tag
+                    + ", applicationTag=" + applicationTag + ", info=" + info
+                    + ", cause=" + cause + "]";
+        }
+    }
+
+    private Collection<RpcError> errors;
+    private T result;
+    private final boolean successful;
+
+    private RpcResultBuilder( boolean successful, T result ) {
+        this.successful = successful;
+        this.result = result;
+    }
+
+    /**
+     * Returns a builder for a successful result.
+     */
+    public static <T> RpcResultBuilder<T> success() {
+        return new RpcResultBuilder<T>( true, null );
+    }
+
+    /**
+     * Returns a builder for a successful result.
+     *
+     * @param result the result value
+     */
+    public static <T> RpcResultBuilder<T> success( T result ) {
+         return new RpcResultBuilder<T>( true, result );
+    }
+
+    /**
+     * Returns a builder for a failed result.
+     */
+    public static <T> RpcResultBuilder<T> failed() {
+        return new RpcResultBuilder<T>( false, null );
+    }
+
+    /**
+     * Sets the value of the result.
+     *
+     * @param result the result value
+     */
+    public RpcResultBuilder<T> withResult( T result ) {
+        this.result = result;
+        return this;
+    }
+
+    private void addError( ErrorSeverity severity, ErrorType errorType,
+            String tag, String message, String applicationTag, String info,
+            Throwable cause ) {
+
+        if( errors == null ) {
+            errors = new ArrayList<>();
+        }
+
+        errors.add( new RpcErrorImpl( severity, errorType, tag, message,
+                                      applicationTag, info, cause ) );
+    }
+
+    /**
+     * Adds a warning to the result.
+     *
+     * @param errorType the conceptual layer at which the warning occurred.
+     * @param tag a short string that identifies the general type of warning condition. See
+     *        {@link RpcError#getTag} for a list of suggested values.
+     * @param message a string suitable for human display that describes the warning condition.
+     */
+    public RpcResultBuilder<T> withWarning( ErrorType errorType, String tag, String message ) {
+        addError( ErrorSeverity.WARNING, errorType, tag, message, null, null, null );
+        return this;
+    }
+
+    /**
+     * Adds a warning to the result.
+     *
+     * @param errorType the conceptual layer at which the warning occurred.
+     * @param tag a short string that identifies the general type of warning condition. See
+     *        {@link RpcError#getTag} for a list of suggested values.
+     * @param message a string suitable for human display that describes the warning condition.
+     * @param applicationTag a short string that identifies the specific type of warning condition.
+     * @param info a string containing additional information to provide extended
+     *        and/or implementation-specific debugging information.
+     * @param cause the exception that triggered the warning.
+     */
+    public RpcResultBuilder<T> withWarning( ErrorType errorType, String tag, String message,
+            String applicationTag, String info, Throwable cause ) {
+        addError( ErrorSeverity.WARNING, errorType, tag, message, applicationTag, info, cause );
+        return this;
+    }
+
+    /**
+     * Adds an error to the result. The general error tag defaults to "operation-failed".
+     *
+     * @param errorType the conceptual layer at which the error occurred.
+     * @param message a string suitable for human display that describes the error condition.
+     */
+    public RpcResultBuilder<T> withError( ErrorType errorType, String message ) {
+        addError( ErrorSeverity.ERROR, errorType, "operation-failed", message, null, null, null );
+        return this;
+    }
+
+    /**
+     * Adds an error to the result.
+     *
+     * @param errorType the conceptual layer at which the error occurred.
+     * @param tag a short string that identifies the general type of error condition. See
+     *        {@link RpcError#getTag} for a list of suggested values.
+     * @param message a string suitable for human display that describes the error condition.
+     */
+    public RpcResultBuilder<T> withError( ErrorType errorType, String tag, String message ) {
+        addError( ErrorSeverity.ERROR, errorType, tag, message, null, null, null );
+        return this;
+    }
+
+    /**
+     * Adds an error to the result.
+     *
+     * @param errorType the conceptual layer at which the error occurred.
+     * @param tag a short string that identifies the general type of error condition. See
+     *        {@link RpcError#getTag} for a list of suggested values.
+     * @param message a string suitable for human display that describes the error condition.
+     * @param applicationTag a short string that identifies the specific type of error condition.
+     * @param info a string containing additional information to provide extended
+     *        and/or implementation-specific debugging information.
+     * @param cause the exception that triggered the error.
+     */
+    public RpcResultBuilder<T> withError( ErrorType errorType, String tag, String message,
+            String applicationTag, String info, Throwable cause ) {
+        addError( ErrorSeverity.ERROR, errorType, tag, message, applicationTag, info, cause );
+        return this;
+    }
+
+    public RpcResult<T> build() {
+
+        return new RpcResultImpl<T>( successful, result,
+                errors != null ? errors : Collections.<RpcError>emptyList() );
+    }
+}
diff --git a/yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/RpcResultBuilderTest.java b/yang/yang-common/src/test/java/org/opendaylight/yangtools/yang/common/RpcResultBuilderTest.java
new file mode 100644 (file)
index 0000000..1437739
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2014 Brocade Communications 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.common;
+
+import static org.junit.Assert.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorSeverity;
+import org.opendaylight.yangtools.yang.common.RpcError.ErrorType;
+
+/**
+ * Unit tests for RpcResultBuilder.
+ *
+ * @author Thomas Pantelis
+ */
+public class RpcResultBuilderTest {
+
+    @Test
+    public void testSuccess() {
+        RpcResult<String> result = RpcResultBuilder.<String>success().withResult( "foo" ).build();
+        verifyRpcResult( result, true, "foo" );
+        assertNotNull( "getErrors returned null", result.getErrors() );
+        assertEquals( "getErrors size", 0, result.getErrors().size() );
+
+        result = RpcResultBuilder.<String>success( "bar" ).build();
+        verifyRpcResult( result, true, "bar" );
+    }
+
+    @Test
+    public void testFailed() {
+        Throwable cause = new Throwable( "mock cause" );
+        RpcResult<String> result = RpcResultBuilder.<String>failed()
+                  .withError( ErrorType.PROTOCOL, "error message 1" )
+                  .withError( ErrorType.APPLICATION, "lock_denied", "error message 2" )
+                  .withError( ErrorType.RPC, "in-use", "error message 3", "my-app-tag", "my-info", cause )
+                  .build();
+        verifyRpcResult( result, false, null );
+        verifyRpcError( result, 0, ErrorSeverity.ERROR, ErrorType.PROTOCOL, "operation-failed",
+                        "error message 1", null, null, null );
+        verifyRpcError( result, 1, ErrorSeverity.ERROR, ErrorType.APPLICATION, "lock_denied",
+                        "error message 2", null, null, null );
+        verifyRpcError( result, 2, ErrorSeverity.ERROR, ErrorType.RPC, "in-use",
+                        "error message 3", "my-app-tag", "my-info", cause );
+        assertEquals( "getErrors size", 3, result.getErrors().size() );
+    }
+
+    @Test
+    public void testWithWarnings() {
+        Throwable cause = new Throwable( "mock cause" );
+        RpcResult<String> result = RpcResultBuilder.<String>success()
+                  .withWarning( ErrorType.APPLICATION, "lock_denied", "message 1" )
+                  .withWarning( ErrorType.RPC, "in-use", "message 2", "my-app-tag", "my-info", cause )
+                  .build();
+        verifyRpcResult( result, true, null );
+        verifyRpcError( result, 0, ErrorSeverity.WARNING, ErrorType.APPLICATION, "lock_denied",
+                        "message 1", null, null, null );
+        verifyRpcError( result, 1, ErrorSeverity.WARNING, ErrorType.RPC, "in-use",
+                        "message 2", "my-app-tag", "my-info", cause );
+        assertEquals( "getErrors size", 2, result.getErrors().size() );
+    }
+
+    void verifyRpcError( RpcResult<?> result, int errorIndex, ErrorSeverity expSeverity,
+            ErrorType expErrorType, String expTag, String expMessage, String expAppTag,
+            String expInfo, Throwable expCause ) {
+
+        List<RpcError> errors = new ArrayList<>( result.getErrors() );
+        assertTrue( "Expected error at index " + errorIndex + " not found",
+                    errorIndex < errors.size() );
+        RpcError error = errors.get( errorIndex );
+        assertEquals( "getSeverity", expSeverity, error.getSeverity() );
+        assertEquals( "getErrorType", expErrorType, error.getErrorType() );
+        assertEquals( "getTag", expTag, error.getTag() );
+        assertEquals( "getMessage", expMessage, error.getMessage() );
+        assertEquals( "getApplicationTag", expAppTag, error.getApplicationTag() );
+        assertEquals( "getInfo", expInfo, error.getInfo() );
+        assertEquals( "getCause", expCause, error.getCause() );
+    }
+
+    void verifyRpcResult( RpcResult<?> result, boolean expSuccess, Object expValue ) {
+        assertEquals( "isSuccessful", expSuccess, result.isSuccessful() );
+        assertEquals( "getResult", expValue, result.getResult() );
+    }
+}
index 440e68da86f426215a9464e5fbfb3b94ca37ccc0..6051b2681388aeb09fbf3213cba99d5ec33c259d 100644 (file)
@@ -13,19 +13,16 @@ import com.google.common.base.Splitter;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.ArrayList;
-import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ThreadLocalRandom;
+import java.util.Map.Entry;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
@@ -65,32 +62,17 @@ public final class InstanceIdentifierForXmlCodec {
         return InstanceIdentifier.create(result);
     }
 
-    public static Element serialize(final InstanceIdentifier data, final Element element) {
-        Preconditions.checkNotNull(data, "Variable should contain instance of instance identifier and can't be null");
+    public static Element serialize(final InstanceIdentifier id, final Element element) {
+        Preconditions.checkNotNull(id, "Variable should contain instance of instance identifier and can't be null");
         Preconditions.checkNotNull(element, "DOM element can't be null");
-        Map<String, String> prefixes = new HashMap<>();
-        StringBuilder textContent = new StringBuilder();
-        for (PathArgument pathArgument : data.getPathArguments()) {
-            textContent.append('/');
-            writeIdentifierWithNamespacePrefix(element, textContent, pathArgument.getNodeType(), prefixes);
-            if (pathArgument instanceof NodeIdentifierWithPredicates) {
-                Map<QName, Object> predicates = ((NodeIdentifierWithPredicates) pathArgument).getKeyValues();
-
-                for (QName keyValue : predicates.keySet()) {
-                    String predicateValue = String.valueOf(predicates.get(keyValue));
-                    textContent.append('[');
-                    writeIdentifierWithNamespacePrefix(element, textContent, keyValue, prefixes);
-                    textContent.append("='");
-                    textContent.append(predicateValue);
-                    textContent.append("']");
-                }
-            } else if (pathArgument instanceof NodeWithValue) {
-                textContent.append("[.='");
-                textContent.append(((NodeWithValue) pathArgument).getValue());
-                textContent.append("']");
-            }
+
+        final RandomPrefix prefixes = new RandomPrefix();
+        final String str = XmlUtils.encodeIdentifier(prefixes, id);
+
+        for (Entry<URI, String> e: prefixes.getPrefixes()) {
+            element.setAttribute("xmlns:" + e.getValue(), e.getKey().toString());
         }
-        element.setTextContent(textContent.toString());
+        element.setTextContent(str);
         return element;
     }
 
@@ -198,39 +180,4 @@ public final class InstanceIdentifierForXmlCodec {
             return null;
         }
     }
-
-    private static void writeIdentifierWithNamespacePrefix(final Element element, final StringBuilder textContent, final QName qName,
-            final Map<String, String> prefixes) {
-        String namespace = qName.getNamespace().toString();
-        String prefix = prefixes.get(namespace);
-        if (prefix == null) {
-            prefix = qName.getPrefix();
-            if (prefix == null || prefix.isEmpty() || prefixes.containsValue(prefix)) {
-                prefix = generateNewPrefix(prefixes.values());
-            }
-        }
-
-        element.setAttribute("xmlns:" + prefix, namespace.toString());
-        textContent.append(prefix);
-        prefixes.put(namespace, prefix);
-
-        textContent.append(':');
-        textContent.append(qName.getLocalName());
-    }
-
-    private static String generateNewPrefix(final Collection<String> prefixes) {
-        String result;
-
-        final ThreadLocalRandom random = ThreadLocalRandom.current();
-        do {
-            StringBuilder sb = new StringBuilder();
-            for (int i = 0; i < 4; i++) {
-                sb.append('a' + random.nextInt(25));
-            }
-
-            result = sb.toString();
-        } while (prefixes.contains(result));
-
-        return result;
-    }
 }
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/RandomPrefix.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/RandomPrefix.java
new file mode 100644 (file)
index 0000000..8292894
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * 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.codec.xml;
+
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.concurrent.ThreadLocalRandom;
+
+import org.opendaylight.yangtools.yang.common.QName;
+
+final class RandomPrefix {
+    final Map<URI, String> prefixes = new HashMap<>();
+
+    Iterable<Entry<URI, String>> getPrefixes() {
+        return prefixes.entrySet();
+    }
+
+    String encodeQName(final QName qname) {
+        String prefix = prefixes.get(qname.getNamespace());
+        if (prefix == null) {
+            prefix = qname.getPrefix();
+            if (prefix == null || prefix.isEmpty() || prefixes.containsValue(prefix)) {
+                final ThreadLocalRandom random = ThreadLocalRandom.current();
+                do {
+                    final StringBuilder sb = new StringBuilder();
+                    for (int i = 0; i < 4; i++) {
+                        sb.append('a' + random.nextInt(25));
+                    }
+
+                    prefix = sb.toString();
+                } while (prefixes.containsValue(prefix));
+            }
+
+            prefixes.put(qname.getNamespace(), prefix);
+        }
+
+        return prefix + ':' + qname.getLocalName();
+    }
+}
\ No newline at end of file
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlStreamUtils.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlStreamUtils.java
new file mode 100644 (file)
index 0000000..6491391
--- /dev/null
@@ -0,0 +1,160 @@
+package org.opendaylight.yangtools.yang.data.impl.codec.xml;
+
+import com.google.common.base.Preconditions;
+
+import java.net.URI;
+import java.util.Map.Entry;
+
+import javax.xml.stream.XMLStreamException;
+import javax.xml.stream.XMLStreamWriter;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.AttributesContainer;
+import org.opendaylight.yangtools.yang.data.api.CompositeNode;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.Node;
+import org.opendaylight.yangtools.yang.data.api.SimpleNode;
+import org.opendaylight.yangtools.yang.data.impl.codec.TypeDefinitionAwareCodec;
+import org.opendaylight.yangtools.yang.data.impl.schema.SchemaUtils;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafListSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode;
+import org.opendaylight.yangtools.yang.model.api.SchemaNode;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IdentityrefTypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.InstanceIdentifierTypeDefinition;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class XmlStreamUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(XmlStreamUtils.class);
+
+    public static void writeDataDocument(final XMLStreamWriter writer, final CompositeNode data, final SchemaNode schema, final XmlCodecProvider codecProvider) throws XMLStreamException {
+        //        final Boolean repairing = (Boolean) writer.getProperty(XMLOutputFactory.IS_REPAIRING_NAMESPACES);
+        //        Preconditions.checkArgument(repairing == true, "XML Stream Writer has to be repairing namespaces");
+
+        writer.writeStartDocument();
+        writeData(writer, data, schema, codecProvider);
+        writer.writeEndDocument();
+        writer.flush();
+    }
+
+    public static void writeDataDocument(final XMLStreamWriter writer, final CompositeNode data, final XmlCodecProvider codecProvider) throws XMLStreamException {
+        writeDataDocument(writer, data, null, codecProvider);
+    }
+
+    public static void write(final XMLStreamWriter writer, final InstanceIdentifier id) throws XMLStreamException {
+        Preconditions.checkNotNull(writer, "Writer may not be null");
+        Preconditions.checkNotNull(id, "Variable should contain instance of instance identifier and can't be null");
+
+        final RandomPrefix prefixes = new RandomPrefix();
+        final String str = XmlUtils.encodeIdentifier(prefixes, id);
+
+        for (Entry<URI, String> e: prefixes.getPrefixes()) {
+            writer.writeNamespace(e.getValue(), e.getKey().toString());
+        }
+        writer.writeCharacters(str);
+    }
+
+    public static void writeData(final XMLStreamWriter writer, final Node<?> data, final SchemaNode schema, final XmlCodecProvider codecProvider) throws XMLStreamException {
+        final QName qname = data.getNodeType();
+        final String pfx = qname.getPrefix() != null ? qname.getPrefix() : "";
+        final String ns;
+        if (qname.getNamespace() != null) {
+            ns = qname.getNamespace().toString();
+        } else {
+            ns = "";
+        }
+
+        writer.writeStartElement(pfx, qname.getLocalName(), ns);
+        if (data instanceof AttributesContainer && ((AttributesContainer) data).getAttributes() != null) {
+            for (Entry<QName, String> attribute : ((AttributesContainer) data).getAttributes().entrySet()) {
+                writer.writeAttribute(attribute.getKey().getNamespace().toString(), attribute.getKey().getLocalName(), attribute.getValue());
+            }
+        }
+
+        if (data instanceof SimpleNode<?>) {
+            // Simple node
+            if (schema instanceof LeafListSchemaNode) {
+                writeValue(writer, ((LeafListSchemaNode) schema).getType(), codecProvider, data.getValue());
+            } else if (schema instanceof LeafSchemaNode) {
+                writeValue(writer, ((LeafSchemaNode) schema).getType(), codecProvider, data.getValue());
+            } else {
+                Object value = data.getValue();
+                if (value != null) {
+                    writer.writeCharacters(String.valueOf(value));
+                }
+            }
+        } else {
+            // CompositeNode
+            for (Node<?> child : ((CompositeNode) data).getValue()) {
+                DataSchemaNode childSchema = null;
+                if (schema instanceof DataNodeContainer) {
+                    childSchema = SchemaUtils.findFirstSchema(child.getNodeType(), ((DataNodeContainer) schema).getChildNodes()).orNull();
+                    if (LOG.isDebugEnabled()) {
+                        if (childSchema == null) {
+                            LOG.debug("Probably the data node \"{}\" does not conform to schema", child == null ? "" : child.getNodeType().getLocalName());
+                        }
+                    }
+                }
+
+                writeData(writer, child, childSchema, codecProvider);
+            }
+        }
+
+        writer.writeEndElement();
+    }
+
+    public static void writeValue(final XMLStreamWriter writer, final TypeDefinition<?> type, final XmlCodecProvider codecProvider, final Object nodeValue) throws XMLStreamException {
+        TypeDefinition<?> baseType = XmlUtils.resolveBaseTypeFrom(type);
+        if (baseType instanceof IdentityrefTypeDefinition) {
+            if (nodeValue instanceof QName) {
+                QName value = (QName) nodeValue;
+                String prefix = "x";
+                if (value.getPrefix() != null && !value.getPrefix().isEmpty()) {
+                    prefix = value.getPrefix();
+                }
+
+                writer.writeNamespace(prefix, value.getNamespace().toString());
+                writer.writeCharacters(prefix + ':' + value.getLocalName());
+            } else {
+                Object value = nodeValue;
+                LOG.debug("Value of {}:{} is not instance of QName but is {}", baseType.getQName().getNamespace(),
+                        baseType.getQName().getLocalName(), value != null ? value.getClass() : "null");
+                if (value != null) {
+                    writer.writeCharacters(String.valueOf(value));
+                }
+            }
+        } else if (baseType instanceof InstanceIdentifierTypeDefinition) {
+            if (nodeValue instanceof InstanceIdentifier) {
+                write(writer, (InstanceIdentifier)nodeValue);
+            } else {
+                Object value = nodeValue;
+                LOG.debug("Value of {}:{} is not instance of InstanceIdentifier but is {}", baseType.getQName()
+                        .getNamespace(), //
+                        baseType.getQName().getLocalName(), value != null ? value.getClass() : "null");
+                if (value != null) {
+                    writer.writeCharacters(String.valueOf(value));
+                }
+            }
+        } else {
+            if (nodeValue != null) {
+                final TypeDefinitionAwareCodec<Object, ?> codec = codecProvider.codecFor(baseType);
+                String text;
+                if (codec != null) {
+                    try {
+                        text = codec.serialize(nodeValue);
+                    } catch (ClassCastException e) {
+                        LOG.error("Provided node value {} did not have type {} required by mapping. Using stream instead.", nodeValue, baseType, e);
+                        text = String.valueOf(nodeValue);
+                    }
+                } else {
+                    LOG.error("Failed to find codec for {}, falling back to using stream", baseType);
+                    text = String.valueOf(nodeValue);
+                }
+                writer.writeCharacters(text);
+            }
+        }
+    }
+}
diff --git a/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlUtils.java b/yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/xml/XmlUtils.java
new file mode 100644 (file)
index 0000000..dbdb6ff
--- /dev/null
@@ -0,0 +1,62 @@
+/*
+ * 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.codec.xml;
+
+import java.util.Map;
+
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+
+/**
+ * Common XML-related utility methods, which are not specific to a particular
+ * JAXP API.
+ */
+final class XmlUtils {
+
+    private XmlUtils() {
+
+    }
+
+    public static TypeDefinition<?> resolveBaseTypeFrom(final TypeDefinition<?> type) {
+        TypeDefinition<?> superType = type;
+        while (superType.getBaseType() != null) {
+            superType = superType.getBaseType();
+        }
+        return superType;
+    }
+
+    static String encodeIdentifier(final RandomPrefix prefixes, final InstanceIdentifier id) {
+        StringBuilder textContent = new StringBuilder();
+        for (PathArgument pathArgument : id.getPathArguments()) {
+            textContent.append('/');
+            textContent.append(prefixes.encodeQName(pathArgument.getNodeType()));
+            if (pathArgument instanceof NodeIdentifierWithPredicates) {
+                Map<QName, Object> predicates = ((NodeIdentifierWithPredicates) pathArgument).getKeyValues();
+
+                for (QName keyValue : predicates.keySet()) {
+                    String predicateValue = String.valueOf(predicates.get(keyValue));
+                    textContent.append('[');
+                    textContent.append(prefixes.encodeQName(keyValue));
+                    textContent.append("='");
+                    textContent.append(predicateValue);
+                    textContent.append("']");
+                }
+            } else if (pathArgument instanceof NodeWithValue) {
+                textContent.append("[.='");
+                textContent.append(((NodeWithValue) pathArgument).getValue());
+                textContent.append("']");
+            }
+        }
+
+        return textContent.toString();
+    }
+}
index 345ab7618d2d6980b36dc9e24942117f3bfd2028..fe5892a3f61cb5e906ff939fd52b59fe6de90a3d 100644 (file)
@@ -14,39 +14,66 @@ import com.google.common.base.Preconditions;
 import com.google.common.collect.Collections2;
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-import org.opendaylight.yangtools.yang.data.impl.codec.xml.XmlDocumentUtils;
-import org.opendaylight.yangtools.yang.model.api.*;
-import java.util.*;
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema;
+import org.opendaylight.yangtools.yang.model.api.AugmentationTarget;
+import org.opendaylight.yangtools.yang.model.api.ChoiceCaseNode;
+import org.opendaylight.yangtools.yang.model.api.ChoiceNode;
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer;
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode;
 
 public final class SchemaUtils {
 
     private SchemaUtils() {
     }
 
-    public static DataSchemaNode findSchemaForChild(DataNodeContainer schema, QName qname) {
+    public static final Optional<DataSchemaNode> findFirstSchema(final QName qname, final Set<DataSchemaNode> dataSchemaNode) {
+        if (dataSchemaNode != null && !dataSchemaNode.isEmpty() && qname != null) {
+            for (DataSchemaNode dsn : dataSchemaNode) {
+                if (qname.isEqualWithoutRevision(dsn.getQName())) {
+                    return Optional.<DataSchemaNode> of(dsn);
+                } else if (dsn instanceof ChoiceNode) {
+                    for (ChoiceCaseNode choiceCase : ((ChoiceNode) dsn).getCases()) {
+                        Optional<DataSchemaNode> foundDsn = findFirstSchema(qname, choiceCase.getChildNodes());
+                        if (foundDsn != null && foundDsn.isPresent()) {
+                            return foundDsn;
+                        }
+                    }
+                }
+            }
+        }
+        return Optional.absent();
+    }
+
+    public static DataSchemaNode findSchemaForChild(final DataNodeContainer schema, final QName qname) {
         Set<DataSchemaNode> childNodes = schema.getChildNodes();
         return findSchemaForChild(schema, qname, childNodes);
     }
 
-    public static DataSchemaNode findSchemaForChild(DataNodeContainer schema, QName qname, Set<DataSchemaNode> childNodes) {
-        Optional<DataSchemaNode> childSchema = XmlDocumentUtils.findFirstSchema(qname, childNodes);
+    public static DataSchemaNode findSchemaForChild(final DataNodeContainer schema, final QName qname, final Set<DataSchemaNode> childNodes) {
+        Optional<DataSchemaNode> childSchema = findFirstSchema(qname, childNodes);
         Preconditions.checkState(childSchema.isPresent(),
                 "Unknown child(ren) node(s) detected, identified by: %s, in: %s", qname, schema);
         return childSchema.get();
     }
 
-    public static AugmentationSchema findSchemaForAugment(AugmentationTarget schema, Set<QName> qNames) {
+    public static AugmentationSchema findSchemaForAugment(final AugmentationTarget schema, final Set<QName> qNames) {
         Optional<AugmentationSchema> schemaForAugment = findAugment(schema, qNames);
         Preconditions.checkState(schemaForAugment.isPresent(), "Unknown augmentation node detected, identified by: %s, in: %s",
                 qNames, schema);
         return schemaForAugment.get();
     }
 
-    public static AugmentationSchema findSchemaForAugment(ChoiceNode schema, Set<QName> qNames) {
+    public static AugmentationSchema findSchemaForAugment(final ChoiceNode schema, final Set<QName> qNames) {
         Optional<AugmentationSchema> schemaForAugment = Optional.absent();
 
         for (ChoiceCaseNode choiceCaseNode : schema.getCases()) {
@@ -61,12 +88,12 @@ public final class SchemaUtils {
         return schemaForAugment.get();
     }
 
-    private static Optional<AugmentationSchema> findAugment(AugmentationTarget schema, Set<QName> qNames) {
+    private static Optional<AugmentationSchema> findAugment(final AugmentationTarget schema, final Set<QName> qNames) {
         for (AugmentationSchema augment : schema.getAvailableAugmentations()) {
 
             HashSet<QName> qNamesFromAugment = Sets.newHashSet(Collections2.transform(augment.getChildNodes(), new Function<DataSchemaNode, QName>() {
                 @Override
-                public QName apply(DataSchemaNode input) {
+                public QName apply(final DataSchemaNode input) {
                     return input.getQName();
                 }
             }));
@@ -79,10 +106,9 @@ public final class SchemaUtils {
         return Optional.absent();
     }
 
-    public static DataSchemaNode findSchemaForChild(ChoiceNode schema, QName childPartialQName) {
+    public static DataSchemaNode findSchemaForChild(final ChoiceNode schema, final QName childPartialQName) {
         for (ChoiceCaseNode choiceCaseNode : schema.getCases()) {
-            Optional<DataSchemaNode> childSchema = XmlDocumentUtils.findFirstSchema(childPartialQName,
-                    choiceCaseNode.getChildNodes());
+            Optional<DataSchemaNode> childSchema = findFirstSchema(childPartialQName, choiceCaseNode.getChildNodes());
             if (childSchema.isPresent()) {
                 return childSchema.get();
             }
@@ -98,13 +124,13 @@ public final class SchemaUtils {
      *
      * @return Map with all child nodes, to their most top augmentation
      */
-    public static Map<QName, ChoiceNode> mapChildElementsFromChoices(DataNodeContainer schema) {
+    public static Map<QName, ChoiceNode> mapChildElementsFromChoices(final DataNodeContainer schema) {
         Set<DataSchemaNode> childNodes = schema.getChildNodes();
 
         return mapChildElementsFromChoices(schema, childNodes);
     }
 
-    private static Map<QName, ChoiceNode> mapChildElementsFromChoices(DataNodeContainer schema, Set<DataSchemaNode> childNodes) {
+    private static Map<QName, ChoiceNode> mapChildElementsFromChoices(final DataNodeContainer schema, final Set<DataSchemaNode> childNodes) {
         Map<QName, ChoiceNode> mappedChoices = Maps.newLinkedHashMap();
 
         for (final DataSchemaNode childSchema : childNodes) {
@@ -126,7 +152,7 @@ public final class SchemaUtils {
         return mappedChoices;
     }
 
-    private static boolean isFromAugment(DataNodeContainer schema, DataSchemaNode childSchema) {
+    private static boolean isFromAugment(final DataNodeContainer schema, final DataSchemaNode childSchema) {
         if(schema instanceof AugmentationTarget == false) {
             return false;
         }
@@ -145,7 +171,7 @@ public final class SchemaUtils {
      *
      * @return Map with all child nodes, to their most top augmentation
      */
-    public static Map<QName, AugmentationSchema> mapChildElementsFromAugments(AugmentationTarget schema) {
+    public static Map<QName, AugmentationSchema> mapChildElementsFromAugments(final AugmentationTarget schema) {
 
         Map<QName, AugmentationSchema> childNodesToAugmentation = Maps.newLinkedHashMap();
 
@@ -163,8 +189,9 @@ public final class SchemaUtils {
 
             for (DataSchemaNode child : ((DataNodeContainer) schema).getChildNodes()) {
                 // If is not augmented child, continue
-                if (augments.containsKey(child.getQName()) == false)
+                if (augments.containsKey(child.getQName()) == false) {
                     continue;
+                }
 
                 AugmentationSchema mostTopAugmentation = augments.get(child.getQName());
 
@@ -206,7 +233,7 @@ public final class SchemaUtils {
      *
      * In case of choice, augment and cases, step in.
      */
-    public static Set<QName> getChildNodesRecursive(DataNodeContainer nodeContainer) {
+    public static Set<QName> getChildNodesRecursive(final DataNodeContainer nodeContainer) {
         Set<QName> allChildNodes = Sets.newHashSet();
 
         for (DataSchemaNode childSchema : nodeContainer.getChildNodes()) {
@@ -232,7 +259,7 @@ public final class SchemaUtils {
      * Schema of child node from augment is incomplete, therefore its useless for xml <-> normalizedNode translation.
      *
      */
-    public static Set<DataSchemaNode> getRealSchemasForAugment(AugmentationTarget targetSchema, AugmentationSchema augmentSchema) {
+    public static Set<DataSchemaNode> getRealSchemasForAugment(final AugmentationTarget targetSchema, final AugmentationSchema augmentSchema) {
         if(targetSchema.getAvailableAugmentations().contains(augmentSchema) == false) {
             return Collections.emptySet();
         }
@@ -240,7 +267,7 @@ public final class SchemaUtils {
         Set<DataSchemaNode> realChildNodes = Sets.newHashSet();
 
         if(targetSchema instanceof DataNodeContainer) {
-              realChildNodes = getRealSchemasForAugment((DataNodeContainer)targetSchema, augmentSchema);
+            realChildNodes = getRealSchemasForAugment((DataNodeContainer)targetSchema, augmentSchema);
         } else if(targetSchema instanceof ChoiceNode) {
             for (DataSchemaNode dataSchemaNode : augmentSchema.getChildNodes()) {
                 for (ChoiceCaseNode choiceCaseNode : ((ChoiceNode) targetSchema).getCases()) {
@@ -254,8 +281,8 @@ public final class SchemaUtils {
         return realChildNodes;
     }
 
-    public static Set<DataSchemaNode> getRealSchemasForAugment(DataNodeContainer targetSchema,
-            AugmentationSchema augmentSchema) {
+    public static Set<DataSchemaNode> getRealSchemasForAugment(final DataNodeContainer targetSchema,
+            final AugmentationSchema augmentSchema) {
         Set<DataSchemaNode> realChildNodes = Sets.newHashSet();
         for (DataSchemaNode dataSchemaNode : augmentSchema.getChildNodes()) {
             DataSchemaNode realChild = targetSchema.getDataChildByName(dataSchemaNode.getQName());
@@ -264,7 +291,7 @@ public final class SchemaUtils {
         return realChildNodes;
     }
 
-    public static Optional<ChoiceCaseNode> detectCase(ChoiceNode schema, DataContainerChild<?, ?> child) {
+    public static Optional<ChoiceCaseNode> detectCase(final ChoiceNode schema, final DataContainerChild<?, ?> child) {
         for (ChoiceCaseNode choiceCaseNode : schema.getCases()) {
             if (child instanceof AugmentationNode
                     && belongsToCaseAugment(choiceCaseNode,
@@ -278,7 +305,7 @@ public final class SchemaUtils {
         return Optional.absent();
     }
 
-    public static boolean belongsToCaseAugment(ChoiceCaseNode caseNode, InstanceIdentifier.AugmentationIdentifier childToProcess) {
+    public static boolean belongsToCaseAugment(final ChoiceCaseNode caseNode, final InstanceIdentifier.AugmentationIdentifier childToProcess) {
         for (AugmentationSchema augmentationSchema : caseNode.getAvailableAugmentations()) {
 
             Set<QName> currentAugmentChildNodes = Sets.newHashSet();
@@ -294,11 +321,11 @@ public final class SchemaUtils {
         return false;
     }
 
-    public static InstanceIdentifier.AugmentationIdentifier getNodeIdentifierForAugmentation(AugmentationSchema schema) {
+    public static InstanceIdentifier.AugmentationIdentifier getNodeIdentifierForAugmentation(final AugmentationSchema schema) {
         return new InstanceIdentifier.AugmentationIdentifier(getChildQNames(schema));
     }
 
-    public static Set<QName> getChildQNames(AugmentationSchema schema) {
+    public static Set<QName> getChildQNames(final AugmentationSchema schema) {
         Set<QName> qnames = Sets.newHashSet();
 
         for (DataSchemaNode dataSchemaNode : schema.getChildNodes()) {
index f243f7183ca7ba359e9e2bf162c358e76329210d..eeac30bf99d704e220db41c12a98dda0bb279fdf 100644 (file)
@@ -12,7 +12,8 @@ import java.net.URI;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
-import java.util.Stack;
+import java.util.Deque;
+import java.util.LinkedList;
 
 import org.junit.Assert;
 import org.junit.Before;
@@ -145,7 +146,7 @@ public class NodeUtilsTest {
     }
 
     private static void checkFamilyBinding(final CompositeNode treeRoot) throws Exception {
-        Stack<CompositeNode> jobQueue = new Stack<>();
+        Deque<CompositeNode> jobQueue = new LinkedList<>();
         jobQueue.push(treeRoot);
 
         while (!jobQueue.isEmpty()) {