Merge "Added VTN Renderer in User Guide."
[docs.git] / manuals / developer-guide / src / main / asciidoc / yangtools / yang-java-binding-explained.adoc
1 === YANG Java Binding: Mapping rules\r
2 This chapter covers the details of mapping YANG to Java.\r
3 \r
4 NOTE: The following source code examples does not show canonical generated\r
5 code, but rather illustrative example. Generated classes and interfaces may\r
6 differ from this examples, but APIs are preserved.\r
7 \r
8 ==== General conversion rules\r
9 \r
10 ===== Package names of YANG models\r
11 \r
12 The package name consists of the following parts: +\r
13 \r
14 * *Opendaylight prefix* - Specifies the opendaylight prefix. Every package name\r
15 starts with the prefix `org.opendaylight.yang.gen.v`.\r
16 * *Java Binding version* - Specifies the YANG Java Binding version.\r
17   Curent Binding version is `1`.\r
18 * *Namespace* - Specified by the value of `namespace` substatement.\r
19    URI is converted to package name structure.\r
20 * *Revision* - Specifies the concatenation of word `rev` and value of `module`\r
21   substatements `revision` argument value without leading zeros before month and day.\r
22   For example: `rev201379`\r
23 \r
24 After the package name is generated, we check if it contains any Java keywords\r
25 or starts with a digit. If so, then we add an underscore before the offending\r
26 token.\r
27 \r
28 The following is a list of keywords which are prefixed with underscore:\r
29 \r
30 abstract, assert, boolean, break, byte, case, catch, char, class, const,\r
31 continue, default, double, do, else, enum, extends, false, final, finally,\r
32 float, for, goto, if, implements, import, instanceof, int, interface, long,\r
33 native, new, null, package, private, protected, public, return, short, static,\r
34 strictfp, super, switch, synchronized, this, throw, throws, transient, true, try,\r
35 void, volatile, while\r
36 \r
37 As an example suppose following yang model:\r
38 \r
39 [source, yang]\r
40 ----\r
41 module module {\r
42     namespace "urn:2:case#module";\r
43     prefix "sbd";\r
44     organization "OPEN DAYLIGHT";\r
45     contact "http://www.example.com/";\r
46     revision 2013-07-09 {\r
47     }\r
48 }\r
49 ----\r
50 \r
51 After applying rules (replacing digits and Java keywords) the resulting\r
52 package name is `org.opendaylight.yang.gen.v1.urn._2._case.module.rev201379`\r
53 \r
54 ===== Additional Packages\r
55 \r
56 In cases when YANG statement contain some of specific YANG\r
57 statements additional packages are generated to designate this containment.\r
58 Table below provides details of parent statement and nested statements, which\r
59 yields additional package generation:\r
60 \r
61 [options="header"]\r
62 |===\r
63 |Parent statement  | Substatement\r
64 |`list`  |list, container, choice\r
65 |`container` | list, container, choice\r
66 |`choice` | leaf, list, leaf-list, container, case\r
67 |`case`  | list, container, choice\r
68 |rpc `input` or `output` |  list, container, (choice isn't supported)\r
69 |`notification` |  list, container, (choice isn't supported)\r
70 |`augment`  | list, container, choice, case |\r
71 |===\r
72 \r
73 Substatements are not only mapped to Java setter methods in the interface\r
74 representing the parent statement, but they also generate packages with\r
75 names consisting of the parent statement package name with the parent statement\r
76 name appended.\r
77 \r
78 For example, this YANG model considers the container statement `cont` as the\r
79 direct substatement of the module.\r
80 \r
81 [source, yang]\r
82 ----\r
83 container cont {\r
84   container cont-inner {\r
85   }\r
86   list outter-list {\r
87     list list-in-list {\r
88     }\r
89   }\r
90 }\r
91 ----\r
92 \r
93 Container `cont` is the parent statement for the substatements\r
94 `cont-inner` and `outter-list`. `list outter-list` is the parent\r
95 statement for substatement `list-in-list`.\r
96 \r
97 Java code is generated in the following structure: +\r
98 \r
99 * `org.opendaylight.yang.gen.v1.urn.module.rev201379` - package contains direct\r
100    substatements of module statement\r
101 ** `Cont.java`\r
102 * `org.opendaylight.yang.gen.v1.urn.module.rev201379.cont` - package contains\r
103   substatements of `cont` container statement\r
104 ** `ContInner.java` - interface representing container `cont-inner`\r
105 ** `OutterList.java` - interface representing list `outer-list`\r
106 * `org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.outter.list` - package\r
107   contains substatements of outter-list list element\r
108   ** `ListInList.java`\r
109 \r
110 ===== Class and interface names\r
111 Some YANG statements are mapped to Java classes and interfaces. The name of YANG\r
112 element may contain various characters which aren't permitted in Java class names.\r
113 Firstly whitespaces are trimmed from YANG name. Next the characters space, -, `\r
114 are deleted and the subsequent letter is capitalized. At the end, first letter is\r
115 capitalized.\r
116 \r
117 For example, \r
118 `example-name_ without_capitalization` would map to\r
119 `ExampleNameWithoutCapitalization`.\r
120 \r
121 ===== Getter and setter names\r
122 In some cases, YANG statements are converted to getter and/or setter methods.\r
123 The process for getter is:\r
124 \r
125 . the name of YANG statement is converted to Java class name style as \r
126   <<_class_and_interface_names,explained above>>.\r
127 . the word `get` is added as prefix, if resulting type is `Boolean`, the name\r
128   is prefixed with `is` prefix instead of `get`.\r
129 . the return type of the getter method is set to Java type representing substatement\r
130 \r
131 The process for setter is:\r
132 \r
133 . the name of YANG statement is converted to Java class name style as\r
134   <<_class_and_interface_names,explained above>>.\r
135 . the word `set` is added as prefix\r
136 . the input parameter name is set to element's name converted to Java parameter style\r
137 . the return parameter is set to builder type\r
138 \r
139 ==== Statement specific mapping\r
140 \r
141 ===== module statement\r
142 \r
143 YANG `module` statement is converted to Java as two Java classes.\r
144 Each of the classes is in the separate Java file. The names of Java files are\r
145 composed as follows:\r
146 `<module name><suffix>.java` where `<suffix>` is either data or service.\r
147 \r
148 ====== Data Interface\r
149 \r
150 Data Interface has a mapping similar to container, but contains only top level\r
151 nodes defined in module.\r
152 \r
153 Data interface serves only as marker interface for type-safe APIs of\r
154 `InstanceIdentifier`.\r
155 \r
156 ====== Service Interface\r
157 \r
158 Service Interface serves to describe RPC contract defined in the module.\r
159 This RPC contract is defined by `rpc` statements.\r
160 \r
161 RPC implementation usually implement this interface and users of the RPCs\r
162 use this interface to invoke RPCs.\r
163 \r
164 ===== container statement\r
165 YANG containers are mapped to Java interfaces which extend the Java DataObject and\r
166 Augmentable<container-interface>, where container-interface is the name of the mapped\r
167 interface.\r
168 \r
169 For example, the following YANG:\r
170 \r
171 .YANG model\r
172 [source, yang]\r
173 ----\r
174 container cont {\r
175 \r
176 }\r
177 ----\r
178 \r
179 is converted into this Java:\r
180 \r
181 .Cont.java\r
182 [source, java]\r
183 ----\r
184 public interface Cont extends ChildOf<...>, Augmentable<Cont> {\r
185 }\r
186 ----\r
187 \r
188 ===== Leaf statement\r
189 Each leaf has to contain at least one type substatement. The leaf is mapped to\r
190 getter method of parent statement with return type equal to type substatement\r
191 value.\r
192 \r
193 For example, the following YANG:\r
194 \r
195 .YANG model\r
196 [source, yang]\r
197 ----\r
198 container cont {\r
199   leaf lf {\r
200     type string;\r
201   }\r
202 }\r
203 ----\r
204 \r
205 is converted into this Java:\r
206 \r
207 .Cont.java\r
208 [source, java]\r
209 ----\r
210 public interface Cont extends DataObject, Augmentable<Cont> {\r
211     String getLf(); // <1>\r
212 }\r
213 ----\r
214 \r
215 <1> Represents `leaf lf`\r
216 \r
217 ===== leaf-list statement\r
218 Each leaf-list has to contain one type substatement. The leaf-list is mapped\r
219 to getter method of parent statement with return type equal to List of type\r
220 substatement value.\r
221 \r
222 For example, the following YANG:\r
223 \r
224 .YANG model\r
225 [source, yang]\r
226 ----\r
227 container cont {\r
228     leaf-list lf-lst {\r
229         type string;\r
230     }\r
231 }\r
232 ----\r
233 \r
234 is converted into this Java:\r
235 \r
236 .Cont.java\r
237 [source, java]\r
238 ----\r
239 public interface Cont extends DataObject, Augmentable<Cont> {\r
240     List<String> getLfLst();\r
241 }\r
242 ----\r
243 \r
244 ===== list statement\r
245 \r
246 `list` statements are mapped to Java interfaces and a getter method is\r
247 generated in the interface associated with it's parent statement.\r
248 The return type of getter the method is a Java List of objects implementing\r
249 the interface generated corresponding to the `list statement.\r
250 Mapping of `list` substatement to Java:\r
251 \r
252 //[options="header"]\r
253 //|===\r
254 //|Substatement|Mapping to Java\r
255 //|Key|Class\r
256 //|===\r
257 \r
258 For example, the following YANG:\r
259 \r
260 .YANG model\r
261 [source, yang]\r
262 ----\r
263 container cont {\r
264   list outter-list {\r
265     key "leaf-in-list";\r
266     leaf number {\r
267       type uint64;\r
268     }\r
269   }\r
270 }\r
271 ----\r
272 \r
273 The list statement  `example-list` is mapped to the Java interface `ExampleList` and\r
274 the `Cont` interface (parent of `ExampleList`) contains getter method with return\r
275 type `List<ExampleList>`. The presence of a `key` statement, triggers generation\r
276 of `ExampleListKey`, which may be used to identify item in list.\r
277 \r
278 The end result is this Java:\r
279 \r
280 .OutterList.java\r
281 [source, java]\r
282 ----\r
283 package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;\r
284 \r
285 import org.opendaylight.yangtools.yang.binding.DataObject;\r
286 import org.opendaylight.yangtools.yang.binding.Augmentable;\r
287 import Java.util.List;\r
288 import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.outter.list.ListInList;\r
289 \r
290 public interface OutterList extends DataObject, Augmentable<OutterList> {\r
291 \r
292     List<String> getLeafListInList();\r
293 \r
294     List<ListInList> getListInList();\r
295 \r
296     /*\r
297     Returns Primary Key of Yang List Type\r
298     */\r
299     OutterListKey getOutterListKey();\r
300 \r
301 }\r
302 ----\r
303 \r
304 .OutterListKey.java\r
305 [source, java]\r
306 ----\r
307 package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;\r
308 \r
309 import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.OutterListKey;\r
310 import Java.math.BigInteger;\r
311 \r
312 public class OutterListKey {\r
313 \r
314     private BigInteger _leafInList;\r
315 \r
316     public OutterListKey(BigInteger _leafInList) {\r
317         super();\r
318         this_leafInList = _leafInList;\r
319     }\r
320 \r
321     public BigInteger getLeafInList() {\r
322         return _leafInList;\r
323     }\r
324 \r
325     @Override\r
326     public int hashCode() {\r
327         final int prime = 31;\r
328         int result = 1;\r
329         result = prime * result + ((_leafInList == null) ? 0 : _leafInList.hashCode());\r
330         return result;\r
331     }\r
332 \r
333     @Override\r
334     public boolean equals(Object obj) {\r
335         if (this == obj) {\r
336             return true;\r
337         }\r
338         if (obj == null) {\r
339             return false;\r
340         }\r
341         if (getClass() != obj.getClass()) {\r
342             return false;\r
343         }\r
344         OutterListKey other = (OutterListKey) obj;\r
345         if (_leafInList == null) {\r
346             if (other._LeafInList != null) {\r
347                 return false;\r
348             }\r
349         } else if(!_leafInList.equals(other._leafInList)) {\r
350             return false;\r
351         }\r
352         return true;\r
353     }\r
354 \r
355     @Override\r
356     public String toString() {\r
357         StringBuilder builder = new StringBuilder();\r
358         builder.append("OutterListKey [_leafInList=");\r
359         builder.append(_leafInList);\r
360         builder.append("]");\r
361         return builder.toString();\r
362     }\r
363 }\r
364 ----\r
365 \r
366 ===== choice and case statements\r
367 A `choice` element is mapped in mostly the same way a `list` element is. The\r
368 `choice` element is mapped to and interface (marker interface) and a new getter\r
369 method with the return type of a Java `List` of this marker interfaces is added\r
370 to the interface corresponding to the parent statement. Any `case` \r
371 substatements are mapped to Java interfaces which extend the marker interface.\r
372 \r
373 For example, the following YANG:\r
374 \r
375 .YANG model\r
376 [source, yang]\r
377 ----\r
378 container cont {\r
379     choice example-choice {\r
380         case foo-case {\r
381           leaf foo {\r
382             type string;\r
383           }\r
384         }\r
385         case bar-case {\r
386             leaf bar {\r
387               type string;\r
388             }\r
389         }\r
390     }\r
391 }\r
392 ----\r
393 \r
394 is converted into this Java:\r
395 \r
396 .Cont.java\r
397 [source, java]\r
398 ----\r
399 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
400 \r
401 import org.opendaylight.yangtools.yang.binding.DataObject;\r
402 import org.opendaylight.yangtools.yang.binding.Augmentable;\r
403 import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;\r
404 \r
405 public interface Cont extends DataObject, Augmentable<Cont> {\r
406 \r
407     ExampleChoice getExampleChoice();\r
408 \r
409 }\r
410 ----\r
411 \r
412 .ExampleChoice.java\r
413 [source, java]\r
414 ----\r
415 package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont;\r
416 \r
417 import org.opendaylight.yangtools.yang.binding.DataObject;\r
418 \r
419 public interface ExampleChoice extends DataContainer {\r
420 }\r
421 ----\r
422 \r
423 .FooCase.java\r
424 [source, java]\r
425 ----\r
426 package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.example.choice;\r
427 \r
428 import org.opendaylight.yangtools.yang.binding.DataObject;\r
429 import org.opendaylight.yangtools.yang.binding.Augmentable;\r
430 import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;\r
431 \r
432 public interface FooCase extends ExampleChoice, DataObject, Augmentable<FooCase> {\r
433 \r
434     String getFoo();\r
435 \r
436 }\r
437 ----\r
438 \r
439 .BarCase.java\r
440 [source, java]\r
441 ----\r
442 package org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.example.choice;\r
443 \r
444 import org.opendaylight.yangtools.yang.binding.DataObject;\r
445 import org.opendaylight.yangtools.yang.binding.Augmentable;\r
446 import org.opendaylight.yang.gen.v1.urn.module.rev201379.cont.ChoiceTest;\r
447 \r
448 public interface BarCase extends ExampleChoice, DataObject, Augmentable<BarCase> {\r
449 \r
450     String getBar();\r
451 \r
452 }\r
453 ----\r
454 \r
455 ===== grouping and uses statements\r
456 `grouping`s are mapped to Java interfaces. `uses` statements in some element\r
457 (using of concrete grouping) are mapped as extension of interface for this\r
458 element with the interface which represents grouping.\r
459 \r
460 For example, the following YANG:\r
461 \r
462 .YANG Model\r
463 [source, yang]\r
464 ----\r
465 grouping grp {\r
466   leaf foo {\r
467     type string;\r
468   }\r
469 }\r
470 \r
471 container cont {\r
472     uses grp;\r
473 }\r
474 ----\r
475 \r
476 is converted into this Java:\r
477 \r
478 .Grp.java\r
479 [source, java]\r
480 ----\r
481 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
482 \r
483 import org.opendaylight.yangtools.yang.binding.DataObject;\r
484 \r
485 public interface Grp extends DataObject {\r
486 \r
487     String getFoo();\r
488 \r
489 }\r
490 ----\r
491 \r
492 .Cont.java\r
493 [source, java]\r
494 ----\r
495 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
496 \r
497 import org.opendaylight.yangtools.yang.binding.DataObject;\r
498 import org.opendaylight.yangtools.yang.binding.Augmentable;\r
499 \r
500 public interface Cont extends DataObject, Augmentable<Cont>, Grp {\r
501 }\r
502 ----\r
503 \r
504 \r
505 ===== rpc, input and output statements\r
506 An `rpc` statement is mapped to Java as method of class `ModuleService.java`.\r
507 Any substatements of an `rpc` are mapped as follows:\r
508 \r
509 [options="header"]\r
510 |===\r
511 |Rpc Substatement|Mapping\r
512 |input|presence of input statement triggers generation of interface\r
513 |output|presence of output statement triggers generation of interface\r
514 |===\r
515 \r
516 For example, the following YANG:\r
517 \r
518 .YANG model\r
519 [source, yang]\r
520 ----\r
521 rpc rpc-test1 {\r
522     output {\r
523         leaf lf-output {\r
524             type string;\r
525         }\r
526     }\r
527     input {\r
528         leaf lf-input {\r
529             type string;\r
530         }\r
531     }\r
532 }\r
533 ----\r
534 \r
535 is converted into this Java:\r
536 \r
537 .ModuleService.java\r
538 [source, java]\r
539 ----\r
540 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
541 \r
542 import Java.util.concurrent.Future;\r
543 import org.opendaylight.yangtools.yang.common.RpcResult;\r
544 \r
545 public interface ModuleService {\r
546 \r
547     Future<RpcResult<RpcTest1Output>> rpcTest1(RpcTest1Input input);\r
548 \r
549 }\r
550 ----\r
551 \r
552 .RpcTest1Input.java\r
553 [source, java]\r
554 ----\r
555 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
556 \r
557 public interface RpcTest1Input {\r
558 \r
559     String getLfInput();\r
560 \r
561 }\r
562 ----\r
563 \r
564 .RpcTest1Output.java\r
565 [source, java]\r
566 ----\r
567 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
568 \r
569 public interface RpcTest1Output {\r
570 \r
571     String getLfOutput();\r
572 \r
573 }\r
574 ----\r
575 \r
576 \r
577 ===== notification statement\r
578 \r
579 `notification` statements are mapped to Java interfaces which extend\r
580 the Notification interface.\r
581 \r
582 For example, the following YANG:\r
583 \r
584 .YANG model\r
585 [source, yang]\r
586 ----\r
587 notification notif {\r
588         }\r
589 ----\r
590 \r
591 is converted into this Java:\r
592 \r
593 .Notif.java\r
594 [source, java]\r
595 ----\r
596 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
597 \r
598 \r
599 import org.opendaylight.yangtools.yang.binding.DataObject;\r
600 import org.opendaylight.yangtools.yang.binding.Augmentable;\r
601 import org.opendaylight.yangtools.yang.binding.Notification;\r
602 \r
603 public interface Notif extends DataObject, Augmentable<Notif>, Notification {\r
604 }\r
605 ----\r
606 \r
607 ==== augment statement\r
608 `augment` statements are mapped to Java interfaces. The interface starts with\r
609 the same name as the name of augmented interface with a suffix corresponding to\r
610 the order number of augmenting interface. The augmenting interface also extends\r
611 `Augmentation<>` with actual type parameter equal to augmented interface.\r
612 \r
613 For example, the following YANG:\r
614 \r
615 .YANG Model\r
616 [source, yang]\r
617 ----\r
618 container cont {\r
619 }\r
620 \r
621 augment "/cont" {\r
622   leaf additional-value {\r
623     type string;\r
624   }\r
625 }\r
626 ----\r
627 \r
628 is converted into this Java:\r
629 \r
630 .Cont.java\r
631 [source, java]\r
632 ----\r
633 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
634 \r
635 import org.opendaylight.yangtools.yang.binding.DataObject;\r
636 import org.opendaylight.yangtools.yang.binding.Augmentable;\r
637 \r
638 public interface Cont extends DataObject, Augmentable<Cont> {\r
639 \r
640 }\r
641 ----\r
642 \r
643 .Cont1.java\r
644 [source, java]\r
645 ----\r
646 package org.opendaylight.yang.gen.v1.urn.module.rev201379;\r
647 \r
648 import org.opendaylight.yangtools.yang.binding.DataObject;\r
649 import org.opendaylight.yangtools.yang.binding.Augmentation;\r
650 \r
651 public interface Cont1 extends DataObject, Augmentation<Cont> {\r
652 \r
653 }\r
654 ----\r
655 \r
656 ==== YANG Type mapping\r
657 \r
658 ===== typedef statement\r
659 YANG `typedef` statements are mapped to Java classes. A `typedef` may contain following\r
660 substatements:\r
661 \r
662 [options="header"]\r
663 |===\r
664 |Substatement | Behaviour\r
665 |type| determines wrapped type and how class will be generated\r
666 |descripton| Javadoc description\r
667 |units| is not mapped\r
668 |default|is not mapped\r
669 |===\r
670 \r
671 ====== Valid Arguments Type\r
672 \r
673 Simple values of type argument are mapped as follows:\r
674 \r
675 [options="header"]\r
676 |===\r
677 |YANG Type |  Java type\r
678 |boolean| Boolean\r
679 |empty| Boolean\r
680 |int8| Byte\r
681 |int16|Short\r
682 |int32|Integer\r
683 |int64|Long\r
684 |string|String or, wrapper class (if pattern substatement is specified)\r
685 |decimal64|Double\r
686 |uint8|Short\r
687 |uint16|Integer\r
688 |uint32|Long\r
689 |uint64|BigInteger\r
690 |binary|byte[]\r
691 |===\r
692 \r
693 Complex values of type argument are mapped as follows:\r
694 \r
695 [options="header"]\r
696 |===\r
697 |Argument Type| Java type\r
698 |enumeration| generated java enum\r
699 |bits| generated class for bits\r
700 |leafref| same type as referenced leaf\r
701 |identityref| Class\r
702 |union| generated java class\r
703 |instance-identifier| `org.opendaylight.yangtools.yang.binding.InstanceIdentifier`\r
704 |===\r
705 \r
706 ===== Enumeration Substatement Enum\r
707 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
708 \r
709 An `enum` statement can have following substatements:\r
710 \r
711 [options="header"]\r
712 |===\r
713 |Enum's Substatement | Java mapping\r
714 |description|is not mapped in API\r
715 |value| mapped as input parameter for every predefined value of enum\r
716 |===\r
717 \r
718 For example, the following YANG:\r
719 \r
720 .YANG model\r
721 [source, yang]\r
722 ----\r
723 typedef typedef-enumeration {\r
724     type enumeration {\r
725         enum enum1 {\r
726             description "enum1 description";\r
727             value 18;\r
728         }\r
729         enum enum2 {\r
730             value 16;\r
731         }\r
732         enum enum3 {\r
733         }\r
734     }\r
735 }\r
736 ----\r
737 \r
738 is converted into this Java:\r
739 \r
740 .TypedefEnumeration.java\r
741 [source, java]\r
742 ----\r
743 public enum TypedefEnumeration {\r
744     Enum1(18),\r
745     Enum2(16),\r
746     Enum3(19);\r
747 \r
748     int value;\r
749 \r
750     private TypedefEnumeration(int value) {\r
751         this.value = value;\r
752     }\r
753 }\r
754 ----\r
755 \r
756 ===== Bits's Substatement Bit\r
757 The YANG `bits` type has to contain some bit substatements. YANG `bits` is mapped to\r
758 a Java class (standalone class) and every YANG `bits` substatements is mapped to a\r
759 boolean attribute of that class. In addition, the class provides overridden versions\r
760 of the Object methods `hashCode`, `toString`, and `equals`.\r
761 \r
762 For example, the following YANG:\r
763 \r
764 .YANG Model\r
765 [source, yang]\r
766 ----\r
767 typedef typedef-bits {\r
768   type bits {\r
769     bit first-bit {\r
770       description "first-bit description";\r
771         position 15;\r
772       }\r
773     bit second-bit;\r
774   }\r
775 }\r
776 ----\r
777 \r
778 is converted into this Java:\r
779 \r
780 .TypedefBits.java\r
781 [source, java]\r
782 ----\r
783 public class TypedefBits {\r
784 \r
785     private Boolean firstBit;\r
786     private Boolean secondBit;\r
787 \r
788     public TypedefBits() {\r
789         super();\r
790     }\r
791 \r
792     public Boolean getFirstBit() {\r
793         return firstBit;\r
794     }\r
795 \r
796     public void setFirstBit(Boolean firstBit) {\r
797         this.firstBit = firstBit;\r
798     }\r
799 \r
800     public Boolean getSecondBit() {\r
801         return secondBit;\r
802     }\r
803 \r
804     public void setSecondBit(Boolean secondBit) {\r
805         this.secondBit = secondBit;\r
806     }\r
807 \r
808     @Override\r
809     public int hashCode() {\r
810         final int prime = 31;\r
811         int result = 1;\r
812         result = prime * result +\r
813          ((firstBit == null) ? 0 : firstBit.hashCode());\r
814         result = prime * result +\r
815          ((secondBit == null) ? 0 : secondBit.hashCode());\r
816         return result;\r
817     }\r
818 \r
819     @Override\r
820     public boolean equals(Object obj) {\r
821         if (this == obj) {\r
822             return true;\r
823         }\r
824         if (obj == null) {\r
825             return false;\r
826         }\r
827         if (getClass() != obj.getClass()) {\r
828             return false;\r
829         }\r
830         TypedefBits other = (TypedefBits) obj;\r
831         if (firstBit == null) {\r
832             if (other.firstBit != null) {\r
833                 return false;\r
834             }\r
835         } else if(!firstBit.equals(other.firstBit)) {\r
836             return false;\r
837         }\r
838         if (secondBit == null) {\r
839             if (other.secondBit != null) {\r
840                 return false;\r
841             }\r
842         } else if(!secondBit.equals(other.secondBit)) {\r
843             return false;\r
844         }\r
845         return true;\r
846     }\r
847 \r
848     @Override\r
849     public String toString() {\r
850         StringBuilder builder = new StringBuilder();\r
851         builder.append("TypedefBits [firstBit=");\r
852         builder.append(firstBit);\r
853         builder.append(", secondBit=");\r
854         builder.append(secondBit);\r
855         builder.append("]");\r
856         return builder.toString();\r
857     }\r
858 }\r
859 ----\r
860 \r
861 ===== Union's Substatement Type\r
862 If the type of a `typedef` is `union`, it has to contain `type` substatements.\r
863 The `union typedef` is mapped to class and its `type` substatements are mapped\r
864 to private class members. Every YANG union subtype gets its own Java constructor\r
865 with a parameter which represent just that one attribute.\r
866 \r
867 For example, the following YANG:\r
868 \r
869 .YANG model\r
870 [source, yang]\r
871 ----\r
872 typedef typedef-union {\r
873     type union {\r
874         type int32;\r
875         type string;\r
876     }\r
877 }\r
878 ----\r
879 \r
880 is converted into this Java:\r
881 \r
882 .TypdefUnion.java\r
883 [source, java]\r
884 ----\r
885 public class TypedefUnion {\r
886 \r
887     private Integer int32;\r
888     private String string;\r
889 \r
890     public TypedefUnion(Integer int32) {\r
891         super();\r
892         this.int32 = int32;\r
893     }\r
894 \r
895     public TypedefUnion(String string) {\r
896         super();\r
897         this.string = string;\r
898     }\r
899 \r
900     public Integer getInt32() {\r
901         return int32;\r
902     }\r
903 \r
904     public String getString() {\r
905         return string;\r
906     }\r
907 \r
908     @Override\r
909     public int hashCode() {\r
910         final int prime = 31;\r
911         int result = 1;\r
912         result = prime * result + ((int32 == null) ? 0 : int32.hashCode());\r
913         result = prime * result + ((string == null) ? 0 : string.hashCode());\r
914         return result;\r
915     }\r
916 \r
917     @Override\r
918     public boolean equals(Object obj) {\r
919         if (this == obj) {\r
920             return true;\r
921         }\r
922         if (obj == null) {\r
923             return false;\r
924         }\r
925         if (getClass() != obj.getClass()) {\r
926             return false;\r
927         }\r
928         TypedefUnion other = (TypedefUnion) obj;\r
929         if (int32 == null) {\r
930             if (other.int32 != null) {\r
931                 return false;\r
932             }\r
933         } else if(!int32.equals(other.int32)) {\r
934             return false;\r
935         }\r
936         if (string == null) {\r
937             if (other.string != null) {\r
938                 return false;\r
939             }\r
940         } else if(!string.equals(other.string)) {\r
941             return false;\r
942         }\r
943         return true;\r
944     }\r
945 \r
946     @Override\r
947     public String toString() {\r
948         StringBuilder builder = new StringBuilder();\r
949         builder.append("TypedefUnion [int32=");\r
950         builder.append(int32);\r
951         builder.append(", string=");\r
952         builder.append(string);\r
953         builder.append("]");\r
954         return builder.toString();\r
955     }\r
956 }\r
957 ----\r
958 \r
959 ===== String Mapping\r
960 The YANG `string` type can contain the substatements `length`\r
961 and `pattern` which are mapped as follows:\r
962 \r
963 [options="header"]\r
964 |===\r
965 |Type substatements  |  Mapping to Java\r
966 | length | not mapped\r
967 | pattern |\r
968 \r
969 . list of string constants = list of patterns +\r
970 . list of Pattern objects +\r
971 . static initialization block where list of Patterns is initialized from list of string of constants\r
972 |===\r
973 \r
974 For example, the following YANG:\r
975 \r
976 .YANG model\r
977 [source, yang]\r
978 ----\r
979 typedef typedef-string {\r
980     type string {\r
981         length 44;\r
982         pattern "[a][.]*"\r
983     }\r
984 }\r
985 ----\r
986 \r
987 is converted into this Java:\r
988 \r
989 .TypedefString.java\r
990 [source, java]\r
991 ----\r
992 public class TypedefString {\r
993 \r
994     private static final List<Pattern> patterns = new ArrayList<Pattern>();\r
995     public static final List<String> PATTERN`CONSTANTS = Arrays.asList("[a][.]*");\r
996 \r
997     static {\r
998         for (String regEx : PATTERN`CONSTANTS) {\r
999             patterns.add(Pattern.compile(regEx));\r
1000         }\r
1001     }\r
1002 \r
1003     private String typedefString;\r
1004 \r
1005     public TypedefString(String typedefString) {\r
1006         super();\r
1007         // Pattern validation\r
1008         this.typedefString = typedefString;\r
1009     }\r
1010 \r
1011     public String getTypedefString() {\r
1012         return typedefString;\r
1013     }\r
1014 \r
1015     @Override\r
1016     public int hashCode() {\r
1017         final int prime = 31;\r
1018         int result = 1;\r
1019         result = prime * result + ((typedefString == null) ? 0 : typedefString.hashCode());\r
1020         return result;\r
1021     }\r
1022 \r
1023     @Override\r
1024     public boolean equals(Object obj) {\r
1025         if (this == obj) {\r
1026             return true;\r
1027         }\r
1028         if (obj == null) {\r
1029             return false;\r
1030         }\r
1031         if (getClass() != obj.getClass()) {\r
1032             return false;\r
1033         }\r
1034         TypedefString other = (TypedefString) obj;\r
1035         if (typedefString == null) {\r
1036             if (other.typedefString != null) {\r
1037                 return false;\r
1038             }\r
1039         } else if(!typedefString.equals(other.typedefString)) {\r
1040             return false;\r
1041         }\r
1042         return true;\r
1043     }\r
1044 \r
1045     @Override\r
1046     public String toString() {\r
1047         StringBuilder builder = new StringBuilder();\r
1048         builder.append("TypedefString [typedefString=");\r
1049         builder.append(typedefString);\r
1050         builder.append("]");\r
1051         return builder.toString();\r
1052     }\r
1053 }\r
1054 ----\r
1055 \r
1056 ==== identity statement\r
1057 The purpose of the `identity` statement is to define a new globally unique,\r
1058 abstract, and untyped value.\r
1059 \r
1060 The `base` substatement argument is the name of existing identity from which\r
1061 the new identity is derived.\r
1062 \r
1063 Given that, an `identity` statement is mapped to Java abstract class and\r
1064 any `base` substatements are mapped as `extends` Java keyword.\r
1065 The identity name is translated to class name.\r
1066 \r
1067 For example, the following YANG:\r
1068 \r
1069 .YANG Model\r
1070 [source, yang]\r
1071 ----\r
1072 identity toast-type {\r
1073 \r
1074 }\r
1075 \r
1076 identity white-bread {\r
1077    base toast-type;\r
1078 }\r
1079 ----\r
1080 \r
1081 is converted into this Java:\r
1082 \r
1083 .ToastType.java\r
1084 [source, java]\r
1085 ----\r
1086 public abstract class ToastType extends BaseIdentity {\r
1087     protected ToastType() {\r
1088         super();\r
1089     }\r
1090 }\r
1091 ----\r
1092 \r
1093 .WhiteBread.java\r
1094 [source, java]\r
1095 ----\r
1096 public abstract class WhiteBread extends ToastType {\r
1097     protected WhiteBread() {\r
1098         super();\r
1099     }\r
1100 }\r
1101 ----\r