--- /dev/null
+=== YANG Java Binding: Mapping rules\r
+This chapter covers the details of mapping YANG to Java.\r
+\r
+NOTE: The following source code examples does not show canonical generated\r
+code, but rather illustrative example. Generated classes and interfaces may\r
+differ from this examples, but APIs are preserved.\r
+\r
+==== General conversion rules\r
+\r
+===== Package names of YANG models\r
+\r
+The package name consists of the following parts: +\r
+\r
+* *Opendaylight prefix* - Specifies the opendaylight prefix. Every package name\r
+starts with the prefix `org.opendaylight.yang.gen.v`.\r
+* *Java Binding version* - Specifies the YANG Java Binding version.\r
+ Curent Binding version is `1`.\r
+* *Namespace* - Specified by the value of `namespace` substatement.\r
+ URI is converted to package name structure.\r
+* *Revision* - Specifies the concatenation of word `rev` and value of `module`\r
+ substatements `revision` argument value without leading zeros before month and day.\r
+ For example: `rev201379`\r
+\r
+After the package name is generated, we check if it contains any Java keywords\r
+or starts with a digit. If so, then we add an underscore before the offending\r
+token.\r
+\r
+The following is a list of keywords which are prefixed with underscore:\r
+\r
+abstract, assert, boolean, break, byte, case, catch, char, class, const,\r
+continue, default, double, do, else, enum, extends, false, final, finally,\r
+float, for, goto, if, implements, import, instanceof, int, interface, long,\r
+native, new, null, package, private, protected, public, return, short, static,\r
+strictfp, super, switch, synchronized, this, throw, throws, transient, true, try,\r
+void, volatile, while\r
+\r
+As an example suppose following yang model:\r
+\r
+[source, yang]\r
+----\r
+module module {\r
+ namespace "urn:2:case#module";\r
+ prefix "sbd";\r
+ organization "OPEN DAYLIGHT";\r
+ contact "http://www.example.com/";\r
+ revision 2013-07-09 {\r
+ }\r
+}\r
+----\r
+\r
+After applying rules (replacing digits and Java keywords) the resulting\r
+package name is `org.opendaylight.yang.gen.v1.urn._2._case.module.rev201379`\r
+\r
+===== Additional Packages\r
+\r
+In cases when YANG statement contain some of specific YANG\r
+statements additional packages are generated to designate this containment.\r
+Table below provides details of parent statement and nested statements, which\r
+yields additional package generation:\r
+\r
+[options="header"]\r
+|===\r
+|Parent statement | Substatement\r
+|`list` |list, container, choice\r
+|`container` | list, container, choice\r
+|`choice` | leaf, list, leaf-list, container, case\r
+|`case` | list, container, choice\r
+|rpc `input` or `output` | list, container, (choice isn't supported)\r
+|`notification` | list, container, (choice isn't supported)\r
+|`augment` | list, container, choice, case |\r
+|===\r
+\r
+Substatements are not only mapped to Java setter methods in the interface\r
+representing the parent statement, but they also generate packages with\r
+names consisting of the parent statement package name with the parent statement\r
+name appended.\r
+\r
+For example, this YANG model considers the container statement `cont` as the\r
+direct substatement of the module.\r
+\r
+[source, yang]\r
+----\r
+container cont {\r
+ container cont-inner {\r
+ }\r
+ list outter-list {\r
+ list list-in-list {\r
+ }\r
+ }\r
+}\r
+----\r
+\r
+Container `cont` is the parent statement for the substatements\r
+`cont-inner` and `outter-list`. `list outter-list` is the parent\r
+statement for substatement `list-in-list`.\r
+\r
+Java code is generated in the following structure: +\r
+\r
+* `org.opendaylight.yang.gen.v1.urn.module.rev201379` - package contains direct\r
+ substatements of module statement\r
+** `Cont.java`\r
+* `org.opendaylight.yang.gen.v1.urn.module.rev201379.cont` - package contains\r
+ substatements of `cont` container statement\r
+** `ContInner.java` - interface representing container `cont-inner`\r
+** `OutterList.java` - interface representing list `outer-list`\r
+* `org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.outter.list` - package\r
+ contains substatements of outter-list list element\r
+ ** `ListInList.java`\r
+\r
+===== Class and interface names\r
+Some YANG statements are mapped to Java classes and interfaces. The name of YANG\r
+element may contain various characters which aren't permitted in Java class names.\r
+Firstly whitespaces are trimmed from YANG name. Next the characters space, -, `\r
+are deleted and the subsequent letter is capitalized. At the end, first letter is\r
+capitalized.\r
+\r
+For example, \r
+`example-name_ without_capitalization` would map to\r
+`ExampleNameWithoutCapitalization`.\r
+\r
+===== Getter and setter names\r
+In some cases, YANG statements are converted to getter and/or setter methods.\r
+The process for getter is:\r
+\r
+. the name of YANG statement is converted to Java class name style as \r
+ <<_class_and_interface_names,explained above>>.\r
+. the word `get` is added as prefix, if resulting type is `Boolean`, the name\r
+ is prefixed with `is` prefix instead of `get`.\r
+. the return type of the getter method is set to Java type representing substatement\r
+\r
+The process for setter is:\r
+\r
+. the name of YANG statement is converted to Java class name style as\r
+ <<_class_and_interface_names,explained above>>.\r
+. the word `set` is added as prefix\r
+. the input parameter name is set to element's name converted to Java parameter style\r
+. the return parameter is set to builder type\r
+\r
+==== Statement specific mapping\r
+\r
+===== module statement\r
+\r
+YANG `module` statement is converted to Java as two Java classes.\r
+Each of the classes is in the separate Java file. The names of Java files are\r
+composed as follows:\r
+`<module name><suffix>.java` where `<suffix>` is either data or service.\r
+\r
+====== Data Interface\r
+\r
+Data Interface has a mapping similar to container, but contains only top level\r
+nodes defined in module.\r
+\r
+Data interface serves only as marker interface for type-safe APIs of\r
+`InstanceIdentifier`.\r
+\r
+====== Service Interface\r
+\r
+Service Interface serves to describe RPC contract defined in the module.\r
+This RPC contract is defined by `rpc` statements.\r
+\r
+RPC implementation usually implement this interface and users of the RPCs\r
+use this interface to invoke RPCs.\r
+\r
+===== container statement\r
+YANG containers are mapped to Java interfaces which extend the Java DataObject and\r
+Augmentable<container-interface>, where container-interface is the name of the mapped\r
+interface.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+container cont {\r
+\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.Cont.java\r
+[source, java]\r
+----\r
+public interface Cont extends ChildOf<...>, Augmentable<Cont> {\r
+}\r
+----\r
+\r
+===== Leaf statement\r
+Each leaf has to contain at least one type substatement. The leaf is mapped to\r
+getter method of parent statement with return type equal to type substatement\r
+value.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+container cont {\r
+ leaf lf {\r
+ type string;\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.Cont.java\r
+[source, java]\r
+----\r
+public interface Cont extends DataObject, Augmentable<Cont> {\r
+ String getLf(); // <1>\r
+}\r
+----\r
+\r
+<1> Represents `leaf lf`\r
+\r
+===== leaf-list statement\r
+Each leaf-list has to contain one type substatement. The leaf-list is mapped\r
+to getter method of parent statement with return type equal to List of type\r
+substatement value.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+container cont {\r
+ leaf-list lf-lst {\r
+ type string;\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.Cont.java\r
+[source, java]\r
+----\r
+public interface Cont extends DataObject, Augmentable<Cont> {\r
+ List<String> getLfLst();\r
+}\r
+----\r
+\r
+===== list statement\r
+\r
+`list` statements are mapped to Java interfaces and a getter method is\r
+generated in the interface associated with it's parent statement.\r
+The return type of getter the method is a Java List of objects implementing\r
+the interface generated corresponding to the `list statement.\r
+Mapping of `list` substatement to Java:\r
+\r
+//[options="header"]\r
+//|===\r
+//|Substatement|Mapping to Java\r
+//|Key|Class\r
+//|===\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+container cont {\r
+ list outter-list {\r
+ key "leaf-in-list";\r
+ leaf number {\r
+ type uint64;\r
+ }\r
+ }\r
+}\r
+----\r
+\r
+The list statement `example-list` is mapped to the Java interface `ExampleList` and\r
+the `Cont` interface (parent of `ExampleList`) contains getter method with return\r
+type `List<ExampleList>`. The presence of a `key` statement, triggers generation\r
+of `ExampleListKey`, which may be used to identify item in list.\r
+\r
+The end result is this Java:\r
+\r
+.OutterList.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentable;\r
+import Java.util.List;\r
+import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.outter.list.ListInList;\r
+\r
+public interface OutterList extends DataObject, Augmentable<OutterList> {\r
+\r
+ List<String> getLeafListInList();\r
+\r
+ List<ListInList> getListInList();\r
+\r
+ /*\r
+ Returns Primary Key of Yang List Type\r
+ */\r
+ OutterListKey getOutterListKey();\r
+\r
+}\r
+----\r
+\r
+.OutterListKey.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;\r
+\r
+import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.OutterListKey;\r
+import Java.math.BigInteger;\r
+\r
+public class OutterListKey {\r
+\r
+ private BigInteger _leafInList;\r
+\r
+ public OutterListKey(BigInteger _leafInList) {\r
+ super();\r
+ this_leafInList = _leafInList;\r
+ }\r
+\r
+ public BigInteger getLeafInList() {\r
+ return _leafInList;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ final int prime = 31;\r
+ int result = 1;\r
+ result = prime * result + ((_leafInList == null) ? 0 : _leafInList.hashCode());\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+ if (obj == null) {\r
+ return false;\r
+ }\r
+ if (getClass() != obj.getClass()) {\r
+ return false;\r
+ }\r
+ OutterListKey other = (OutterListKey) obj;\r
+ if (_leafInList == null) {\r
+ if (other._LeafInList != null) {\r
+ return false;\r
+ }\r
+ } else if(!_leafInList.equals(other._leafInList)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append("OutterListKey [_leafInList=");\r
+ builder.append(_leafInList);\r
+ builder.append("]");\r
+ return builder.toString();\r
+ }\r
+}\r
+----\r
+\r
+===== choice and case statements\r
+A `choice` element is mapped in mostly the same way a `list` element is. The\r
+`choice` element is mapped to and interface (marker interface) and a new getter\r
+method with the return type of a Java `List` of this marker interfaces is added\r
+to the interface corresponding to the parent statement. Any `case` \r
+substatements are mapped to Java interfaces which extend the marker interface.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+container cont {\r
+ choice example-choice {\r
+ case foo-case {\r
+ leaf foo {\r
+ type string;\r
+ }\r
+ }\r
+ case bar-case {\r
+ leaf bar {\r
+ type string;\r
+ }\r
+ }\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.Cont.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentable;\r
+import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;\r
+\r
+public interface Cont extends DataObject, Augmentable<Cont> {\r
+\r
+ ExampleChoice getExampleChoice();\r
+\r
+}\r
+----\r
+\r
+.ExampleChoice.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+\r
+public interface ExampleChoice extends DataContainer {\r
+}\r
+----\r
+\r
+.FooCase.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.example.choice;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentable;\r
+import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;\r
+\r
+public interface FooCase extends ExampleChoice, DataObject, Augmentable<FooCase> {\r
+\r
+ String getFoo();\r
+\r
+}\r
+----\r
+\r
+.BarCase.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.example.choice;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentable;\r
+import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;\r
+\r
+public interface BarCase extends ExampleChoice, DataObject, Augmentable<BarCase> {\r
+\r
+ String getBar();\r
+\r
+}\r
+----\r
+\r
+===== grouping and uses statements\r
+`grouping`s are mapped to Java interfaces. `uses` statements in some element\r
+(using of concrete grouping) are mapped as extension of interface for this\r
+element with the interface which represents grouping.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG Model\r
+[source, yang]\r
+----\r
+grouping grp {\r
+ leaf foo {\r
+ type string;\r
+ }\r
+}\r
+\r
+container cont {\r
+ uses grp;\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.Grp.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+\r
+public interface Grp extends DataObject {\r
+\r
+ String getFoo();\r
+\r
+}\r
+----\r
+\r
+.Cont.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentable;\r
+\r
+public interface Cont extends DataObject, Augmentable<Cont>, Grp {\r
+}\r
+----\r
+\r
+\r
+===== rpc, input and output statements\r
+An `rpc` statement is mapped to Java as method of class `ModuleService.java`.\r
+Any substatements of an `rpc` are mapped as follows:\r
+\r
+[options="header"]\r
+|===\r
+|Rpc Substatement|Mapping\r
+|input|presence of input statement triggers generation of interface\r
+|output|presence of output statement triggers generation of interface\r
+|===\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+rpc rpc-test1 {\r
+ output {\r
+ leaf lf-output {\r
+ type string;\r
+ }\r
+ }\r
+ input {\r
+ leaf lf-input {\r
+ type string;\r
+ }\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.ModuleService.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+import Java.util.concurrent.Future;\r
+import org.opendaylight.yangtools.yang.common.RpcResult;\r
+\r
+public interface ModuleService {\r
+\r
+ Future<RpcResult<RpcTest1Output>> rpcTest1(RpcTest1Input input);\r
+\r
+}\r
+----\r
+\r
+.RpcTest1Input.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+public interface RpcTest1Input {\r
+\r
+ String getLfInput();\r
+\r
+}\r
+----\r
+\r
+.RpcTest1Output.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+public interface RpcTest1Output {\r
+\r
+ String getLfOutput();\r
+\r
+}\r
+----\r
+\r
+\r
+===== notification statement\r
+\r
+`notification` statements are mapped to Java interfaces which extend\r
+the Notification interface.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+notification notif {\r
+ }\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.Notif.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentable;\r
+import org.opendaylight.yangtools.yang.binding.Notification;\r
+\r
+public interface Notif extends DataObject, Augmentable<Notif>, Notification {\r
+}\r
+----\r
+\r
+==== augment statement\r
+`augment` statements are mapped to Java interfaces. The interface starts with\r
+the same name as the name of augmented interface with a suffix corresponding to\r
+the order number of augmenting interface. The augmenting interface also extends\r
+`Augmentation<>` with actual type parameter equal to augmented interface.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG Model\r
+[source, yang]\r
+----\r
+container cont {\r
+}\r
+\r
+augment "/cont" {\r
+ leaf additional-value {\r
+ type string;\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.Cont.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentable;\r
+\r
+public interface Cont extends DataObject, Augmentable<Cont> {\r
+\r
+}\r
+----\r
+\r
+.Cont1.java\r
+[source, java]\r
+----\r
+package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
+\r
+import org.opendaylight.yangtools.yang.binding.DataObject;\r
+import org.opendaylight.yangtools.yang.binding.Augmentation;\r
+\r
+public interface Cont1 extends DataObject, Augmentation<Cont> {\r
+\r
+}\r
+----\r
+\r
+==== YANG Type mapping\r
+\r
+===== typedef statement\r
+YANG `typedef` statements are mapped to Java classes. A `typedef` may contain following\r
+substatements:\r
+\r
+[options="header"]\r
+|===\r
+|Substatement | Behaviour\r
+|type| determines wrapped type and how class will be generated\r
+|descripton| Javadoc description\r
+|units| is not mapped\r
+|default|is not mapped\r
+|===\r
+\r
+====== Valid Arguments Type\r
+\r
+Simple values of type argument are mapped as follows:\r
+\r
+[options="header"]\r
+|===\r
+|YANG Type | Java type\r
+|boolean| Boolean\r
+|empty| Boolean\r
+|int8| Byte\r
+|int16|Short\r
+|int32|Integer\r
+|int64|Long\r
+|string|String or, wrapper class (if pattern substatement is specified)\r
+|decimal64|Double\r
+|uint8|Short\r
+|uint16|Integer\r
+|uint32|Long\r
+|uint64|BigInteger\r
+|binary|byte[]\r
+|===\r
+\r
+Complex values of type argument are mapped as follows:\r
+\r
+[options="header"]\r
+|===\r
+|Argument Type| Java type\r
+|enumeration| generated java enum\r
+|bits| generated class for bits\r
+|leafref| same type as referenced leaf\r
+|identityref| Class\r
+|union| generated java class\r
+|instance-identifier| `org.opendaylight.yangtools.yang.binding.InstanceIdentifier`\r
+|===\r
+\r
+===== Enumeration Substatement Enum\r
+The YANG `enumeration` type has to contain some `enum` substatements. An `enumeration` is mapped as Java enum type (standalone class) and every YANG enum substatements is mapped to Java enum's predefined values.\r
+\r
+An `enum` statement can have following substatements:\r
+\r
+[options="header"]\r
+|===\r
+|Enum's Substatement | Java mapping\r
+|description|is not mapped in API\r
+|value| mapped as input parameter for every predefined value of enum\r
+|===\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+typedef typedef-enumeration {\r
+ type enumeration {\r
+ enum enum1 {\r
+ description "enum1 description";\r
+ value 18;\r
+ }\r
+ enum enum2 {\r
+ value 16;\r
+ }\r
+ enum enum3 {\r
+ }\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.TypedefEnumeration.java\r
+[source, java]\r
+----\r
+public enum TypedefEnumeration {\r
+ Enum1(18),\r
+ Enum2(16),\r
+ Enum3(19);\r
+\r
+ int value;\r
+\r
+ private TypedefEnumeration(int value) {\r
+ this.value = value;\r
+ }\r
+}\r
+----\r
+\r
+===== Bits's Substatement Bit\r
+The YANG `bits` type has to contain some bit substatements. YANG `bits` is mapped to\r
+a Java class (standalone class) and every YANG `bits` substatements is mapped to a\r
+boolean attribute of that class. In addition, the class provides overridden versions\r
+of the Object methods `hashCode`, `toString`, and `equals`.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG Model\r
+[source, yang]\r
+----\r
+typedef typedef-bits {\r
+ type bits {\r
+ bit first-bit {\r
+ description "first-bit description";\r
+ position 15;\r
+ }\r
+ bit second-bit;\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.TypedefBits.java\r
+[source, java]\r
+----\r
+public class TypedefBits {\r
+\r
+ private Boolean firstBit;\r
+ private Boolean secondBit;\r
+\r
+ public TypedefBits() {\r
+ super();\r
+ }\r
+\r
+ public Boolean getFirstBit() {\r
+ return firstBit;\r
+ }\r
+\r
+ public void setFirstBit(Boolean firstBit) {\r
+ this.firstBit = firstBit;\r
+ }\r
+\r
+ public Boolean getSecondBit() {\r
+ return secondBit;\r
+ }\r
+\r
+ public void setSecondBit(Boolean secondBit) {\r
+ this.secondBit = secondBit;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ final int prime = 31;\r
+ int result = 1;\r
+ result = prime * result +\r
+ ((firstBit == null) ? 0 : firstBit.hashCode());\r
+ result = prime * result +\r
+ ((secondBit == null) ? 0 : secondBit.hashCode());\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+ if (obj == null) {\r
+ return false;\r
+ }\r
+ if (getClass() != obj.getClass()) {\r
+ return false;\r
+ }\r
+ TypedefBits other = (TypedefBits) obj;\r
+ if (firstBit == null) {\r
+ if (other.firstBit != null) {\r
+ return false;\r
+ }\r
+ } else if(!firstBit.equals(other.firstBit)) {\r
+ return false;\r
+ }\r
+ if (secondBit == null) {\r
+ if (other.secondBit != null) {\r
+ return false;\r
+ }\r
+ } else if(!secondBit.equals(other.secondBit)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append("TypedefBits [firstBit=");\r
+ builder.append(firstBit);\r
+ builder.append(", secondBit=");\r
+ builder.append(secondBit);\r
+ builder.append("]");\r
+ return builder.toString();\r
+ }\r
+}\r
+----\r
+\r
+===== Union's Substatement Type\r
+If the type of a `typedef` is `union`, it has to contain `type` substatements.\r
+The `union typedef` is mapped to class and its `type` substatements are mapped\r
+to private class members. Every YANG union subtype gets its own Java constructor\r
+with a parameter which represent just that one attribute.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+typedef typedef-union {\r
+ type union {\r
+ type int32;\r
+ type string;\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.TypdefUnion.java\r
+[source, java]\r
+----\r
+public class TypedefUnion {\r
+\r
+ private Integer int32;\r
+ private String string;\r
+\r
+ public TypedefUnion(Integer int32) {\r
+ super();\r
+ this.int32 = int32;\r
+ }\r
+\r
+ public TypedefUnion(String string) {\r
+ super();\r
+ this.string = string;\r
+ }\r
+\r
+ public Integer getInt32() {\r
+ return int32;\r
+ }\r
+\r
+ public String getString() {\r
+ return string;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ final int prime = 31;\r
+ int result = 1;\r
+ result = prime * result + ((int32 == null) ? 0 : int32.hashCode());\r
+ result = prime * result + ((string == null) ? 0 : string.hashCode());\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+ if (obj == null) {\r
+ return false;\r
+ }\r
+ if (getClass() != obj.getClass()) {\r
+ return false;\r
+ }\r
+ TypedefUnion other = (TypedefUnion) obj;\r
+ if (int32 == null) {\r
+ if (other.int32 != null) {\r
+ return false;\r
+ }\r
+ } else if(!int32.equals(other.int32)) {\r
+ return false;\r
+ }\r
+ if (string == null) {\r
+ if (other.string != null) {\r
+ return false;\r
+ }\r
+ } else if(!string.equals(other.string)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append("TypedefUnion [int32=");\r
+ builder.append(int32);\r
+ builder.append(", string=");\r
+ builder.append(string);\r
+ builder.append("]");\r
+ return builder.toString();\r
+ }\r
+}\r
+----\r
+\r
+===== String Mapping\r
+The YANG `string` type can contain the substatements `length`\r
+and `pattern` which are mapped as follows:\r
+\r
+[options="header"]\r
+|===\r
+|Type substatements | Mapping to Java\r
+| length | not mapped\r
+| pattern |\r
+\r
+. list of string constants = list of patterns +\r
+. list of Pattern objects +\r
+. static initialization block where list of Patterns is initialized from list of string of constants\r
+|===\r
+\r
+For example, the following YANG:\r
+\r
+.YANG model\r
+[source, yang]\r
+----\r
+typedef typedef-string {\r
+ type string {\r
+ length 44;\r
+ pattern "[a][.]*"\r
+ }\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.TypedefString.java\r
+[source, java]\r
+----\r
+public class TypedefString {\r
+\r
+ private static final List<Pattern> patterns = new ArrayList<Pattern>();\r
+ public static final List<String> PATTERN`CONSTANTS = Arrays.asList("[a][.]*");\r
+\r
+ static {\r
+ for (String regEx : PATTERN`CONSTANTS) {\r
+ patterns.add(Pattern.compile(regEx));\r
+ }\r
+ }\r
+\r
+ private String typedefString;\r
+\r
+ public TypedefString(String typedefString) {\r
+ super();\r
+ // Pattern validation\r
+ this.typedefString = typedefString;\r
+ }\r
+\r
+ public String getTypedefString() {\r
+ return typedefString;\r
+ }\r
+\r
+ @Override\r
+ public int hashCode() {\r
+ final int prime = 31;\r
+ int result = 1;\r
+ result = prime * result + ((typedefString == null) ? 0 : typedefString.hashCode());\r
+ return result;\r
+ }\r
+\r
+ @Override\r
+ public boolean equals(Object obj) {\r
+ if (this == obj) {\r
+ return true;\r
+ }\r
+ if (obj == null) {\r
+ return false;\r
+ }\r
+ if (getClass() != obj.getClass()) {\r
+ return false;\r
+ }\r
+ TypedefString other = (TypedefString) obj;\r
+ if (typedefString == null) {\r
+ if (other.typedefString != null) {\r
+ return false;\r
+ }\r
+ } else if(!typedefString.equals(other.typedefString)) {\r
+ return false;\r
+ }\r
+ return true;\r
+ }\r
+\r
+ @Override\r
+ public String toString() {\r
+ StringBuilder builder = new StringBuilder();\r
+ builder.append("TypedefString [typedefString=");\r
+ builder.append(typedefString);\r
+ builder.append("]");\r
+ return builder.toString();\r
+ }\r
+}\r
+----\r
+\r
+==== identity statement\r
+The purpose of the `identity` statement is to define a new globally unique,\r
+abstract, and untyped value.\r
+\r
+The `base` substatement argument is the name of existing identity from which\r
+the new identity is derived.\r
+\r
+Given that, an `identity` statement is mapped to Java abstract class and\r
+any `base` substatements are mapped as `extends` Java keyword.\r
+The identity name is translated to class name.\r
+\r
+For example, the following YANG:\r
+\r
+.YANG Model\r
+[source, yang]\r
+----\r
+identity toast-type {\r
+\r
+}\r
+\r
+identity white-bread {\r
+ base toast-type;\r
+}\r
+----\r
+\r
+is converted into this Java:\r
+\r
+.ToastType.java\r
+[source, java]\r
+----\r
+public abstract class ToastType extends BaseIdentity {\r
+ protected ToastType() {\r
+ super();\r
+ }\r
+}\r
+----\r
+\r
+.WhiteBread.java\r
+[source, java]\r
+----\r
+public abstract class WhiteBread extends ToastType {\r
+ protected WhiteBread() {\r
+ super();\r
+ }\r
+}\r
+----\r