Refactored yang-model-parser-impl to improve readability. SchemaContextImpl moved... 92/392/1
authorMartin Vitez <mvitez@cisco.com>
Fri, 24 May 2013 15:14:33 +0000 (17:14 +0200)
committerMartin Vitez <mvitez@cisco.com>
Fri, 24 May 2013 15:14:33 +0000 (17:14 +0200)
Updated tests. Improved code generation: added import statemets to generated code.

Signed-off-by: Martin Vitez <mvitez@cisco.com>
31 files changed:
opendaylight/sal/yang-prototype/code-generator/binding-generator-impl/src/main/java/org/opendaylight/controller/sal/binding/yang/types/BaseYangTypes.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/ClassCodeGenerator.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/GeneratorUtil.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/main/java/org/opendaylight/controller/sal/java/api/generator/InterfaceGenerator.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/ClassCodeGeneratorTest.java
opendaylight/sal/yang-prototype/code-generator/binding-java-api-generator/src/test/java/org/opendaylight/controller/sal/java/api/generator/test/GeneratorJavaFileTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/antlr/YangParser.g4
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/api/UsesNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AnyXmlBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/AugmentationSchemaBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ChoiceCaseBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ContainerSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/IdentitySchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/LeafSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ListSchemaNodeBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/ModuleBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/NotificationBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/RpcDefinitionBuilder.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/builder/impl/UsesNodeBuilderImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java [new file with mode: 0644]
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/YangParserListenerImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/BitImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/MustDefinitionImpl.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/ParserUtils.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/UnknownBoundaryNumber.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/util/YangModelBuilderUtil.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/java/org/opendaylight/controller/yang/parser/impl/YangParserTest.java
opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/test/resources/model/testfile2.yang

