Merge "Clean up yang parser."
authorTony Tkacik <ttkacik@cisco.com>
Mon, 16 Dec 2013 17:29:14 +0000 (17:29 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 16 Dec 2013 17:29:14 +0000 (17:29 +0000)
15 files changed:
code-generator/.gitignore
code-generator/binding-java-api-generator/src/main/java/org/opendaylight/yangtools/sal/java/api/generator/ClassTemplate.xtend
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/wadl/generator/WadlRestconfGenerator.xtend [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenerator.java [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenTest.java [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/controller-network.yang [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/controller-openflow.yang [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/demo-topology.yang [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/ietf-inet-types@2010-09-24.yang [new file with mode: 0644]
code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/ietf-yang-types@2010-09-24.yang [new file with mode: 0644]
model/yang-ext/pom.xml
yang/yang-common/src/main/java/org/opendaylight/yangtools/yang/common/QName.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/codec/Uint8Codec.java
yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/codec/UnionCodec.java [new file with mode: 0644]
yang/yang-data-impl/src/main/java/org/opendaylight/yangtools/yang/data/impl/codec/TypeDefinitionAwareCodec.java

index acda8836cea878e3d670904f31751a69e9e6fa5a..e3b94d917510640e7a96c838a190b9ae44001539 100644 (file)
@@ -1,2 +1,3 @@
 /.settings
 /binding-java-api-generator/src/main/xtend-gen
+/maven-sal-api-gen-plugin/src/main/xtend-gen
index 5f001d8401c043ad819c9348340e8ec4a55aa2ed..4504d2161698ee3abe79d658e03e9646fd6b9ee1 100644 (file)
@@ -426,7 +426,6 @@ class ClassTemplate extends BaseTemplate {
         «IF restrictions != null && !(restrictions.lengthConstraints.empty)»\r
             public static «List.importedName»<«Range.importedName»<Integer>> getLength() {\r
                 final «List.importedName»<«Range.importedName»<Integer>> result = new «ArrayList.importedName»<>();\r
-                «List.importedName»<«Range.importedName»<«Integer.importedName»>> lengthConstraints = new «ArrayList.importedName»<>(); \r
                 «FOR r : restrictions.lengthConstraints»\r
                     result.add(«Range.importedName».closed(«r.min», «r.max»));\r
                 «ENDFOR»\r
diff --git a/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/wadl/generator/WadlRestconfGenerator.xtend b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/wadl/generator/WadlRestconfGenerator.xtend
new file mode 100644 (file)
index 0000000..18cd6d8
--- /dev/null
@@ -0,0 +1,256 @@
+package org.opendaylight.yangtools.yang.wadl.generator
+
+import java.io.BufferedWriter
+import java.io.File
+import java.io.OutputStreamWriter
+import java.util.ArrayList
+import java.util.HashSet
+import java.util.List
+import java.util.Set
+import org.opendaylight.yangtools.yang.model.api.ContainerSchemaNode
+import org.opendaylight.yangtools.yang.model.api.DataNodeContainer
+import org.opendaylight.yangtools.yang.model.api.DataSchemaNode
+import org.opendaylight.yangtools.yang.model.api.LeafSchemaNode
+import org.opendaylight.yangtools.yang.model.api.ListSchemaNode
+import org.opendaylight.yangtools.yang.model.api.Module
+import org.opendaylight.yangtools.yang.model.api.SchemaContext
+import org.sonatype.plexus.build.incremental.BuildContext
+import org.sonatype.plexus.build.incremental.DefaultBuildContext
+
+class WadlRestconfGenerator {
+       
+       File path
+       static val BuildContext CTX = new DefaultBuildContext();
+       var SchemaContext context;
+       var List<DataSchemaNode> configData;
+       var List<DataSchemaNode> operationalData;
+       var Module module;
+       var List<LeafSchemaNode> pathListParams;
+       val PATH_DELIMETER = "/"
+
+       new(File targetPath) {
+               if (!targetPath.exists) targetPath.mkdirs
+               path = targetPath
+       }
+
+       def generate(SchemaContext context, Set<Module> modules) {
+        val result = new HashSet;
+               this.context = context
+               for (module : modules) {
+                       val dataContainers = module.childNodes.filter[it|it instanceof ContainerSchemaNode || it instanceof ListSchemaNode]
+                       if (!dataContainers.empty) {
+                               configData = new ArrayList
+                               operationalData = new ArrayList
+                               
+                               for (data : dataContainers) {
+                                       if (data.configuration) {
+                                               configData.add(data)    
+                                       } else {
+                                               operationalData.add(data)
+                                       }
+                               }
+                               
+                               this.module = module
+                               val destination = new File(path, '''«module.name».wadl''')
+                   val fw = new OutputStreamWriter(CTX.newFileOutputStream(destination))
+                   val bw = new BufferedWriter(fw)
+                   bw.append(application);
+                   bw.close();
+                   fw.close();
+                       result.add(destination)
+                       }
+               }
+               return result
+       }
+       
+       private def application() '''
+               <?xml version="1.0"?>
+               <application xmlns="http://wadl.dev.java.net/2009/02" «module.importsAsNamespaces» xmlns:«module.prefix»="«module.namespace»">
+               
+                       «grammars»
+                       
+                       «resources»
+               </application>
+       '''
+       
+       private def importsAsNamespaces(Module module) '''
+               «FOR imprt : module.imports»
+                       xmlns:«imprt.prefix»="«context.findModuleByName(imprt.moduleName, imprt.revision).namespace»"
+               «ENDFOR»
+       '''
+       
+       private def grammars() '''
+               <grammars>
+                       <include href="«module.name».yang"/>
+                       «FOR imprt : module.imports»
+                               <include href="«imprt.moduleName».yang"/>
+                       «ENDFOR»
+               </grammars>
+       '''
+       
+       private def resources() '''
+               <resources base="http://localhost:9998/restconf">
+                       «resourceOperational»
+                       «resourceConfig»
+                       «resourceOperations»
+               </resources>
+       '''
+       
+       private def resourceOperational() '''
+               «IF !operationalData.nullOrEmpty»
+                       <resource path="operational">
+                               «FOR schemaNode : operationalData»
+                                       «schemaNode.firstResource(false)»
+                               «ENDFOR»
+                       </resource>
+               «ENDIF»
+       '''
+       
+       private def resourceConfig() '''
+               «IF !configData.nullOrEmpty»
+                       <resource path="config">
+                               «FOR schemaNode : configData»
+                                       «schemaNode.firstResource(true)»
+                               «ENDFOR»
+                       </resource>
+               «ENDIF»
+       '''
+       
+       private def resourceOperations() '''
+               «IF !module.rpcs.nullOrEmpty»
+                       <resource path="operations">
+                               «FOR rpc : module.rpcs»
+                                       <resource path="«module.name»:«rpc.QName.localName»">
+                                               «methodPostRpc(rpc.input != null, rpc.output !== null)»
+                                       </resource>
+                               «ENDFOR»
+                       </resource>
+               «ENDIF»
+       '''
+       
+       private def String firstResource(DataSchemaNode schemaNode, boolean config) '''
+               <resource path="«module.name»:«schemaNode.createPath»">
+                       «IF !pathListParams.nullOrEmpty»
+                               «resourceParams»
+                       «ENDIF»
+                       «schemaNode.methodGet»
+                       «IF config»
+                               «schemaNode.mehodPut»
+                               «schemaNode.mehodPost»
+                       «ENDIF»
+                       
+                       «IF schemaNode instanceof DataNodeContainer»
+                               «val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it instanceof ContainerSchemaNode || it instanceof ListSchemaNode]»
+                               «IF !children.empty»
+                                       «FOR child : children»
+                                               «child.resource(config)»
+                                       «ENDFOR»
+                               «ENDIF»
+                       «ENDIF»
+               </resource>
+       '''
+               
+       private def String resource(DataSchemaNode schemaNode, boolean config) '''
+               <resource path="«schemaNode.createPath»">
+                       «IF !pathListParams.nullOrEmpty»
+                               «resourceParams»
+                       «ENDIF»
+                       «schemaNode.methodGet»
+                       «IF config»
+                               «schemaNode.mehodPut»
+                               «schemaNode.mehodPost»
+                       «ENDIF»
+                       
+                       «IF schemaNode instanceof DataNodeContainer»
+                               «val children = (schemaNode as DataNodeContainer).childNodes.filter[it|it instanceof ContainerSchemaNode || it instanceof ListSchemaNode]»
+                               «IF !children.empty»
+                                       «FOR child : children»
+                                               «child.resource(config)»
+                                       «ENDFOR»
+                               «ENDIF»
+                       «ENDIF»
+               </resource>
+       '''
+       
+       private def String createPath(DataSchemaNode schemaNode) {
+               pathListParams = new ArrayList
+               var StringBuilder path = new StringBuilder
+               path.append(schemaNode.QName.localName)
+               if (schemaNode instanceof ListSchemaNode) {
+                       val listKeys = (schemaNode as ListSchemaNode).keyDefinition
+                       for (listKey : listKeys) {
+                               pathListParams.add((schemaNode as DataNodeContainer).getDataChildByName(listKey) as LeafSchemaNode) 
+                               path.append(PATH_DELIMETER + "{" + listKey.localName + "}")
+                       }
+               }
+               return path.toString
+       }
+       
+       private def resourceParams() '''
+               «FOR pathParam : pathListParams»
+                       «val prefix = pathParam.type.QName.prefix»
+                       «val type = if (prefix.nullOrEmpty) pathParam.type.QName.localName else prefix + ":" + pathParam.type.QName.localName»
+                       <param required="true" style="template" name="«pathParam.QName.localName»" type="«type»"/>
+               «ENDFOR»
+       '''
+       
+       private def methodGet(DataSchemaNode schemaNode) '''
+               <method name="GET">
+                       <response>
+                               <representation mediaType="application/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="text/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/yang.data+xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/yang.data+json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                       </response>
+               </method>
+       '''
+       
+       private def mehodPut(DataSchemaNode schemaNode) '''
+               <method name="PUT">
+                       <request>
+                               <representation mediaType="application/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="text/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/yang.data+xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/yang.data+json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                       </request>
+               </method>
+       '''
+       
+       private def mehodPost(DataSchemaNode schemaNode) '''
+               <method name="POST">
+                       <request>
+                               <representation mediaType="application/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="text/xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/yang.data+xml" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                               <representation mediaType="application/yang.data+json" element="«schemaNode.QName.prefix»:«schemaNode.QName.localName»"/>
+                       </request>
+               </method>
+       '''
+       
+       private def methodPostRpc(boolean input, boolean output) '''
+               <method name="POST">
+                       «IF input»
+                       <request>
+                               <representation mediaType="application/xml" element="input"/>
+                               <representation mediaType="text/xml" element="input"/>
+                               <representation mediaType="application/json" element="input"/>
+                               <representation mediaType="application/yang.data+xml" element="input"/>
+                               <representation mediaType="application/yang.data+json" element="input"/>
+                       </request>
+                       «ENDIF»
+                       «IF output»
+                       <response>
+                               <representation mediaType="application/xml" element="output"/>
+                               <representation mediaType="text/xml" element="output"/>
+                               <representation mediaType="application/json" element="output"/>
+                               <representation mediaType="application/yang.data+xml" element="output"/>
+                               <representation mediaType="application/yang.data+json" element="output"/>
+                       </response>
+                       «ENDIF»
+               </method>
+       '''
+
+}
diff --git a/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenerator.java b/code-generator/maven-sal-api-gen-plugin/src/main/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenerator.java
new file mode 100644 (file)
index 0000000..a10c509
--- /dev/null
@@ -0,0 +1,58 @@
+package org.opendaylight.yangtools.yang.wadl.generator.maven;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+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.wadl.generator.WadlRestconfGenerator;
+import org.opendaylight.yangtools.yang2sources.spi.CodeGenerator;
+
+public class WadlGenerator implements CodeGenerator {
+    
+    @Override
+    public Collection<File> generateSources(SchemaContext context, File outputDir, Set<Module> currentModules)
+            throws IOException {
+        
+        final File outputBaseDir;
+        if (outputDir == null) {
+            outputBaseDir = new File("target" + File.separator + "generated-sources" + File.separator
+                    + "maven-sal-api-gen" + File.separator + "wadl");
+        } else {
+            outputBaseDir = outputDir;
+        }
+
+        final WadlRestconfGenerator generator = new WadlRestconfGenerator(outputBaseDir);
+        return generator.generate(context, currentModules);
+    }
+
+    @Override
+    public void setLog(Log log) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void setAdditionalConfig(Map<String, String> additionalConfiguration) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void setResourceBaseDir(File resourceBaseDir) {
+        // TODO Auto-generated method stub
+        
+    }
+
+    @Override
+    public void setMavenProject(MavenProject project) {
+        // TODO Auto-generated method stub
+        
+    }
+
+}
diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenTest.java b/code-generator/maven-sal-api-gen-plugin/src/test/java/org/opendaylight/yangtools/yang/wadl/generator/maven/WadlGenTest.java
new file mode 100644 (file)
index 0000000..11c5ad7
--- /dev/null
@@ -0,0 +1,81 @@
+package org.opendaylight.yangtools.yang.wadl.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 WadlGenTest {
+    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("/wadl-gen");
+        final Set<Module> modulesToBuild = parser.parseYangModels(sourceFiles);
+        final SchemaContext context = parser.resolveSchemaContext(modulesToBuild);
+        final CodeGenerator generator = new WadlGenerator();
+        generator.generateSources(context, GENERATOR_OUTPUT_DIR, modulesToBuild);
+    }
+
+    private static List<File> getSourceFiles(String path) throws FileNotFoundException {
+        final String resPath = WadlGenTest.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/wadl-gen/controller-network.yang b/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/controller-network.yang
new file mode 100644 (file)
index 0000000..a8693bb
--- /dev/null
@@ -0,0 +1,193 @@
+module controller-network {
+       yang-version 1;
+       namespace "urn:opendaylight:controller:network";
+       prefix "topos";
+       
+       import ietf-inet-types { prefix "inet"; }
+       
+       revision 2013-05-20 {
+          description "Initial demo";
+       }
+       
+
+       
+       
+       typedef topology-id {
+               type string;
+       }
+
+       typedef node-id {
+               type string;
+       }
+
+       typedef link-id {
+               type string;
+       }
+
+       typedef tp-id {
+               type string;
+               description "identifier for termination points on a port";
+       }
+
+       typedef tp-ref {
+               type leafref {
+                       path "/network/topologies/topology/nodes/node/termination-points/termination-point/tp-id";
+               }
+       }
+       typedef topology-ref {
+               type leafref {
+                       path "/network/topologies/topology/topology-id";
+               }
+               description "This type is used for leafs that reference topology identifier instance.";
+               // currently not used
+       }
+
+       typedef node-ref {
+               type leafref {
+                       path "/network/topologies/topology/nodes/node/node-id";
+               }
+               description "This type is used for leafs that reference a node instance.";
+       }
+
+       typedef link-ref {
+               type leafref {
+                       path "/network/topologies/topology/links/link/link-id";
+               }
+               description "This type is used for leafs that reference a link instance.";
+               // currently not used
+       }
+       
+       typedef network-element-ref {
+               type leafref {
+                       path "/network/network-elements/network-element/element-id";
+               }
+       }
+
+
+       typedef element-id {
+               type string;
+       }
+       
+       container network {
+               container topologies {
+                       list topology {
+                               description "
+                                       This is the model of abstract topology which contains only Network
+                                       Nodes and Network Links. Each topology MUST be identified by
+                                       unique topology-id for reason that the store could contain many
+                                       topologies.
+                               ";
+                               key "topology-id";
+                               leaf topology-id {
+                                       type topology-id; 
+                                       description "
+                                               It is presumed that datastore will contain many topologies. To
+                                               distinguish between topologies it is vital to have UNIQUE
+                                               topology identifier.
+                                       ";
+                               }
+
+                               container types {
+                                       description "
+                                               The container for definition of topology types.
+                                               The augmenting modules should add empty optional leaf 
+                                               to this container to signalize topology type.
+                                       ";
+                               }
+
+                               container nodes {
+                                       list node {
+                                               description "The list of network nodes defined for topology.";
+
+                                               key "node-id";
+                                               leaf node-id {
+                                                       type node-id;
+                                                       description "The Topology identifier of network-node.";
+                                               }
+
+                                               leaf supporting-ne {
+                                                       type network-element-ref;
+                                               }
+                                               
+                                               container termination-points {
+                                                       list termination-point {
+                                                               key "tp-id";
+                                                               leaf tp-id {
+                                                                       type tp-id;
+                                                               }
+                                                       }
+                                               }
+                                       }
+                               }
+               
+                               container links {
+                                       list link {
+                                               description "
+                                                       The Network Link which is defined by Local (Source) and
+                                                       Remote (Destination) Network Nodes. Every link MUST be
+                                                       defined either by identifier and his local and remote
+                                                       Network Nodes (in real applications it is common that many
+                                                       links are originated from one node and end up in same
+                                                       remote node). To ensure that we would always know to
+                                                       distinguish between links, every link SHOULD have
+                                                       identifier.
+                                               ";
+                                               key "link-id";
+               
+                                               leaf link-id {
+                                                       type link-id;
+                                               }
+                                               container source { 
+                                                       leaf source-node {
+                                                               type node-ref;
+                                                               description "Source node identifier.";
+                                                       }
+                                                       leaf source-tp {
+                                                               type tp-ref;
+                                                       }
+                                               }
+                                               container destination { 
+                                                       leaf dest-node {
+                                                               type node-ref;
+                                                               description "Destination node identifier.";
+                                                       }
+                                                       leaf dest-tp {
+                                                               type tp-ref;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               container network-elements {
+                       config true;
+                       list network-element {
+                               key "element-id";
+                               leaf element-id {
+                                       type element-id;
+                               }
+                       }
+               }
+       }
+       
+       rpc activate-software-image {
+         input {
+             leaf image-name {
+                 type string;
+             }
+         }
+         output {
+             leaf status {
+                 type string;
+             }
+         }
+     }
+     
+     rpc rock-the-house {
+         input {
+             leaf zip-code {
+                 type string;
+             }
+         }
+     }
+}
diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/controller-openflow.yang b/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/controller-openflow.yang
new file mode 100644 (file)
index 0000000..62e937e
--- /dev/null
@@ -0,0 +1,79 @@
+module controller-openflow {
+
+    namespace "urn:opendaylight:controller:openflow";
+    prefix "of";
+    import controller-network {prefix cn;}
+    
+    
+    revision 2013-05-20 {
+       description "Initial demo";
+    }
+
+   
+
+
+
+    typedef datapath-id {
+        type string {
+            length 16;
+        }
+    }
+
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:types" {
+        leaf openflow {type string;}
+    }
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:links/cn:link/cn:source" {
+        when "../../../cn:types/of:openflow";
+
+        leaf logical-port {
+            type int32;
+        }
+    }
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:links/cn:link/cn:destination" {
+        when "../../../cn:types/of:openflow";
+
+        leaf logical-port {
+            type int32;
+        }
+    }
+
+    augment "/cn:network/cn:topologies/cn:topology/cn:nodes/cn:node/" {
+        when "../../../cn:types/of:openflow";
+        leaf datapath-id {
+            type datapath-id;
+        }
+    }
+    
+    augment "/cn:network/cn:network-elements/cn:network-element" {
+        leaf datapath-id {
+            type datapath-id;
+        }
+
+        container ports {
+            list port {
+                key "logical-port-id";
+                
+                leaf logical-port-id {
+                    type int32;
+                }
+
+                // Should be replaced with ref to interface
+                leaf physical-name {
+                    type string;
+                }
+            }
+        }
+        container flow-tables {
+            list flow-table {
+                key "flow-table-id";
+                leaf flow-table-id {
+                    type string;
+                }
+
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/demo-topology.yang b/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/demo-topology.yang
new file mode 100644 (file)
index 0000000..4fef1cd
--- /dev/null
@@ -0,0 +1,121 @@
+module demo-topology {
+       yang-version 1;
+    namespace "urn:model.1demo-275topology.4.5.my";
+    prefix "tp";
+
+    organization "OPEN DAYLIGHT";
+    contact "http://www.opendaylight.org/";
+
+    description "
+               This module contains the definitions of elements that creates network 
+               topology i.e. definition of network nodes and links. This module is
+               not designed to be used solely for network representation. This module
+               SHOULD be used as base module in defining the network topology.
+       ";
+
+    revision "2013-02-08"{
+               reference " WILL BE DEFINED LATER";
+       }
+
+       container topology {
+        description "
+                       This is the model of abstract topology which contains only Network
+                       Nodes and Network Links. Each topology MUST be identified by
+                       unique topology-id for reason that the store could contain many
+                       topologies.
+               ";
+
+        leaf topology-id {
+            type string;
+            description "
+                               It is presumed that datastore will contain many topologies. To
+                               distinguish between topologies it is vital to have UNIQUE
+                               topology identifier.
+                       ";
+        }
+
+        container network-nodes {
+               list network-node {
+                   description "The list of network nodes defined for topology.";
+
+                       key "node-id";
+
+                       leaf node-id {
+                               type string;
+                               description "The Topology identifier of network-node.";
+                       }
+                
+                list network-interface {
+                    key "interface-id";
+                    
+                    leaf interface-id {
+                        type uint8;
+                    }
+                    
+                    leaf interface-address {
+                        type string;
+                    }
+                }
+                
+                   container node-attributes {
+                                       description "
+                                               Additional attributes that can Network Node contains.
+                                       ";
+
+                                       leaf geo-latitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+
+                                       leaf geo-longitude {
+                                               type decimal64 {
+                                                       fraction-digits 2;
+                                               }
+                                               config true;
+                                       }
+                               }
+               }
+        }
+        
+        container network-links {
+               list network-link {
+                   description "
+                                       The Network Link which is defined by Local (Source) and
+                                       Remote (Destination) Network Nodes. Every link MUST be
+                                       defined either by identifier and his local and remote
+                                       Network Nodes (in real applications it is common that many
+                                       links are originated from one node and end up in same
+                                       remote node). To ensure that we would always know to
+                                       distinguish between links, every link SHOULD have
+                                       identifier.
+                               ";
+                       key "link-id";
+
+                       leaf link-id {
+                               type string;
+                               description "";
+                       }
+
+                   container source {
+                                       leaf node-id {
+                                               type string;
+                                               description "Source node identifier.";
+                                       }
+                               }
+
+                               container destination {
+                                       leaf node-id {
+                                               type string;
+                                               description "Destination node identifier.";
+                                       }
+                               }
+
+                               container link-attributes {
+                                       description "Aditional attributes that can Network Link contains.";
+                               }
+                   }
+        }
+    }
+}
\ No newline at end of file
diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/ietf-inet-types@2010-09-24.yang b/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/ietf-inet-types@2010-09-24.yang
new file mode 100644 (file)
index 0000000..de20feb
--- /dev/null
@@ -0,0 +1,418 @@
+ module ietf-inet-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-inet-types";
+   prefix "inet";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types for Internet addresses and related things.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of protocol field related types ***/
+
+   typedef ip-version {
+     type enumeration {
+       enum unknown {
+         value "0";
+         description
+          "An unknown or unspecified version of the Internet protocol.";
+       }
+       enum ipv4 {
+         value "1";
+         description
+          "The IPv4 protocol as defined in RFC 791.";
+       }
+       enum ipv6 {
+         value "2";
+         description
+          "The IPv6 protocol as defined in RFC 2460.";
+       }
+     }
+     description
+      "This value represents the version of the IP protocol.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetVersion textual convention of the SMIv2.";
+     reference
+      "RFC  791: Internet Protocol
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   typedef dscp {
+     type uint8 {
+       range "0..63";
+     }
+     description
+      "The dscp type represents a Differentiated Services Code-Point
+       that may be used for marking packets in a traffic stream.
+
+       In the value set and its semantics, this type is equivalent
+       to the Dscp textual convention of the SMIv2.";
+     reference
+      "RFC 3289: Management Information Base for the Differentiated
+                 Services Architecture
+       RFC 2474: Definition of the Differentiated Services Field
+                 (DS Field) in the IPv4 and IPv6 Headers
+       RFC 2780: IANA Allocation Guidelines For Values In
+                 the Internet Protocol and Related Headers";
+   }
+
+   typedef ipv6-flow-label {
+     type uint32 {
+       range "0..1048575";
+     }
+     description
+      "The flow-label type represents flow identifier or Flow Label
+       in an IPv6 packet header that may be used to discriminate
+       traffic flows.
+
+       In the value set and its semantics, this type is equivalent
+       to the IPv6FlowLabel textual convention of the SMIv2.";
+     reference
+      "RFC 3595: Textual Conventions for IPv6 Flow Label
+       RFC 2460: Internet Protocol, Version 6 (IPv6) Specification";
+   }
+
+   typedef port-number {
+     type uint16 {
+       range "0..65535";
+     }
+     description
+      "The port-number type represents a 16-bit port number of an
+       Internet transport layer protocol such as UDP, TCP, DCCP, or
+       SCTP.  Port numbers are assigned by IANA.  A current list of
+       all assignments is available from <http://www.iana.org/>.
+
+       Note that the port number value zero is reserved by IANA.  In
+       situations where the value zero does not make sense, it can
+       be excluded by subtyping the port-number type.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetPortNumber textual convention of the SMIv2.";
+     reference
+      "RFC  768: User Datagram Protocol
+       RFC  793: Transmission Control Protocol
+       RFC 4960: Stream Control Transmission Protocol
+       RFC 4340: Datagram Congestion Control Protocol (DCCP)
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of autonomous system related types ***/
+
+   typedef as-number {
+     type uint32;
+     description
+      "The as-number type represents autonomous system numbers
+       which identify an Autonomous System (AS).  An AS is a set
+       of routers under a single technical administration, using
+       an interior gateway protocol and common metrics to route
+       packets within the AS, and using an exterior gateway
+       protocol to route packets to other ASs'.  IANA maintains
+       the AS number space and has delegated large parts to the
+       regional registries.
+
+       Autonomous system numbers were originally limited to 16
+       bits.  BGP extensions have enlarged the autonomous system
+       number space to 32 bits.  This type therefore uses an uint32
+       base type without a range restriction in order to support
+       a larger autonomous system number space.
+
+       In the value set and its semantics, this type is equivalent
+       to the InetAutonomousSystemNumber textual convention of
+       the SMIv2.";
+     reference
+      "RFC 1930: Guidelines for creation, selection, and registration
+                 of an Autonomous System (AS)
+       RFC 4271: A Border Gateway Protocol 4 (BGP-4)
+       RFC 4893: BGP Support for Four-octet AS Number Space
+       RFC 4001: Textual Conventions for Internet Network Addresses";
+   }
+
+   /*** collection of IP address and hostname related types ***/
+
+   typedef ip-address {
+     type union {
+       type inet:ipv4-address;
+       type inet:ipv6-address;
+     }
+     description
+      "The ip-address type represents an IP address and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-address {
+     type string {
+       pattern
+         '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+       +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+       + '(%[\p{N}\p{L}]+)?';
+     }
+     description
+       "The ipv4-address type represents an IPv4 address in
+        dotted-quad notation.  The IPv4 address may include a zone
+        index, separated by a % sign.
+
+        The zone index is used to disambiguate identical address
+        values.  For link-local addresses, the zone index will
+        typically be the interface index number or the name of an
+        interface.  If the zone index is not present, the default
+        zone of the device will be used.
+
+        The canonical format for the zone index is the numerical
+        format";
+   }
+
+   typedef ipv6-address {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(%[\p{N}\p{L}]+)?';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(%.+)?';
+     }
+     description
+      "The ipv6-address type represents an IPv6 address in full,
+       mixed, shortened, and shortened-mixed notation.  The IPv6
+       address may include a zone index, separated by a % sign.
+
+       The zone index is used to disambiguate identical address
+       values.  For link-local addresses, the zone index will
+       typically be the interface index number or the name of an
+       interface.  If the zone index is not present, the default
+       zone of the device will be used.
+
+       The canonical format of IPv6 addresses uses the compressed
+       format described in RFC 4291, Section 2.2, item 2 with the
+       following additional rules: the :: substitution must be
+       applied to the longest sequence of all-zero 16-bit chunks
+       in an IPv6 address.  If there is a tie, the first sequence
+       of all-zero 16-bit chunks is replaced by ::.  Single
+       all-zero 16-bit chunks are not compressed.  The canonical
+       format uses lowercase characters and leading zeros are
+       not allowed.  The canonical format for the zone index is
+       the numerical format as described in RFC 4007, Section
+       11.2.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture
+       RFC 4007: IPv6 Scoped Address Architecture
+       RFC 5952: A Recommendation for IPv6 Address Text Representation";
+   }
+
+   typedef ip-prefix {
+     type union {
+       type inet:ipv4-prefix;
+       type inet:ipv6-prefix;
+     }
+     description
+      "The ip-prefix type represents an IP prefix and is IP
+       version neutral.  The format of the textual representations
+       implies the IP version.";
+   }
+
+   typedef ipv4-prefix {
+     type string {
+       pattern
+          '(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}'
+        +  '([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])'
+        + '/(([0-9])|([1-2][0-9])|(3[0-2]))';
+     }
+     description
+      "The ipv4-prefix type represents an IPv4 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal to 32.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The canonical format of an IPv4 prefix has all bits of
+       the IPv4 address set to zero that are not part of the
+       IPv4 prefix.";
+   }
+
+   typedef ipv6-prefix {
+     type string {
+       pattern '((:|[0-9a-fA-F]{0,4}):)([0-9a-fA-F]{0,4}:){0,5}'
+             + '((([0-9a-fA-F]{0,4}:)?(:|[0-9a-fA-F]{0,4}))|'
+             + '(((25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])\.){3}'
+             + '(25[0-5]|2[0-4][0-9]|[01]?[0-9]?[0-9])))'
+             + '(/(([0-9])|([0-9]{2})|(1[0-1][0-9])|(12[0-8])))';
+       pattern '(([^:]+:){6}(([^:]+:[^:]+)|(.*\..*)))|'
+             + '((([^:]+:)*[^:]+)?::(([^:]+:)*[^:]+)?)'
+             + '(/.+)';
+     }
+     description
+      "The ipv6-prefix type represents an IPv6 address prefix.
+       The prefix length is given by the number following the
+       slash character and must be less than or equal 128.
+
+       A prefix length value of n corresponds to an IP address
+       mask that has n contiguous 1-bits from the most
+       significant bit (MSB) and all other bits set to 0.
+
+       The IPv6 address should have all bits that do not belong
+       to the prefix set to zero.
+
+       The canonical format of an IPv6 prefix has all bits of
+       the IPv6 address set to zero that are not part of the
+       IPv6 prefix.  Furthermore, IPv6 address is represented
+       in the compressed format described in RFC 4291, Section
+       2.2, item 2 with the following additional rules: the ::
+       substitution must be applied to the longest sequence of
+       all-zero 16-bit chunks in an IPv6 address.  If there is
+       a tie, the first sequence of all-zero 16-bit chunks is
+       replaced by ::.  Single all-zero 16-bit chunks are not
+       compressed.  The canonical format uses lowercase
+       characters and leading zeros are not allowed.";
+     reference
+      "RFC 4291: IP Version 6 Addressing Architecture";
+   }
+
+   /*** collection of domain name and URI types ***/
+
+   typedef domain-name {
+     type string {
+       pattern '((([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.)*'
+            +  '([a-zA-Z0-9_]([a-zA-Z0-9\-_]){0,61})?[a-zA-Z0-9]\.?)'
+            +  '|\.';
+       length "1..253";
+     }
+     description
+      "The domain-name type represents a DNS domain name.  The
+       name SHOULD be fully qualified whenever possible.
+
+       Internet domain names are only loosely specified.  Section
+       3.5 of RFC 1034 recommends a syntax (modified in Section
+       2.1 of RFC 1123).  The pattern above is intended to allow
+       for current practice in domain name use, and some possible
+       future expansion.  It is designed to hold various types of
+       domain names, including names used for A or AAAA records
+       (host names) and other records, such as SRV records.  Note
+       that Internet host names have a stricter syntax (described
+       in RFC 952) than the DNS recommendations in RFCs 1034 and
+       1123, and that systems that want to store host names in
+       schema nodes using the domain-name type are recommended to
+       adhere to this stricter standard to ensure interoperability.
+
+       The encoding of DNS names in the DNS protocol is limited
+       to 255 characters.  Since the encoding consists of labels
+       prefixed by a length bytes and there is a trailing NULL
+       byte, only 253 characters can appear in the textual dotted
+       notation.
+
+       The description clause of schema nodes using the domain-name
+       type MUST describe when and how these names are resolved to
+       IP addresses.  Note that the resolution of a domain-name value
+       may require to query multiple DNS records (e.g., A for IPv4
+       and AAAA for IPv6).  The order of the resolution process and
+       which DNS record takes precedence can either be defined
+       explicitely or it may depend on the configuration of the
+       resolver.
+
+       Domain-name values use the US-ASCII encoding.  Their canonical
+       format uses lowercase US-ASCII characters.  Internationalized
+       domain names MUST be encoded in punycode as described in RFC
+       3492";
+     reference
+      "RFC  952: DoD Internet Host Table Specification
+       RFC 1034: Domain Names - Concepts and Facilities
+       RFC 1123: Requirements for Internet Hosts -- Application
+                 and Support
+       RFC 2782: A DNS RR for specifying the location of services
+                 (DNS SRV)
+       RFC 3492: Punycode: A Bootstring encoding of Unicode for
+                 Internationalized Domain Names in Applications
+                 (IDNA)
+       RFC 5891: Internationalizing Domain Names in Applications
+                 (IDNA): Protocol";
+   }
+
+   typedef host {
+     type union {
+       type inet:ip-address;
+       type inet:domain-name;
+     }
+     description
+      "The host type represents either an IP address or a DNS
+       domain name.";
+   }
+
+   typedef uri {
+     type string;
+     description
+      "The uri type represents a Uniform Resource Identifier
+       (URI) as defined by STD 66.
+
+       Objects using the uri type MUST be in US-ASCII encoding,
+       and MUST be normalized as described by RFC 3986 Sections
+       6.2.1, 6.2.2.1, and 6.2.2.2.  All unnecessary
+       percent-encoding is removed, and all case-insensitive
+       characters are set to lowercase except for hexadecimal
+       digits, which are normalized to uppercase as described in
+       Section 6.2.2.1.
+
+       The purpose of this normalization is to help provide
+       unique URIs.  Note that this normalization is not
+       sufficient to provide uniqueness.  Two URIs that are
+       textually distinct after this normalization may still be
+       equivalent.
+
+       Objects using the uri type may restrict the schemes that
+       they permit.  For example, 'data:' and 'urn:' schemes
+       might not be appropriate.
+
+       A zero-length URI is not a valid URI.  This can be used to
+       express 'URI absent' where required.
+
+       In the value set and its semantics, this type is equivalent
+       to the Uri SMIv2 textual convention defined in RFC 5017.";
+     reference
+      "RFC 3986: Uniform Resource Identifier (URI): Generic Syntax
+       RFC 3305: Report from the Joint W3C/IETF URI Planning Interest
+                 Group: Uniform Resource Identifiers (URIs), URLs,
+                 and Uniform Resource Names (URNs): Clarifications
+                 and Recommendations
+       RFC 5017: MIB Textual Conventions for Uniform Resource
+                 Identifiers (URIs)";
+   }
+
+ }
diff --git a/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/ietf-yang-types@2010-09-24.yang b/code-generator/maven-sal-api-gen-plugin/src/test/resources/wadl-gen/ietf-yang-types@2010-09-24.yang
new file mode 100644 (file)
index 0000000..51d9f8b
--- /dev/null
@@ -0,0 +1,396 @@
+ module ietf-yang-types {
+
+   namespace "urn:ietf:params:xml:ns:yang:ietf-yang-types";
+   prefix "yang";
+
+   organization
+    "IETF NETMOD (NETCONF Data Modeling Language) Working Group";
+
+   contact
+    "WG Web:   <http://tools.ietf.org/wg/netmod/>
+     WG List:  <mailto:netmod@ietf.org>
+
+     WG Chair: David Partain
+               <mailto:david.partain@ericsson.com>
+
+     WG Chair: David Kessens
+               <mailto:david.kessens@nsn.com>
+
+     Editor:   Juergen Schoenwaelder
+               <mailto:j.schoenwaelder@jacobs-university.de>";
+
+   description
+    "This module contains a collection of generally useful derived
+     YANG data types.
+
+     Copyright (c) 2010 IETF Trust and the persons identified as
+     authors of the code.  All rights reserved.
+
+     Redistribution and use in source and binary forms, with or without
+     modification, is permitted pursuant to, and subject to the license
+     terms contained in, the Simplified BSD License set forth in Section
+     4.c of the IETF Trust's Legal Provisions Relating to IETF Documents
+     (http://trustee.ietf.org/license-info).
+
+     This version of this YANG module is part of RFC 6021; see
+     the RFC itself for full legal notices.";
+
+   revision 2010-09-24 {
+     description
+      "Initial revision.";
+     reference
+      "RFC 6021: Common YANG Data Types";
+   }
+
+   /*** collection of counter and gauge types ***/
+
+   typedef counter32 {
+     type uint32;
+     description
+      "The counter32 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter32 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter32 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter32.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter32 {
+     type yang:counter32;
+     default "0";
+     description
+      "The zero-based-counter32 type represents a counter32
+       that has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^32-1 (4294967295 decimal), when it
+       wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter32 textual convention of the SMIv2.";
+     reference
+       "RFC 4502: Remote Network Monitoring Management Information
+                  Base Version 2";
+   }
+
+   typedef counter64 {
+     type uint64;
+     description
+      "The counter64 type represents a non-negative integer
+       that monotonically increases until it reaches a
+       maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Counters have no defined 'initial' value, and thus, a
+       single value of a counter has (in general) no information
+       content.  Discontinuities in the monotonically increasing
+       value normally occur at re-initialization of the
+       management system, and at other times as specified in the
+       description of a schema node using this type.  If such
+       other times can occur, for example, the creation of
+       a schema node of type counter64 at times other than
+       re-initialization, then a corresponding schema node
+       should be defined, with an appropriate type, to indicate
+       the last discontinuity.
+
+       The counter64 type should not be used for configuration
+       schema nodes.  A default statement SHOULD NOT be used in
+       combination with the type counter64.
+
+       In the value set and its semantics, this type is equivalent
+       to the Counter64 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef zero-based-counter64 {
+     type yang:counter64;
+     default "0";
+     description
+      "The zero-based-counter64 type represents a counter64 that
+       has the defined 'initial' value zero.
+
+       A schema node of this type will be set to zero (0) on creation
+       and will thereafter increase monotonically until it reaches
+       a maximum value of 2^64-1 (18446744073709551615 decimal),
+       when it wraps around and starts increasing again from zero.
+
+       Provided that an application discovers a new schema node
+       of this type within the minimum time to wrap, it can use the
+       'initial' value as a delta.  It is important for a management
+       station to be aware of this minimum time and the actual time
+       between polls, and to discard data if the actual time is too
+       long or there is no defined minimum time.
+
+       In the value set and its semantics, this type is equivalent
+       to the ZeroBasedCounter64 textual convention of the SMIv2.";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   typedef gauge32 {
+     type uint32;
+     description
+      "The gauge32 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^32-1 (4294967295 decimal), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge32 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge32 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the Gauge32 type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef gauge64 {
+     type uint64;
+     description
+      "The gauge64 type represents a non-negative integer, which
+       may increase or decrease, but shall never exceed a maximum
+       value, nor fall below a minimum value.  The maximum value
+       cannot be greater than 2^64-1 (18446744073709551615), and
+       the minimum value cannot be smaller than 0.  The value of
+       a gauge64 has its maximum value whenever the information
+       being modeled is greater than or equal to its maximum
+       value, and has its minimum value whenever the information
+       being modeled is smaller than or equal to its minimum value.
+       If the information being modeled subsequently decreases
+       below (increases above) the maximum (minimum) value, the
+       gauge64 also decreases (increases).
+
+       In the value set and its semantics, this type is equivalent
+       to the CounterBasedGauge64 SMIv2 textual convention defined
+       in RFC 2856";
+     reference
+      "RFC 2856: Textual Conventions for Additional High Capacity
+                 Data Types";
+   }
+
+   /*** collection of identifier related types ***/
+
+   typedef object-identifier {
+     type string {
+       pattern '(([0-1](\.[1-3]?[0-9]))|(2\.(0|([1-9]\d*))))'
+             + '(\.(0|([1-9]\d*)))*';
+     }
+     description
+      "The object-identifier type represents administratively
+       assigned names in a registration-hierarchical-name tree.
+
+       Values of this type are denoted as a sequence of numerical
+       non-negative sub-identifier values.  Each sub-identifier
+       value MUST NOT exceed 2^32-1 (4294967295).  Sub-identifiers
+       are separated by single dots and without any intermediate
+       whitespace.
+
+       The ASN.1 standard restricts the value space of the first
+       sub-identifier to 0, 1, or 2.  Furthermore, the value space
+       of the second sub-identifier is restricted to the range
+       0 to 39 if the first sub-identifier is 0 or 1.  Finally,
+       the ASN.1 standard requires that an object identifier
+       has always at least two sub-identifier.  The pattern
+       captures these restrictions.
+
+       Although the number of sub-identifiers is not limited,
+       module designers should realize that there may be
+       implementations that stick with the SMIv2 limit of 128
+       sub-identifiers.
+
+       This type is a superset of the SMIv2 OBJECT IDENTIFIER type
+       since it is not restricted to 128 sub-identifiers.  Hence,
+       this type SHOULD NOT be used to represent the SMIv2 OBJECT
+       IDENTIFIER type, the object-identifier-128 type SHOULD be
+       used instead.";
+     reference
+      "ISO9834-1: Information technology -- Open Systems
+       Interconnection -- Procedures for the operation of OSI
+       Registration Authorities: General procedures and top
+       arcs of the ASN.1 Object Identifier tree";
+   }
+
+
+
+
+   typedef object-identifier-128 {
+     type object-identifier {
+       pattern '\d*(\.\d*){1,127}';
+     }
+     description
+      "This type represents object-identifiers restricted to 128
+       sub-identifiers.
+
+       In the value set and its semantics, this type is equivalent
+       to the OBJECT IDENTIFIER type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   /*** collection of date and time related types ***/
+
+   typedef date-and-time {
+     type string {
+       pattern '\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d+)?'
+             + '(Z|[\+\-]\d{2}:\d{2})';
+     }
+     description
+      "The date-and-time type is a profile of the ISO 8601
+       standard for representation of dates and times using the
+       Gregorian calendar.  The profile is defined by the
+       date-time production in Section 5.6 of RFC 3339.
+
+       The date-and-time type is compatible with the dateTime XML
+       schema type with the following notable exceptions:
+
+       (a) The date-and-time type does not allow negative years.
+
+       (b) The date-and-time time-offset -00:00 indicates an unknown
+           time zone (see RFC 3339) while -00:00 and +00:00 and Z all
+           represent the same time zone in dateTime.
+
+       (c) The canonical format (see below) of data-and-time values
+           differs from the canonical format used by the dateTime XML
+           schema type, which requires all times to be in UTC using the
+           time-offset 'Z'.
+
+       This type is not equivalent to the DateAndTime textual
+       convention of the SMIv2 since RFC 3339 uses a different
+       separator between full-date and full-time and provides
+       higher resolution of time-secfrac.
+
+       The canonical format for date-and-time values with a known time
+       zone uses a numeric time zone offset that is calculated using
+       the device's configured known offset to UTC time.  A change of
+       the device's offset to UTC time will cause date-and-time values
+       to change accordingly.  Such changes might happen periodically
+       in case a server follows automatically daylight saving time
+       (DST) time zone offset changes.  The canonical format for
+       date-and-time values with an unknown time zone (usually referring
+       to the notion of local time) uses the time-offset -00:00.";
+     reference
+      "RFC 3339: Date and Time on the Internet: Timestamps
+       RFC 2579: Textual Conventions for SMIv2
+       XSD-TYPES: XML Schema Part 2: Datatypes Second Edition";
+   }
+
+   typedef timeticks {
+     type uint32;
+     description
+      "The timeticks type represents a non-negative integer that
+       represents the time, modulo 2^32 (4294967296 decimal), in
+       hundredths of a second between two epochs.  When a schema
+       node is defined that uses this type, the description of
+       the schema node identifies both of the reference epochs.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeTicks type of the SMIv2.";
+     reference
+      "RFC 2578: Structure of Management Information Version 2 (SMIv2)";
+   }
+
+   typedef timestamp {
+     type yang:timeticks;
+     description
+      "The timestamp type represents the value of an associated
+       timeticks schema node at which a specific occurrence happened.
+       The specific occurrence must be defined in the description
+       of any schema node defined using this type.  When the specific
+       occurrence occurred prior to the last time the associated
+       timeticks attribute was zero, then the timestamp value is
+       zero.  Note that this requires all timestamp values to be
+       reset to zero when the value of the associated timeticks
+       attribute reaches 497+ days and wraps around to zero.
+
+       The associated timeticks schema node must be specified
+       in the description of any schema node using this type.
+
+       In the value set and its semantics, this type is equivalent
+       to the TimeStamp textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of generic address types ***/
+
+   typedef phys-address {
+     type string {
+       pattern '([0-9a-fA-F]{2}(:[0-9a-fA-F]{2})*)?';
+     }
+     description
+      "Represents media- or physical-level addresses represented
+       as a sequence octets, each octet represented by two hexadecimal
+       numbers.  Octets are separated by colons.  The canonical
+       representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the PhysAddress textual convention of the SMIv2.";
+     reference
+      "RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   typedef mac-address {
+     type string {
+       pattern '[0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5}';
+     }
+     description
+      "The mac-address type represents an IEEE 802 MAC address.
+       The canonical representation uses lowercase characters.
+
+       In the value set and its semantics, this type is equivalent
+       to the MacAddress textual convention of the SMIv2.";
+     reference
+      "IEEE 802: IEEE Standard for Local and Metropolitan Area
+                 Networks: Overview and Architecture
+       RFC 2579: Textual Conventions for SMIv2";
+   }
+
+   /*** collection of XML specific types ***/
+
+   typedef xpath1.0 {
+     type string;
+     description
+      "This type represents an XPATH 1.0 expression.
+
+       When a schema node is defined that uses this type, the
+       description of the schema node MUST specify the XPath
+       context in which the XPath expression is evaluated.";
+     reference
+      "XPATH: XML Path Language (XPath) Version 1.0";
+   }
+
+ }
index db78ba71dd70df6183d5d897f4df7a1321d9e392..24ce16c819b7de6015702fd7b44fc5396e6621a2 100644 (file)
     <build>\r
         <plugins>\r
             <plugin>\r
-                <groupId>org.apache.maven.plugins</groupId>\r
                 <artifactId>maven-jar-plugin</artifactId>\r
-                <version>${maven.jar.version}</version>\r
-                <configuration>\r
-                    <archive>\r
-                        <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>\r
-                    </archive>\r
-                </configuration>\r
             </plugin>\r
             <plugin>\r
                 <groupId>org.apache.felix</groupId>\r
                     </instructions>\r
                 </configuration>\r
             </plugin>\r
-            <plugin>\r
-                <groupId>org.opendaylight.yangtools</groupId>\r
-                <artifactId>yang-maven-plugin</artifactId>\r
-                <version>0.5.9-SNAPSHOT</version>\r
-                <executions>\r
-                    <execution>\r
-                        <goals>\r
-                            <goal>generate-sources</goal>\r
-                        </goals>\r
-                        <configuration>\r
-                            <yangFilesRootDir>src/main/yang</yangFilesRootDir>\r
-                            <codeGenerators>\r
-                                <generator>\r
-                                    <codeGeneratorClass>\r
-                                        org.opendaylight.yangtools.maven.sal.api.gen.plugin.CodeGeneratorImpl\r
-                                    </codeGeneratorClass>\r
-                                    <outputBaseDir>\r
-                                        target/generated-sources/sal\r
-                                    </outputBaseDir>\r
-                                </generator>\r
-                            </codeGenerators>\r
-                            <inspectDependencies>true</inspectDependencies>\r
-                        </configuration>\r
-                    </execution>\r
-                </executions>\r
-                <dependencies>\r
-                    <dependency>\r
-                        <groupId>org.opendaylight.yangtools</groupId>\r
-                        <artifactId>maven-sal-api-gen-plugin</artifactId>\r
-                        <version>0.5.8-SNAPSHOT</version>\r
-                        <type>jar</type>\r
-                    </dependency>\r
-                </dependencies>\r
-            </plugin>\r
-            <plugin>\r
-                <groupId>org.codehaus.mojo</groupId>\r
-                <artifactId>build-helper-maven-plugin</artifactId>\r
-                <version>1.7</version>\r
-                <executions>\r
-                    <execution>\r
-                        <phase>generate-sources</phase>\r
-                        <goals>\r
-                            <goal>add-source</goal>\r
-                        </goals>\r
-                        <configuration>\r
-                            <sources>\r
-                                <source>target/generated-sources/sal</source>\r
-                            </sources>\r
-                        </configuration>\r
-                    </execution>\r
-                </executions>\r
-            </plugin>\r
         </plugins>\r
-        <pluginManagement>\r
-            <plugins>\r
-                <!--This plugin's configuration is used to store Eclipse \r
-                    m2e settings only. It has no influence on the Maven build itself. -->\r
-                <plugin>\r
-                    <groupId>org.eclipse.m2e</groupId>\r
-                    <artifactId>lifecycle-mapping</artifactId>\r
-                    <version>1.0.0</version>\r
-                    <configuration>\r
-                        <lifecycleMappingMetadata>\r
-                            <pluginExecutions>\r
-                                <pluginExecution>\r
-                                    <pluginExecutionFilter>\r
-                                        <groupId>\r
-                                            org.opendaylight.yangtools\r
-                                        </groupId>\r
-                                        <artifactId>\r
-                                            yang-maven-plugin\r
-                                        </artifactId>\r
-                                        <versionRange>\r
-                                            [0.5,)\r
-                                        </versionRange>\r
-                                        <goals>\r
-                                            <goal>\r
-                                                generate-sources\r
-                                            </goal>\r
-                                        </goals>\r
-                                    </pluginExecutionFilter>\r
-                                    <action>\r
-                                        <ignore />\r
-                                    </action>\r
-                                </pluginExecution>\r
-                            </pluginExecutions>\r
-                        </lifecycleMappingMetadata>\r
-                    </configuration>\r
-                </plugin>\r
-            </plugins>\r
-        </pluginManagement>\r
     </build>\r
 \r
-    <dependencies>\r
-        <dependency>\r
-            <groupId>org.opendaylight.yangtools</groupId>\r
-            <artifactId>yang-binding</artifactId>\r
-            <version>0.5.9-SNAPSHOT</version>\r
-        </dependency>\r
-        <dependency>\r
-            <groupId>org.opendaylight.yangtools</groupId>\r
-            <artifactId>yang-common</artifactId>\r
-            <version>0.5.9-SNAPSHOT</version>\r
-        </dependency>\r
-    </dependencies>\r
-\r
 </project>\r
index 9b8f6e335fb713ac0ba852e56692f806cd80bcfe..790889a2d70b6ede50197b3bc81355354d23d137 100644 (file)
@@ -21,12 +21,12 @@ import org.slf4j.LoggerFactory;
 /**
  * The QName from XML consists of local name of element and XML namespace, but
  * for our use, we added module revision to it.
- * 
+ *
  * In YANG context QName is full name of defined node, type, procedure or
  * notification. QName consists of XML namespace, YANG model revision and local
  * name of defined type. It is used to prevent name clashes between nodes with
  * same local name, but from different schemas.
- * 
+ *
  * <ul>
  * <li><b>XMLNamespace</b> - the namespace assigned to the YANG module which
  * defined element, type, procedure or notification.</li>
@@ -35,8 +35,8 @@ import org.slf4j.LoggerFactory;
  * <li><b>LocalName</b> - the YANG schema identifier which were defined for this
  * node in the YANG module</li>
  * </ul>
- * 
- * 
+ *
+ *
  */
 public final class QName implements Immutable,Serializable {
 
@@ -45,17 +45,17 @@ public final class QName implements Immutable,Serializable {
     protected static final Logger LOGGER = LoggerFactory.getLogger(QName.class);
 
     private static final ThreadLocal<SimpleDateFormat> REVISION_FORMAT = new ThreadLocal<SimpleDateFormat>() {
-        
+
         protected SimpleDateFormat initialValue() {
             return new SimpleDateFormat("yyyy-MM-dd");
         };
-        
+
         public void set(SimpleDateFormat value) {
             throw new UnsupportedOperationException();
         };
-        
+
     };
-    
+
     private final URI namespace;
     private final String localName;
     private final String prefix;
@@ -64,7 +64,7 @@ public final class QName implements Immutable,Serializable {
 
     /**
      * QName Constructor.
-     * 
+     *
      * @param namespace
      *            the namespace assigned to the YANG module
      * @param revision
@@ -88,7 +88,7 @@ public final class QName implements Immutable,Serializable {
 
     /**
      * QName Constructor.
-     * 
+     *
      * @param namespace
      *            the namespace assigned to the YANG module
      * @param localName
@@ -100,7 +100,7 @@ public final class QName implements Immutable,Serializable {
 
     /**
      * QName Constructor.
-     * 
+     *
      * @param namespace
      *            the namespace assigned to the YANG module
      * @param revision
@@ -116,9 +116,31 @@ public final class QName implements Immutable,Serializable {
         this(base.getNamespace(), base.getRevision(), base.getPrefix(), localName);
     }
 
+    // TODO: rework with pattern
+    public QName(String base) throws ParseException {
+        Date revision = null;
+        String nsAndRev = base.substring(base.indexOf("(") + 1, base.indexOf(")"));
+        if (nsAndRev.contains("?")) {
+            String[] splitted = nsAndRev.split("\\?");
+            this.namespace = URI.create(splitted[0]);
+            revision = REVISION_FORMAT.get().parse(splitted[1]);
+        } else {
+            this.namespace = URI.create(nsAndRev);
+        }
+
+        this.localName = base.substring(base.indexOf(")") + 1);
+        this.revision = revision;
+        this.prefix = null;
+        if (revision != null) {
+            this.formattedRevision = REVISION_FORMAT.get().format(revision);
+        } else {
+            this.formattedRevision = null;
+        }
+    }
+
     /**
      * Returns XMLNamespace assigned to the YANG module.
-     * 
+     *
      * @return XMLNamespace assigned to the YANG module.
      */
     public URI getNamespace() {
@@ -128,7 +150,7 @@ public final class QName implements Immutable,Serializable {
     /**
      * Returns YANG schema identifier which were defined for this node in the
      * YANG module
-     * 
+     *
      * @return YANG schema identifier which were defined for this node in the
      *         YANG module
      */
@@ -139,7 +161,7 @@ public final class QName implements Immutable,Serializable {
     /**
      * Returns revision of the YANG module if the module has defined revision,
      * otherwise returns <code>null</code>
-     * 
+     *
      * @return revision of the YANG module if the module has defined revision,
      *         otherwise returns <code>null</code>
      */
@@ -149,7 +171,7 @@ public final class QName implements Immutable,Serializable {
 
     /**
      * Returns locally defined prefix assigned to local name
-     * 
+     *
      * @return locally defined prefix assigned to local name
      */
     public String getPrefix() {
@@ -201,17 +223,17 @@ public final class QName implements Immutable,Serializable {
         }
         return true;
     }
-    
-    
+
+
     public static QName create(QName base, String localName){
         return new QName(base, localName);
     }
-    
+
     public static QName create(URI namespace, Date revision, String localName){
         return new QName(namespace, revision, localName);
     }
-    
-    
+
+
     public static QName create(String namespace, String revision, String localName) throws IllegalArgumentException{
         try {
             URI namespaceUri = new URI(namespace);
@@ -244,11 +266,11 @@ public final class QName implements Immutable,Serializable {
      * ://tools.ietf.org/html/rfc6020}, if namespace is not correctly defined,
      * the method will return <code>null</code> <br>
      * example "http://example.acme.com/system?revision=2008-04-01"
-     * 
+     *
      * @return namespace in form defined by section 5.6.4. of {@link https
      *         ://tools.ietf.org/html/rfc6020}, if namespace is not correctly
      *         defined, the method will return <code>null</code>
-     * 
+     *
      */
     URI getRevisionNamespace() {
 
@@ -270,7 +292,7 @@ public final class QName implements Immutable,Serializable {
         }
         return compositeURI;
     }
-    
+
     public String getFormattedRevision() {
         return formattedRevision;
     }
index 4aaeb5d375a7a2a49c6ce46595c1ab6ced65194c..b7ed7b11f3f1490be7ff5fb7d0582571925d69f7 100644 (file)
@@ -1,5 +1,7 @@
 package org.opendaylight.yangtools.yang.data.api.codec;
 
+import org.opendaylight.yangtools.concepts.Codec;
+
 /**
  * 
  * FIXME: Should be changed to UnsignedByte
@@ -8,7 +10,7 @@ package org.opendaylight.yangtools.yang.data.api.codec;
  *
  * @param <T>
  */
-public interface Uint8Codec<T> {
+public interface Uint8Codec<T> extends Codec<T,Short>{
 
     public T serialize(Short data);
 
diff --git a/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/codec/UnionCodec.java b/yang/yang-data-api/src/main/java/org/opendaylight/yangtools/yang/data/api/codec/UnionCodec.java
new file mode 100644 (file)
index 0000000..4337687
--- /dev/null
@@ -0,0 +1,10 @@
+package org.opendaylight.yangtools.yang.data.api.codec;
+
+import org.opendaylight.yangtools.concepts.Codec;
+
+public interface UnionCodec<T> extends Codec<T,String> {
+
+    public T serialize(String data);
+
+    public String deserialize(T data);
+}
index 31a23b509c56442daa25be86b15dab384a4069ef..eb0d319fc1faa27f8024a4ccef45790c5fe7467c 100644 (file)
@@ -6,8 +6,6 @@ import java.math.BigDecimal;
 import java.math.BigInteger;
 import java.util.Set;
 
-import javax.xml.bind.DatatypeConverter;
-
 import org.opendaylight.yangtools.yang.data.api.codec.*;
 import org.opendaylight.yangtools.yang.model.api.TypeDefinition;
 import org.opendaylight.yangtools.yang.model.api.type.*;
@@ -66,6 +64,9 @@ public abstract class TypeDefinitionAwareCodec<J, T extends TypeDefinition<T>> i
     public static final Uint64CodecStringImpl UINT64_DEFAULT_CODEC = new Uint64CodecStringImpl(
             Optional.<UnsignedIntegerTypeDefinition> absent());
 
+    public static final UnionCodecStringImpl UNION_DEFAULT_CODEC = new UnionCodecStringImpl(
+            Optional.<UnionTypeDefinition> absent());
+
     public Class<J> getInputClass() {
         return inputClass;
     }
@@ -119,6 +120,8 @@ public abstract class TypeDefinitionAwareCodec<J, T extends TypeDefinition<T>> i
             }
         } else if (superType instanceof StringTypeDefinition) {
             codec = STRING_DEFAULT_CODEC;
+        } else if (superType instanceof UnionTypeDefinition) {
+            codec = UNION_DEFAULT_CODEC;
         } else if (superType instanceof UnsignedIntegerTypeDefinition) {
             if (UINT8_QNAME.equals(superType.getQName())) {
                 codec = UINT8_DEFAULT_CODEC;
@@ -407,4 +410,22 @@ public abstract class TypeDefinitionAwareCodec<J, T extends TypeDefinition<T>> i
             return new BigDecimal(stringRepresentation);
         }
     };
+
+    public static class UnionCodecStringImpl extends TypeDefinitionAwareCodec<String, UnionTypeDefinition> implements
+            UnionCodec<String> {
+
+        protected UnionCodecStringImpl(Optional<UnionTypeDefinition> typeDef) {
+            super(typeDef, String.class);
+        }
+
+        @Override
+        public String serialize(String data) {
+            return data;
+        }
+
+        @Override
+        public String deserialize(String stringRepresentation) {
+            return stringRepresentation;
+        }
+    };
 }