Merge "Added export of augmentation schemas to Binding Context"
authorTony Tkacik <ttkacik@cisco.com>
Tue, 19 Nov 2013 13:56:40 +0000 (13:56 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 19 Nov 2013 13:56:40 +0000 (13:56 +0000)
24 files changed:
code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/BindingGeneratorUtil.java
code-generator/binding-generator-util/src/main/java/org/opendaylight/yangtools/binding/generator/util/Types.java
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BaseTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/BuilderTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/GeneratorUtil.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/AugmentToUsesInAugmentCompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CascadeUsesCompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTest.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/CompilationTestUtils.java
code-generator/binding-java-api-generator/src/test/java/org/opendaylight/yangtools/sal/java/api/generator/test/TypedefCompilationTest.java
code-generator/binding-java-api-generator/src/test/resources/compilation/typedef/foo.yang
code-generator/binding-type-provider/src/main/java/org/opendaylight/yangtools/sal/binding/yang/types/TypeProviderImpl.java
code-generator/maven-sal-api-gen-plugin/pom.xml
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/GeneratorImpl.xtend [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocumentationGeneratorImpl.java [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocGenTest.java [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/resources/doc-gen/network-topology@2013-07-12.yang [new file with mode: 0644]
model/ietf/ietf-topology/pom.xml
pom.xml
src/main/resources/stylesheet.css [new file with mode: 0644]
yang/yang-binding/src/main/java/org/opendaylight/yangtools/yang/binding/InstanceIdentifier.java
yang/yang-model-util/src/main/java/org/opendaylight/yangtools/yang/model/util/Int64.java
yang/yang-parser-impl/src/main/java/org/opendaylight/yangtools/yang/parser/util/ParserListenerUtils.java

index 57e319f5904aacbf7146988bbd99136d40b52742..344d29829dcbfaf399f1a54bca7562aa11e2b0aa 100644 (file)
@@ -26,9 +26,11 @@ import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.model.api.Module;
 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.PatternConstraint;
 import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint;
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition;
 import org.opendaylight.yangtools.yang.model.util.ExtendedType;
 
 /**
@@ -404,9 +406,17 @@ public final class BindingGeneratorUtil {
 
         if (type instanceof ExtendedType) {
             ExtendedType ext = (ExtendedType)type;
+            TypeDefinition<?> base = ext.getBaseType();
             length.addAll(ext.getLengthConstraints());
             pattern.addAll(ext.getPatternConstraints());
             range.addAll(ext.getRangeConstraints());
+
+            if (base instanceof IntegerTypeDefinition && range.isEmpty()) {
+                range.addAll(((IntegerTypeDefinition)base).getRangeConstraints());
+            } else if (base instanceof UnsignedIntegerTypeDefinition && range.isEmpty()) {
+                range.addAll(((UnsignedIntegerTypeDefinition)base).getRangeConstraints());
+            }
+
         }
 
         return new Restrictions() {
index ffcbf175b6314817db87dbcffaf93a4a54c801f0..b658d2f2fa51f5bda45ee330484def38754f59a6 100644 (file)
@@ -30,6 +30,7 @@ public final class Types {
 
     public static final ConcreteType BOOLEAN = typeForClass(Boolean.class);
     public static final ConcreteType FUTURE = typeForClass(Future.class);
+    public static final ConcreteType STRING = typeForClass(String.class);
     public static final ConcreteType VOID = typeForClass(Void.class);
 
     /**
index 532850f37bc10ce9c8ffde1a8c7b8c8e4faf3a2e..f60393221088645894e66227ee46e7e8f0b63766 100644 (file)
@@ -16,36 +16,36 @@ import org.opendaylight.yangtools.sal.binding.model.api.GeneratedTransferObject
 import java.util.Collection
 
 abstract class BaseTemplate {
-    
-    
+
     protected val GeneratedType type;
-    protected val Map<String,String> importMap;
+    protected val Map<String, String> importMap;
     static val paragraphSplitter = Splitter.on("\n\n").omitEmptyStrings();
+
     new(GeneratedType _type) {
-         if (_type== null) {
+        if (_type == null) {
             throw new IllegalArgumentException("Generated type reference cannot be NULL!")
         }
         this.type = _type;
         this.importMap = GeneratorUtil.createImports(type)
     }
-    
-    def packageDefinition () '''package «type.packageName»;'''
 
+    def packageDefinition() '''package «type.packageName»;'''
 
     protected def getFullyQualifiedName() {
         return type.fullyQualifiedName
     }
-    
-    final public def generate() {
-    val _body = body()
-    '''
-    «packageDefinition»
-    «imports»
 
-    «_body»
-    '''.toString
+    final public def generate() {
+        val _body = body()
+        '''
+            «packageDefinition»
+            «imports»
+            
+            «_body»
+        '''.toString
     }
-    protected def imports()  ''' 
+
+    protected def imports() ''' 
         «IF !importMap.empty»
             «FOR entry : importMap.entrySet»
                 «IF entry.value != fullyQualifiedName»
@@ -53,16 +53,14 @@ abstract class BaseTemplate {
                 «ENDIF»
             «ENDFOR»
         «ENDIF»
-
+        
     '''
 
     protected abstract def CharSequence body();
 
     // Helper patterns
-
     final protected def fieldName(GeneratedProperty property) '''_«property.name»'''
 
-
     final protected def propertyNameFromGetter(MethodSignature getter) {
         var int prefix;
         if (getter.name.startsWith("is")) {
@@ -83,18 +81,18 @@ abstract class BaseTemplate {
      * @return string with the getter method source code in JAVA format 
      */
     final protected def getterMethod(GeneratedProperty field) {
-    '''
-        public «field.returnType.importedName» «field.getterMethodName»() {
-            return «field.fieldName»;
-        }
-    '''
+        '''
+            public «field.returnType.importedName» «field.getterMethodName»() {
+                return «field.fieldName»;
+            }
+        '''
     }
 
     final protected def getterMethodName(GeneratedProperty field) {
         val prefix = if(field.returnType.equals(Types.BOOLEAN)) "is" else "get"
         return '''«prefix»«field.name.toFirstUpper»'''
     }
-    
+
     /**
      * Template method which generates the setter method for <code>field</code>
      * 
@@ -109,16 +107,16 @@ abstract class BaseTemplate {
             return this;
         }
     '''
-    
+
     final protected def importedName(Type intype) {
         GeneratorUtil.putTypeIntoImports(type, intype, importMap);
         GeneratorUtil.getExplicitType(type, intype, importMap)
     }
-    
+
     final protected def importedName(Class<?> cls) {
         importedName(Types.typeForClass(cls))
     }
-    
+
     /**
      * Template method which generates method parameters with their types from <code>parameters</code>.
      * 
@@ -126,9 +124,9 @@ abstract class BaseTemplate {
      * group of generated property instances which are transformed to the method parameters
      * @return string with the list of the method parameters with their types in JAVA format
      */
-    def final protected asArgumentsDeclaration(Iterable<GeneratedProperty> parameters) 
-    '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.returnType.importedName» «parameter.fieldName»«ENDFOR»«ENDIF»'''
-    
+    def final protected asArgumentsDeclaration(Iterable<GeneratedProperty> parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.
+        returnType.importedName» «parameter.fieldName»«ENDFOR»«ENDIF»'''
+
     /**
      * Template method which generates sequence of the names of the class attributes from <code>parameters</code>.
      * 
@@ -136,67 +134,64 @@ abstract class BaseTemplate {
      * group of generated property instances which are transformed to the sequence of parameter names
      * @return string with the list of the parameter names of the <code>parameters</code> 
      */
-    def final protected asArguments(Iterable<GeneratedProperty> parameters) 
-    '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.fieldName»«ENDFOR»«ENDIF»'''
-    
-    
-        /**
+    def final protected asArguments(Iterable<GeneratedProperty> parameters) '''«IF !parameters.empty»«FOR parameter : parameters SEPARATOR ", "»«parameter.
+        fieldName»«ENDFOR»«ENDIF»'''
+
+    /**
      * Template method which generates JAVA comments.
      * 
      * @param comment string with the comment for whole JAVA class
      * @return string with comment in JAVA format
      */
     def protected CharSequence asJavadoc(String comment) {
-        if (comment==null) return '';
+        if(comment == null) return '';
         val paragraphs = paragraphSplitter.split(comment)
-        
+
         return '''
             /**
               «FOR p : paragraphs SEPARATOR "<p>"»
-              «p»
+                  «p»
               «ENDFOR»
             **/
-            '''
+        '''
     }
 
-    def generateLengthRestrictions(Type type, String paramName, Type returnType) '''
+    def generateRestrictions(Type type, String paramName, Type returnType) '''
         «val boolean isArray = returnType.name.contains("[")»
-        «IF type instanceof ConcreteType»
-            «val restrictions = (type as ConcreteType).restrictions»
-            «IF restrictions !== null && !restrictions.lengthConstraints.empty»
-                «generateLengthRestriction(type, restrictions, paramName, isArray, !(returnType instanceof ConcreteType))»
-            «ENDIF»
-        «ENDIF»
-        «IF type instanceof GeneratedTransferObject»
-            «val restrictions = (type as GeneratedTransferObject).restrictions»
-            «IF restrictions !== null && !restrictions.lengthConstraints.empty»
-                «generateLengthRestriction(type, restrictions, paramName, isArray, !(returnType instanceof ConcreteType))»
-            «ENDIF»
-        «ENDIF»
+        «processRestrictions(type, paramName, returnType, isArray)»
     '''
 
-    def generateLengthRestrictions(GeneratedProperty field, String paramName) '''
+    def generateRestrictions(GeneratedProperty field, String paramName) '''
         «val Type type = field.returnType»
         «IF type instanceof ConcreteType»
-            «val boolean isArray = type.name.contains("[")»
-            «val restrictions = (type as ConcreteType).restrictions»
-            «IF restrictions !== null && !restrictions.lengthConstraints.empty»
-                «generateLengthRestriction(type, restrictions, paramName, isArray, false)»
-            «ENDIF»
+            «processRestrictions(type, paramName, field.returnType, type.name.contains("["))»
+        «ELSEIF type instanceof GeneratedTransferObject»
+            «processRestrictions(type, paramName, field.returnType, isArrayType(type as GeneratedTransferObject))»
         «ENDIF»
-        «IF type instanceof GeneratedTransferObject»
-            «var isArray = isArrayType(type as GeneratedTransferObject)»
-            «val restrictions = (type as GeneratedTransferObject).restrictions»
-            «IF restrictions !== null && !restrictions.lengthConstraints.empty»
-                «generateLengthRestriction(type, restrictions, paramName, isArray, true)»
+    '''
+
+
+    private def processRestrictions(Type type, String paramName, Type returnType, boolean isArray) '''
+        «val restrictions = type.getRestrictions»
+        «IF restrictions !== null»
+            «IF !restrictions.lengthConstraints.empty»
+                «generateLengthRestriction(type, restrictions, paramName, isArray,
+            !(returnType instanceof ConcreteType))»
+            «ENDIF»
+            «IF !restrictions.rangeConstraints.empty &&
+            ("java.lang".equals(returnType.packageName) || "java.math".equals(returnType.packageName))»
+                «generateRangeRestriction(type, returnType, restrictions, paramName,
+            !(returnType instanceof ConcreteType))»
             «ENDIF»
         «ENDIF»
     '''
 
-    def generateLengthRestriction(Type type, Restrictions restrictions, String paramName, boolean isArray, boolean isNestedType) '''
+    def generateLengthRestriction(Type type, Restrictions restrictions, String paramName, boolean isArray,
+        boolean isNestedType) '''
         if («paramName» != null) {
             boolean isValidLength = false;
-            «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>(); 
+            «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.
+            importedName»<>(); 
             «FOR r : restrictions.lengthConstraints»
                 lengthConstraints.add(«Range.importedName».closed(«r.min», «r.max»));
             «ENDFOR»
@@ -214,7 +209,7 @@ abstract class BaseTemplate {
                         if (r.contains(«paramName».length())) {
                     «ENDIF»
                 «ENDIF»
-                    isValidLength = true;
+                isValidLength = true;
                 }
             }
             if (!isValidLength) {
@@ -223,6 +218,32 @@ abstract class BaseTemplate {
         }
     '''
 
+    def generateRangeRestriction(Type type, Type returnType, Restrictions restrictions, String paramName,
+        boolean isNestedType) '''
+        «val javaType = Class.forName(returnType.fullyQualifiedName)»
+        if («paramName» != null) {
+            boolean isValidRange = false;
+            «List.importedName»<«Range.importedName»<«javaType.importedName»>> rangeConstraints = new «ArrayList.
+            importedName»<>(); 
+            «FOR r : restrictions.rangeConstraints»
+                rangeConstraints.add(«Range.importedName».closed(new «javaType.importedName»(«r.min.toQuote»), new «javaType.
+            importedName»(«r.max.toQuote»)));
+            «ENDFOR»
+            for («Range.importedName»<«javaType.importedName»> r : rangeConstraints) {
+                «IF isNestedType»
+                    if (r.contains(«paramName».getValue())) {
+                «ELSE»
+                    if (r.contains(«paramName»)) {
+                «ENDIF»
+                isValidRange = true;
+                }
+            }
+            if (!isValidRange) {
+                throw new IllegalArgumentException("illegal length");
+            }
+        }
+    '''
+
     def GeneratedProperty getPropByName(GeneratedType gt, String name) {
         for (GeneratedProperty prop : gt.properties) {
             if (prop.name.equals(name)) {
@@ -241,6 +262,16 @@ abstract class BaseTemplate {
         return null;
     }
 
+    def getRestrictions(Type type) {
+        var Restrictions restrictions = null
+        if (type instanceof ConcreteType) {
+            restrictions = (type as ConcreteType).restrictions
+        } else if (type instanceof GeneratedTransferObject) {
+            restrictions = (type as GeneratedTransferObject).restrictions
+        }
+        return restrictions
+    }
+
     def boolean isArrayType(GeneratedTransferObject type) {
         var isArray = false
         val GeneratedTransferObject superType = type.findSuperType
@@ -261,4 +292,8 @@ abstract class BaseTemplate {
         return base;
     }
 
+    def String toQuote(Object obj) {
+        return "\"" + obj.toString + "\"";
+    }
+
 }
index 9608aeaa2150a9f93a29cc07e94327c292c7e916..fbe9886d00c375b13ebf9b41cc413a3e50e40833 100644 (file)
@@ -399,7 +399,7 @@ class BuilderTemplate extends BaseTemplate {
     def private generateSetters() '''\r
         «FOR field : properties SEPARATOR '\n'»\r
             public «type.name»«BUILDER» set«field.name.toFirstUpper»(«field.returnType.importedName» value) {\r
-                «generateLengthRestrictions(field, "value")»\r
+                «generateRestrictions(field, "value")»\r
 \r
                 this.«field.fieldName» = value;\r
                 return this;\r
@@ -442,7 +442,6 @@ class BuilderTemplate extends BaseTemplate {
                         «ENDFOR»\r
                     );\r
                     «FOR field : keyProps»\r
-                        «val genProp = getPropByName(allProps, field.name)»\r
                         this.«field.fieldName» = builder.«field.getterMethodName»();\r
                     «ENDFOR»\r
                 } else {\r
index 458b8114e0cba8a59eb790fd8129f1a2147a21a8..de3ceb454dc68a7d78554cad3fffd9ff2ade9734 100644 (file)
@@ -11,6 +11,7 @@ import java.util.ArrayList
 import java.util.Collections\rimport java.util.Arrays
 import org.opendaylight.yangtools.sal.binding.model.api.Restrictions
 import com.google.common.collect.Range
+import java.util.regex.Pattern
 
 /**\r
  * Template for generating JAVA class. \r
@@ -152,7 +153,7 @@ class ClassTemplate extends BaseTemplate {
             super(«parentProperties.asArguments»);\r
         «ENDIF»\r
         «FOR p : allProperties» \r
-            «generateLengthRestrictions(type, p.fieldName.toString, p.returnType)»\r
+            «generateRestrictions(type, p.fieldName.toString, p.returnType)»\r
         «ENDFOR»\r
         «FOR p : properties» \r
             this.«p.fieldName» = «p.fieldName»;\r
@@ -174,7 +175,7 @@ class ClassTemplate extends BaseTemplate {
         «IF false == parentProperties.empty»\r
             super(«parentProperties.asArguments»);\r
         «ENDIF»\r
-            «generateLengthRestrictions(type, property.fieldName.toString, property.returnType)»\r
+            «generateRestrictions(type, property.fieldName.toString, property.returnType)»\r
             this.«property.fieldName» = «property.name»;\r
             «FOR p : other»\r
             this.«p.fieldName» = null;\r
@@ -269,8 +270,8 @@ class ClassTemplate extends BaseTemplate {
                     «val cValue = c.value»\r
                     «IF cValue instanceof List<?>»\r
                         «val cValues = cValue as List<?>»\r
-                        private static final List<Pattern> «Constants.MEMBER_PATTERN_LIST» = new ArrayList<Pattern>();\r
-                        public static final List<String> «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(«\r
+                        private static final «List.importedName»<«Pattern.importedName»> «Constants.MEMBER_PATTERN_LIST» = new «ArrayList.importedName»<«Pattern.importedName»>();\r
+                        public static final «List.importedName»<String> «TypeConstants.PATTERN_CONSTANT_NAME» = «Arrays.importedName».asList(«\r
                         FOR v : cValues SEPARATOR ", "»«\r
                             IF v instanceof String»"«\r
                                 v as String»"«\r
index 9db1ce8540293d662798ab4517ab94b11ab2f7e1..da285e37bec39d80c12000d68d4821e367198ee2 100644 (file)
@@ -60,17 +60,6 @@ public final class GeneratorUtil {
             }
         }
 
-        final List<Constant> constants = genType.getConstantDefinitions();
-        final List<MethodSignature> methods = genType.getMethodDefinitions();
-
-        // CONSTANTS
-        if (constants != null) {
-            for (final Constant constant : constants) {
-                final Type constantType = constant.getType();
-                putTypeIntoImports(genType, constantType, imports);
-            }
-        }
-
         // REGULAR EXPRESSION
         if (genType instanceof GeneratedTransferObject
                 && isConstantInTO(TypeConstants.PATTERN_CONSTANT_NAME, (GeneratedTransferObject) genType)) {
@@ -79,6 +68,7 @@ public final class GeneratorUtil {
             putTypeIntoImports(genType, Types.typeForClass(java.util.ArrayList.class), imports);
         }
 
+        final List<MethodSignature> methods = genType.getMethodDefinitions();
         // METHODS
         if (methods != null) {
             for (final MethodSignature method : methods) {
index 6f0aaae29e9ae7757f7b9040cee11bfd9c2f33ba..833fcab8545be0bc6b3533aafccafda5592bc3e1 100644 (file)
@@ -41,14 +41,14 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest {
 
         // Test if all sources are generated from 'module foo'
         File fooParent = new File(sourcesOutputDir, NS_FOO);
-        testFilesCount(fooParent, 4);
+        assertFilesCount(fooParent, 4);
         assertTrue(new File(fooParent, "IgpLinkAttributes.java").exists());
         assertTrue(new File(fooParent, "Link1.java").exists());
         assertTrue(new File(fooParent, "Link1Builder.java").exists());
 
         // Test if all sources are generated from 'module bar'
         File barParent = new File(sourcesOutputDir, NS_BAR);
-        testFilesCount(barParent, 7);
+        assertFilesCount(barParent, 7);
         assertTrue(new File(barParent, "BarData.java").exists());
         assertTrue(new File(barParent, "NetworkTopology.java").exists());
         assertTrue(new File(barParent, "NetworkTopologyBuilder.java").exists());
@@ -56,22 +56,22 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest {
         assertTrue(new File(barParent, "LinkAttributes.java").exists());
 
         File networkParent = new File(barParent, "network");
-        testFilesCount(networkParent, 1);
+        assertFilesCount(networkParent, 1);
         File topologyParent = new File(networkParent, "topology");
-        testFilesCount(topologyParent, 3);
+        assertFilesCount(topologyParent, 3);
         assertTrue(new File(topologyParent, "Topology.java").exists());
         assertTrue(new File(topologyParent, "TopologyBuilder.java").exists());
         assertTrue(new File(topologyParent, "TopologyKey.java").exists());
 
         File linkParent = new File(barParent, "link");
-        testFilesCount(linkParent, 3);
+        assertFilesCount(linkParent, 3);
         assertTrue(new File(linkParent, "Link.java").exists());
         assertTrue(new File(linkParent, "LinkBuilder.java").exists());
         assertTrue(new File(linkParent, "LinkKey.java").exists());
 
         // Test if all sources are generated from 'module baz'
         File bazParent = new File(sourcesOutputDir, NS_BAZ);
-        testFilesCount(bazParent, 4);
+        assertFilesCount(bazParent, 4);
         assertTrue(new File(bazParent, "IgpLinkAttributes1.java").exists());
         assertTrue(new File(bazParent, "IgpLinkAttributes1Builder.java").exists());
         assertTrue(new File(bazParent, "LinkAttributes.java").exists());
@@ -88,7 +88,7 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest {
 
             Class<?> igpLinkAttributesClass = Class.forName(BASE_PKG
                     + ".urn.opendaylight.foo.rev131008.IgpLinkAttributes", true, loader);
-            testImplementsIfc(link1Class, igpLinkAttributesClass);
+            assertImplementsIfc(link1Class, igpLinkAttributesClass);
         } catch (ClassNotFoundException e) {
             throw new AssertionError("Class for augment wasn't generated");
         }
@@ -101,7 +101,7 @@ public class AugmentToUsesInAugmentCompilationTest extends BaseCompilationTest {
 
             Class<?> linkAttributesClass = Class.forName(BASE_PKG + ".urn.opendaylight.baz.rev131008.LinkAttributes",
                     true, loader);
-            testImplementsIfc(igpLinkAttributes1Class, linkAttributesClass);
+            assertImplementsIfc(igpLinkAttributes1Class, linkAttributesClass);
         } catch (ClassNotFoundException e) {
             throw new AssertionError("Class for augment wasn't generated");
         }
index 06ac678afe5c9a0e00abcbfb5f4579ee24eabfb7..a4f42fe8605c9b74e141ef9d7c671aafc8e5d571 100644 (file)
@@ -43,7 +43,7 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest {
 
         // Test if all sources are generated from module foo
         File parent = new File(sourcesOutputDir, NS_FOO);
-        testFilesCount(parent, 5);
+        assertFilesCount(parent, 5);
         File fooData = new File(parent, "FooData.java");
         File foo_gr1 = new File(parent, "FooGr1.java");
         File nodes = new File(parent, "Nodes.java");
@@ -55,7 +55,7 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest {
 
         // Test if all sources are generated from module bar
         parent = new File(sourcesOutputDir, NS_BAR);
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
         File barGr1 = new File(parent, "BarGr1.java");
         File barGr2 = new File(parent, "BarGr2.java");
         assertTrue(barGr1.exists());
@@ -63,7 +63,7 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest {
 
         // Test if all sources are generated from module baz
         parent = new File(sourcesOutputDir, NS_BAZ);
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         File bazGr1 = new File(parent, "BazGr1.java");
         assertTrue(bazGr1.exists());
 
@@ -81,8 +81,8 @@ public class CascadeUsesCompilationTest extends BaseCompilationTest {
         Class<?> bazGr1Class = Class.forName(BASE_PKG + ".urn.opendaylight.baz.rev131008.BazGr1", true, loader);
 
         // test generated interface from 'container nodes'
-        testImplementsIfc(nodesClass, fooGr1Class);
-        testImplementsIfc(nodesClass, barGr2Class);
+        assertImplementsIfc(nodesClass, fooGr1Class);
+        assertImplementsIfc(nodesClass, barGr2Class);
 
         // test generated builder for 'container nodes'
         assertFalse(nodesBuilderClass.isInterface());
index 1fe839cef992454a545de17ef17b0be9473985d0..3d9ece434ed9f6030ac373489ab94ad755443400 100644 (file)
@@ -64,7 +64,7 @@ public class CompilationTest extends BaseCompilationTest {
         assertTrue(linksBuilder.exists());
         assertTrue(linksKey.exists());
         assertTrue(testData.exists());
-        testFilesCount(parent, 6);
+        assertFilesCount(parent, 6);
 
         parent = new File(sourcesOutputDir, NS_TEST + FS + "links");
         File level = new File(parent, "Level.java");
@@ -81,7 +81,7 @@ public class CompilationTest extends BaseCompilationTest {
         assertTrue(nodeList.exists());
         assertTrue(nodeListBuilder.exists());
         assertTrue(nodesType.exists());
-        testFilesCount(parent, 7);
+        assertFilesCount(parent, 7);
 
         // Test if sources are compilable
         testCompilation(sourcesOutputDir, compiledOutputDir);
@@ -101,7 +101,7 @@ public class CompilationTest extends BaseCompilationTest {
         assertTrue(linksClass.isInterface());
         // TODO: anyxml
         assertEquals(6, linksClass.getDeclaredMethods().length);
-        testImplementsIfc(linksClass, keyArgsClass);
+        assertImplementsIfc(linksClass, keyArgsClass);
 
         // Test list key constructor arguments ordering
         assertContainsConstructor(linksKeyClass, Byte.class, String.class, Integer.class);
@@ -133,77 +133,77 @@ public class CompilationTest extends BaseCompilationTest {
         assertTrue(new File(parent, "OpenObject.java").exists());
         assertTrue(new File(parent, "ExplicitRouteObject.java").exists());
         assertTrue(new File(parent, "PathKeySubobject.java").exists());
-        testFilesCount(parent, 7);
+        assertFilesCount(parent, 7);
 
         parent = new File(parent, "object");
         assertTrue(new File(parent, "Nodes.java").exists());
         assertTrue(new File(parent, "NodesBuilder.java").exists());
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
 
         parent = new File(sourcesOutputDir, NS_FOO + FS + "open");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
 
         parent = new File(parent, "object");
         assertTrue(new File(parent, "Nodes1.java").exists());
         assertTrue(new File(parent, "Nodes1Builder.java").exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
 
         parent = new File(parent, "nodes");
         assertTrue(new File(parent, "Links.java").exists());
         assertTrue(new File(parent, "LinksBuilder.java").exists());
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
 
         parent = new File(sourcesOutputDir, NS_FOO + FS + "explicit");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "route");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "object");
         assertTrue(new File(parent, "Subobjects.java").exists());
         assertTrue(new File(parent, "SubobjectsBuilder.java").exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
 
         parent = new File(parent, "subobjects");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "subobject");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "type");
         assertTrue(new File(parent, "PathKey.java").exists());
         assertTrue(new File(parent, "PathKeyBuilder.java").exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
 
         parent = new File(parent, "path");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "key");
         assertTrue(new File(parent, "PathKey.java").exists());
         assertTrue(new File(parent, "PathKeyBuilder.java").exists());
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
 
         // Test if all sources were generated from 'module bar'
         parent = new File(sourcesOutputDir, NS_BAR);
         assertTrue(new File(parent, "BasicExplicitRouteSubobjects.java").exists());
         assertTrue(new File(parent, "ExplicitRouteSubobjects.java").exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
 
         parent = new File(parent, "basic");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "explicit");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "route");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
 
         parent = new File(parent, "subobjects");
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
         assertTrue(new File(parent, "SubobjectType.java").exists());
 
         parent = new File(parent, "subobject");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
 
         parent = new File(parent, "type");
         assertTrue(new File(parent, "IpPrefix.java").exists());
         assertTrue(new File(parent, "IpPrefixBuilder.java").exists());
         assertTrue(new File(parent, "Label.java").exists());
         assertTrue(new File(parent, "LabelBuilder.java").exists());
-        testFilesCount(parent, 4);
+        assertFilesCount(parent, 4);
 
         // Test if sources are compilable
         testCompilation(sourcesOutputDir, compiledOutputDir);
@@ -235,19 +235,19 @@ public class CompilationTest extends BaseCompilationTest {
         assertTrue(pathAttributes.exists());
         assertTrue(update.exists());
         assertTrue(updateBuilder.exists());
-        testFilesCount(parent, 6);
+        assertFilesCount(parent, 6);
 
         parent = new File(sourcesOutputDir, NS_FOO + FS + "path");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "attributes");
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
         File origin = new File(parent, "Origin.java");
         File originBuilder = new File(parent, "OriginBuilder.java");
         assertTrue(origin.exists());
         assertTrue(originBuilder.exists());
 
         parent = new File(sourcesOutputDir, NS_FOO + FS + "update");
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
         pathAttributes = new File(parent, "PathAttributes.java");
         File pathAttributesBuilder = new File(parent, "PathAttributesBuilder.java");
         assertTrue(pathAttributes.exists());
@@ -261,94 +261,94 @@ public class CompilationTest extends BaseCompilationTest {
         assertTrue(destination.exists());
         assertTrue(pathAttributes1.exists());
         assertTrue(pathAttributes1Builder.exists());
-        testFilesCount(parent, 5);
+        assertFilesCount(parent, 5);
 
         parent = new File(sourcesOutputDir, NS_BAR + FS + "destination");
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
         File destinationType = new File(parent, "DestinationType.java");
         assertTrue(destinationType.exists());
 
         parent = new File(parent, "destination");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "type");
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
         File destinationIpv4 = new File(parent, "DestinationIp.java");
         File destinationIpv4Builder = new File(parent, "DestinationIpBuilder.java");
         assertTrue(destinationIpv4.exists());
         assertTrue(destinationIpv4Builder.exists());
 
         parent = new File(sourcesOutputDir, NS_BAR + FS + "update");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "path");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "attributes");
         File mpUnreachNlri = new File(parent, "MpUnreachNlri.java");
         File mpUnreachNlriBuilder = new File(parent, "MpUnreachNlriBuilder.java");
         assertTrue(mpUnreachNlri.exists());
         assertTrue(mpUnreachNlriBuilder.exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
 
         parent = new File(parent, "mp");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "unreach");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "nlri");
         File withdrawnRoutes = new File(parent, "WithdrawnRoutes.java");
         File withdrawnRoutesBuilder = new File(parent, "WithdrawnRoutesBuilder.java");
         assertTrue(withdrawnRoutes.exists());
         assertTrue(withdrawnRoutesBuilder.exists());
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
 
         // Test if all sources were generated from 'module baz'
         parent = new File(sourcesOutputDir, NS_BAZ);
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
         File linkstateDestination = new File(parent, "LinkstateDestination.java");
         assertTrue(linkstateDestination.exists());
 
         parent = new File(sourcesOutputDir, NS_BAZ + FS + "update");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "path");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "attributes");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "mp");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "unreach");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "nlri");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "withdrawn");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "routes");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "destination");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "type");
         File destinationLinkstate = new File(parent, "DestinationLinkstate.java");
         File destinationLinkstateBuilder = new File(parent, "DestinationLinkstateBuilder.java");
         assertTrue(destinationLinkstate.exists());
         assertTrue(destinationLinkstateBuilder.exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
         parent = new File(parent, "destination");
-        testFilesCount(parent, 1);
+        assertFilesCount(parent, 1);
         parent = new File(parent, "linkstate");
         File links = new File(parent, "Links.java");
         File linksBuilder = new File(parent, "LinksBuilder.java");
         assertTrue(links.exists());
         assertTrue(linksBuilder.exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
         parent = new File(parent, "links");
         File source = new File(parent, "Source.java");
         File sourceBuilder = new File(parent, "SourceBuilder.java");
         assertTrue(source.exists());
         assertTrue(sourceBuilder.exists());
-        testFilesCount(parent, 3);
+        assertFilesCount(parent, 3);
         parent = new File(parent, "source");
         File address = new File(parent, "Address.java");
         File addressBuilder = new File(parent, "AddressBuilder.java");
         assertTrue(address.exists());
         assertTrue(addressBuilder.exists());
-        testFilesCount(parent, 2);
+        assertFilesCount(parent, 2);
 
         // Test if sources are compilable
         testCompilation(sourcesOutputDir, compiledOutputDir);
@@ -371,7 +371,7 @@ public class CompilationTest extends BaseCompilationTest {
         generator.generateToFile(sourcesOutputDir);
 
         File parent = new File(sourcesOutputDir, NS_TEST);
-        testFilesCount(parent, 4);
+        assertFilesCount(parent, 4);
         assertTrue(new File(parent, "TestData.java").exists());
         assertTrue(new File(parent, "Nodes.java").exists());
         assertTrue(new File(parent, "NodesBuilder.java").exists());
@@ -425,13 +425,13 @@ public class CompilationTest extends BaseCompilationTest {
 
         // Test if all sources are generated
         File fooParent = new File(sourcesOutputDir, NS_FOO);
-        testFilesCount(fooParent, 3);
+        assertFilesCount(fooParent, 3);
         assertTrue(new File(fooParent, "FooData.java").exists());
         assertTrue(new File(fooParent, "Nodes.java").exists());
         assertTrue(new File(fooParent, "NodesBuilder.java").exists());
 
         File barParent = new File(sourcesOutputDir, NS_BAR);
-        testFilesCount(barParent, 1);
+        assertFilesCount(barParent, 1);
         assertTrue(new File(barParent, "IdentityClass.java").exists());
 
         // Test if sources are compilable
index c20a52dbb033d4e62766b435d4cb89492651d72b..a9f85265964bfa3148e2ac3de7667930ad8bc66c 100644 (file)
@@ -11,6 +11,7 @@ import static org.junit.Assert.*;
 
 import java.io.File;
 import java.io.FileNotFoundException;
+import java.lang.reflect.Constructor;
 import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 import java.lang.reflect.ParameterizedType;
@@ -54,6 +55,17 @@ public class CompilationTestUtils {
         }
     }
 
+    /**
+     * Asserts that class contains field with fiven name and type.
+     *
+     * @param clazz
+     *            class to test
+     * @param name
+     *            field name
+     * @param type
+     *            field type
+     * @return field with given name if present in class
+     */
     static Field assertContainsField(Class<?> clazz, String name, Class<?> type) {
         try {
             Field f = clazz.getDeclaredField(name);
@@ -64,6 +76,71 @@ public class CompilationTestUtils {
         }
     }
 
+    /**
+     * Asserts that class contains field with given name and value. Method tries
+     * to create new instance of class and get value of field. If class
+     * constructor contains any arguments, class is instantiated with null
+     * values.
+     *
+     * @param clazz
+     *            class to test
+     * @param name
+     *            name of field
+     * @param returnType
+     *            return type of field
+     * @param expectedValue
+     *            expected value of field
+     * @param constructorArgs
+     *            constructor arguments of class to test
+     */
+    static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
+            Class<?>... constructorArgs) {
+        Object[] initargs = null;
+        if (constructorArgs != null && constructorArgs.length > 0) {
+            initargs = new Object[constructorArgs.length];
+            for (int i = 0; i < constructorArgs.length; i++) {
+                initargs[i] = null;
+            }
+        }
+        assertContainsFieldWithValue(clazz, name, returnType, expectedValue, constructorArgs, initargs);
+    }
+
+    /**
+     * Asserts that class contains field with given name, return type and value.
+     *
+     * @param clazz
+     *            class to test
+     * @param name
+     *            name of field
+     * @param returnType
+     *            return type of field
+     * @param expectedValue
+     *            expected value of field
+     * @param constructorArgs
+     *            array of constructor arguments classes
+     * @param initargs
+     *            array of constructor values
+     */
+    static void assertContainsFieldWithValue(Class<?> clazz, String name, Class<?> returnType, Object expectedValue,
+            Class<?>[] constructorArgs, Object... initargs) {
+        Field f = assertContainsField(clazz, name, returnType);
+        try {
+            Constructor<?> c = clazz.getDeclaredConstructor(constructorArgs);
+            Object o = c.newInstance(initargs);
+            assertEquals(expectedValue, f.get(o));
+        } catch (Exception e) {
+            throw new AssertionError("Failed to perform " + name + " field test", e);
+        }
+    }
+
+    /**
+     * Asserts that class contains constructor with parameter types.
+     *
+     * @param clazz
+     *            class to test
+     * @param args
+     *            array of argument classes
+     */
     static void assertContainsConstructor(Class<?> clazz, Class<?>... args) {
         try {
             clazz.getDeclaredConstructor(args);
@@ -73,6 +150,19 @@ public class CompilationTestUtils {
         }
     }
 
+    /**
+     * Asserts that class contains method with given name, return type and
+     * parameter types.
+     *
+     * @param clazz
+     *            class to test
+     * @param returnType
+     *            method return type
+     * @param name
+     *            method name
+     * @param args
+     *            array of parameter type classes
+     */
     static void assertContainsMethod(Class<?> clazz, Class<?> returnType, String name, Class<?>... args) {
         try {
             Method m = clazz.getDeclaredMethod(name, args);
@@ -83,8 +173,19 @@ public class CompilationTestUtils {
         }
     }
 
-    static void assertContainsMethod(Class<?> clazz, String returnTypeStr, String name, ClassLoader loader)
-            throws Exception {
+    /**
+     * Asserts that class contains method with given name and return type.
+     *
+     * @param clazz
+     *            class to test
+     * @param returnTypeStr
+     *            name of method return type
+     * @param name
+     *            method name
+     * @param loader
+     *            current class loader
+     */
+    static void assertContainsMethod(Class<?> clazz, String returnTypeStr, String name, ClassLoader loader) {
         Class<?> returnType;
         try {
             returnType = Class.forName(returnTypeStr, true, loader);
@@ -92,14 +193,16 @@ public class CompilationTestUtils {
             assertEquals(returnType, method.getReturnType());
         } catch (ClassNotFoundException e) {
             throw new AssertionError("Return type of method '" + name + "' not found");
+        } catch (NoSuchMethodException e) {
+            throw new AssertionError("Method " + name + " does not exists in class " + clazz.getSimpleName());
         }
     }
 
     /**
-     * Check for presence of hashCode, equals and toString methods.
+     * Asserts that class containes hashCode, equals and toString methods.
      *
      * @param clazz
-     *            class to check
+     *            class to test
      */
     static void assertContainsDefaultMethods(Class<?> clazz) {
         assertContainsMethod(clazz, Integer.TYPE, "hashCode");
@@ -108,12 +211,12 @@ public class CompilationTestUtils {
     }
 
     /**
-     * Check for presence of 'public static
+     * Asserts that class contains 'public static
      * java.util.List<com.google.common.collect.Range<java.lang.Integer>>
      * getLength()' method.
      *
      * @param clazz
-     *            class to check
+     *            class to test
      */
     static void assertContainsGetLength(Class<?> clazz) {
         try {
@@ -141,18 +244,18 @@ public class CompilationTestUtils {
     }
 
     /**
-     * Test if generated source implements interface.
+     * Asserts that class implements given interface.
      *
-     * @param classToTest
+     * @param clazz
      *            source to test
-     * @param ifcClass
-     *            expected interface type
+     * @param ifc
+     *            expected interface
      */
-    static void testImplementsIfc(Class<?> classToTest, Class<?> ifcClass) {
-        Class<?>[] interfaces = classToTest.getInterfaces();
+    static void assertImplementsIfc(Class<?> clazz, Class<?> ifc) {
+        Class<?>[] interfaces = clazz.getInterfaces();
         List<Class<?>> ifcsList = Arrays.asList(interfaces);
-        if (!ifcsList.contains(ifcClass)) {
-            throw new AssertionError(classToTest + " should implement " + ifcClass);
+        if (!ifcsList.contains(ifc)) {
+            throw new AssertionError(clazz + " should implement " + ifc);
         }
     }
 
@@ -160,31 +263,42 @@ public class CompilationTestUtils {
      * Test if interface generated from augment extends Augmentation interface
      * with correct generic type.
      *
-     * @param classToTest
+     * @param clazz
      *            interface generated from augment
-     * @param genericType
+     * @param genericTypeName
      *            fully qualified name of expected parameter type
      */
-    static void testAugmentation(Class<?> classToTest, String genericType) {
-        final String ifcToImplement = "interface org.opendaylight.yangtools.yang.binding.Augmentation";
-        testImplementParameterizedIfc(classToTest, ifcToImplement, genericType);
+    static void testAugmentation(Class<?> clazz, String genericTypeName) {
+        final String ifcName = "interface org.opendaylight.yangtools.yang.binding.Augmentation";
+        assertImplementsParameterizedIfc(clazz, ifcName, genericTypeName);
     }
 
-    static void testImplementParameterizedIfc(Class<?> classToTest, String ifcToImplement, String genericType) {
-        ParameterizedType augmentation = null;
-        for (java.lang.reflect.Type ifc : classToTest.getGenericInterfaces()) {
+    /**
+     * Asserts that class implements interface with given name and generic type
+     * parameter.
+     *
+     * @param clazz
+     *            class to test
+     * @param ifcName
+     *            name of interface
+     * @param genericTypeName
+     *            name of generic type
+     */
+    static void assertImplementsParameterizedIfc(Class<?> clazz, String ifcName, String genericTypeName) {
+        ParameterizedType ifcType = null;
+        for (java.lang.reflect.Type ifc : clazz.getGenericInterfaces()) {
             if (ifc instanceof ParameterizedType) {
                 ParameterizedType pt = (ParameterizedType) ifc;
-                if (ifcToImplement.equals(pt.getRawType().toString())) {
-                    augmentation = pt;
+                if (ifcName.equals(pt.getRawType().toString())) {
+                    ifcType = pt;
                 }
             }
         }
-        assertNotNull(augmentation);
+        assertNotNull(ifcType);
 
-        java.lang.reflect.Type[] typeArguments = augmentation.getActualTypeArguments();
+        java.lang.reflect.Type[] typeArguments = ifcType.getActualTypeArguments();
         assertEquals(1, typeArguments.length);
-        assertEquals("interface " + genericType, typeArguments[0].toString());
+        assertEquals("interface " + genericTypeName, typeArguments[0].toString());
     }
 
     /**
@@ -205,7 +319,15 @@ public class CompilationTestUtils {
         assertTrue(compiled);
     }
 
-    static void testFilesCount(File dir, int count) {
+    /**
+     * Asserts that directory contains exactly given count of files.
+     *
+     * @param dir
+     *            directory to test
+     * @param count
+     *            expected count of files in directory
+     */
+    static void assertFilesCount(File dir, int count) {
         File[] dirContent = dir.listFiles();
         if (dirContent == null) {
             throw new AssertionError("File " + dir + " doesn't exists or it's not a directory");
index d335633792b5bdf8efed378a40f41e2447413175..5d3029f09e3364e2cc6caad0d4674f13a6ede0c3 100644 (file)
@@ -30,6 +30,7 @@ import org.opendaylight.yangtools.yang.model.api.SchemaContext;
  */
 public class TypedefCompilationTest extends BaseCompilationTest {
     private static final String VAL = "_value";
+    private static final String UNITS = "_UNITS";
 
     @Test
     public void test() throws Exception {
@@ -46,6 +47,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         generator.generateToFile(sourcesOutputDir);
 
         File parent = new File(sourcesOutputDir, NS_FOO);
+        File int32Ext0 = new File(parent, "Int32Ext0.java");
         File int32Ext1 = new File(parent, "Int32Ext1.java");
         File int32Ext2 = new File(parent, "Int32Ext2.java");
         File myDecimalType = new File(parent, "MyDecimalType.java");
@@ -56,6 +58,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         File unionExt2 = new File(parent, "UnionExt2.java");
         File unionExt3 = new File(parent, "UnionExt3.java");
         File unionExt4 = new File(parent, "UnionExt4.java");
+        assertTrue(int32Ext0.exists());
         assertTrue(int32Ext1.exists());
         assertTrue(int32Ext2.exists());
         assertTrue(myDecimalType.exists());
@@ -66,7 +69,7 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertTrue(unionExt2.exists());
         assertTrue(unionExt3.exists());
         assertTrue(unionExt4.exists());
-        testFilesCount(parent, 16);
+        assertFilesCount(parent, 25);
 
         // Test if sources are compilable
         testCompilation(sourcesOutputDir, compiledOutputDir);
@@ -95,12 +98,14 @@ public class TypedefCompilationTest extends BaseCompilationTest {
 
         // typedef int32-ext2
         assertFalse(int32Ext2Class.isInterface());
-        assertEquals(0, int32Ext2Class.getDeclaredFields().length);
+        assertContainsFieldWithValue(int32Ext2Class, UNITS, String.class, "mile", Integer.class);
+        assertEquals(1, int32Ext2Class.getDeclaredFields().length);
         assertContainsConstructor(int32Ext2Class, Integer.class);
         assertContainsConstructor(int32Ext2Class, int32Ext2Class);
         assertContainsConstructor(int32Ext2Class, int32Ext1Class);
         assertEquals(3, int32Ext2Class.getDeclaredConstructors().length);
-        assertEquals(0, int32Ext2Class.getDeclaredMethods().length);
+        assertContainsMethod(int32Ext2Class, String.class, "toString");
+        assertEquals(1, int32Ext2Class.getDeclaredMethods().length);
 
         // typedef string-ext1
         assertFalse(stringExt1Class.isInterface());
@@ -171,7 +176,8 @@ public class TypedefCompilationTest extends BaseCompilationTest {
         assertFalse(unionExt3Class.isInterface());
         assertContainsField(unionExt3Class, "_string", String.class);
         assertContainsField(unionExt3Class, "_unionExt2", unionExt2Class);
-        assertEquals(2, unionExt3Class.getDeclaredFields().length);
+        assertContainsFieldWithValue(unionExt3Class, UNITS, String.class, "object id", String.class);
+        assertEquals(3, unionExt3Class.getDeclaredFields().length);
         assertContainsMethod(unionExt3Class, String.class, "getString");
         assertContainsMethod(unionExt3Class, unionExt2Class, "getUnionExt2");
         assertContainsConstructor(unionExt3Class, String.class);
index 7a43a64458fc0f1d6a47317de4ba1f7cef5a5af0..1cbe5b9d7cf8376574f328edfe667b8b91108df6 100644 (file)
@@ -6,9 +6,13 @@ module foo {
     revision "2013-10-08" {
     }
 
+    typedef int32-ext0 {
+        type int32;
+    }
+
     typedef int32-ext1 {
         type int32 {
-            range "2..20";
+            range "2..2147483647";
         }
     }
 
@@ -63,6 +67,7 @@ module foo {
             type union-ext2;
             type string;
         }
+        units "object id";
     }
 
     typedef union-ext4 {
@@ -94,4 +99,39 @@ module foo {
         }
     }
 
+
+    typedef a {
+        type int8;
+    }
+
+    typedef b {
+        type int16;
+    }
+
+    typedef c {
+        type int32;
+    }
+
+    typedef d {
+        type int64 {
+            range 0..max;
+        }
+    }
+
+    typedef e {
+        type uint8;
+    }
+
+    typedef f {
+        type uint16;
+    }
+
+    typedef g {
+        type uint32;
+    }
+
+    typedef h {
+        type uint64;
+    }
+
 }
index 712d079c32fd60b74f1375533a606e05085f7b9d..5ca744e9093cdc61574a35f8b0696a3f227b36e2 100644 (file)
@@ -25,6 +25,7 @@ import org.opendaylight.yangtools.binding.generator.util.BindingGeneratorUtil;
 import org.opendaylight.yangtools.binding.generator.util.TypeConstants;
 import org.opendaylight.yangtools.binding.generator.util.Types;
 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.EnumerationBuilderImpl;
+import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedPropertyBuilderImpl;
 import org.opendaylight.yangtools.binding.generator.util.generated.type.builder.GeneratedTOBuilderImpl;
 import org.opendaylight.yangtools.sal.binding.generator.spi.TypeProvider;
 import org.opendaylight.yangtools.sal.binding.model.api.ConcreteType;
@@ -617,15 +618,17 @@ public final class TypeProviderImpl implements TypeProvider {
                     final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForUnionTypeDef(basePackageName,
                             (UnionTypeDefinition) innerTypeDefinition, typedefName, typedef);
                     genTOBuilder.setIsUnion(true);
+                    addUnitsToGenTO(genTOBuilder, typedef.getUnits());
                     returnType = genTOBuilder.toInstance();
                 } else if (innerTypeDefinition instanceof EnumTypeDefinition) {
                     final EnumTypeDefinition enumTypeDef = (EnumTypeDefinition) innerTypeDefinition;
+                    // TODO units for typedef enum
                     returnType = provideTypeForEnum(enumTypeDef, typedefName, typedef);
-
                 } else if (innerTypeDefinition instanceof BitsTypeDefinition) {
                     final BitsTypeDefinition bitsTypeDefinition = (BitsTypeDefinition) innerTypeDefinition;
                     final GeneratedTOBuilder genTOBuilder = provideGeneratedTOBuilderForBitsTypeDefinition(
                             basePackageName, bitsTypeDefinition, typedefName);
+                    addUnitsToGenTO(genTOBuilder, typedef.getUnits());
                     returnType = genTOBuilder.toInstance();
                 } else {
                     final Type javaType = BaseYangTypes.BASE_YANG_TYPES_PROVIDER.javaTypeForSchemaDefinitionType(
@@ -657,23 +660,22 @@ public final class TypeProviderImpl implements TypeProvider {
      */
     private GeneratedTransferObject wrapJavaTypeIntoTO(final String basePackageName, final TypeDefinition<?> typedef,
             final Type javaType) {
-        if (javaType != null) {
-            final String propertyName = "value";
-
-            final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
-            genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef));
-            final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
-            genPropBuilder.setReturnType(javaType);
-            genTOBuilder.addEqualsIdentity(genPropBuilder);
-            genTOBuilder.addHashIdentity(genPropBuilder);
-            genTOBuilder.addToStringProperty(genPropBuilder);
-            if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef instanceof ExtendedType) {
-                final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
-                addStringRegExAsConstant(genTOBuilder, regExps);
-            }
-            return genTOBuilder.toInstance();
+        Preconditions.checkNotNull(javaType, "javaType cannot be null");
+        final String propertyName = "value";
+
+        final GeneratedTOBuilder genTOBuilder = typedefToTransferObject(basePackageName, typedef);
+        genTOBuilder.setRestrictions(BindingGeneratorUtil.getRestrictions(typedef));
+        final GeneratedPropertyBuilder genPropBuilder = genTOBuilder.addProperty(propertyName);
+        genPropBuilder.setReturnType(javaType);
+        genTOBuilder.addEqualsIdentity(genPropBuilder);
+        genTOBuilder.addHashIdentity(genPropBuilder);
+        genTOBuilder.addToStringProperty(genPropBuilder);
+        if (javaType instanceof ConcreteType && "String".equals(javaType.getName()) && typedef instanceof ExtendedType) {
+            final List<String> regExps = resolveRegExpressionsFromTypedef((ExtendedType) typedef);
+            addStringRegExAsConstant(genTOBuilder, regExps);
         }
-        return null;
+        addUnitsToGenTO(genTOBuilder, typedef.getUnits());
+        return genTOBuilder.toInstance();
     }
 
     /**
@@ -1105,6 +1107,7 @@ public final class TypeProviderImpl implements TypeProvider {
                 genTOBuilder.setExtendsType((GeneratedTransferObject) type);
             }
         }
+        addUnitsToGenTO(genTOBuilder, typedef.getUnits());
 
         return genTOBuilder.toInstance();
     }
@@ -1199,4 +1202,13 @@ public final class TypeProviderImpl implements TypeProvider {
         }
     }
 
+    private void addUnitsToGenTO(GeneratedTOBuilder to, String units) {
+        if (units != null && !units.isEmpty()) {
+            to.addConstant(Types.STRING, "_UNITS", "\"" + units + "\"");
+            GeneratedPropertyBuilder prop = new GeneratedPropertyBuilderImpl("UNITS");
+            prop.setReturnType(Types.STRING);
+            to.addToStringProperty(prop);
+        }
+    }
+
 }
index 0fa60578607a3b086cc5dfeac658d87aca57dacc..97fe5d27347e6cbf8a9c0152a8d2c33d20b33298 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>binding-java-api-generator</artifactId>
         </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+            <scope>test</scope>
+        </dependency>
     </dependencies>
 
     <build>
                     </instructions>
                 </configuration>
             </plugin>
+            <plugin>
+                <groupId>org.eclipse.xtend</groupId>
+                <artifactId>xtend-maven-plugin</artifactId>
+            </plugin>
+            <plugin>
+                <artifactId>maven-clean-plugin</artifactId>
+            </plugin>
         </plugins>
     </build>
 
diff --git a/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/GeneratorImpl.xtend b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/GeneratorImpl.xtend
new file mode 100644 (file)
index 0000000..78eeaf3
--- /dev/null
@@ -0,0 +1,533 @@
+package org.opendaylight.yangtools.yang.unified.doc.generator
+
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import java.io.File
+import java.util.Set
+import org.opendaylight.yangtools.yang.model.api.Module
+import java.io.IOException
+import java.util.HashSet
+import java.io.FileWriter
+import java.io.BufferedWriter
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.TypeDefinition
+import org.opendaylight.yangtools.yang.model.api.SchemaNode
+import org.opendaylight.yangtools.yang.model.util.ExtendedType
+import org.opendaylight.yangtools.yang.model.api.type.StringTypeDefinition
+import java.text.SimpleDateFormat
+import java.util.Collection
+import org.opendaylight.yangtools.yang.model.api.type.LengthConstraint
+import org.opendaylight.yangtools.yang.model.api.type.BinaryTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.DecimalTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.RangeConstraint
+import org.opendaylight.yangtools.yang.model.api.type.IntegerTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.type.UnsignedIntegerTypeDefinition
+import org.opendaylight.yangtools.yang.model.api.NotificationDefinition
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.slf4j.LoggerFactory
+import org.slf4j.Logger
+import org.opendaylight.yangtools.yang.model.api.AugmentationSchema
+import java.util.List
+import org.opendaylight.yangtools.yang.common.QName
+import org.opendaylight.yangtools.yang.model.api.RpcDefinition
+import org.opendaylight.yangtools.yang.model.api.ExtensionDefinition
+
+class GeneratorImpl {
+
+    File path
+    static val REVISION_FORMAT = new SimpleDateFormat("yyyy-MM-dd")
+    static val Logger LOG = LoggerFactory.getLogger(GeneratorImpl)
+
+
+    def generate(SchemaContext context, File targetPath, Set<Module> modulesToGen) throws IOException {
+        path = targetPath;
+        path.mkdirs();
+        val it = new HashSet;
+        for (module : modulesToGen) {
+            add(module.generateDocumentation());
+        }
+        return it;
+    }
+
+    def generateDocumentation(Module module) {
+        val destination = new File(path, '''«module.name».html''')
+        try {
+            val fw = new FileWriter(destination)
+            destination.createNewFile();
+            val bw = new BufferedWriter(fw)
+
+            bw.append(module.generate);
+            bw.close();
+            fw.close();
+        } catch (IOException e) {
+            LOG.error(e.getMessage());
+        }
+        return destination;
+    }
+
+    def generate(Module module) '''
+        <!DOCTYPE html>
+        <html lang="en">
+          <head>
+            <title>«module.name»</title>
+          </head>
+          <body>
+            «module.body»
+          </body>
+        </html>
+    '''
+
+    def body(Module module) '''
+        «header(module)»
+
+        «typeDefinitions(module)»
+
+        «identities(module)»
+
+        «groupings(module)»
+
+        «dataStore(module)»
+
+        «notifications(module)»
+
+        «augmentations(module)»
+
+        «rpcs(module)»
+
+        «extensions(module)»
+
+        «features(module)»
+
+    '''
+
+
+    def typeDefinitions(Module module) {
+        val Set<TypeDefinition<?>> typedefs = module.typeDefinitions
+        if (typedefs.empty) {
+            return '';
+        }
+        return '''
+            <h2>Type Definitions</h2>
+            <ul>
+            «FOR typedef : typedefs»
+                <li>
+                    «strong("typedef " + typedef.QName.localName)»
+                    <ul>
+                    «typedef.descAndRef»
+                    «typedef.restrictions»
+                    </ul>
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    private def identities(Module module) {
+        if (module.identities.empty) {
+            return '';
+        }
+        return '''
+            <h2>Identities</h2>
+            <ul>
+            «FOR identity : module.identities»
+                <li>
+                    «strong("identity " + identity.QName.localName)»
+                    <ul>
+                    «identity.descAndRef»
+                    «IF identity.baseIdentity != null»
+                        «listItem("base", identity.baseIdentity.QName.localName)»
+                    «ENDIF»
+                    </ul>
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    private def groupings(Module module) {
+        if (module.groupings.empty) {
+            return '';
+        }
+        return '''
+            <h2>Groupings</h2>
+            <ul>
+            «FOR grouping : module.groupings»
+                <li>
+                    «strong("grouping " + grouping.QName.localName)»
+                    <ul>
+                        «grouping.descAndRef»
+                    </ul>
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    def dataStore(Module module) {
+        if (module.childNodes.empty) {
+            return '';
+        }
+        return '''
+            <h2>Datastore Structure</h2>
+            «tree(module)»
+        '''
+    }
+
+    def augmentations(Module module) {
+        if (module.augmentations.empty) {
+            return '';
+        }
+        return '''
+            <h2>Augmentations</h2>
+
+            <ul>
+            «FOR augment : module.augmentations»
+                <li>
+                    augment
+                    «augment.tree»
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    def notifications(Module module) {
+        val Set<NotificationDefinition> notificationdefs = module.notifications
+        if (notificationdefs.empty) {
+            return '';
+        }
+        return '''
+            <h2>Notifications</h2>
+
+            <ul>
+            «FOR notificationdef : notificationdefs»
+                <li>
+                    «notificationdef.nodeName»
+                    «notificationdef.tree»
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    def rpcs(Module module) {
+        if (module.rpcs.empty) {
+            return '';
+        }
+        return '''
+            <h2>RPC Definitions</h2>
+
+            <ul>
+            «FOR rpc : module.rpcs»
+                <li>
+                    «rpc.nodeName»
+                    «rpc.tree»
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    def extensions(Module module) {
+        if (module.extensionSchemaNodes.empty) {
+            return '';
+        }
+        return '''
+            <h2>Extensions</h2>
+
+            <ul>
+            «FOR ext : module.extensionSchemaNodes»
+                <li>
+                    «ext.nodeName»
+                    «ext.tree»
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    def features(Module module) {
+        if (module.features.empty) {
+            return '';
+        }
+        return '''
+            <h2>Features</h2>
+
+            <ul>
+            «FOR feature : module.features»
+                <li>
+                    «strong("feature " + feature.QName.localName)»
+                    <ul>
+                        «feature.descAndRef»
+                    </ul>
+                </li>
+            «ENDFOR»
+            </ul>
+        '''
+    }
+
+    def header(Module module) '''
+        <h1>«module.name»</h1>
+        
+        <h2>Base Information</h2>
+        <dl>
+            <dt>Prefix</dt>
+            <dd>«pre(module.prefix)»</dd>
+            <dt>Namespace</dt>
+            <dd>«pre(module.namespace.toString)»</dd>
+            <dt>Revision</dt>
+            <dd>«pre(REVISION_FORMAT.format(module.revision))»</dd>
+            
+            «FOR imp : module.imports BEFORE "<dt>Imports</dt>" »
+                <dd>«pre(imp.prefix)» = «pre(imp.moduleName)»</dd>
+            «ENDFOR»
+        </dl>
+    '''
+
+    def process(Module module) {
+        throw new UnsupportedOperationException("TODO: auto-generated method stub")
+    }
+
+
+
+    /* #################### TREE STRUCTURE #################### */
+    def dispatch CharSequence tree(Module module) '''
+        «strong("module " + module.name)»
+        «module.childNodes.tree»
+    '''
+
+    def dispatch CharSequence tree(DataNodeContainer node) '''
+        «IF node instanceof SchemaNode»
+            «(node as SchemaNode).nodeName»
+        «ENDIF»
+        «node.childNodes.tree»
+    '''
+
+    def dispatch CharSequence tree(DataSchemaNode node) '''
+        «node.nodeName»
+    '''
+
+    def dispatch CharSequence tree(ListSchemaNode node) '''
+        «node.nodeName»
+        «node.childNodes.tree»
+    '''
+
+    def dispatch CharSequence tree(Collection<DataSchemaNode> childNodes) '''
+        «IF childNodes !== null && !childNodes.empty»
+            <ul>
+            «FOR child : childNodes»
+                <li>
+                    «child.tree»
+                </li>
+            «ENDFOR»
+            </ul>
+        «ENDIF»
+    '''
+
+    def listKeys(ListSchemaNode node) '''
+        [«FOR key : node.keyDefinition SEPARATOR " "»«key.localName»«ENDFOR»]
+    '''
+
+    def dispatch CharSequence tree(AugmentationSchema augment) '''
+        <ul>
+            «listItem(augment.description)»
+            «listItem("Reference", augment.reference)»
+            «IF augment.whenCondition !== null»
+                «listItem("When", augment.whenCondition.toString)»
+            «ENDIF»
+            <li>
+                Path «augment.targetPath.path.pathToTree»
+            </li>
+            <li>
+                Child nodes
+                «augment.childNodes.tree»
+            </li>
+        </ul>
+    '''
+
+    def dispatch CharSequence tree(NotificationDefinition notification) '''
+        <ul>
+            «notification.descAndRef»
+            <li>
+                Child nodes
+                «notification.childNodes.tree»
+            </li>
+        </ul>
+    '''
+
+    def dispatch CharSequence tree(RpcDefinition rpc) '''
+        <ul>
+            «rpc.descAndRef»
+            <li>
+                «rpc.input.tree»
+            </li>
+            <li>
+                «rpc.output.tree»
+            </li>
+        </ul>
+    '''
+
+    def dispatch CharSequence tree(ExtensionDefinition ext) '''
+        <ul>
+            «ext.descAndRef»
+            «listItem("Argument", ext.argument)»
+        </ul>
+    '''
+
+
+
+    /* #################### RESTRICTIONS #################### */
+    private def restrictions(TypeDefinition<?> type) '''
+        «type.toLength»
+        «type.toRange»
+    '''
+
+    def dispatch toLength(TypeDefinition<?> type) {
+    }
+
+    def dispatch toLength(BinaryTypeDefinition type) '''
+        «type.lengthConstraints.toLengthStmt»
+    '''
+
+    def dispatch toLength(StringTypeDefinition type) '''
+        «type.lengthConstraints.toLengthStmt»
+    '''
+
+    def dispatch toLength(ExtendedType type) '''
+        «type.lengthConstraints.toLengthStmt»
+    '''
+
+    def dispatch toRange(TypeDefinition<?> type) {
+    }
+
+    def dispatch toRange(DecimalTypeDefinition type) '''
+        «type.rangeConstraints.toRangeStmt»
+    '''
+
+    def dispatch toRange(IntegerTypeDefinition type) '''
+        «type.rangeConstraints.toRangeStmt»
+    '''
+
+    def dispatch toRange(UnsignedIntegerTypeDefinition type) '''
+        «type.rangeConstraints.toRangeStmt»
+    '''
+
+    def dispatch toRange(ExtendedType type) '''
+        «type.rangeConstraints.toRangeStmt»
+    '''
+
+    def toLengthStmt(Collection<LengthConstraint> lengths) '''
+        «IF lengths != null && !lengths.empty»
+            «listItem("Length restrictions")»
+            <ul>
+            «FOR length : lengths»
+                <li>
+                «IF length.min == length.max»
+                    «length.min»
+                «ELSE»
+                    &lt;«length.min», «length.max»&gt;
+                «ENDIF»
+                </li>
+            «ENDFOR»
+            </ul>
+        «ENDIF»
+    '''
+
+    def toRangeStmt(Collection<RangeConstraint> ranges) '''
+        «IF ranges != null && !ranges.empty»
+            «listItem("Range restrictions")»
+            <ul>
+            «FOR range : ranges»
+                <li>
+                «IF range.min == range.max»
+                    «range.min»
+                «ELSE»
+                    &lt;«range.min», «range.max»&gt;
+                «ENDIF»
+                </li>
+            «ENDFOR»
+            </ul>
+        «ENDIF»
+    '''
+
+
+
+    /* #################### UTILITY #################### */
+    private def strong(String str) '''<strong>«str»</strong>'''
+    private def italic(String str) '''<i>«str»</i>'''
+    private def pre(String str) '''<pre>«str»</pre>'''
+
+    def CharSequence descAndRef(SchemaNode node) '''
+        «listItem(node.description)»
+        «listItem("Reference", node.reference)»
+    '''
+
+    private def listItem(String value) '''
+        «IF value !== null && !value.empty»
+            <li>
+                «value»
+            </li>
+        «ENDIF»
+    '''
+
+    private def listItem(String name, String value) '''
+        «IF value !== null && !value.empty»
+            <li>
+                «name»
+                <ul>
+                    <li>
+                        «value»
+                    </li>
+                </ul>
+            </li>
+        «ENDIF»
+    '''
+
+    private def CharSequence pathToTree(List<QName> path) '''
+        «IF path !== null && !path.empty»
+            <ul>
+            «FOR pathElement : path»
+                <li>
+                    «pathElement.namespace» «pathElement.localName»
+                </li>
+            «ENDFOR»
+            </ul>
+        «ENDIF»
+    '''
+
+    def dispatch addedByInfo(SchemaNode node) '''
+    '''
+
+    def dispatch addedByInfo(DataSchemaNode node) '''
+        «IF node.augmenting»(A)«ENDIF»«IF node.addedByUses»(U)«ENDIF»
+    '''
+
+    def dispatch isAddedBy(SchemaNode node) {
+        return false;
+    }
+
+    def dispatch isAddedBy(DataSchemaNode node) {
+        if (node.augmenting || node.addedByUses) {
+            return true
+        } else {
+            return false;
+        }
+    }
+
+    def dispatch nodeName(SchemaNode node) '''
+        «IF node.isAddedBy»
+            «italic(node.QName.localName)»«node.addedByInfo»
+        «ELSE»
+            «strong(node.QName.localName)»«node.addedByInfo»
+        «ENDIF»
+    '''
+
+    def dispatch nodeName(ListSchemaNode node) '''
+        «IF node.isAddedBy»
+            «italic(node.QName.localName)» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF»«node.addedByInfo»
+        «ELSE»
+            «strong(node.QName.localName)» «IF node.keyDefinition !== null && !node.keyDefinition.empty»«node.listKeys»«ENDIF»
+        «ENDIF»
+    '''
+
+}
diff --git a/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocumentationGeneratorImpl.java b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocumentationGeneratorImpl.java
new file mode 100644 (file)
index 0000000..39a1d0b
--- /dev/null
@@ -0,0 +1,46 @@
+package org.opendaylight.yangtools.yang.unified.doc.generator.maven;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.unified.doc.generator.GeneratorImpl;
+import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+
+public class DocumentationGeneratorImpl extends GeneratorImpl implements CodeGenerator {
+
+    @Override
+    public Collection<File> generateSources(SchemaContext arg0, File arg1, Set<Module> arg2) throws IOException {
+        // TODO Auto-generated method stub
+         generate(arg0, arg1, arg2);
+         return Collections.emptySet();
+    }
+
+    @Override
+    public void setLog(Log log) {
+        // use maven logging if necessary
+
+    }
+
+    @Override
+    public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
+        // no additional config utilized
+    }
+
+    @Override
+    public void setResourceBaseDir(File resourceBaseDir) {
+        // no resource processing necessary
+    }
+
+    @Override
+    public void setMavenProject(MavenProject project) {
+        // no additional information needed
+    }
+}
diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocGenTest.java b/code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/unified/doc/generator/maven/DocGenTest.java
new file mode 100644 (file)
index 0000000..7bf8f3e
--- /dev/null
@@ -0,0 +1,81 @@
+package org.opendaylight.yangtools.yang.unified.doc.generator.maven;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.opendaylight.yangtools.yang.model.api.Module;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.parser.impl.YangParserImpl;
+import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+
+public class DocGenTest {
+    public static final String FS = File.separator;
+    private static final String TEST_PATH = "target" + FS + "test" + FS + "site";
+    private static final File GENERATOR_OUTPUT_DIR = new File(TEST_PATH);
+    private YangParserImpl parser;
+
+    @Before
+    public void init() {
+        if (GENERATOR_OUTPUT_DIR.exists()) {
+            deleteTestDir(GENERATOR_OUTPUT_DIR);
+        }
+        assertTrue(GENERATOR_OUTPUT_DIR.mkdirs());
+        parser = new YangParserImpl();
+    }
+
+    @After
+    public void cleanUp() {
+        if (GENERATOR_OUTPUT_DIR.exists()) {
+            deleteTestDir(GENERATOR_OUTPUT_DIR);
+        }
+    }
+
+    @Test
+    public void testListGeneration() throws Exception {
+        final List<File> sourceFiles = getSourceFiles("/doc-gen");
+        final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
+        final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
+        final CodeGenerator generator = new DocumentationGeneratorImpl();
+        generator.generateSources(context, GENERATOR_OUTPUT_DIR, modulesToBuild);
+    }
+
+    private static List<File> getSourceFiles(String path) throws FileNotFoundException {
+        final String resPath = DocGenTest.class.getResource(path).getPath();
+        final File sourcesDir = new File(resPath);
+        if (sourcesDir.exists()) {
+            final List<File> sourceFiles = new ArrayList<>();
+            final File[] fileArray = sourcesDir.listFiles();
+            if (fileArray == null) {
+                throw new IllegalArgumentException("Unable to locate files in " + sourcesDir);
+            }
+            sourceFiles.addAll(Arrays.asList(fileArray));
+            return sourceFiles;
+        } else {
+            throw new FileNotFoundException("Testing files were not found(" + sourcesDir.getName() + ")");
+        }
+    }
+
+    private static void deleteTestDir(File file) {
+        if (file.isDirectory()) {
+            File[] filesToDelete = file.listFiles();
+            if (filesToDelete != null) {
+                for (File f : filesToDelete) {
+                    deleteTestDir(f);
+                }
+            }
+        }
+        if (!file.delete()) {
+            throw new RuntimeException("Failed to clean up after test");
+        }
+    }
+
+}
diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/resources/doc-gen/network-topology@2013-07-12.yang b/code-generator/maven-sal-api-gen-plugin/src/test/resources/doc-gen/network-topology@2013-07-12.yang
new file mode 100644 (file)
index 0000000..fb18be4
--- /dev/null
@@ -0,0 +1,432 @@
+module network-topology  {
+    yang-version 1;
+    namespace "urn:TBD:params:xml:ns:yang:network-topology";
+    // replace with IANA namespace when assigned
+    prefix "nt";
+
+    organization "TBD";
+
+    contact "WILL-BE-DEFINED-LATER";
+/*
+    description 
+        "This module defines a model for the topology of a network.
+        Key design decisions are as follows:
+        A topology consists of a set of nodes and links.  
+        Links are point-to-point and unidirectional.  
+        Bidirectional connections need to be represented through
+        two separate links.  
+        Multipoint connections, broadcast domains etc can be represented 
+        through a hierarchy of nodes, then connecting nodes at 
+        upper layers of the hierarchy.";  
+*/
+    revision 2013-07-12 {
+        description
+            "Initial revision.";
+    }
+        
+    typedef topology-id {
+        type string;
+        description 
+            "An identifier for a topology.";
+    }
+
+    typedef node-id {
+        type string;
+        description
+            "An identifier for a node in a topology.  
+            The identifier may be opaque.  
+            The identifier SHOULD be chosen such that the same node in a 
+            real network topology will always be identified through the 
+            same identifier, even if the model is instantiated in separate 
+            datastores. An implementation MAY choose to capture semantics 
+            in the identifier, for example to indicate the type of node 
+            and/or the type of topology that the node is a part of.";  
+    }
+
+    typedef link-id {
+        type string;
+        description
+            "An identifier for a link in a topology.  
+            The identifier may be opaque.  
+            The identifier SHOULD be chosen such that the same link in a 
+            real network topology will always be identified through the 
+            same identifier, even if the model is instantiated in separate 
+            datastores. An implementation MAY choose to capture semantics 
+            in the identifier, for example to indicate the type of link 
+            and/or the type of topology that the link is a part of.";  
+    }
+
+    typedef tp-id {
+        type string;
+        description 
+            "An identifier for termination points on a node. 
+            The identifier may be opaque.  
+            The identifier SHOULD be chosen such that the same TP in a 
+            real network topology will always be identified through the 
+            same identifier, even if the model is instantiated in separate 
+            datastores. An implementation MAY choose to capture semantics 
+            in the identifier, for example to indicate the type of TP 
+            and/or the type of node and topology that the TP is a part of.";  
+    }
+
+    typedef tp-ref {
+        type leafref {
+            path "/network-topology/topology/node/termination-point/tp-id";
+        }
+        description 
+            "A type for an absolute reference to a termination point.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+    typedef topology-ref {
+        type leafref {
+            path "/network-topology/topology/topology-id";
+        }
+        description 
+            "A type for an absolute reference a topology instance.";
+    }
+    
+    typedef node-ref {
+        type leafref {
+            path "/network-topology/topology/node/node-id";
+        }
+        description 
+            "A type for an absolute reference to a node instance.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+
+    typedef link-ref {
+        type leafref {
+            path "/network-topology/topology/link/link-id";
+        }
+        description 
+            "A type for an absolute reference a link instance.
+            (This type should not be used for relative references.
+            In such a case, a relative path should be used instead.)";
+    }
+
+    typedef x {
+        type binary {
+            length 5..10|15..20|25..30;
+        }
+        description "x type description";
+        reference "x type reference";
+    }
+
+    typedef y {
+        type int32 {
+            range 5..555;
+        }
+    }
+
+    identity crypto-alg {
+        description "Base identity from which all crypto algorithms are derived.";
+    }
+
+    identity des {
+        base "crypto-alg";
+        description "DES crypto algorithm";
+    }
+
+    identity des3 {
+        base "crypto-alg";
+        description "Triple DES crypto algorithm";
+    }
+
+    grouping tp-attributes {
+        description 
+            "The data objects needed to define a termination point.
+            (This only includes a single leaf at this point, used
+            to identify the termination point.)  
+            Provided in a grouping so that in addition to the datastore,
+            the data can also be included in notifications.";
+        leaf tp-id {
+            type tp-id;
+        }
+        leaf-list tp-ref {
+            type tp-ref;
+            config false;
+            description 
+                "The leaf list identifies any termination points that the 
+                termination point is dependent on, or maps onto.  
+                Those termination points will themselves be contained 
+                in a supporting node.  
+                This dependency information can be inferred from 
+                the dependencies between links.  For this reason, 
+                this item is not separately configurable.  Hence no
+                corresponding constraint needs to be articulated.  
+                The corresponding information is simply provided by the
+                implementing system.";
+        }
+    } 
+    
+    grouping node-attributes {
+        description
+            "The data objects needed to define a node.
+            The objects are provided in a grouping so that in addition to
+            the datastore, the data can also be included in notifications
+            as needed.";
+        leaf node-id {
+            type node-id;
+            description 
+                "The identifier of a node in the topology.  
+                A node is specific to a topology to which it belongs.";   
+        }
+        list supporting-node {
+            description 
+                "This list defines vertical layering information for nodes. 
+                It allows to capture for any given node, which node (or nodes)
+                in the corresponding underlay topology it maps onto.  
+                A node can map to zero, one, or more nodes below it;
+                accordingly there can be zero, one, or more elements in the list.
+                If there are specific layering requirements, for example
+                specific to a particular type of topology that only allows
+                for certain layering relationships, the choice
+                below can be augmented with additional cases.
+                A list has been chosen rather than a leaf-list in order 
+                to provide room for augmentations, e.g. for 
+                statistics or priorization information associated with 
+                supporting nodes.";
+            key "node-ref";
+            leaf node-ref {
+                type node-ref;
+            }
+        }
+    }
+            
+    grouping link-attributes {
+        // This is a grouping, not defined inline with the link definition itself,
+        // so it can be included in a notification, if needed
+        leaf link-id {
+            type link-id;
+            description
+                "The identifier of a link in the topology.  
+                A link is specific to a topology to which it belongs.";   
+        }
+        container source { 
+            description "XYZ";
+            leaf source-node {
+                mandatory true;
+                type node-ref; 
+                description 
+                    "Source node identifier, must be in same topology.";
+            }
+            leaf source-tp {
+                type tp-ref; 
+                description 
+                    "Termination point within source node that terminates the link.";           
+            }
+        }
+        container destination { 
+            leaf dest-node {
+                mandatory true;
+                type node-ref; 
+                description 
+                    "Destination node identifier, must be in same topology.";
+            }
+            leaf dest-tp {
+                type tp-ref;
+                description 
+                    "Termination point within destination node that terminates the link.";
+            }
+        }
+        list supporting-link {
+            key "link-ref";
+            leaf link-ref {
+                type link-ref;
+            }
+        }
+    }
+    
+
+    container network-topology {
+        list topology {
+            description "
+                This is the model of an abstract topology.
+                A topology contins nodes and links.  
+                Each topology MUST be identified by
+                unique topology-id for reason that a network could contain many
+                topologies.
+            ";
+            key "topology-id";
+            leaf topology-id {
+                type topology-id; 
+                description "
+                    It is presumed that a datastore will contain many topologies. To
+                    distinguish between topologies it is vital to have UNIQUE
+                    topology identifiers.
+                ";
+            }
+            container topology-types {
+                description 
+                    "This container is used to identify the type, or types 
+                    (as a topology can support several types simultaneously), 
+                    of the topology.  
+                    Topology types are the subject of several integrity constraints 
+                    that an implementing server can validate in order to 
+                    maintain integrity of the datastore.  
+                    Topology types are indicated through separate data nodes; 
+                    the set of topology types is expected to increase over time.
+                    To add support for a new topology, an augmenting module
+                    needs to augment this container with a new empty optional 
+                    container to indicate the new topology type.  
+                    The use of a container allows to indicate a subcategorization
+                    of topology types.  
+                    The container SHALL NOT be augmented with any data nodes 
+                    that serve a purpose other than identifying a particular 
+                    topology type.  
+                ";
+            }   
+            list underlay-topology {
+                key "topology-ref";
+                leaf topology-ref {
+                    type topology-ref;
+                }  
+                // a list, not a leaf-list, to allow for potential augmentation 
+                // with properties specific to the underlay topology, 
+                // such as statistics, preferences, or cost.  
+                description 
+                    "Identifies the topology, or topologies, that this topology
+                    is dependent on.";
+            }
+            
+            list node {
+                description "The list of network nodes defined for the topology.";
+                key "node-id";
+                uses node-attributes;
+                must "boolean(../underlay-topology[*]/node[./supporting-nodes/node-ref])";
+                    // This constraint is meant to ensure that a referenced node is in fact 
+                    // a node in an underlay topology.  
+                list termination-point {
+                    description
+                        "A termination point can terminate a link.  
+                        Depending on the type of topology, a termination point could, 
+                        for example, refer to a port or an interface."; 
+                    key "tp-id";
+                    uses tp-attributes;
+                }
+            }
+            
+            list link {
+                description "
+                    A Network Link connects a by Local (Source) node and
+                    a Remote (Destination) Network Nodes via a set of the 
+                    nodes' termination points. 
+                    As it is possible to have several links between the same
+                    source and destination nodes, and as a link could potentially
+                    be re-homed between termination points, to ensure that we 
+                    would always know to distinguish between links, every link 
+                    is identified by a dedicated link identifier.  
+                    Note that a link models a point-to-point link, not a multipoint
+                    link.  
+                    Layering dependencies on links in underlay topologies are
+                    not represented as the layering information of nodes and of 
+                    termination points is sufficient.  
+                ";
+                key "link-id";
+                uses link-attributes;
+                must "boolean(../underlay-topology/link[./supporting-link]";
+                    // Constraint: any supporting link must be part of an underlay topology
+                must "boolean(../node[./source/source-node])";
+                    // Constraint: A link must have as source a node of the same topology
+                must "boolean(../node[./destination/dest-node])";
+                    // Constraint: A link must have as source a destination of the same topology
+                must "boolean(../node/termination-point[./source/source-tp])";
+                    // Constraint: The source termination point must be contained in the source node
+                must "boolean(../node/termination-point[./destination/dest-tp])";
+                    // Constraint: The destination termination point must be contained 
+                    // in the destination node
+            }
+        }
+    }
+
+    notification n1 {
+        description "This example defines a notification 1.";
+        leaf event-class {
+            type string;
+        }
+        anyxml reporting-entity;
+        container severity {
+            list links {
+                container endpoints {
+                    leaf start {
+                        type x;
+                    }
+                    leaf end {
+                        type y;
+                    }
+                }
+                leaf id {
+                    type string;
+                }
+            }
+        }
+    }
+
+    notification n2 {
+        description "This example defines a notification 2.";
+        leaf event-class {
+            type string;
+        }
+        anyxml reporting-entity;
+        leaf severity {
+            type string;
+        }
+    }
+
+    augment "/network-topology" {
+        anyxml any-a;
+        anyxml any-b;
+    }
+
+    augment "/network-topology/topology" {
+        description "description of augment 2";
+        reference "reference of augment 2";
+        list list-a {}
+        list list-b {
+            leaf leaf-c {
+                type string;
+            }
+        }
+    }
+
+    augment "/network-topology/topology/topology-types" {
+        container container-c {
+            leaf id {
+                type binary;
+            }
+        }
+    }
+
+    rpc rock-the-house {
+        description "This statement is used to define a NETCONF RPC operation.";
+        reference "http://tools.ietf.org/html/rfc6020#section-7.13";
+        input {
+            leaf zip-code {
+                type string;
+            }
+        }
+        output {
+            leaf number {
+                type int32;
+            }
+        }
+    }
+
+    extension c-define {
+        description
+            "Takes as argument a name string.
+            Makes the code generator use the given name in the
+            #define.";
+        argument "name";
+    }
+
+    feature local-storage {
+        description
+            "This feature means the device supports local
+            storage (memory, flash or disk) that can be used to
+            store syslog messages.";
+    }
+
+}
index 27b0559f4be2265e8708028c5b61082d4199801f..828aa89c8250bd7af041810878ae82f1255460a8 100644 (file)
@@ -1,4 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
 
     <parent>
         <artifactId>model-ietf</artifactId>
 
     <build>
         <plugins>
+            <plugin>
+                <groupId>org.opendaylight.yangtools</groupId>
+                <artifactId>yang-maven-plugin</artifactId>
+                <version>0.5.9-SNAPSHOT</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>generate-sources</goal>
+                        </goals>
+                        <configuration>
+                            <yangFilesRootDir>src/main/yang</yangFilesRootDir>
+                            <codeGenerators>
+                                <generator>
+                                    <codeGeneratorClass>org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl</codeGeneratorClass>
+                                    <outputBaseDir>target/generated-sources/sal</outputBaseDir>
+                                </generator>
+                                <generator>
+                                    <codeGeneratorClass>org.opendaylight.yangtools.yang.unified.doc.generator.maven.DocumentationGeneratorImpl</codeGeneratorClass>
+                                    <outputBaseDir>target/generated-sources/site</outputBaseDir>
+                                </generator>
+                            </codeGenerators>
+                            <inspectDependencies>true</inspectDependencies>
+                        </configuration>
+                    </execution>
+                </executions>
+                <dependencies>
+                    <dependency>
+                        <groupId>org.opendaylight.yangtools</groupId>
+                        <artifactId>maven-sal-api-gen-plugin</artifactId>
+                        <version>0.6.0-SNAPSHOT</version>
+                        <type>jar</type>
+                    </dependency>
+                </dependencies>
+            </plugin>
             <plugin>
                 <artifactId>maven-jar-plugin</artifactId>
             </plugin>
diff --git a/pom.xml b/pom.xml
index 1dc89df7ea36494515d78dd2b41e41cc02520b26..3faec7b0315bcf5d384656b4738c6aded34eeb1b 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -1,4 +1,5 @@
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">\r
 \r
     <modelVersion>4.0.0</modelVersion>\r
     <artifactId>yangtools</artifactId>\r
@@ -9,7 +10,7 @@
     <properties>\r
         <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>\r
         <nexusproxy>http://nexus.opendaylight.org/content</nexusproxy>\r
-        \r
+\r
         <!-- Java Versions -->\r
         <maven.compiler.source>1.7</maven.compiler.source>\r
         <maven.compiler.target>1.7</maven.compiler.target>\r
@@ -19,7 +20,7 @@
         <maven.jar.version>2.4</maven.jar.version>\r
         <maven.javadoc.version>2.9.1</maven.javadoc.version>\r
         <maven.source.version>2.2.1</maven.source.version>\r
-        <maven.surefire.version>2.16</maven.surefire.version>       \r
+        <maven.surefire.version>2.16</maven.surefire.version>\r
 \r
         <!-- Supporting Libraries -->\r
         <commons.lang.version>3.1</commons.lang.version>\r
                     <version>${maven.jar.version}</version>\r
                     <configuration>\r
                         <archive>\r
-                            <!-- Bundle OSGi Manifest created by maven-bundle-plugin into jar file -->\r
+                            <!-- Bundle OSGi Manifest created by maven-bundle-plugin \r
+                                into jar file -->\r
                             <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>\r
                         </archive>\r
                     </configuration>\r
                         </lifecycleMappingMetadata>\r
                     </configuration>\r
                 </plugin>\r
+                <plugin>\r
+                    <groupId>org.apache.maven.plugins</groupId>\r
+                    <artifactId>maven-javadoc-plugin</artifactId>\r
+                    <version>${maven.javadoc.version}</version>\r
+                    <configuration>\r
+                        <stylesheetfile>stylesheet.css</stylesheetfile>\r
+                    </configuration>\r
+                    <executions>\r
+                        <execution>\r
+                            <id>attach-javadocs</id>\r
+                            <goals>\r
+                                <goal>jar</goal>\r
+                            </goals>\r
+                        </execution>\r
+                        <execution>\r
+                            <goals>\r
+                                <goal>aggregate</goal>\r
+                            </goals>\r
+                            <phase>site</phase>\r
+                        </execution>\r
+                    </executions>\r
+                </plugin>\r
             </plugins>\r
         </pluginManagement>\r
         <plugins>\r
             <plugin>\r
                 <groupId>org.apache.maven.plugins</groupId>\r
                 <artifactId>maven-javadoc-plugin</artifactId>\r
-                <version>${maven.javadoc.version}</version>\r
-                <configuration>\r
-                    <stylesheet>maven</stylesheet>\r
-                </configuration>\r
-                <executions>\r
-                    <execution>\r
-                        <id>attach-javadocs</id>\r
-                        <goals>\r
-                            <goal>jar</goal>\r
-                        </goals>\r
-                    </execution>\r
-                    <execution>\r
-                        <goals>\r
-                            <goal>aggregate</goal>\r
-                        </goals>\r
-                        <phase>site</phase>\r
-                    </execution>\r
-                </executions>\r
             </plugin>\r
         </plugins>\r
     </build>\r
diff --git a/src/main/resources/stylesheet.css b/src/main/resources/stylesheet.css
new file mode 100644 (file)
index 0000000..76de82b
--- /dev/null
@@ -0,0 +1,475 @@
+/* Javadoc style sheet */
+/*
+Overall document style
+*/
+body {
+    background-color:#ffffff;
+    color:#353833;
+    font-family:Arial, Helvetica, sans-serif;
+    font-size:76%;
+    margin:0;
+}
+a:link, a:visited {
+    text-decoration:none;
+    color:#4c6b87;
+}
+a:hover, a:focus {
+    text-decoration:none;
+    color:#bb7a2a;
+}
+a:active {
+    text-decoration:none;
+    color:#4c6b87;
+}
+a[name] {
+    color:#353833;
+}
+a[name]:hover {
+    text-decoration:none;
+    color:#353833;
+}
+pre {
+    font-size:1.3em;
+}
+h1 {
+    font-size:1.8em;
+}
+h2 {
+    font-size:1.5em;
+}
+h3 {
+    font-size:1.4em;
+}
+h4 {
+    font-size:1.3em;
+}
+h5 {
+    font-size:1.2em;
+}
+h6 {
+    font-size:1.1em;
+}
+ul {
+    list-style-type:disc;
+}
+code, tt {
+    font-size:1.2em;
+}
+dt code {
+    font-size:1.2em;
+}
+table tr td dt code {
+    font-size:1.2em;
+    vertical-align:top;
+}
+sup {
+    font-size:.6em;
+}
+/*
+Document title and Copyright styles
+*/
+.clear {
+    clear:both;
+    height:0px;
+    overflow:hidden;
+}
+.aboutLanguage {
+    float:right;
+    padding:0px 21px;
+    font-size:.8em;
+    z-index:200;
+    margin-top:-7px;
+}
+.legalCopy {
+    margin-left:.5em;
+}
+.bar a, .bar a:link, .bar a:visited, .bar a:active {
+    color:#FFFFFF;
+    text-decoration:none;
+}
+.bar a:hover, .bar a:focus {
+    color:#bb7a2a;
+}
+.tab {
+    background-color:#0066FF;
+    background-image:url(resources/titlebar.gif);
+    background-position:left top;
+    background-repeat:no-repeat;
+    color:#ffffff;
+    padding:8px;
+    width:5em;
+    font-weight:bold;
+}
+/*
+Navigation bar styles
+*/
+.bar {
+    background-image:url(resources/background.gif);
+    background-repeat:repeat-x;
+    color:#FFFFFF;
+    padding:.8em .5em .4em .8em;
+    height:auto;/*height:1.8em;*/
+    font-size:1em;
+    margin:0;
+}
+.topNav {
+    background-image:url(resources/background.gif);
+    background-repeat:repeat-x;
+    color:#FFFFFF;
+    float:left;
+    padding:0;
+    width:100%;
+    clear:right;
+    height:2.8em;
+    padding-top:10px;
+    overflow:hidden;
+}
+.bottomNav {
+    margin-top:10px;
+    background-image:url(resources/background.gif);
+    background-repeat:repeat-x;
+    color:#FFFFFF;
+    float:left;
+    padding:0;
+    width:100%;
+    clear:right;
+    height:2.8em;
+    padding-top:10px;
+    overflow:hidden;
+}
+.subNav {
+    background-color:#dee3e9;
+    border-bottom:1px solid #9eadc0;
+    float:left;
+    width:100%;
+    overflow:hidden;
+}
+.subNav div {
+    clear:left;
+    float:left;
+    padding:0 0 5px 6px;
+}
+ul.navList, ul.subNavList {
+    float:left;
+    margin:0 25px 0 0;
+    padding:0;
+}
+ul.navList li{
+    list-style:none;
+    float:left;
+    padding:3px 6px;
+}
+ul.subNavList li{
+    list-style:none;
+    float:left;
+    font-size:90%;
+}
+.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
+    color:#FFFFFF;
+    text-decoration:none;
+}
+.topNav a:hover, .bottomNav a:hover {
+    text-decoration:none;
+    color:#bb7a2a;
+}
+.navBarCell1Rev {
+    background-image:url(resources/tab.gif);
+    background-color:#a88834;
+    color:#FFFFFF;
+    margin: auto 5px;
+    border:1px solid #c9aa44;
+}
+/*
+Page header and footer styles
+*/
+.header, .footer {
+    clear:both;
+    margin:0 20px;
+    padding:5px 0 0 0;
+}
+.indexHeader {
+    margin:10px;
+    position:relative;
+}
+.indexHeader h1 {
+    font-size:1.3em;
+}
+.title {
+    color:#2c4557;
+    margin:10px 0;
+}
+.subTitle {
+    margin:5px 0 0 0;
+}
+.header ul {
+    margin:0 0 25px 0;
+    padding:0;
+}
+.footer ul {
+    margin:20px 0 5px 0;
+}
+.header ul li, .footer ul li {
+    list-style:none;
+    font-size:1.2em;
+}
+/*
+Heading styles
+*/
+div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
+    background-color:#dee3e9;
+    border-top:1px solid #9eadc0;
+    border-bottom:1px solid #9eadc0;
+    margin:0 0 6px -8px;
+    padding:2px 5px;
+}
+ul.blockList ul.blockList ul.blockList li.blockList h3 {
+    background-color:#dee3e9;
+    border-top:1px solid #9eadc0;
+    border-bottom:1px solid #9eadc0;
+    margin:0 0 6px -8px;
+    padding:2px 5px;
+}
+ul.blockList ul.blockList li.blockList h3 {
+    padding:0;
+    margin:15px 0;
+}
+ul.blockList li.blockList h2 {
+    padding:0px 0 20px 0;
+}
+/*
+Page layout container styles
+*/
+.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {
+    clear:both;
+    padding:10px 20px;
+    position:relative;
+}
+.indexContainer {
+    margin:10px;
+    position:relative;
+    font-size:1.0em;
+}
+.indexContainer h2 {
+    font-size:1.1em;
+    padding:0 0 3px 0;
+}
+.indexContainer ul {
+    margin:0;
+    padding:0;
+}
+.indexContainer ul li {
+    list-style:none;
+}
+.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
+    font-size:1.1em;
+    font-weight:bold;
+    margin:10px 0 0 0;
+    color:#4E4E4E;
+}
+.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
+    margin:10px 0 10px 20px;
+}
+.serializedFormContainer dl.nameValue dt {
+    margin-left:1px;
+    font-size:1.1em;
+    display:inline;
+    font-weight:bold;
+}
+.serializedFormContainer dl.nameValue dd {
+    margin:0 0 0 1px;
+    font-size:1.1em;
+    display:inline;
+}
+/*
+List styles
+*/
+ul.horizontal li {
+    display:inline;
+    font-size:0.9em;
+}
+ul.inheritance {
+    margin:0;
+    padding:0;
+}
+ul.inheritance li {
+    display:inline;
+    list-style:none;
+}
+ul.inheritance li ul.inheritance {
+    margin-left:15px;
+    padding-left:15px;
+    padding-top:1px;
+}
+ul.blockList, ul.blockListLast {
+    margin:10px 0 10px 0;
+    padding:0;
+}
+ul.blockList li.blockList, ul.blockListLast li.blockList {
+    list-style:none;
+    margin-bottom:25px;
+}
+ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
+    padding:0px 20px 5px 10px;
+    border:1px solid #9eadc0;
+    background-color:#f9f9f9;
+}
+ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
+    padding:0 0 5px 8px;
+    background-color:#ffffff;
+    border:1px solid #9eadc0;
+    border-top:none;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
+    margin-left:0;
+    padding-left:0;
+    padding-bottom:15px;
+    border:none;
+    border-bottom:1px solid #9eadc0;
+}
+ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
+    list-style:none;
+    border-bottom:none;
+    padding-bottom:0;
+}
+table tr td dl, table tr td dl dt, table tr td dl dd {
+    margin-top:0;
+    margin-bottom:1px;
+}
+/*
+Table styles
+*/
+.contentContainer table, .classUseContainer table, .constantValuesContainer table {
+    border-bottom:1px solid #9eadc0;
+    width:100%;
+}
+.contentContainer ul li table, .classUseContainer ul li table, .constantValuesContainer ul li table {
+    width:100%;
+}
+.contentContainer .description table, .contentContainer .details table {
+    border-bottom:none;
+}
+.contentContainer ul li table th.colOne, .contentContainer ul li table th.colFirst, .contentContainer ul li table th.colLast, .classUseContainer ul li table th, .constantValuesContainer ul li table th, .contentContainer ul li table td.colOne, .contentContainer ul li table td.colFirst, .contentContainer ul li table td.colLast, .classUseContainer ul li table td, .constantValuesContainer ul li table td{
+    vertical-align:top;
+    padding-right:20px;
+}
+.contentContainer ul li table th.colLast, .classUseContainer ul li table th.colLast,.constantValuesContainer ul li table th.colLast,
+.contentContainer ul li table td.colLast, .classUseContainer ul li table td.colLast,.constantValuesContainer ul li table td.colLast,
+.contentContainer ul li table th.colOne, .classUseContainer ul li table th.colOne,
+.contentContainer ul li table td.colOne, .classUseContainer ul li table td.colOne {
+    padding-right:3px;
+}
+.overviewSummary caption, .packageSummary caption, .contentContainer ul.blockList li.blockList caption, .summary caption, .classUseContainer caption, .constantValuesContainer caption {
+    position:relative;
+    text-align:left;
+    background-repeat:no-repeat;
+    color:#FFFFFF;
+    font-weight:bold;
+    clear:none;
+    overflow:hidden;
+    padding:0px;
+    margin:0px;
+}
+caption a:link, caption a:hover, caption a:active, caption a:visited {
+    color:#FFFFFF;
+}
+.overviewSummary caption span, .packageSummary caption span, .contentContainer ul.blockList li.blockList caption span, .summary caption span, .classUseContainer caption span, .constantValuesContainer caption span {
+    white-space:nowrap;
+    padding-top:8px;
+    padding-left:8px;
+    display:block;
+    float:left;
+    background-image:url(resources/titlebar.gif);
+    height:18px;
+}
+.overviewSummary .tabEnd, .packageSummary .tabEnd, .contentContainer ul.blockList li.blockList .tabEnd, .summary .tabEnd, .classUseContainer .tabEnd, .constantValuesContainer .tabEnd {
+    width:10px;
+    background-image:url(resources/titlebar_end.gif);
+    background-repeat:no-repeat;
+    background-position:top right;
+    position:relative;
+    float:left;
+}
+ul.blockList ul.blockList li.blockList table {
+    margin:0 0 12px 0px;
+    width:100%;
+}
+.tableSubHeadingColor {
+    background-color: #EEEEFF;
+}
+.altColor {
+    background-color:#eeeeef;
+}
+.rowColor {
+    background-color:#ffffff;
+}
+.overviewSummary td, .packageSummary td, .contentContainer ul.blockList li.blockList td, .summary td, .classUseContainer td, .constantValuesContainer td {
+    text-align:left;
+    padding:3px 3px 3px 7px;
+}
+th.colFirst, th.colLast, th.colOne, .constantValuesContainer th {
+    background:#dee3e9;
+    border-top:1px solid #9eadc0;
+    border-bottom:1px solid #9eadc0;
+    text-align:left;
+    padding:3px 3px 3px 7px;
+}
+td.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {
+    font-weight:bold;
+}
+td.colFirst, th.colFirst {
+    border-left:1px solid #9eadc0;
+    white-space:nowrap;
+}
+td.colLast, th.colLast {
+    border-right:1px solid #9eadc0;
+}
+td.colOne, th.colOne {
+    border-right:1px solid #9eadc0;
+    border-left:1px solid #9eadc0;
+}
+table.overviewSummary  {
+    padding:0px;
+    margin-left:0px;
+}
+table.overviewSummary td.colFirst, table.overviewSummary th.colFirst,
+table.overviewSummary td.colOne, table.overviewSummary th.colOne {
+    width:25%;
+    vertical-align:middle;
+}
+table.packageSummary td.colFirst, table.overviewSummary th.colFirst {
+    width:25%;
+    vertical-align:middle;
+}
+/*
+Content styles
+*/
+.description pre {
+    margin-top:0;
+}
+.deprecatedContent {
+    margin:0;
+    padding:10px 0;
+}
+.docSummary {
+    padding:0;
+}
+/*
+Formatting effect styles
+*/
+.sourceLineNo {
+    color:green;
+    padding:0 30px 0 0;
+}
+h1.hidden {
+    visibility:hidden;
+    overflow:hidden;
+    font-size:.9em;
+}
+.block {
+    display:block;
+    margin:3px 0 0 0;
+}
+.strong {
+    font-weight:bold;
+}
+
index 4bf91e32ea9ed4c7e802c4007cae9bcfbb163ac5..66c745e29a674e19cd129f7496800a085f1bd2e5 100644 (file)
@@ -159,9 +159,16 @@ public final class InstanceIdentifier<T extends DataObject> implements Path<Inst
     }
 
     public interface InstanceIdentifierBuilder<T extends DataObject> extends Builder<InstanceIdentifier<T>> {
-
+        /**
+         * @deprecated use {@link child(Class)} or {@link augmentation(Class)} instead.
+         */
+        @Deprecated
         <N extends DataObject> InstanceIdentifierBuilder<N> node(Class<N> container);
 
+        /**
+         * @deprecated use {@link child(Class,Identifier)} or {@link augmentation(Class,Identifier)} instead.
+         */
+        @Deprecated
         <N extends Identifiable<K> & DataObject, K extends Identifier<N>> InstanceIdentifierBuilder<N> node(
                 Class<N> listItem, K listKey);
 
@@ -170,14 +177,28 @@ public final class InstanceIdentifier<T extends DataObject> implements Path<Inst
         <N extends Identifiable<K> & ChildOf<? super T>, K extends Identifier<N>> InstanceIdentifierBuilder<N> child(
                 Class<N> listItem, K listKey);
 
+        <N extends DataObject & Augmentation<? super T>> InstanceIdentifierBuilder<N> augmentation(Class<N> container);
+
     }
 
+    /**
+     * @deprecated use {@link builder(Class)} or {@link builder(Class,Identifier)} instead.
+     */
+    @Deprecated
     @SuppressWarnings("rawtypes")
     public static InstanceIdentifierBuilder<?> builder() {
         return new BuilderImpl();
     }
 
-    @SuppressWarnings({ "rawtypes", "unchecked" })
+    public static <T extends ChildOf<? extends DataRoot>> InstanceIdentifierBuilder<T> builder(Class<T> container) {
+        return new BuilderImpl<T>().addNode(container);
+    }
+
+    public static <N extends Identifiable<K> & DataObject, K extends Identifier<N>> InstanceIdentifierBuilder<N> builder(
+            Class<N> listItem, K listKey) {
+        return new BuilderImpl<N>().addNode(listItem, listKey);
+    }
+
     public static <T extends DataObject> InstanceIdentifierBuilder<T> builder(InstanceIdentifier<T> basePath) {
         return new BuilderImpl<T>(basePath.path,basePath.targetType);
     }
@@ -191,12 +212,26 @@ public final class InstanceIdentifier<T extends DataObject> implements Path<Inst
             this.path = new ArrayList<>();
         }
         
-
         public BuilderImpl(List<? extends PathArgument> prefix,Class<? extends DataObject> target) {
             this.path = new ArrayList<>(prefix);
             this.target = target;
         }
 
+        @SuppressWarnings("unchecked")
+        private <N extends DataObject> InstanceIdentifierBuilder<N> addNode(Class<N> container) {
+            target = container;
+            path.add(new Item<N>(container));
+            return (InstanceIdentifierBuilder<N>) this;
+        }
+
+        @SuppressWarnings("unchecked")
+        private <N extends DataObject & Identifiable<K> , K extends Identifier<N>> InstanceIdentifierBuilder<N> addNode(
+                Class<N> listItem, K listKey) {
+            target = listItem;
+            path.add(new IdentifiableItem<N, K>(listItem, listKey));
+            return (InstanceIdentifierBuilder<N>) this;
+        }
+
         @SuppressWarnings({ "unchecked", "rawtypes" })
         @Override
         public InstanceIdentifier<T> toInstance() {
@@ -205,31 +240,31 @@ public final class InstanceIdentifier<T extends DataObject> implements Path<Inst
         }
 
         @Override
-        @SuppressWarnings("unchecked")
         public <N extends DataObject> InstanceIdentifierBuilder<N> node(Class<N> container) {
-            target = container;
-            path.add(new Item<N>(container));
-            return (InstanceIdentifierBuilder<N>) this;
+            return addNode(container);
         }
 
         @Override
-        @SuppressWarnings("unchecked")
         public <N extends DataObject & Identifiable<K> , K extends Identifier<N>> InstanceIdentifierBuilder<N> node(
                 Class<N> listItem, K listKey) {
-            target = listItem;
-            path.add(new IdentifiableItem<N, K>(listItem, listKey));
-            return (InstanceIdentifierBuilder<N>) this;
+            return addNode(listItem, listKey);
         }
-        
+
         @Override
         public <N extends ChildOf<? super T>> InstanceIdentifierBuilder<N> child(Class<N> container) {
-            return node(container);
+            return addNode(container);
         }
         
         @Override
         public <N extends Identifiable<K> & ChildOf<? super T>, K extends Identifier<N>> InstanceIdentifierBuilder<N> child(
                 Class<N> listItem, K listKey) {
-            return node(listItem,listKey);
+            return addNode(listItem,listKey);
+        }
+
+        @Override
+        public <N extends DataObject & Augmentation<? super T>> InstanceIdentifierBuilder<N> augmentation(
+                Class<N> container) {
+            return addNode(container);
         }
     }
 
index 5f4202254786df35c1a3c22609bdf50c7e78eb17..892a1436ee37441dc6d180b0b51cefa5c8b9b2b3 100644 (file)
@@ -22,7 +22,7 @@ public final class Int64 extends AbstractSignedInteger {
     private static final String DESCRIPTION = "int64  represents integer values between -9223372036854775808 and 9223372036854775807, inclusively.";
 
     private Int64() {
-        super(NAME, DESCRIPTION, Integer.MIN_VALUE, Integer.MAX_VALUE, "");
+        super(NAME, DESCRIPTION, Long.MIN_VALUE, Long.MAX_VALUE, "");
     }
 
     public static Int64 getInstance() {
index 917a001c6b449385a27d342e2735a5416bea41a5..3f4166bd08331b059caef4946ddf2827dee73f1e 100644 (file)
@@ -132,12 +132,16 @@ public final class ParserListenerUtils {
      * @return first string value from given tree
      */
     public static String stringFromNode(final ParseTree treeNode) {
-        final String result = "";
+        String result = "";
         for (int i = 0; i < treeNode.getChildCount(); ++i) {
             if (treeNode.getChild(i) instanceof StringContext) {
                 final StringContext context = (StringContext) treeNode.getChild(i);
                 if (context != null) {
-                    return context.getChild(0).getText().replace("\"", "");
+                    result = context.getChild(0).getText();
+                    if (!(result.startsWith("\"")) && result.endsWith("\"")) {
+                        LOG.error("Syntax error at line " + context.getStart().getLine() + ": missing '\"'.");
+                    }
+                    return result.replace("\"", "");
                 }
             }
         }