index 4cf4fad..374ad8b 100644 (file)
@@ -21,6 +21,7 @@ public class BaseYangTypes {
     private static Map<String, Type> typeMap = new HashMap<String, Type>();
 
     public static final Type BOOLEAN_TYPE = Types.typeForClass(Boolean.class);
+    public static final Type EMPTY_TYPE = Types.typeForClass(Boolean.class);
     public static final Type INT8_TYPE = Types.typeForClass(Byte.class);
     public static final Type INT16_TYPE = Types.typeForClass(Short.class);
     public static final Type INT32_TYPE = Types.typeForClass(Integer.class);
@@ -34,6 +35,7 @@ public class BaseYangTypes {
 
     static {
         typeMap.put("boolean", BOOLEAN_TYPE);
+        typeMap.put("empty", EMPTY_TYPE);
         typeMap.put("int8", INT8_TYPE);
         typeMap.put("int16", INT16_TYPE);
         typeMap.put("int32", INT32_TYPE);
index 6c8f9de..942174f 100644 (file)
@@ -7,14 +7,14 @@
  */
 package org.opendaylight.controller.sal.java.api.generator;
 
-import static org.opendaylight.controller.sal.java.api.generator.Constants.NL;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.RCB;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.TAB;
+import static org.opendaylight.controller.sal.java.api.generator.Constants.*;
 
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;
 import org.opendaylight.controller.sal.binding.model.api.GeneratedProperty;
@@ -23,52 +23,70 @@ import org.opendaylight.controller.sal.binding.model.api.Type;
 
 public class ClassCodeGenerator implements CodeGenerator {
 
+    private Map<String, LinkedHashMap<String, Integer>> imports;
+
     @Override
     public Writer generate(Type type) throws IOException {
         final Writer writer = new StringWriter();
         if (type instanceof GeneratedTransferObject) {
             GeneratedTransferObject genTO = (GeneratedTransferObject) type;
+            imports = GeneratorUtil.createImports(genTO);
+
+            final String currentPkg = genTO.getPackageName();
             final List<GeneratedProperty> fields = genTO.getProperties();
 
-            writer.write(GeneratorUtil.createClassDeclarationWithPkgName(genTO,
-                    ""));
+            writer.write(GeneratorUtil.createPackageDeclaration(currentPkg));
+            writer.write(NL);
+
+            List<String> importLines = GeneratorUtil.createImportLines(imports);
+            for (String line : importLines) {
+                writer.write(line + NL);
+            }
+            writer.write(NL);
+
+            writer.write(GeneratorUtil.createClassDeclaration(genTO, "",
+                    imports));
             writer.write(NL);
             writer.write(NL);
 
             if (fields != null) {
                 for (GeneratedProperty field : fields) {
-                    writer.write(GeneratorUtil.createField(field, TAB) + NL);
+                    writer.write(GeneratorUtil.createField(field, TAB, imports,
+                            currentPkg) + NL);
                 }
                 writer.write(NL);
-                writer.write(GeneratorUtil.createConstructor(genTO, TAB) + NL);
+                writer.write(GeneratorUtil.createConstructor(genTO, TAB,
+                        imports) + NL);
                 writer.write(NL);
                 for (GeneratedProperty field : fields) {
-                    writer.write(GeneratorUtil.createGetter(field, TAB) + NL);
+                    writer.write(GeneratorUtil.createGetter(field, TAB,
+                            imports, currentPkg) + NL);
                     if (!field.isReadOnly()) {
-                        writer.write(GeneratorUtil.createSetter(field, TAB) + NL);
+                        writer.write(GeneratorUtil.createSetter(field, TAB,
+                                imports, currentPkg) + NL);
                     }
                 }
                 writer.write(NL);
-                
+
                 if (!genTO.getHashCodeIdentifiers().isEmpty()) {
                     writer.write(GeneratorUtil.createHashCode(
                             genTO.getHashCodeIdentifiers(), TAB)
                             + NL);
                 }
-                
+
                 if (!genTO.getEqualsIdentifiers().isEmpty()) {
                     writer.write(GeneratorUtil.createEquals(genTO,
                             genTO.getEqualsIdentifiers(), TAB)
                             + NL);
                 }
-                
+
                 if (!genTO.getToStringIdentifiers().isEmpty()) {
                     writer.write(GeneratorUtil.createToString(genTO,
                             genTO.getToStringIdentifiers(), TAB)
                             + NL);
 
                 }
-                
+
                 writer.write(RCB);
             }
         }
index 9e9a3e5..b85e2b0 100644 (file)
@@ -7,28 +7,13 @@
  */
 package org.opendaylight.controller.sal.java.api.generator;
 
-import static org.opendaylight.controller.sal.java.api.generator.Constants.CLASS;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.COMMA;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.ENUM;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.FINAL;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.GAP;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.IFC;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.LB;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.LCB;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.NL;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.PKG;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.PRIVATE;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.PUBLIC;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.RB;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.RCB;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.SC;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.STATIC;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.TAB;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.EXTENDS;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.IMPLEMENTS;
+import static org.opendaylight.controller.sal.java.api.generator.Constants.*;
 
 import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.opendaylight.controller.sal.binding.model.api.AnnotationType;
 import org.opendaylight.controller.sal.binding.model.api.Constant;
@@ -47,23 +32,30 @@ public class GeneratorUtil {
     private GeneratorUtil() {
     }
 
-    public static String createIfcDeclarationWithPkgName(
-            final GeneratedType genType, final String indent) {
-        return createFileDeclarationWithPkgName(IFC, genType, indent);
+    public static String createIfcDeclaration(final GeneratedType genType,
+            final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports) {
+        return createFileDeclaration(IFC, genType, indent, availableImports);
     }
 
-    public static String createClassDeclarationWithPkgName(
-            final GeneratedTransferObject genTransferObject, final String indent) {
-        return createFileDeclarationWithPkgName(CLASS, genTransferObject,
-                indent);
+    public static String createClassDeclaration(
+            final GeneratedTransferObject genTransferObject,
+            final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports) {
+        return createFileDeclaration(CLASS, genTransferObject, indent,
+                availableImports);
     }
 
-    private static String createFileDeclarationWithPkgName(final String type,
-            final GeneratedType genType, final String indent) {
+    public static String createPackageDeclaration(final String packageName) {
+        return PKG + GAP + packageName + SC;
+    }
+
+    private static String createFileDeclaration(final String type,
+            final GeneratedType genType, final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports) {
         final StringBuilder builder = new StringBuilder();
-        builder.append(PKG + GAP + genType.getPackageName() + SC);
-        builder.append(NL);
-        builder.append(NL);
+        final String currentPkg = genType.getPackageName();
+
         createComment(builder, genType.getComment(), indent);
 
         if (!genType.getAnnotations().isEmpty()) {
@@ -73,7 +65,6 @@ public class GeneratorUtil {
         }
         builder.append(PUBLIC + GAP + type + GAP + genType.getName() + GAP);
 
-        final List<Type> genImplements = genType.getImplements();
         if (genType instanceof GeneratedTransferObject) {
             GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
 
@@ -82,16 +73,21 @@ public class GeneratorUtil {
                 builder.append(genTO.getExtends() + GAP);
             }
         }
+
+        final List<Type> genImplements = genType.getImplements();
         if (!genImplements.isEmpty()) {
             if (genType instanceof GeneratedTransferObject) {
                 builder.append(IMPLEMENTS + GAP);
             } else {
                 builder.append(EXTENDS + GAP);
             }
-            builder.append(getExplicitType(genImplements.get(0)));
+            builder.append(getExplicitType(genImplements.get(0),
+                    availableImports, currentPkg));
+
             for (int i = 1; i < genImplements.size(); ++i) {
                 builder.append(", ");
-                builder.append(getExplicitType(genImplements.get(i)));
+                builder.append(getExplicitType(genImplements.get(i),
+                        availableImports, currentPkg));
             }
         }
 
@@ -155,18 +151,22 @@ public class GeneratorUtil {
     }
 
     public static String createConstant(final Constant constant,
-            final String indent) {
+            final String indent,
+            final Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
         builder.append(indent + PUBLIC + GAP + STATIC + GAP + FINAL + GAP);
-        builder.append(getExplicitType(constant.getType()) + GAP
-                + constant.getName());
+        builder.append(getExplicitType(constant.getType(), availableImports,
+                currentPkg) + GAP + constant.getName());
         builder.append(GAP + "=" + GAP);
         builder.append(constant.getValue() + SC);
         return builder.toString();
     }
 
     public static String createField(final GeneratedProperty property,
-            final String indent) {
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
         builder.append(indent);
         if (!property.getAnnotations().isEmpty()) {
@@ -175,23 +175,28 @@ public class GeneratorUtil {
             builder.append(NL);
         }
         builder.append(indent + PRIVATE + GAP);
-        builder.append(getExplicitType(property.getReturnType()) + GAP
-                + property.getName());
+        builder.append(getExplicitType(property.getReturnType(),
+                availableImports, currentPkg) + GAP + property.getName());
         builder.append(SC);
         return builder.toString();
     }
 
     /**
      * Create method declaration in interface.
-     * 
+     *
      * @param method
      * @param indent
      * @return
      */
     public static String createMethodDeclaration(final MethodSignature method,
-            final String indent) {
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
+        final StringBuilder builder = new StringBuilder();
+
         if (method == null) {
-            throw new IllegalArgumentException("Method Signature parameter MUST be specified and cannot be NULL!");
+            throw new IllegalArgumentException(
+                    "Method Signature parameter MUST be specified and cannot be NULL!");
         }
 
         final String comment = method.getComment();
@@ -202,12 +207,12 @@ public class GeneratorUtil {
 
         final Type type = method.getReturnType();
         if (type == null) {
-            throw new IllegalStateException("Method Return type cannot be NULL!");
+            throw new IllegalStateException(
+                    "Method Return type cannot be NULL!");
         }
 
         final List<Parameter> parameters = method.getParameters();
 
-        final StringBuilder builder = new StringBuilder();
         createComment(builder, comment, indent);
         builder.append(NL);
         builder.append(indent);
@@ -218,7 +223,9 @@ public class GeneratorUtil {
             builder.append(NL);
         }
 
-        builder.append(indent + getExplicitType(type) + GAP + name);
+        builder.append(indent
+                + getExplicitType(type, availableImports, currentPkg) + GAP
+                + name);
         builder.append(LB);
         for (int i = 0; i < parameters.size(); i++) {
             Parameter p = parameters.get(i);
@@ -226,8 +233,8 @@ public class GeneratorUtil {
             if (i + 1 == parameters.size()) {
                 separator = "";
             }
-            builder.append(getExplicitType(p.getType()) + GAP + p.getName()
-                    + separator);
+            builder.append(getExplicitType(p.getType(), availableImports,
+                    currentPkg) + GAP + p.getName() + separator);
         }
         builder.append(RB);
         builder.append(SC);
@@ -236,9 +243,11 @@ public class GeneratorUtil {
     }
 
     public static String createConstructor(
-            GeneratedTransferObject genTransferObject, final String indent) {
+            GeneratedTransferObject genTransferObject, final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports) {
         final StringBuilder builder = new StringBuilder();
 
+        final String currentPkg = genTransferObject.getPackageName();
         final List<GeneratedProperty> properties = genTransferObject
                 .getProperties();
         final List<GeneratedProperty> ctorParams = new ArrayList<GeneratedProperty>();
@@ -247,21 +256,23 @@ public class GeneratorUtil {
                 ctorParams.add(property);
             }
         }
-        
+
         builder.append(indent);
         builder.append(PUBLIC);
         builder.append(GAP);
         builder.append(genTransferObject.getName());
         builder.append(LB);
-        
+
         if (!ctorParams.isEmpty()) {
-            builder.append(getExplicitType(ctorParams.get(0).getReturnType()));
+            builder.append(getExplicitType(ctorParams.get(0).getReturnType(),
+                    availableImports, currentPkg));
             builder.append(" ");
             builder.append(ctorParams.get(0).getName());
             for (int i = 1; i < ctorParams.size(); ++i) {
                 final GeneratedProperty param = ctorParams.get(i);
                 builder.append(", ");
-                builder.append(getExplicitType(param.getReturnType()));
+                builder.append(getExplicitType(param.getReturnType(),
+                        availableImports, currentPkg));
                 builder.append(GAP);
                 builder.append(param.getName());
             }
@@ -285,7 +296,9 @@ public class GeneratorUtil {
     }
 
     public static String createGetter(final GeneratedProperty property,
-            final String indent) {
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
         final StringBuilder builder = new StringBuilder();
 
         final Type type = property.getReturnType();
@@ -293,7 +306,8 @@ public class GeneratorUtil {
         final char first = Character.toUpperCase(varName.charAt(0));
         final String methodName = "get" + first + varName.substring(1);
 
-        builder.append(indent + PUBLIC + GAP + getExplicitType(type) + GAP
+        builder.append(indent + PUBLIC + GAP
+                + getExplicitType(type, availableImports, currentPkg) + GAP
                 + methodName);
         builder.append(LB + RB + LCB + NL);
 
@@ -304,9 +318,11 @@ public class GeneratorUtil {
         builder.append(indent + RCB);
         return builder.toString();
     }
-    
+
     public static String createSetter(final GeneratedProperty property,
-            final String indent) {
+            final String indent,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            String currentPkg) {
         final StringBuilder builder = new StringBuilder();
 
         final Type type = property.getReturnType();
@@ -314,11 +330,12 @@ public class GeneratorUtil {
         final char first = Character.toUpperCase(varName.charAt(0));
         final String methodName = "set" + first + varName.substring(1);
 
-        builder.append(indent + PUBLIC + GAP + "void" + GAP
-                + methodName);
-        builder.append(LB + getExplicitType(type) + GAP + varName + RB + LCB + NL);
+        builder.append(indent + PUBLIC + GAP + "void" + GAP + methodName);
+        builder.append(LB + getExplicitType(type, availableImports, currentPkg)
+                + GAP + varName + RB + LCB + NL);
         String currentIndent = indent + TAB;
-        builder.append(currentIndent + "this." + varName + " = " + varName + SC + NL);
+        builder.append(currentIndent + "this." + varName + " = " + varName + SC
+                + NL);
         builder.append(indent + RCB);
         return builder.toString();
     }
@@ -329,7 +346,7 @@ public class GeneratorUtil {
         builder.append(indent + "public int hashCode() {" + NL);
         builder.append(indent + TAB + "final int prime = 31;" + NL);
         builder.append(indent + TAB + "int result = 1;" + NL);
-        
+
         for (GeneratedProperty property : properties) {
             String fieldName = property.getName();
             builder.append(indent + TAB + "result = prime * result + (("
@@ -346,8 +363,8 @@ public class GeneratorUtil {
             final List<GeneratedProperty> properties, final String indent) {
         StringBuilder builder = new StringBuilder();
         final String indent1 = indent + TAB;
-        final String indent2 = indent + TAB + TAB;
-        final String indent3 = indent + TAB + TAB + TAB;
+        final String indent2 = indent1 + TAB;
+        final String indent3 = indent2 + TAB;
 
         builder.append(indent + "public boolean equals(Object obj) {" + NL);
         builder.append(indent1 + "if (this == obj) {" + NL);
@@ -360,7 +377,7 @@ public class GeneratorUtil {
         builder.append(indent2 + "return false;" + NL);
         builder.append(indent1 + "}" + NL);
 
-        String typeStr = type.getPackageName() + "." + type.getName();
+        String typeStr = type.getName();
         builder.append(indent1 + typeStr + " other = (" + typeStr + ") obj;"
                 + NL);
 
@@ -461,31 +478,59 @@ public class GeneratorUtil {
         return builder.toString();
     }
 
-    private static String getExplicitType(final Type type) {
+    private static String getExplicitType(final Type type,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            final String currentPkg) {
         if (type == null) {
-            throw new IllegalArgumentException("Type parameter MUST be specified and cannot be NULL!");
+            throw new IllegalArgumentException(
+                    "Type parameter MUST be specified and cannot be NULL!");
         }
         String packageName = type.getPackageName();
-        if (packageName.endsWith(".")) {
-            packageName = packageName.substring(0, packageName.length() - 1);
-        }
 
-        final StringBuilder builder = new StringBuilder(packageName + "."
-                + type.getName());
-        if (type instanceof ParameterizedType) {
-            final ParameterizedType pType = (ParameterizedType) type;
-            Type[] pTypes = pType.getActualTypeArguments();
-            builder.append("<");
-            builder.append(getParameters(pTypes));
-            builder.append(">");
-        }
-        if (builder.toString().equals("java.lang.Void")) {
-            return "void";
+        LinkedHashMap<String, Integer> imports = availableImports.get(type
+                .getName());
+
+        if ((imports != null && packageName
+                .equals(findMaxValue(imports).get(0)))
+                || packageName.equals(currentPkg)) {
+            final StringBuilder builder = new StringBuilder(type.getName());
+            if (type instanceof ParameterizedType) {
+                ParameterizedType pType = (ParameterizedType) type;
+                Type[] pTypes = pType.getActualTypeArguments();
+                builder.append("<");
+                builder.append(getParameters(pTypes, availableImports,
+                        currentPkg));
+                builder.append(">");
+            }
+            if (builder.toString().equals("Void")) {
+                return "void";
+            }
+            return builder.toString();
+        } else {
+            final StringBuilder builder = new StringBuilder();
+            if (packageName.startsWith("java.lang")) {
+                builder.append(type.getName());
+            } else {
+                builder.append(packageName + "." + type.getName());
+            }
+            if (type instanceof ParameterizedType) {
+                ParameterizedType pType = (ParameterizedType) type;
+                Type[] pTypes = pType.getActualTypeArguments();
+                builder.append("<");
+                builder.append(getParameters(pTypes, availableImports,
+                        currentPkg));
+                builder.append(">");
+            }
+            if (builder.toString().equals("Void")) {
+                return "void";
+            }
+            return builder.toString();
         }
-        return builder.toString();
     }
 
-    private static String getParameters(final Type[] pTypes) {
+    private static String getParameters(final Type[] pTypes,
+            Map<String, LinkedHashMap<String, Integer>> availableImports,
+            String currentPkg) {
         final StringBuilder builder = new StringBuilder();
         for (int i = 0; i < pTypes.length; i++) {
             Type t = pTypes[i];
@@ -494,11 +539,30 @@ public class GeneratorUtil {
             if (i + 1 == pTypes.length) {
                 separator = "";
             }
-            builder.append(getExplicitType(t) + separator);
+            builder.append(getExplicitType(t, availableImports, currentPkg)
+                    + separator);
         }
         return builder.toString();
     }
 
+    private static List<String> findMaxValue(
+            LinkedHashMap<String, Integer> imports) {
+        final List<String> result = new ArrayList<String>();
+
+        int maxValue = 0;
+        int currentValue = 0;
+        for (Map.Entry<String, Integer> entry : imports.entrySet()) {
+            currentValue = entry.getValue();
+            if (currentValue > maxValue) {
+                result.clear();
+                result.add(entry.getKey());
+            } else if (currentValue == maxValue) {
+                result.add(entry.getKey());
+            }
+        }
+        return result;
+    }
+
     private static void createComment(final StringBuilder builder,
             final String comment, final String indent) {
         if (comment != null && comment.length() > 0) {
@@ -508,4 +572,101 @@ public class GeneratorUtil {
         }
     }
 
+    public static Map<String, LinkedHashMap<String, Integer>> createImports(
+            GeneratedType genType) {
+        final Map<String, LinkedHashMap<String, Integer>> imports = new HashMap<String, LinkedHashMap<String, Integer>>();
+        final String genTypePkg = genType.getPackageName();
+
+        final List<Constant> constants = genType.getConstantDefinitions();
+        final List<MethodSignature> methods = genType.getMethodDefinitions();
+        List<Type> impl = genType.getImplements();
+
+        // IMPLEMENTATIONS
+        if (impl != null) {
+            for (Type t : impl) {
+                addTypeToImports(t, imports, genTypePkg);
+            }
+        }
+
+        // CONSTANTS
+        if (constants != null) {
+            for (Constant c : constants) {
+                Type ct = c.getType();
+                addTypeToImports(ct, imports, genTypePkg);
+            }
+        }
+
+        // METHODS
+        if (methods != null) {
+            for (MethodSignature m : methods) {
+                Type ct = m.getReturnType();
+                addTypeToImports(ct, imports, genTypePkg);
+                for (MethodSignature.Parameter p : m.getParameters()) {
+                    addTypeToImports(p.getType(), imports, genTypePkg);
+                }
+            }
+        }
+
+        // PROPERTIES
+        if (genType instanceof GeneratedTransferObject) {
+            GeneratedTransferObject genTO = (GeneratedTransferObject) genType;
+
+            List<GeneratedProperty> props = genTO.getProperties();
+            if (props != null) {
+                for (GeneratedProperty prop : props) {
+                    Type pt = prop.getReturnType();
+                    addTypeToImports(pt, imports, genTypePkg);
+                }
+            }
+        }
+
+        return imports;
+    }
+
+    private static void addTypeToImports(Type type,
+            Map<String, LinkedHashMap<String, Integer>> importedTypes,
+            String genTypePkg) {
+        String typeName = type.getName();
+        String typePkg = type.getPackageName();
+        if (typePkg.startsWith("java.lang") || typePkg.equals(genTypePkg)) {
+            return;
+        }
+        LinkedHashMap<String, Integer> packages = importedTypes.get(typeName);
+        if (packages == null) {
+            packages = new LinkedHashMap<String, Integer>();
+            packages.put(typePkg, 1);
+            importedTypes.put(typeName, packages);
+        } else {
+            Integer occurrence = packages.get(typePkg);
+            if (occurrence == null) {
+                packages.put(typePkg, 1);
+            } else {
+                occurrence++;
+                packages.put(typePkg, occurrence);
+            }
+        }
+
+        if (type instanceof ParameterizedType) {
+            ParameterizedType pt = (ParameterizedType) type;
+            Type[] params = pt.getActualTypeArguments();
+            for (Type param : params) {
+                addTypeToImports(param, importedTypes, genTypePkg);
+            }
+        }
+    }
+
+    public static List<String> createImportLines(
+            Map<String, LinkedHashMap<String, Integer>> imports) {
+        List<String> importLines = new ArrayList<String>();
+
+        for (Map.Entry<String, LinkedHashMap<String, Integer>> entry : imports
+                .entrySet()) {
+            String typeName = entry.getKey();
+            LinkedHashMap<String, Integer> typePkgMap = entry.getValue();
+            String typePkg = typePkgMap.keySet().iterator().next();
+            importLines.add("import " + typePkg + "." + typeName + SC);
+        }
+        return importLines;
+    }
+
 }
index 51ce324..abaf4fa 100644 (file)
@@ -7,14 +7,14 @@
  */
 package org.opendaylight.controller.sal.java.api.generator;
 
-import static org.opendaylight.controller.sal.java.api.generator.Constants.NL;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.RCB;
-import static org.opendaylight.controller.sal.java.api.generator.Constants.TAB;
+import static org.opendaylight.controller.sal.java.api.generator.Constants.*;
 
 import java.io.IOException;
 import java.io.StringWriter;
 import java.io.Writer;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Map;
 
 import org.opendaylight.controller.sal.binding.model.api.CodeGenerator;
 import org.opendaylight.controller.sal.binding.model.api.Constant;
@@ -26,31 +26,47 @@ import org.opendaylight.controller.sal.binding.model.api.Type;
 
 public class InterfaceGenerator implements CodeGenerator {
 
+    private Map<String, LinkedHashMap<String, Integer>> imports;
+
     public Writer generate(Type type) throws IOException {
         Writer writer = new StringWriter();
-        if (type instanceof GeneratedType && !(type instanceof GeneratedTransferObject)) {
+        if (type instanceof GeneratedType
+                && !(type instanceof GeneratedTransferObject)) {
             GeneratedType genType = (GeneratedType) type;
+            imports = GeneratorUtil.createImports(genType);
 
+            final String currentPkg = genType.getPackageName();
             final List<Constant> constants = genType.getConstantDefinitions();
             final List<MethodSignature> methods = genType
                     .getMethodDefinitions();
             final List<Enumeration> enums = genType.getEnumDefintions();
 
-            writer.write(GeneratorUtil.createIfcDeclarationWithPkgName(genType,
-                    ""));
+            writer.write(GeneratorUtil.createPackageDeclaration(genType
+                    .getPackageName()));
+            writer.write(NL);
+
+            List<String> importLines = GeneratorUtil.createImportLines(imports);
+            for (String line : importLines) {
+                writer.write(line + NL);
+            }
+            writer.write(NL);
+
+            writer.write(GeneratorUtil.createIfcDeclaration(genType, "",
+                    imports));
             writer.write(NL);
 
             if (constants != null) {
                 for (Constant c : constants) {
-                    writer.write(GeneratorUtil.createConstant(c, TAB) + NL);
+                    writer.write(GeneratorUtil.createConstant(c, TAB, imports,
+                            currentPkg) + NL);
                 }
                 writer.write(NL);
             }
 
             if (methods != null) {
                 for (MethodSignature m : methods) {
-                    writer.write(GeneratorUtil.createMethodDeclaration(m, TAB)
-                            + NL);
+                    writer.write(GeneratorUtil.createMethodDeclaration(m, TAB,
+                            imports, currentPkg) + NL);
                 }
                 writer.write(NL);
             }
index ea505cc..3295bec 100644 (file)
@@ -1,8 +1,6 @@
 package org.opendaylight.controller.sal.java.api.generator.test;
 
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.*;
 
 import java.io.File;
 import java.io.IOException;
@@ -73,7 +71,7 @@ public class ClassCodeGeneratorTest {
                             propertyCount++;
                         }
                     }
-                    
+
                     final ClassCodeGenerator clsGen = new ClassCodeGenerator();
                     try {
                         final Writer writer = clsGen.generate(genTO);
@@ -81,16 +79,16 @@ public class ClassCodeGeneratorTest {
 
                         final String outputStr = writer.toString();
                         writer.close();
-                        
+
                         assertNotNull(outputStr);
                         assertTrue(outputStr
-                                .contains("public CompositeKeyListKey(java.lang.String Key2, " +
-                                               "java.lang.Byte Key1)"));
+                                .contains("public CompositeKeyListKey(String Key2, "
+                                        + "Byte Key1)"));
 
                     } catch (IOException e) {
                         e.printStackTrace();
                     }
-                    
+
                     assertEquals(2, propertyCount);
                     genTOsCount++;
                 } else if (genTO.getName().equals("InnerListKey")) {
@@ -108,18 +106,19 @@ public class ClassCodeGeneratorTest {
 
     @Test
     public void defaultConstructorTest() {
-        final GeneratedTOBuilder toBuilder = new GeneratedTOBuilderImpl("simple.pack", "DefCtor");
-        
+        final GeneratedTOBuilder toBuilder = new GeneratedTOBuilderImpl(
+                "simple.pack", "DefCtor");
+
         GeneratedPropertyBuilder propBuilder = toBuilder.addProperty("foo");
         propBuilder.addReturnType(Types.typeForClass(String.class));
         propBuilder.setReadOnly(false);
-        
+
         propBuilder = toBuilder.addProperty("bar");
         propBuilder.addReturnType(Types.typeForClass(Integer.class));
         propBuilder.setReadOnly(false);
-        
+
         final GeneratedTransferObject genTO = toBuilder.toInstance();
-        
+
         final ClassCodeGenerator clsGen = new ClassCodeGenerator();
         try {
             final Writer writer = clsGen.generate(genTO);
@@ -127,10 +126,9 @@ public class ClassCodeGeneratorTest {
 
             final String outputStr = writer.toString();
             writer.close();
-            
+
             assertNotNull(outputStr);
-            assertTrue(outputStr
-                    .contains("public DefCtor()"));
+            assertTrue(outputStr.contains("public DefCtor()"));
 
         } catch (IOException e) {
             e.printStackTrace();
index 6c40c40..076e248 100644 (file)
@@ -7,9 +7,23 @@
  */
 package org.opendaylight.controller.sal.java.api.generator.test;
 
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import javax.tools.JavaCompiler;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import javax.tools.ToolProvider;
+
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.opendaylight.controller.binding.generator.util.generated.type.builder.GeneratedTypeBuilderImpl;
 import org.opendaylight.controller.sal.binding.generator.api.BindingGenerator;
@@ -24,39 +38,34 @@ import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang.parser.impl.YangParserImpl;
 
-import javax.tools.JavaCompiler;
-import javax.tools.JavaFileObject;
-import javax.tools.StandardJavaFileManager;
-import javax.tools.ToolProvider;
-import java.io.File;
-import java.io.IOException;
-import java.util.*;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
 public class GeneratorJavaFileTest {
     private static final String FS = File.separator;
-    private static final String PATH = "test-dir";
+    private static final String PATH = "target/test/test-dir";
     private final File testDir = new File(PATH);
 
-    private static final String GENERATOR_OUTPUT_PATH = "src/test/resources/src";
+    private static final String GENERATOR_OUTPUT_PATH = "target/test/src";
     private static final File GENERATOR_OUTPUT = new File(GENERATOR_OUTPUT_PATH);
-    private static final String COMPILER_OUTPUT_PATH = "src/test/resources/bin";
+    private static final String COMPILER_OUTPUT_PATH = "target/test/bin";
     private static final File COMPILER_OUTPUT = new File(COMPILER_OUTPUT_PATH);
 
     @Before
     public void init() {
-        assertTrue(testDir.mkdir());
+        assertTrue(testDir.mkdirs());
         assertTrue(COMPILER_OUTPUT.mkdirs());
         assertTrue(GENERATOR_OUTPUT.mkdirs());
     }
 
     @After
     public void cleanUp() {
-        deleteTestDir(testDir);
-        deleteTestDir(COMPILER_OUTPUT);
-        deleteTestDir(GENERATOR_OUTPUT);
+        if(testDir.exists()) {
+            deleteTestDir(testDir);
+        }
+        if(COMPILER_OUTPUT.exists()) {
+            deleteTestDir(COMPILER_OUTPUT);
+        }
+        if(GENERATOR_OUTPUT.exists()) {
+            deleteTestDir(GENERATOR_OUTPUT);
+        }
     }
 
     @Test
@@ -85,7 +94,6 @@ public class GeneratorJavaFileTest {
         assertTrue(filesList.contains("Type3.java"));
     }
 
-    @Ignore
     @Test
     public void compilationTest() throws Exception {
         final YangParserImpl parser = new YangParserImpl();
index eea482a..36aff55 100644 (file)
@@ -53,8 +53,9 @@ container_stmt : CONTAINER_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_
 grouping_stmt : GROUPING_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt |status_stmt | description_stmt | reference_stmt | typedef_stmt | grouping_stmt | data_def_stmt )* RIGHT_BRACE));
 value_stmt : VALUE_KEYWORD string stmtend;
 max_value_arg : /*UNBOUNDED_KEYWORD |*/ string;
+min_value_arg : /*UNBOUNDED_KEYWORD |*/ string;
 max_elements_stmt : MAX_ELEMENTS_KEYWORD max_value_arg stmtend;
-min_elements_stmt : MIN_ELEMENTS_KEYWORD string stmtend;
+min_elements_stmt : MIN_ELEMENTS_KEYWORD min_value_arg stmtend;
 error_app_tag_stmt : ERROR_APP_TAG_KEYWORD string stmtend;
 error_message_stmt : ERROR_MESSAGE_KEYWORD string stmtend;
 must_stmt : MUST_KEYWORD string (SEMICOLON | (LEFT_BRACE  (identifier_stmt |error_message_stmt | error_app_tag_stmt | description_stmt | reference_stmt )* RIGHT_BRACE));
index b3e8ad2..7ac4ec0 100644 (file)
@@ -19,11 +19,17 @@ import org.opendaylight.controller.yang.parser.util.RefineHolder;
 public interface UsesNodeBuilder extends Builder {
 
     SchemaPath getGroupingPath();
+
     void addAugment(AugmentationSchemaBuilder builder);
+
     void setAugmenting(boolean augmenting);
+
     List<RefineHolder> getRefines();
+
     void addRefine(RefineHolder refine);
+
     void addRefineNode(SchemaNodeBuilder refineNode);
+
     UsesNode build();
 
 }
index 4b95ab9..7d9e3ea 100644 (file)
@@ -18,8 +18,10 @@ import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.Status;
 import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public class AnyXmlBuilder implements DataSchemaNodeBuilder {
+    private boolean built;
     private final int line;
     private final QName qname;
     private SchemaPath path;
@@ -41,20 +43,23 @@ public class AnyXmlBuilder implements DataSchemaNodeBuilder {
 
     @Override
     public AnyXmlSchemaNode build() {
-        instance.setPath(path);
-        instance.setConstraints(constraints.build());
-        instance.setDescription(description);
-        instance.setReference(reference);
-        instance.setStatus(status);
-
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
-        }
-        instance.setUnknownSchemaNodes(unknownNodes);
+        if (!built) {
+            instance.setPath(path);
+            instance.setConstraints(constraints.build());
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+            instance.setConfiguration(configuration);
+
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
-        instance.setConfiguration(configuration);
+            built = true;
+        }
         return instance;
     }
 
@@ -122,7 +127,7 @@ public class AnyXmlBuilder implements DataSchemaNodeBuilder {
 
     @Override
     public void setAugmenting(final boolean augmenting) {
-        throw new UnsupportedOperationException(
+        throw new YangParseException(line,
                 "An anyxml node cannot be augmented.");
     }
 
@@ -135,7 +140,7 @@ public class AnyXmlBuilder implements DataSchemaNodeBuilder {
         instance.setConfiguration(configuration);
     }
 
-    private class AnyXmlSchemaNodeImpl implements AnyXmlSchemaNode {
+    private final class AnyXmlSchemaNodeImpl implements AnyXmlSchemaNode {
         private final QName qname;
         private SchemaPath path;
         private String description;
index 70079b3..a5db03b 100644 (file)
@@ -29,8 +29,10 @@ import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.controller.yang.parser.util.YangModelBuilderUtil;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public class AugmentationSchemaBuilderImpl implements AugmentationSchemaBuilder {
+    private boolean built;
     private final AugmentationSchemaImpl instance;
     private final int line;
     private final String augmentTargetStr;
@@ -94,37 +96,40 @@ public class AugmentationSchemaBuilderImpl implements AugmentationSchemaBuilder
 
     @Override
     public AugmentationSchema build() {
-        instance.setTargetPath(finalAugmentTarget);
+        if (!built) {
+            instance.setTargetPath(finalAugmentTarget);
 
-        RevisionAwareXPath whenStmt;
-        if (whenCondition == null) {
-            whenStmt = null;
-        } else {
-            whenStmt = new RevisionAwareXPathImpl(whenCondition, false);
-        }
-        instance.setWhenCondition(whenStmt);
+            RevisionAwareXPath whenStmt;
+            if (whenCondition == null) {
+                whenStmt = null;
+            } else {
+                whenStmt = new RevisionAwareXPathImpl(whenCondition, false);
+            }
+            instance.setWhenCondition(whenStmt);
 
-        // CHILD NODES
-        final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-        for (DataSchemaNodeBuilder node : childNodes) {
-            childs.put(node.getQName(), node.build());
-        }
-        instance.setChildNodes(childs);
+            // CHILD NODES
+            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            for (DataSchemaNodeBuilder node : childNodes) {
+                childs.put(node.getQName(), node.build());
+            }
+            instance.setChildNodes(childs);
 
-        // GROUPINGS
-        final Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();
-        for (GroupingBuilder builder : groupings) {
-            groupingDefinitions.add(builder.build());
-        }
-        instance.setGroupings(groupingDefinitions);
+            // GROUPINGS
+            final Set<GroupingDefinition> groupingDefinitions = new HashSet<GroupingDefinition>();
+            for (GroupingBuilder builder : groupings) {
+                groupingDefinitions.add(builder.build());
+            }
+            instance.setGroupings(groupingDefinitions);
 
-        // USES
-        final Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();
-        for (UsesNodeBuilder builder : usesNodes) {
-            usesNodeDefinitions.add(builder.build());
-        }
-        instance.setUses(usesNodeDefinitions);
+            // USES
+            final Set<UsesNode> usesNodeDefinitions = new HashSet<UsesNode>();
+            for (UsesNodeBuilder builder : usesNodes) {
+                usesNodeDefinitions.add(builder.build());
+            }
+            instance.setUses(usesNodeDefinitions);
 
+            built = true;
+        }
         return instance;
     }
 
@@ -148,7 +153,7 @@ public class AugmentationSchemaBuilderImpl implements AugmentationSchemaBuilder
 
     @Override
     public void addTypedef(TypeDefinitionBuilder type) {
-        throw new UnsupportedOperationException(
+        throw new YangParseException(line,
                 "Augmentation can not contains type definitions");
     }
 
@@ -186,7 +191,8 @@ public class AugmentationSchemaBuilderImpl implements AugmentationSchemaBuilder
     public int hashCode() {
         final int prime = 17;
         int result = 1;
-        result = prime * result
+        result = prime
+                * result
                 + ((augmentTargetStr == null) ? 0 : augmentTargetStr.hashCode());
         result = prime * result
                 + ((whenCondition == null) ? 0 : whenCondition.hashCode());
@@ -231,8 +237,7 @@ public class AugmentationSchemaBuilderImpl implements AugmentationSchemaBuilder
         return true;
     }
 
-
-    private static class AugmentationSchemaImpl implements AugmentationSchema {
+    private final class AugmentationSchemaImpl implements AugmentationSchema {
         private SchemaPath targetPath;
         private RevisionAwareXPath whenCondition;
         private Map<QName, DataSchemaNode> childNodes = Collections.emptyMap();
index 7f3680e..04e7d33 100644 (file)
@@ -28,9 +28,11 @@ import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public class ChoiceBuilder implements DataSchemaNodeBuilder, ChildNodeBuilder,
         AugmentationTargetBuilder {
+    private boolean built;
     private final ChoiceNodeImpl instance;
     private final int line;
     // SchemaNode args
@@ -62,36 +64,39 @@ public class ChoiceBuilder implements DataSchemaNodeBuilder, ChildNodeBuilder,
 
     @Override
     public ChoiceNode build() {
-        instance.setPath(schemaPath);
-        instance.setDescription(description);
-        instance.setReference(reference);
-        instance.setStatus(status);
-        instance.setAugmenting(augmenting);
-        instance.setConfiguration(configuration);
-        instance.setConstraints(constraints.build());
-        instance.setDefaultCase(defaultCase);
-
-        // CASES
-        final Set<ChoiceCaseNode> choiceCases = new HashSet<ChoiceCaseNode>();
-        for (ChoiceCaseBuilder caseBuilder : cases) {
-            choiceCases.add(caseBuilder.build());
-        }
-        instance.setCases(choiceCases);
+        if (!built) {
+            instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+            instance.setAugmenting(augmenting);
+            instance.setConfiguration(configuration);
+            instance.setConstraints(constraints.build());
+            instance.setDefaultCase(defaultCase);
+
+            // CASES
+            final Set<ChoiceCaseNode> choiceCases = new HashSet<ChoiceCaseNode>();
+            for (ChoiceCaseBuilder caseBuilder : cases) {
+                choiceCases.add(caseBuilder.build());
+            }
+            instance.setCases(choiceCases);
 
-        // AUGMENTATIONS
-        final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
-        for (AugmentationSchemaBuilder builder : addedAugmentations) {
-            augmentations.add(builder.build());
-        }
-        instance.setAvailableAugmentations(augmentations);
+            // AUGMENTATIONS
+            final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+            for (AugmentationSchemaBuilder builder : addedAugmentations) {
+                augmentations.add(builder.build());
+            }
+            instance.setAvailableAugmentations(augmentations);
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
-        }
-        instance.setUnknownSchemaNodes(unknownNodes);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
+            built = true;
+        }
         return instance;
     }
 
@@ -125,7 +130,7 @@ public class ChoiceBuilder implements DataSchemaNodeBuilder, ChildNodeBuilder,
      * Choice can not contains grouping statements, so this method always
      * returns an empty set.
      *
-     * @return
+     * @return empty set
      */
     public Set<GroupingBuilder> getGroupings() {
         return Collections.emptySet();
@@ -133,7 +138,7 @@ public class ChoiceBuilder implements DataSchemaNodeBuilder, ChildNodeBuilder,
 
     @Override
     public void addGrouping(GroupingBuilder groupingBuilder) {
-        throw new IllegalStateException(
+        throw new YangParseException(line,
                 "Can not add grouping to 'choice' node.");
     }
 
@@ -247,7 +252,7 @@ public class ChoiceBuilder implements DataSchemaNodeBuilder, ChildNodeBuilder,
         return new HashSet<DataSchemaNodeBuilder>(cases);
     }
 
-    private static class ChoiceNodeImpl implements ChoiceNode {
+    private class ChoiceNodeImpl implements ChoiceNode {
         private final QName qname;
         private SchemaPath path;
         private String description;
index d86db6d..a3b21b4 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.controller.yang.parser.builder.api.AbstractChildNodeBuil
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
+import org.opendaylight.controller.yang.parser.util.YangParseException;
 
 public final class ChoiceCaseBuilder extends AbstractChildNodeBuilder implements
         DataSchemaNodeBuilder {
@@ -151,13 +152,13 @@ public final class ChoiceCaseBuilder extends AbstractChildNodeBuilder implements
 
     @Override
     public void addTypedef(TypeDefinitionBuilder typedefBuilder) {
-        throw new UnsupportedOperationException(
+        throw new YangParseException(line,
                 "Can not add type definition to choice case.");
     }
 
     @Override
     public void setConfiguration(boolean configuration) {
-        throw new UnsupportedOperationException(
+        throw new YangParseException(line,
                 "Can not add config definition to choice case.");
     }
 
@@ -372,7 +373,6 @@ public final class ChoiceCaseBuilder extends AbstractChildNodeBuilder implements
             sb.append("]");
             return sb.toString();
         }
-
     }
 
 }
index 81a701c..e12a3a9 100644 (file)
@@ -38,6 +38,7 @@ import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 public class ContainerSchemaNodeBuilder extends AbstractChildNodeBuilder
         implements TypeDefinitionAwareBuilder, AugmentationTargetBuilder,
         DataSchemaNodeBuilder {
+    private boolean built;
     private final ContainerSchemaNodeImpl instance;
     private final int line;
     private final ConstraintsBuilder constraints;
@@ -63,59 +64,62 @@ public class ContainerSchemaNodeBuilder extends AbstractChildNodeBuilder
 
     @Override
     public ContainerSchemaNode build() {
-        instance.setPath(schemaPath);
-        instance.setDescription(description);
-        instance.setReference(reference);
-        instance.setStatus(status);
-        instance.setPresenceContainer(presence);
-        instance.setAugmenting(augmenting);
-        instance.setConfiguration(configuration);
-
-        // CHILD NODES
-        final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-        for (DataSchemaNodeBuilder node : childNodes) {
-            childs.put(node.getQName(), node.build());
-        }
-        instance.setChildNodes(childs);
+        if(!built) {
+            instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+            instance.setPresenceContainer(presence);
+            instance.setAugmenting(augmenting);
+            instance.setConfiguration(configuration);
+
+            // CHILD NODES
+            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            for (DataSchemaNodeBuilder node : childNodes) {
+                childs.put(node.getQName(), node.build());
+            }
+            instance.setChildNodes(childs);
 
-        // GROUPINGS
-        final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-        for (GroupingBuilder builder : groupings) {
-            groupingDefs.add(builder.build());
-        }
-        instance.setGroupings(groupingDefs);
+            // GROUPINGS
+            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
+            for (GroupingBuilder builder : groupings) {
+                groupingDefs.add(builder.build());
+            }
+            instance.setGroupings(groupingDefs);
 
-        // TYPEDEFS
-        final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-        for (TypeDefinitionBuilder entry : addedTypedefs) {
-            typedefs.add(entry.build());
-        }
-        instance.setTypeDefinitions(typedefs);
+            // TYPEDEFS
+            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
+            for (TypeDefinitionBuilder entry : addedTypedefs) {
+                typedefs.add(entry.build());
+            }
+            instance.setTypeDefinitions(typedefs);
 
-        // USES
-        final Set<UsesNode> uses = new HashSet<UsesNode>();
-        for (UsesNodeBuilder builder : addedUsesNodes) {
-            uses.add(builder.build());
-        }
-        instance.setUses(uses);
+            // USES
+            final Set<UsesNode> uses = new HashSet<UsesNode>();
+            for (UsesNodeBuilder builder : addedUsesNodes) {
+                uses.add(builder.build());
+            }
+            instance.setUses(uses);
 
-        // AUGMENTATIONS
-        final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
-        for(AugmentationSchemaBuilder builder : addedAugmentations) {
-            augmentations.add(builder.build());
-        }
-        instance.setAvailableAugmentations(augmentations);
+            // AUGMENTATIONS
+            final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+            for(AugmentationSchemaBuilder builder : addedAugmentations) {
+                augmentations.add(builder.build());
+            }
+            instance.setAvailableAugmentations(augmentations);
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
-        }
-        instance.setUnknownSchemaNodes(unknownNodes);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
-        instance.setConstraints(constraints.build());
-        instance.setAvailableAugmentations(augmentations);
+            instance.setConstraints(constraints.build());
+            instance.setAvailableAugmentations(augmentations);
 
+            built = true;
+        }
         return instance;
     }
 
index 60d8fb4..28f250f 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 
 public class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder
         implements SchemaNodeBuilder, DataSchemaNodeBuilder {
+    private boolean built;
     private final LeafListSchemaNodeImpl instance;
     private final int line;
     // SchemaNode args
@@ -49,28 +50,31 @@ public class LeafListSchemaNodeBuilder extends AbstractTypeAwareBuilder
 
     @Override
     public LeafListSchemaNode build() {
-        instance.setConstraints(constraints.build());
-        instance.setPath(schemaPath);
-        instance.setDescription(description);
-        instance.setReference(reference);
-        instance.setStatus(status);
-        instance.setAugmenting(augmenting);
-        instance.setConfiguration(configuration);
-        instance.setUserOrdered(userOrdered);
-
-        if (type == null) {
-            instance.setType(typedef.build());
-        } else {
-            instance.setType(type);
-        }
+        if (!built) {
+            instance.setConstraints(constraints.build());
+            instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+            instance.setAugmenting(augmenting);
+            instance.setConfiguration(configuration);
+            instance.setUserOrdered(userOrdered);
+
+            if (type == null) {
+                instance.setType(typedef.build());
+            } else {
+                instance.setType(type);
+            }
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
-        }
-        instance.setUnknownSchemaNodes(unknownNodes);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
+            built = true;
+        }
         return instance;
     }
 
index be58c7e..ee7b3b1 100644 (file)
@@ -24,6 +24,7 @@ import org.opendaylight.controller.yang.parser.builder.api.SchemaNodeBuilder;
 
 public class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implements
         DataSchemaNodeBuilder, SchemaNodeBuilder {
+    private boolean built;
     private final LeafSchemaNodeImpl instance;
     private final int line;
     // SchemaNode args
@@ -50,30 +51,33 @@ public class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implements
 
     @Override
     public LeafSchemaNode build() {
-        instance.setPath(path);
-        instance.setConstraints(constraints.build());
-        instance.setDescription(description);
-        instance.setReference(reference);
-        instance.setStatus(status);
-
-        // TYPE
-        if (type == null) {
-            instance.setType(typedef.build());
-        } else {
-            instance.setType(type);
-        }
+        if(!built) {
+            instance.setPath(path);
+            instance.setConstraints(constraints.build());
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+            instance.setAugmenting(augmenting);
+            instance.setConfiguration(configuration);
+            instance.setDefault(defaultStr);
+            instance.setUnits(unitsStr);
+
+            // TYPE
+            if (type == null) {
+                instance.setType(typedef.build());
+            } else {
+                instance.setType(type);
+            }
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
-        }
-        instance.setUnknownSchemaNodes(unknownNodes);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
-        instance.setAugmenting(augmenting);
-        instance.setConfiguration(configuration);
-        instance.setDefault(defaultStr);
-        instance.setUnits(unitsStr);
+            built = true;
+        }
         return instance;
     }
 
@@ -148,6 +152,8 @@ public class LeafSchemaNodeBuilder extends AbstractTypeAwareBuilder implements
         this.augmenting = augmenting;
     }
 
+
+
     public boolean isConfiguration() {
         return configuration;
     }
index b97399b..c9b1e73 100644 (file)
@@ -38,6 +38,7 @@ import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 public class ListSchemaNodeBuilder extends AbstractChildNodeBuilder implements
         DataSchemaNodeBuilder, AugmentationTargetBuilder,
         TypeDefinitionAwareBuilder {
+    private boolean built;
     private final ListSchemaNodeImpl instance;
     private final int line;
     // SchemaNode args
@@ -68,60 +69,63 @@ public class ListSchemaNodeBuilder extends AbstractChildNodeBuilder implements
 
     @Override
     public ListSchemaNode build() {
-        instance.setKeyDefinition(keyDefinition);
-        instance.setPath(schemaPath);
-        instance.setDescription(description);
-        instance.setReference(reference);
-        instance.setStatus(status);
-        instance.setAugmenting(augmenting);
-        instance.setConfiguration(configuration);
-        instance.setUserOrdered(userOrdered);
-
-        // CHILD NODES
-        final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-        for (DataSchemaNodeBuilder node : childNodes) {
-            childs.put(node.getQName(), node.build());
-        }
-        instance.setChildNodes(childs);
+        if(!built) {
+            instance.setKeyDefinition(keyDefinition);
+            instance.setPath(schemaPath);
+            instance.setDescription(description);
+            instance.setReference(reference);
+            instance.setStatus(status);
+            instance.setAugmenting(augmenting);
+            instance.setConfiguration(configuration);
+            instance.setUserOrdered(userOrdered);
+
+            // CHILD NODES
+            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            for (DataSchemaNodeBuilder node : childNodes) {
+                childs.put(node.getQName(), node.build());
+            }
+            instance.setChildNodes(childs);
 
-        // TYPEDEFS
-        final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-        for (TypeDefinitionBuilder entry : addedTypedefs) {
-            typedefs.add(entry.build());
-        }
-        instance.setTypeDefinitions(typedefs);
+            // TYPEDEFS
+            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
+            for (TypeDefinitionBuilder entry : addedTypedefs) {
+                typedefs.add(entry.build());
+            }
+            instance.setTypeDefinitions(typedefs);
 
-        // USES
-        final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
-        for (UsesNodeBuilder builder : addedUsesNodes) {
-            usesNodeDefs.add(builder.build());
-        }
-        instance.setUses(usesNodeDefs);
+            // USES
+            final Set<UsesNode> usesNodeDefs = new HashSet<UsesNode>();
+            for (UsesNodeBuilder builder : addedUsesNodes) {
+                usesNodeDefs.add(builder.build());
+            }
+            instance.setUses(usesNodeDefs);
 
-        // GROUPINGS
-        final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-        for (GroupingBuilder builder : groupings) {
-            groupingDefs.add(builder.build());
-        }
-        instance.setGroupings(groupingDefs);
+            // GROUPINGS
+            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
+            for (GroupingBuilder builder : groupings) {
+                groupingDefs.add(builder.build());
+            }
+            instance.setGroupings(groupingDefs);
 
-        // AUGMENTATIONS
-        final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
-        for (AugmentationSchemaBuilder builder : addedAugmentations) {
-            augmentations.add(builder.build());
-        }
-        instance.setAvailableAugmentations(augmentations);
+            // AUGMENTATIONS
+            final Set<AugmentationSchema> augmentations = new HashSet<AugmentationSchema>();
+            for (AugmentationSchemaBuilder builder : addedAugmentations) {
+                augmentations.add(builder.build());
+            }
+            instance.setAvailableAugmentations(augmentations);
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
-        }
-        instance.setUnknownSchemaNodes(unknownNodes);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
-        instance.setConstraints(constraints.build());
-        instance.setAvailableAugmentations(augmentations);
+            instance.setConstraints(constraints.build());
+            instance.setAvailableAugmentations(augmentations);
 
+            built = true;
+        }
         return instance;
     }
 
index f88e8d1..740f399 100644 (file)
@@ -555,7 +555,7 @@ public class ModuleBuilder implements Builder {
                 .get(pathToAnyXml);
         if (parent != null) {
             if (parent instanceof AugmentationSchemaBuilder) {
-                throw new UnsupportedOperationException(
+                throw new YangParseException(
                         "An anyxml node cannot be augmented.");
             }
             parent.addChildNode(builder);
@@ -646,9 +646,11 @@ public class ModuleBuilder implements Builder {
         Builder builder = moduleNodes.get(parentPath);
         // current api did not support adding config to deviate
         if (!(builder instanceof DeviationBuilder)) {
-            DataSchemaNodeBuilder configBuilder = (DataSchemaNodeBuilder) moduleNodes
-                    .get(parentPath);
-            configBuilder.setConfiguration(configuration);
+            if(builder instanceof RefineHolder) {
+                ((RefineHolder)builder).setConfig(configuration);
+            } else {
+                ((DataSchemaNodeBuilder)builder).setConfiguration(configuration);
+            }
         }
     }
 
index fda7dc7..3e9b930 100644 (file)
@@ -35,6 +35,7 @@ import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 
 public class NotificationBuilder extends AbstractChildNodeBuilder implements
         TypeDefinitionAwareBuilder, SchemaNodeBuilder {
+    private boolean built;
     private final NotificationDefinitionImpl instance;
     private final int line;
     private SchemaPath schemaPath;
@@ -50,42 +51,46 @@ public class NotificationBuilder extends AbstractChildNodeBuilder implements
 
     @Override
     public SchemaNode build() {
-        instance.setPath(schemaPath);
+        if(!built) {
+            instance.setPath(schemaPath);
 
-        // CHILD NODES
-        final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
-        for (DataSchemaNodeBuilder node : childNodes) {
-            childs.put(node.getQName(), node.build());
-        }
-        instance.setChildNodes(childs);
+            // CHILD NODES
+            final Map<QName, DataSchemaNode> childs = new HashMap<QName, DataSchemaNode>();
+            for (DataSchemaNodeBuilder node : childNodes) {
+                childs.put(node.getQName(), node.build());
+            }
+            instance.setChildNodes(childs);
 
-        // GROUPINGS
-        final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
-        for (GroupingBuilder builder : groupings) {
-            groupingDefs.add(builder.build());
-        }
-        instance.setGroupings(groupingDefs);
+            // GROUPINGS
+            final Set<GroupingDefinition> groupingDefs = new HashSet<GroupingDefinition>();
+            for (GroupingBuilder builder : groupings) {
+                groupingDefs.add(builder.build());
+            }
+            instance.setGroupings(groupingDefs);
 
-        // TYPEDEFS
-        final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-        for (TypeDefinitionBuilder entry : addedTypedefs) {
-            typedefs.add(entry.build());
-        }
-        instance.setTypeDefinitions(typedefs);
+            // TYPEDEFS
+            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
+            for (TypeDefinitionBuilder entry : addedTypedefs) {
+                typedefs.add(entry.build());
+            }
+            instance.setTypeDefinitions(typedefs);
 
-        // USES
-        final Set<UsesNode> uses = new HashSet<UsesNode>();
-        for (UsesNodeBuilder builder : addedUsesNodes) {
-            uses.add(builder.build());
-        }
-        instance.setUses(uses);
+            // USES
+            final Set<UsesNode> uses = new HashSet<UsesNode>();
+            for (UsesNodeBuilder builder : addedUsesNodes) {
+                uses.add(builder.build());
+            }
+            instance.setUses(uses);
+
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
+            built = true;
         }
-        instance.setUnknownSchemaNodes(unknownNodes);
 
         return instance;
     }
index ac25f9b..003ccce 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.controller.yang.parser.builder.api.TypeDefinitionBuilder
 
 public class RpcDefinitionBuilder implements SchemaNodeBuilder,
         TypeDefinitionAwareBuilder {
+    private boolean built;
     private final RpcDefinitionImpl instance;
     private final int line;
     private final QName qname;
@@ -46,34 +47,37 @@ public class RpcDefinitionBuilder implements SchemaNodeBuilder,
 
     @Override
     public RpcDefinition build() {
-        final ContainerSchemaNode input = inputBuilder.build();
-        final ContainerSchemaNode output = outputBuilder.build();
-        instance.setInput(input);
-        instance.setOutput(output);
-
-        instance.setPath(schemaPath);
+        if(!built) {
+            final ContainerSchemaNode input = inputBuilder.build();
+            final ContainerSchemaNode output = outputBuilder.build();
+            instance.setInput(input);
+            instance.setOutput(output);
+
+            instance.setPath(schemaPath);
+
+            // TYPEDEFS
+            final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
+            for (TypeDefinitionBuilder entry : addedTypedefs) {
+                typedefs.add(entry.build());
+            }
+            instance.setTypeDefinitions(typedefs);
 
-        // TYPEDEFS
-        final Set<TypeDefinition<?>> typedefs = new HashSet<TypeDefinition<?>>();
-        for (TypeDefinitionBuilder entry : addedTypedefs) {
-            typedefs.add(entry.build());
-        }
-        instance.setTypeDefinitions(typedefs);
+            // GROUPINGS
+            final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
+            for (GroupingBuilder entry : addedGroupings) {
+                groupings.add(entry.build());
+            }
+            instance.setGroupings(groupings);
 
-        // GROUPINGS
-        final Set<GroupingDefinition> groupings = new HashSet<GroupingDefinition>();
-        for (GroupingBuilder entry : addedGroupings) {
-            groupings.add(entry.build());
-        }
-        instance.setGroupings(groupings);
+            // UNKNOWN NODES
+            final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
+            for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
+                unknownNodes.add(b.build());
+            }
+            instance.setUnknownSchemaNodes(unknownNodes);
 
-        // UNKNOWN NODES
-        final List<UnknownSchemaNode> unknownNodes = new ArrayList<UnknownSchemaNode>();
-        for (UnknownSchemaNodeBuilder b : addedUnknownNodes) {
-            unknownNodes.add(b.build());
+            built = true;
         }
-        instance.setUnknownSchemaNodes(unknownNodes);
-
         return instance;
     }
 
index c54a0dc..0534f9d 100644 (file)
@@ -26,6 +26,7 @@ import org.opendaylight.controller.yang.parser.builder.api.UsesNodeBuilder;
 import org.opendaylight.controller.yang.parser.util.RefineHolder;\r
 \r
 final class UsesNodeBuilderImpl implements UsesNodeBuilder {\r
+    private boolean built;\r
     private final UsesNodeImpl instance;\r
     private final int line;\r
     private final SchemaPath groupingPath;\r
@@ -41,21 +42,24 @@ final class UsesNodeBuilderImpl implements UsesNodeBuilder {
 \r
     @Override\r
     public UsesNode build() {\r
-        // AUGMENTATIONS\r
-        final Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();\r
-        for (AugmentationSchemaBuilder builder : addedAugments) {\r
-            augments.add(builder.build());\r
-        }\r
-        instance.setAugmentations(augments);\r
+        if(!built) {\r
+            // AUGMENTATIONS\r
+            final Set<AugmentationSchema> augments = new HashSet<AugmentationSchema>();\r
+            for (AugmentationSchemaBuilder builder : addedAugments) {\r
+                augments.add(builder.build());\r
+            }\r
+            instance.setAugmentations(augments);\r
 \r
-        // REFINES\r
-        final Map<SchemaPath, SchemaNode> refineNodes = new HashMap<SchemaPath, SchemaNode>();\r
-        for (SchemaNodeBuilder refineBuilder : refineBuilders) {\r
-            SchemaNode refineNode = refineBuilder.build();\r
-            refineNodes.put(refineNode.getPath(), refineNode);\r
-        }\r
-        instance.setRefines(refineNodes);\r
+            // REFINES\r
+            final Map<SchemaPath, SchemaNode> refineNodes = new HashMap<SchemaPath, SchemaNode>();\r
+            for (SchemaNodeBuilder refineBuilder : refineBuilders) {\r
+                SchemaNode refineNode = refineBuilder.build();\r
+                refineNodes.put(refineNode.getPath(), refineNode);\r
+            }\r
+            instance.setRefines(refineNodes);\r
 \r
+            built = true;\r
+        }\r
         return instance;\r
     }\r
 \r
diff --git a/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java b/opendaylight/sal/yang-prototype/code-generator/yang-model-parser-impl/src/main/java/org/opendaylight/controller/yang/parser/impl/SchemaContextImpl.java
new file mode 100644 (file)
index 0000000..1a71abf
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2013 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.controller.yang.parser.impl;
+
+import java.net.URI;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Set;
+
+import org.opendaylight.controller.yang.model.api.DataSchemaNode;
+import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
+import org.opendaylight.controller.yang.model.api.Module;
+import org.opendaylight.controller.yang.model.api.NotificationDefinition;
+import org.opendaylight.controller.yang.model.api.RpcDefinition;
+import org.opendaylight.controller.yang.model.api.SchemaContext;
+
+final class SchemaContextImpl implements SchemaContext {
+    private final Set<Module> modules;
+
+    SchemaContextImpl(final Set<Module> modules) {
+        this.modules = modules;
+    }
+
+    @Override
+    public Set<DataSchemaNode> getDataDefinitions() {
+        final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
+        for (Module m : modules) {
+            dataDefs.addAll(m.getChildNodes());
+        }
+        return dataDefs;
+    }
+
+    @Override
+    public Set<Module> getModules() {
+        return modules;
+    }
+
+    @Override
+    public Set<NotificationDefinition> getNotifications() {
+        final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
+        for (Module m : modules) {
+            notifications.addAll(m.getNotifications());
+        }
+        return notifications;
+    }
+
+    @Override
+    public Set<RpcDefinition> getOperations() {
+        final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
+        for (Module m : modules) {
+            rpcs.addAll(m.getRpcs());
+        }
+        return rpcs;
+    }
+
+    @Override
+    public Set<ExtensionDefinition> getExtensions() {
+        final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
+        for (Module m : modules) {
+            extensions.addAll(m.getExtensionSchemaNodes());
+        }
+        return extensions;
+    }
+
+    @Override
+    public Module findModuleByName(final String name, final Date revision) {
+        if (name != null) {
+            for (final Module module : modules) {
+                if (revision == null) {
+                    if (module.getName().equals(name)) {
+                        return module;
+                    }
+                } else if (module.getName().equals(name)
+                        && module.getRevision().equals(revision)) {
+                    return module;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    public Module findModuleByNamespace(final URI namespace) {
+        if (namespace != null) {
+            for (final Module module : modules) {
+                if (module.getNamespace().equals(namespace)) {
+                    return module;
+                }
+            }
+        }
+        return null;
+    }
+
+}
index 41392b0..85ca367 100644 (file)
@@ -12,7 +12,6 @@ import java.io.FileInputStream;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
-import java.net.URI;
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.Date;
@@ -34,13 +33,8 @@ import org.antlr.v4.runtime.tree.ParseTreeWalker;
 import org.opendaylight.controller.antlrv4.code.gen.YangLexer;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser;
 import org.opendaylight.controller.yang.common.QName;
-import org.opendaylight.controller.yang.model.api.DataSchemaNode;
-import org.opendaylight.controller.yang.model.api.ExtensionDefinition;
 import org.opendaylight.controller.yang.model.api.Module;
 import org.opendaylight.controller.yang.model.api.ModuleImport;
-import org.opendaylight.controller.yang.model.api.MustDefinition;
-import org.opendaylight.controller.yang.model.api.NotificationDefinition;
-import org.opendaylight.controller.yang.model.api.RpcDefinition;
 import org.opendaylight.controller.yang.model.api.SchemaContext;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
@@ -123,7 +117,8 @@ public class YangParserImpl implements YangModelParser {
 
     private Map<String, TreeMap<Date, ModuleBuilder>> resolveModuleBuilders(
             final List<InputStream> yangFileStreams) {
-        //Linked Hash Map MUST be used because Linked Hash Map preserves ORDER of items stored in map.
+        // Linked Hash Map MUST be used because Linked Hash Map preserves ORDER
+        // of items stored in map.
         final Map<String, TreeMap<Date, ModuleBuilder>> modules = new LinkedHashMap<String, TreeMap<Date, ModuleBuilder>>();
         final ParseTreeWalker walker = new ParseTreeWalker();
         final List<ParseTree> trees = parseStreams(yangFileStreams);
@@ -141,7 +136,7 @@ public class YangParserImpl implements YangModelParser {
 
         // module dependency graph sorted
         List<ModuleBuilder> sorted = ModuleDependencySort.sort(builders);
-        
+
         for (ModuleBuilder builder : sorted) {
             final String builderName = builder.getName();
             Date builderRevision = builder.getRevision();
@@ -195,7 +190,8 @@ public class YangParserImpl implements YangModelParser {
         resolveAugments(modules);
 
         // build
-        // Linked Hash Set MUST be used otherwise the Set will not maintain order!
+        // Linked Hash Set MUST be used otherwise the Set will not maintain
+        // order!
         // http://docs.oracle.com/javase/6/docs/api/java/util/LinkedHashSet.html
         final Set<Module> result = new LinkedHashSet<Module>();
         for (Map.Entry<String, TreeMap<Date, ModuleBuilder>> entry : modules
@@ -224,7 +220,7 @@ public class YangParserImpl implements YangModelParser {
     /**
      * Search for dirty nodes (node which contains UnknownType) and resolve
      * unknown types.
-     * 
+     *
      * @param modules
      *            all available modules
      * @param module
@@ -544,38 +540,36 @@ public class YangParserImpl implements YangModelParser {
     }
 
     /**
-     * Go through all typedef statements from given module and search for one
-     * with given name
-     * 
-     * @param typedefs
-     *            typedef statements to search
+     * Search for type definition builder by name.
+     *
+     * @param dependentModule
+     *            module to search
      * @param name
-     *            name of searched typedef
-     * @return typedef with name equals to given name
+     *            name of type definition
+     * @param currentModuleName
+     *            current module name
+     * @param line
+     *            current line in yang model
+     * @return
      */
     private TypeDefinitionBuilder findTypedefBuilderByName(
             final ModuleBuilder dependentModule, final String name,
             final String currentModuleName, final int line) {
-        TypeDefinitionBuilder result = null;
         final Set<TypeDefinitionBuilder> typedefs = dependentModule
                 .getModuleTypedefs();
         for (TypeDefinitionBuilder td : typedefs) {
             if (td.getQName().getLocalName().equals(name)) {
-                result = td;
-                break;
+                return td;
             }
         }
-        if (result == null) {
-            throw new YangParseException(currentModuleName, line,
-                    "Target module '" + dependentModule.getName()
-                            + "' does not contain typedef '" + name + "'.");
-        }
-        return result;
+        throw new YangParseException(currentModuleName, line, "Target module '"
+                + dependentModule.getName() + "' does not contain typedef '"
+                + name + "'.");
     }
 
     /**
      * Pull restriction from referenced type and add them to given constraints
-     * 
+     *
      * @param referencedType
      * @param constraints
      */
@@ -603,9 +597,9 @@ public class YangParserImpl implements YangModelParser {
     }
 
     /**
-     * Go through all augmentation definitions and resolve them. This method
-     * also finds referenced node and add child nodes to it.
-     * 
+     * Go through all augment definitions and resolve them. This method also
+     * finds augment target node and add child nodes to it.
+     *
      * @param modules
      *            all available modules
      */
@@ -648,7 +642,7 @@ public class YangParserImpl implements YangModelParser {
     }
 
     /**
-     * 
+     *
      * @param modules
      *            all available modules
      * @param module
@@ -666,8 +660,7 @@ public class YangParserImpl implements YangModelParser {
                             .getTargetPath();
                     final List<QName> path = augmentTargetSchemaPath.getPath();
 
-                    int i = 0;
-                    final QName qname = path.get(i);
+                    final QName qname = path.get(0);
                     String prefix = qname.getPrefix();
                     if (prefix == null) {
                         prefix = module.getPrefix();
@@ -682,12 +675,11 @@ public class YangParserImpl implements YangModelParser {
                         if (childQName.getLocalName().equals(
                                 qname.getLocalName())) {
                             currentParent = child;
-                            i++;
                             break;
                         }
                     }
 
-                    for (; i < path.size(); i++) {
+                    for (int i = 1; i < path.size(); i++) {
                         final QName currentQName = path.get(i);
                         DataSchemaNodeBuilder newParent = null;
                         for (DataSchemaNodeBuilder child : ((ChildNodeBuilder) currentParent)
@@ -730,7 +722,7 @@ public class YangParserImpl implements YangModelParser {
     /**
      * Go through identity statements defined in current module and resolve
      * their 'base' statement if present.
-     * 
+     *
      * @param modules
      *            all modules
      * @param module
@@ -772,7 +764,7 @@ public class YangParserImpl implements YangModelParser {
     /**
      * Go through uses statements defined in current module and resolve their
      * refine statements.
-     * 
+     *
      * @param modules
      *            all modules
      * @param module
@@ -787,120 +779,52 @@ public class YangParserImpl implements YangModelParser {
                 .entrySet()) {
             final List<String> key = entry.getKey();
             final UsesNodeBuilder usesNode = entry.getValue();
+            final int line = usesNode.getLine();
 
             final String groupingName = key.get(key.size() - 1);
 
             for (RefineHolder refine : usesNode.getRefines()) {
-                // refine statements
-                final String defaultStr = refine.getDefaultStr();
-                final Boolean mandatory = refine.isMandatory();
-                final MustDefinition must = refine.getMust();
-                final Boolean presence = refine.isPresence();
-                final Integer min = refine.getMinElements();
-                final Integer max = refine.getMaxElements();
-                final List<UnknownSchemaNodeBuilder> unknownNodes = refine
-                        .getUnknownNodes();
-
-                Builder refineTarget = getRefineTargetBuilder(groupingName,
+                Builder refineTarget = getRefineNodeBuilderCopy(groupingName,
                         refine, modules, module);
+                ParserUtils.refineDefault(refineTarget, refine, line);
                 if (refineTarget instanceof LeafSchemaNodeBuilder) {
                     final LeafSchemaNodeBuilder leaf = (LeafSchemaNodeBuilder) refineTarget;
-                    if (defaultStr != null && !("".equals(defaultStr))) {
-                        leaf.setDefaultStr(defaultStr);
-                    }
-                    if (mandatory != null) {
-                        leaf.getConstraints().setMandatory(mandatory);
-                    }
-                    if (must != null) {
-                        leaf.getConstraints().addMustDefinition(must);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            leaf.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineLeaf(leaf, refine, line);
                     usesNode.addRefineNode(leaf);
                 } else if (refineTarget instanceof ContainerSchemaNodeBuilder) {
                     final ContainerSchemaNodeBuilder container = (ContainerSchemaNodeBuilder) refineTarget;
-                    if (presence != null) {
-                        container.setPresence(presence);
-                    }
-                    if (must != null) {
-                        container.getConstraints().addMustDefinition(must);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            container.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineContainer(container, refine, line);
                     usesNode.addRefineNode(container);
                 } else if (refineTarget instanceof ListSchemaNodeBuilder) {
                     final ListSchemaNodeBuilder list = (ListSchemaNodeBuilder) refineTarget;
-                    if (must != null) {
-                        list.getConstraints().addMustDefinition(must);
-                    }
-                    if (min != null) {
-                        list.getConstraints().setMinElements(min);
-                    }
-                    if (max != null) {
-                        list.getConstraints().setMaxElements(max);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            list.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineList(list, refine, line);
+                    usesNode.addRefineNode(list);
                 } else if (refineTarget instanceof LeafListSchemaNodeBuilder) {
-                    final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) getRefineTargetBuilder(
+                    final LeafListSchemaNodeBuilder leafList = (LeafListSchemaNodeBuilder) getRefineNodeBuilderCopy(
                             groupingName, refine, modules, module);
-                    if (must != null) {
-                        leafList.getConstraints().addMustDefinition(must);
-                    }
-                    if (min != null) {
-                        leafList.getConstraints().setMinElements(min);
-                    }
-                    if (max != null) {
-                        leafList.getConstraints().setMaxElements(max);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            leafList.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineLeafList(leafList, refine, line);
+                    usesNode.addRefineNode(leafList);
                 } else if (refineTarget instanceof ChoiceBuilder) {
                     final ChoiceBuilder choice = (ChoiceBuilder) refineTarget;
-                    if (defaultStr != null) {
-                        choice.setDefaultCase(defaultStr);
-                    }
-                    if (mandatory != null) {
-                        choice.getConstraints().setMandatory(mandatory);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            choice.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineChoice(choice, refine, line);
+                    usesNode.addRefineNode(choice);
                 } else if (refineTarget instanceof AnyXmlBuilder) {
                     final AnyXmlBuilder anyXml = (AnyXmlBuilder) refineTarget;
-                    if (mandatory != null) {
-                        anyXml.getConstraints().setMandatory(mandatory);
-                    }
-                    if (must != null) {
-                        anyXml.getConstraints().addMustDefinition(must);
-                    }
-                    if (unknownNodes != null) {
-                        for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
-                            anyXml.addUnknownSchemaNode(unknown);
-                        }
-                    }
+                    ParserUtils.refineAnyxml(anyXml, refine, line);
+                    usesNode.addRefineNode(anyXml);
                 }
             }
         }
     }
 
     /**
-     * Find original builder of refine node and return copy of this builder.
-     * 
+     * Find original builder of node to refine and return copy of this builder.
+     * <p>
+     * We must make a copy of builder to preserve original builder, because this
+     * object will be refined (modified) and later added to
+     * {@link UsesNodeBuilder}.
+     * </p>
+     *
      * @param groupingPath
      *            path to grouping which contains node to refine
      * @param refine
@@ -909,10 +833,10 @@ public class YangParserImpl implements YangModelParser {
      *            all loaded modules
      * @param module
      *            current module
-     * @return copy of Builder object of node to be refined if it is present in
-     *         grouping, null otherwise
+     * @return copy of node to be refined if it is present in grouping, null
+     *         otherwise
      */
-    private Builder getRefineTargetBuilder(final String groupingPath,
+    private Builder getRefineNodeBuilderCopy(final String groupingPath,
             final RefineHolder refine,
             final Map<String, TreeMap<Date, ModuleBuilder>> modules,
             final ModuleBuilder module) {
@@ -946,7 +870,7 @@ public class YangParserImpl implements YangModelParser {
 
     /**
      * Find builder of refine node.
-     * 
+     *
      * @param groupingPath
      *            path to grouping which contains node to refine
      * @param refineNodeName
@@ -1033,7 +957,7 @@ public class YangParserImpl implements YangModelParser {
 
     /**
      * Find dependent module based on given prefix
-     * 
+     *
      * @param modules
      *            all available modules
      * @param module
@@ -1086,82 +1010,4 @@ public class YangParserImpl implements YangModelParser {
         return dependentModule;
     }
 
-    private static class SchemaContextImpl implements SchemaContext {
-        private final Set<Module> modules;
-
-        private SchemaContextImpl(final Set<Module> modules) {
-            this.modules = modules;
-        }
-
-        @Override
-        public Set<DataSchemaNode> getDataDefinitions() {
-            final Set<DataSchemaNode> dataDefs = new HashSet<DataSchemaNode>();
-            for (Module m : modules) {
-                dataDefs.addAll(m.getChildNodes());
-            }
-            return dataDefs;
-        }
-
-        @Override
-        public Set<Module> getModules() {
-            return modules;
-        }
-
-        @Override
-        public Set<NotificationDefinition> getNotifications() {
-            final Set<NotificationDefinition> notifications = new HashSet<NotificationDefinition>();
-            for (Module m : modules) {
-                notifications.addAll(m.getNotifications());
-            }
-            return notifications;
-        }
-
-        @Override
-        public Set<RpcDefinition> getOperations() {
-            final Set<RpcDefinition> rpcs = new HashSet<RpcDefinition>();
-            for (Module m : modules) {
-                rpcs.addAll(m.getRpcs());
-            }
-            return rpcs;
-        }
-
-        @Override
-        public Set<ExtensionDefinition> getExtensions() {
-            final Set<ExtensionDefinition> extensions = new HashSet<ExtensionDefinition>();
-            for (Module m : modules) {
-                extensions.addAll(m.getExtensionSchemaNodes());
-            }
-            return extensions;
-        }
-
-        @Override
-        public Module findModuleByName(final String name, final Date revision) {
-            if (name != null) {
-                for (final Module module : modules) {
-                    if (revision == null) {
-                        if (module.getName().equals(name)) {
-                            return module;
-                        }
-                    } else if (module.getName().equals(name)
-                            && module.getRevision().equals(revision)) {
-                        return module;
-                    }
-                }
-            }
-            return null;
-        }
-
-        @Override
-        public Module findModuleByNamespace(final URI namespace) {
-            if (namespace != null) {
-                for (final Module module : modules) {
-                    if (module.getNamespace().equals(namespace)) {
-                        return module;
-                    }
-                }
-            }
-            return null;
-        }
-    }
-
 }
index fcc4cd0..4626552 100644 (file)
@@ -409,8 +409,7 @@ public final class YangParserListenerImpl extends YangParserBaseListener {
         QName containerQName = new QName(namespace, revision, yangModelPrefix,
                 containerName);
         ContainerSchemaNodeBuilder containerBuilder = moduleBuilder
-                .addContainerNode(containerQName, actualPath, ctx.getStart()
-                        .getLine());
+                .addContainerNode(containerQName, actualPath, ctx.getStart().getLine());
         updatePath(containerName);
 
         containerBuilder.setPath(createActualSchemaPath(actualPath, namespace,
index c744f1b..c6bbc65 100644 (file)
@@ -17,7 +17,7 @@ import org.opendaylight.controller.yang.model.api.UnknownSchemaNode;
 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition;
 import org.opendaylight.controller.yang.model.api.type.BitsTypeDefinition.Bit;
 
-public final class BitImpl implements BitsTypeDefinition.Bit {
+final class BitImpl implements BitsTypeDefinition.Bit {
     private final Long position;
     private final QName qname;
     private final SchemaPath schemaPath;
index 31f39e3..977b3ff 100644 (file)
@@ -10,15 +10,15 @@ package org.opendaylight.controller.yang.parser.util;
 import org.opendaylight.controller.yang.model.api.MustDefinition;
 import org.opendaylight.controller.yang.model.api.RevisionAwareXPath;
 
-public final class MustDefinitionImpl implements MustDefinition {
+final class MustDefinitionImpl implements MustDefinition {
     private final String mustStr;
     private final String description;
     private final String reference;
     private final String errorAppTag;
     private final String errorMessage;
 
-    public MustDefinitionImpl(String mustStr, String description,
-            String reference, String errorAppTag, String errorMessage) {
+    MustDefinitionImpl(String mustStr, String description, String reference,
+            String errorAppTag, String errorMessage) {
         this.mustStr = mustStr;
         this.description = description;
         this.reference = reference;
index 757c02c..84e0b04 100644 (file)
@@ -7,6 +7,7 @@
  */
 package org.opendaylight.controller.yang.parser.util;
 
+import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -16,6 +17,7 @@ import org.opendaylight.controller.yang.model.api.MustDefinition;
 import org.opendaylight.controller.yang.model.api.SchemaPath;
 import org.opendaylight.controller.yang.model.api.TypeDefinition;
 import org.opendaylight.controller.yang.parser.builder.api.AugmentationSchemaBuilder;
+import org.opendaylight.controller.yang.parser.builder.api.Builder;
 import org.opendaylight.controller.yang.parser.builder.api.ChildNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.DataSchemaNodeBuilder;
 import org.opendaylight.controller.yang.parser.builder.api.GroupingBuilder;
@@ -103,21 +105,206 @@ public final class ParserUtils {
 
     private static void correctPath(final ChildNodeBuilder node,
             final SchemaPath parentSchemaPath) {
-        for(DataSchemaNodeBuilder builder : node.getChildNodes()) {
+        for (DataSchemaNodeBuilder builder : node.getChildNodes()) {
 
             // add correct path
             SchemaPath targetNodeSchemaPath = parentSchemaPath;
-            List<QName> targetNodePath = new ArrayList<QName>(targetNodeSchemaPath.getPath());
+            List<QName> targetNodePath = new ArrayList<QName>(
+                    targetNodeSchemaPath.getPath());
             targetNodePath.add(builder.getQName());
             builder.setPath(new SchemaPath(targetNodePath, true));
 
-            if(builder instanceof ChildNodeBuilder) {
-                ChildNodeBuilder cnb = (ChildNodeBuilder)builder;
+            if (builder instanceof ChildNodeBuilder) {
+                ChildNodeBuilder cnb = (ChildNodeBuilder) builder;
                 correctPath(cnb, builder.getPath());
             }
         }
     }
 
+    public static void refineLeaf(LeafSchemaNodeBuilder leaf,
+            RefineHolder refine, int line) {
+        String defaultStr = refine.getDefaultStr();
+        Boolean mandatory = refine.isMandatory();
+        MustDefinition must = refine.getMust();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (defaultStr != null && !("".equals(defaultStr))) {
+            leaf.setDefaultStr(defaultStr);
+        }
+        if (mandatory != null) {
+            leaf.getConstraints().setMandatory(mandatory);
+        }
+        if (must != null) {
+            leaf.getConstraints().addMustDefinition(must);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                leaf.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineContainer(ContainerSchemaNodeBuilder container,
+            RefineHolder refine, int line) {
+        Boolean presence = refine.isPresence();
+        MustDefinition must = refine.getMust();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (presence != null) {
+            container.setPresence(presence);
+        }
+        if (must != null) {
+            container.getConstraints().addMustDefinition(must);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                container.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineList(ListSchemaNodeBuilder list,
+            RefineHolder refine, int line) {
+        MustDefinition must = refine.getMust();
+        Integer min = refine.getMinElements();
+        Integer max = refine.getMaxElements();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (must != null) {
+            list.getConstraints().addMustDefinition(must);
+        }
+        if (min != null) {
+            list.getConstraints().setMinElements(min);
+        }
+        if (max != null) {
+            list.getConstraints().setMaxElements(max);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                list.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineLeafList(LeafListSchemaNodeBuilder leafList,
+            RefineHolder refine, int line) {
+        MustDefinition must = refine.getMust();
+        Integer min = refine.getMinElements();
+        Integer max = refine.getMaxElements();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (must != null) {
+            leafList.getConstraints().addMustDefinition(must);
+        }
+        if (min != null) {
+            leafList.getConstraints().setMinElements(min);
+        }
+        if (max != null) {
+            leafList.getConstraints().setMaxElements(max);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                leafList.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineChoice(ChoiceBuilder choice, RefineHolder refine,
+            int line) {
+        String defaultStr = refine.getDefaultStr();
+        Boolean mandatory = refine.isMandatory();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (defaultStr != null) {
+            choice.setDefaultCase(defaultStr);
+        }
+        if (mandatory != null) {
+            choice.getConstraints().setMandatory(mandatory);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                choice.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    public static void refineAnyxml(AnyXmlBuilder anyXml, RefineHolder refine,
+            int line) {
+        Boolean mandatory = refine.isMandatory();
+        MustDefinition must = refine.getMust();
+        List<UnknownSchemaNodeBuilder> unknownNodes = refine.getUnknownNodes();
+
+        if (mandatory != null) {
+            anyXml.getConstraints().setMandatory(mandatory);
+        }
+        if (must != null) {
+            anyXml.getConstraints().addMustDefinition(must);
+        }
+        if (unknownNodes != null) {
+            for (UnknownSchemaNodeBuilder unknown : unknownNodes) {
+                anyXml.addUnknownSchemaNode(unknown);
+            }
+        }
+    }
+
+    /**
+     * Perform refine operation of following parameters:
+     * <ul>
+     * <li>description</li>
+     * <li>reference</li>
+     * <li>config</li>
+     * </ul>
+     *
+     * These parameters may be refined for any node.
+     *
+     * @param node
+     *            node to refine
+     * @param refine
+     *            refine holder containing values to refine
+     * @param line
+     *            current line in yang model
+     */
+    public static void refineDefault(Builder node, RefineHolder refine,
+            int line) {
+        Class<? extends Builder> cls = node.getClass();
+
+        String description = refine.getDescription();
+        if (description != null) {
+            try {
+                Method method = cls.getDeclaredMethod("setDescription",
+                        String.class);
+                method.invoke(node, description);
+            } catch (Exception e) {
+                throw new YangParseException(line,
+                        "Cannot refine description in " + cls.getName(), e);
+            }
+        }
+
+        String reference = refine.getReference();
+        if (reference != null) {
+            try {
+                Method method = cls.getDeclaredMethod("setReference",
+                        String.class);
+                method.invoke(node, reference);
+            } catch (Exception e) {
+                throw new YangParseException(line,
+                        "Cannot refine reference in " + cls.getName(), e);
+            }
+        }
+
+        Boolean config = refine.isConfig();
+        if (config != null) {
+            try {
+                Method method = cls.getDeclaredMethod("setConfiguration",
+                        Boolean.TYPE);
+                method.invoke(node, config);
+            } catch (Exception e) {
+                throw new YangParseException(line, "Cannot refine config in "
+                        + cls.getName(), e);
+            }
+        }
+    }
+
     public static LeafSchemaNodeBuilder copyLeafBuilder(
             final LeafSchemaNodeBuilder old) {
         final LeafSchemaNodeBuilder copy = new LeafSchemaNodeBuilder(
@@ -244,7 +431,8 @@ public final class ParserUtils {
     }
 
     public static ChoiceBuilder copyChoiceBuilder(final ChoiceBuilder old) {
-        final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(), old.getLine());
+        final ChoiceBuilder copy = new ChoiceBuilder(old.getQName(),
+                old.getLine());
         copy.setPath(old.getPath());
         copyConstraints(old, copy);
         for (ChoiceCaseBuilder caseBuilder : old.getCases()) {
@@ -272,7 +460,8 @@ public final class ParserUtils {
     }
 
     public static AnyXmlBuilder copyAnyXmlBuilder(final AnyXmlBuilder old) {
-        final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(), old.getLine());
+        final AnyXmlBuilder copy = new AnyXmlBuilder(old.getQName(),
+                old.getLine());
         copy.setPath(old.getPath());
         copyConstraints(old, copy);
         for (UnknownSchemaNodeBuilder unknown : old.getUnknownNodes()) {
index ac3263a..7f74333 100644 (file)
@@ -10,7 +10,7 @@ package org.opendaylight.controller.yang.parser.util;
 /**
  * Marker object representing special 'min' or 'max' values in YANG.
  */
-public final class UnknownBoundaryNumber extends Number {
+final class UnknownBoundaryNumber extends Number {
     private static final long serialVersionUID = 1464861684686434869L;
 
     private final String value;
index 0df5d2c..873e384 100644 (file)
@@ -36,7 +36,9 @@ import org.opendaylight.controller.antlrv4.code.gen.YangParser.Length_stmtContex
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Mandatory_argContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Mandatory_stmtContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Max_elements_stmtContext;
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Max_value_argContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Min_elements_stmtContext;
+import org.opendaylight.controller.antlrv4.code.gen.YangParser.Min_value_argContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Must_stmtContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Numerical_restrictionsContext;
 import org.opendaylight.controller.antlrv4.code.gen.YangParser.Ordered_by_argContext;
@@ -372,6 +374,7 @@ public final class YangModelBuilderUtil {
         }
         if (value < -2147483648 || value > 2147483647) {
             throw new YangParseException(
+                    ctx.getStart().getLine(),
                     "Error on enum '"
                             + name
                             + "': the enum value MUST be in the range from -2147483648 to 2147483647, but was: "
@@ -671,8 +674,8 @@ public final class YangModelBuilderUtil {
             try {
                 result = Long.valueOf(value);
             } catch (NumberFormatException e) {
-                throw new YangParseException("Error on line " + line
-                        + ": Unable to parse range value '" + value + "'.", e);
+                throw new YangParseException(line,
+                        "Unable to parse range value '" + value + "'.", e);
             }
         }
         return result;
@@ -790,7 +793,7 @@ public final class YangModelBuilderUtil {
                 try {
                     result = Integer.valueOf(value);
                 } catch (NumberFormatException e) {
-                    throw new YangParseException(
+                    throw new YangParseException(ctx.getStart().getLine(),
                             "Unable to parse fraction digits value '" + value
                                     + "'.", e);
                 }
@@ -888,6 +891,7 @@ public final class YangModelBuilderUtil {
         }
         if (position < 0 || position > 4294967295L) {
             throw new YangParseException(
+                    ctx.getStart().getLine(),
                     "Error on bit '"
                             + name
                             + "': the position value MUST be in the range 0 to 4294967295");
@@ -1193,10 +1197,10 @@ public final class YangModelBuilderUtil {
         for (int i = 0; i < ctx.getChildCount(); ++i) {
             final ParseTree childNode = ctx.getChild(i);
             if (childNode instanceof Max_elements_stmtContext) {
-                Integer max = Integer.valueOf(stringFromNode(childNode));
-                constraints.setMinElements(max);
+                Integer max = parseMaxElements((Max_elements_stmtContext) childNode);
+                constraints.setMaxElements(max);
             } else if (childNode instanceof Min_elements_stmtContext) {
-                Integer min = Integer.valueOf(stringFromNode(childNode));
+                Integer min = parseMinElements((Min_elements_stmtContext) childNode);
                 constraints.setMinElements(min);
             } else if (childNode instanceof Must_stmtContext) {
                 MustDefinition must = parseMust((Must_stmtContext) childNode);
@@ -1216,6 +1220,44 @@ public final class YangModelBuilderUtil {
         }
     }
 
+    private static Integer parseMinElements(Min_elements_stmtContext ctx) {
+        Integer result = null;
+        try {
+            for (int j = 0; j < ctx.getChildCount(); j++) {
+                ParseTree minArg = ctx.getChild(j);
+                if (minArg instanceof Min_value_argContext) {
+                    result = Integer.valueOf(stringFromNode(minArg));
+                }
+            }
+            if (result == null) {
+                throw new IllegalArgumentException();
+            }
+            return result;
+        } catch (Exception e) {
+            throw new YangParseException(ctx.getStart().getLine(),
+                    "Failed to parse min-elements.", e);
+        }
+    }
+
+    private static Integer parseMaxElements(Max_elements_stmtContext ctx) {
+        Integer result = null;
+        try {
+            for (int j = 0; j < ctx.getChildCount(); j++) {
+                ParseTree maxArg = ctx.getChild(j);
+                if (maxArg instanceof Max_value_argContext) {
+                    result = Integer.valueOf(stringFromNode(maxArg));
+                }
+            }
+            if (result == null) {
+                throw new IllegalArgumentException();
+            }
+            return result;
+        } catch (Exception e) {
+            throw new YangParseException(ctx.getStart().getLine(),
+                    "Failed to parse max-elements.", e);
+        }
+    }
+
     /**
      * Parse given context and return yin value.
      *
@@ -1278,8 +1320,12 @@ public final class YangModelBuilderUtil {
 
     /**
      * Parse refine statement.
-     * @param refineCtx refine statement
-     * @return
+     *
+     * @param refineCtx
+     *            refine statement
+     * @param line
+     *            current line in yang model
+     * @return RefineHolder object representing this refine statement
      */
     public static RefineHolder parseRefine(Refine_stmtContext refineCtx) {
         final String refineTarget = stringFromNode(refineCtx);
@@ -1290,6 +1336,8 @@ public final class YangModelBuilderUtil {
             if (refinePom instanceof Refine_pomContext) {
                 for (int k = 0; k < refinePom.getChildCount(); k++) {
                     ParseTree refineStmt = refinePom.getChild(k);
+                    parseRefineDefault(refine, refineStmt);
+
                     if (refineStmt instanceof Refine_leaf_stmtsContext) {
                         parseRefine(refine,
                                 (Refine_leaf_stmtsContext) refineStmt);
@@ -1315,6 +1363,23 @@ public final class YangModelBuilderUtil {
         return refine;
     }
 
+    private static void parseRefineDefault(RefineHolder refine,
+            ParseTree refineStmt) {
+        for (int i = 0; i < refineStmt.getChildCount(); i++) {
+            ParseTree refineArg = refineStmt.getChild(i);
+            if (refineArg instanceof Description_stmtContext) {
+                String description = stringFromNode(refineArg);
+                refine.setDescription(description);
+            } else if (refineArg instanceof Reference_stmtContext) {
+                String reference = stringFromNode(refineArg);
+                refine.setReference(reference);
+            } else if (refineArg instanceof Config_stmtContext) {
+                boolean config = parseConfig((Config_stmtContext) refineArg);
+                refine.setConfig(config);
+            }
+        }
+    }
+
     private static RefineHolder parseRefine(RefineHolder refine,
             Refine_leaf_stmtsContext refineStmt) {
         for (int i = 0; i < refineStmt.getChildCount(); i++) {
@@ -1362,10 +1427,10 @@ public final class YangModelBuilderUtil {
                 MustDefinition must = parseMust((Must_stmtContext) refineArg);
                 refine.setMust(must);
             } else if (refineArg instanceof Max_elements_stmtContext) {
-                Integer max = Integer.valueOf(stringFromNode(refineArg));
-                refine.setMinElements(max);
+                Integer max = parseMaxElements((Max_elements_stmtContext) refineArg);
+                refine.setMaxElements(max);
             } else if (refineArg instanceof Min_elements_stmtContext) {
-                Integer min = Integer.valueOf(stringFromNode(refineArg));
+                Integer min = parseMinElements((Min_elements_stmtContext) refineArg);
                 refine.setMinElements(min);
             }
         }
@@ -1380,10 +1445,10 @@ public final class YangModelBuilderUtil {
                 MustDefinition must = parseMust((Must_stmtContext) refineArg);
                 refine.setMust(must);
             } else if (refineArg instanceof Max_elements_stmtContext) {
-                Integer max = Integer.valueOf(stringFromNode(refineArg));
-                refine.setMinElements(max);
+                Integer max = parseMaxElements((Max_elements_stmtContext) refineArg);
+                refine.setMaxElements(max);
             } else if (refineArg instanceof Min_elements_stmtContext) {
-                Integer min = Integer.valueOf(stringFromNode(refineArg));
+                Integer min = parseMinElements((Min_elements_stmtContext) refineArg);
                 refine.setMinElements(min);
             }
         }
index 9cbf5b9..fe35899 100644 (file)
@@ -165,8 +165,8 @@ public class YangParserTest {
         assertNull(constraints.getWhenCondition());
         assertEquals(0, constraints.getMustConstraints().size());
         assertFalse(constraints.isMandatory());
-        assertNull(constraints.getMinElements());
-        assertNull(constraints.getMaxElements());
+        assertEquals(1, (int)constraints.getMinElements());
+        assertEquals(11, (int)constraints.getMaxElements());
         // test AugmentationTarget args
         Set<AugmentationSchema> availableAugmentations = ifEntry
                 .getAvailableAugmentations();
@@ -551,25 +551,62 @@ public class YangParserTest {
         assertEquals(1, usesNodes.size());
         UsesNode usesNode = usesNodes.iterator().next();
         Map<SchemaPath, SchemaNode> refines = usesNode.getRefines();
-        assertEquals(2, refines.size());
+        assertEquals(3, refines.size());
 
+        LeafSchemaNode refineLeaf = null;
+        ContainerSchemaNode refineContainer = null;
+        ListSchemaNode refineList = null;
         for (Map.Entry<SchemaPath, SchemaNode> entry : refines.entrySet()) {
             SchemaNode value = entry.getValue();
-
             if (value instanceof LeafSchemaNode) {
-                LeafSchemaNode refineLeaf = (LeafSchemaNode) value;
-                assertNotNull(refineLeaf);
-            } else {
-                ContainerSchemaNode refineContainer = (ContainerSchemaNode) value;
-                Set<MustDefinition> mustConstraints = refineContainer
-                        .getConstraints().getMustConstraints();
-                assertEquals(1, mustConstraints.size());
-                MustDefinition must = mustConstraints.iterator().next();
-                assertEquals("must-condition", must.toString());
-                assertEquals("An error message test", must.getErrorMessage());
-                assertEquals(("An error app tag test"), must.getErrorAppTag());
+                refineLeaf = (LeafSchemaNode) value;
+            } else if(value instanceof ContainerSchemaNode) {
+                refineContainer = (ContainerSchemaNode) value;
+            } else if(value instanceof ListSchemaNode) {
+                refineList = (ListSchemaNode)value;
             }
         }
+
+        // leaf address
+        assertNotNull(refineLeaf);
+        assertEquals("address", refineLeaf.getQName().getLocalName());
+        assertEquals("description of address defined by refine",
+                refineLeaf.getDescription());
+        assertEquals("address reference added by refine",
+                refineLeaf.getReference());
+        assertFalse(refineLeaf.isConfiguration());
+        assertTrue(refineLeaf.getConstraints().isMandatory());
+        Set<MustDefinition> leafMustConstraints = refineLeaf.getConstraints()
+                .getMustConstraints();
+        assertEquals(1, leafMustConstraints.size());
+        MustDefinition leafMust = leafMustConstraints.iterator().next();
+        assertEquals(
+                "\"ifType != 'ethernet' or (ifType = 'ethernet' and ifMTU = 1500)\"",
+                leafMust.toString());
+
+        // container port
+        assertNotNull(refineContainer);
+        Set<MustDefinition> mustConstraints = refineContainer.getConstraints()
+                .getMustConstraints();
+        assertEquals(1, mustConstraints.size());
+        MustDefinition must = mustConstraints.iterator().next();
+        assertEquals("must-condition", must.toString());
+        assertEquals("An error message test", must.getErrorMessage());
+        assertEquals(("An error app tag test"), must.getErrorAppTag());
+        assertEquals("description of port defined by refine",
+                refineContainer.getDescription());
+        assertEquals("port reference added by refine",
+                refineContainer.getReference());
+        assertFalse(refineContainer.isConfiguration());
+        assertTrue(refineContainer.isPresenceContainer());
+
+        // list addresses
+        assertNotNull(refineList);
+        assertEquals("description of addresses defined by refine", refineList.getDescription());
+        assertEquals("addresses reference added by refine", refineList.getReference());
+        assertFalse(refineList.isConfiguration());
+        assertEquals(2, (int)refineList.getConstraints().getMinElements());
+        assertEquals(12, (int)refineList.getConstraints().getMaxElements());
     }
 
     @Test
index 783c89b..a4e5868 100644 (file)
@@ -143,6 +143,13 @@ module types2 {
         container port {
             description "Target port container";
         }
+        
+        list addresses {
+            key "id";
+            leaf id {
+                type int8;
+            }
+        }
     }
 
     container peer {
@@ -150,12 +157,31 @@ module types2 {
             uses target {
                 refine address {
                     default "1.2.3.4";
+                    description "description of address defined by refine";
+                    reference "address reference added by refine";
+                    config false;
+                    mandatory true;
+                    must "ifType != 'ethernet' or " +
+                            "(ifType = 'ethernet' and ifMTU = 1500)" {
+                        error-message "An ethernet MTU must be 1500";
+                    }
                 }
                 refine port {
                     must "must-condition" {
                         error-message "An error message test";
                         error-app-tag "An error app tag test";
                     }
+                    description "description of port defined by refine";
+                    reference "port reference added by refine";
+                    config false;
+                    presence "presence is required";
+                }
+                refine addresses {
+                    description "description of addresses defined by refine";
+                    reference "addresses reference added by refine";
+                    config false;
+                    min-elements 2;
+                    max-elements 12;
                 }
             }
         }
@@ -173,6 +199,9 @@ module types2 {
              leaf ifMtu {
                  type int32;
              }
+             
+             min-elements 1;
+             max-elements 11;
          }
     }