Normalizing package names according to
[mdsal.git] / binding2 / mdsal-binding2-spec / src / site / asciidoc / binding-2.adoc
index 257801cb6c1667dc883c2ef640df21dd211b6583..797750c68cb0ffb438183c592cb3badb36179acb 100644 (file)
@@ -20,16 +20,133 @@ Transfer Object::
 Builder::
   builder
 
+=== YANG Identifiers Mapping
+
+Every non-Java char in identifier is converted to Java char by its unicode name http://docs.oracle.com/javase/specs/jls/se8/html/jls-3.html#jls-3.8
+JAVA SE SPECIFICATIONS - Identifiers. This mapping solves various issues from Binding Specification v1, which led to compilation issues.
+
+There are special types of mapping non-java chars to original identifiers according to specific Java type:
+
+* class, enum, interface
+
+** without special separator
+the first character of identifier, any other first character of identifier part mapped by
+** non-Java char name from unicode and char in identifier behind non-java char name are converting to upper case
+
+ examples:
+ example* - ExampleAsterisk
+ example*example - ExampleAserisksExample
+ \example - ReverseSolidusExample
+ 1example - DigitOneExample
+ example1 - Example1
+ int - IntReservedKeyword
+ con - ConReservedKeyword
+
+* enum value, constant
+** used underscore as special separator
+** converted identifier to upper case
+
+ examples:
+ example* - EXAMPLE_ASTERISK
+ example*example - EXAMPLE_ASTERISK_EXAMPLE
+ \example - REVERSE_SOLIDUS_EXAMPLE
+ 1example - DIGIT_ONE_EXAMPLE
+ example1 - EXAMPLE1
+ int - INT_RESERVED_KEYWORD
+ con - CON_RESERVED_KEYWORD
+
+* method, variable
+** without special separator
+** the first character of identifier is converting to lower case
+** any other first character of identifier part mapped by non-Java char name from unicode and char in identifier behind non-java char name are converting to upper case
+
+ examples:
+ example* - exampleAsterisk
+ example*example - exampleAserisksExample
+ \example - reverseSolidusExample
+ 1example - digitOneExample
+ example1 - example1
+ int - intReservedKeyword
+ con - conReservedKeyword
+
+* package - full package name - https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
+** parts of package name are separated by dots
+** parts of package name are converting to lower case
+** if parts of package name are reserved Java or Windows keywords, such as 'int' the suggested convention is to add an underscore to keyword
+** dash is parsed as underscore according to https://docs.oracle.com/javase/tutorial/java/package/namingpkgs.html
+
+ examples:
+ org.example* - org.exampleasterisk
+ org.example*example - org.exampleasteriskexample
+ org.example - org.reversesolidusexample
+ org.1example - org.digitoneexample
+ org.example1 - org.example1
+ org.int - org.int_
+ org.con - org.con_
+ org.foo-cont - org.foo_cont
+
+==== Special case - '-' in identifiers
+There is special case in CLASS, INTERFACE, ENUM, ENUM VALUE, CONSTANT, METHOD and VARIABLE if
+identifier contains single dash - then the converter ignores the single dash in the way of the
+non-java chars. In other way, if dash is the first or the last char in the identifier or there is
+more dashes in a row in the identifier, then these dashes are converted as non-java chars.
+
+Example:
+
+* class, enum, interface
+
+ foo-cont - FooCont
+ foo--cont - FooHyphenMinusHyphenMinusCont
+ -foo - HyphenMinusFoo
+ foo- - FooHyphenMinus
+
+* enum value, constant
+
+ foo-cont - FOO_CONT
+ foo--cont - FOO_HYPHEN_MINUS_HYPHEN_MINUS_CONT
+ -foo - HYPHEN_MINUS_FOO
+ foo- - FOO_HYPHEN_MINUS
+
+* method, variable
+
+ foo-cont - fooCont
+ foo--cont - fooHyphenMinusHyphenMinusCont
+ -foo - hyphenMinusFoo
+ foo- - fooHyphenMinus
+
+==== Special case - same class (or enum or interface) names with different camel cases
+Next special case talks about normalizing class name which already exists in package - but with
+different camel cases (foo, Foo, fOo, ...). To every next classes with same names will by added
+their actual rank (serial number), except the first one. This working for CLASS, ENUM and
+INTEFACE java identifiers. If there exist the same ENUM VALUES in ENUM (with different camel
+cases), then it's parsed with same logic like CLASSES, ENUMS and INTERFACES but according to list
+of pairs of their ENUM parent. Example:
+
+* class, enum, interface
+
+ package name org.example, class (or interface or enum) Foo - normalized to Foo
+ package name org.example, class (or interface or enum) fOo - normalized to Foo1
+
+* enum value
+
+ type enumeration {
+     enum foo;
+     enum Foo;
+ }
+ YANG enum values will be mapped to 'FOO' and 'FOO_1' Java enum values.
+
+
 === Binding Specification v2 Concepts
 
-<<Instantiated>>::
-  Represent node, which is instantiated
+<<Instantiable>>::
+  Represent node, which is instantiable by users as a part of notification,
+  rpc, action or data tree.
 <<TreeNode>>::
   Represents node, which is part of instantiated data tree, this interface
   is not used directly, but rather via <<TreeChildNode>>. See <<instantiated-data-tree-rules>>
   for more information.
 <<TreeRoot>>::
-  Represents virtual root of instantiated data tree node.
+  Represents virtual root of instantiated data tree.
 <<TreeChildNode>>::
   Represents node, which is part of instantiated data tree and is not root of
   data tree.
@@ -43,6 +160,38 @@ Builder::
   Unique identifier of node / subtree in data tree, which provides unambiguous
   information, how to reference node / subtree in Instantiated Data Tree.
 
+
+[cols="6"]
+|===
+.2+|Statement .2+| In groupings 3+| Instantiable .2+| Augmentable
+| In Data | In RPC | In Notification
+
+| `grouping` | Yes | No | No | No | No
+
+| `container` | Yes | Yes | Yes | Yes | Yes
+
+| `leaf` | Yes | Yes | Yes | Yes | No
+
+| `leaf-list` | Yes | Yes | Yes | Yes | No
+
+| `list` | Yes | Yes | Yes | Yes | Yes
+
+| `anydata` | Yes | Yes | Yes | Yes | No
+
+| `anyxml` | Yes | Yes | Yes | Yes | No
+
+| `choice` | Yes | Yes | Yes | Yes | Yes
+
+| `case` | Yes | Yes | Yes | Yes | Yes
+
+| `input` | Yes | No | Yes | No | Yes
+
+| `output` | Yes | No | Yes | No | Yes
+
+| `notification` | Yes | No | No | Yes | Yes
+
+|===
+
 == Namespaces
 
 YANG defines several namespaces and naming space of YANG is wider then applicable
@@ -69,8 +218,7 @@ YANG namespace::
 Binding namespace::
   Naming space introduced by Binding Specification for additional properties
   and functionality of Binding Specification. This namespaces needs to be separate
-  from YANG namespaces in order to not have naming conflict with YANG-derived
-  names.
+  from YANG namespaces in order to not have naming conflict with YANG-derived.
 
 
 Binding Specification v2 uses following namespaces:
@@ -275,10 +423,90 @@ Interior node::
 
 === `container` Statement
 
+Builders will be located in package "dto"
+
+
+[source,yang]
+----
+container foo {
+}
+
+container foo-builder {
+}
+----
+
+[uml, file="container-builder.png"]
+--
+set namespaceSeparator none
+
+interface data.Foo {
+}
+
+interface data.FooBuilder {
+}
+--
+
+In situations where we have a containing element which has as its child a single container, we should make it easy to autobox it. This should not be implemented in the interfaces themselves, but rather should be a method in the associated builder.
+
+[source,yang]
+----
+container example-outter {
+    container example-inner {
+        leaf example {
+            type string;
+        }
+    }
+}
+----
+
 === `list` Statement
 
 ==== Keyed List
 
+[source,yang]
+----
+list foo {
+    key identifier key fookey;
+    leaf identifier {
+        type union {
+            type string;
+        }
+    }
+
+    leaf key {
+        type string;
+    }
+
+    leaf fookey {
+        type string;
+    }
+}
+----
+[uml, file="list-Keyed.png"]
+--
+set namespaceSeparator none
+
+interface data.Foo {
+}
+
+interface key.foo.FooIdentifier {
+}
+
+interface key.foo.FooKey {
+}
+
+interface key.foo.FooFooKey {
+}
+
+interface type.foo.identifier.IdentifierUnion {
+}
+
+data.Foo o- key.foo.FooIdentifier
+data.Foo o- key.foo.FooKey
+data.Foo o- key.foo.FooFooKey
+key.foo.FooIdentifier o- type.foo.identifier.IdentifierUnion
+--
+
 ==== List without Key
 
 === `choice` Statement
@@ -299,8 +527,8 @@ container top {
 }
 ----
 
-[plantuml]
-....
+[uml, file="case.png"]
+--
 set namespaceSeparator none
 
 package spec {
@@ -325,11 +553,11 @@ data.top.base.Foo -u-|> Case
 data.top.base.Bar -u-|> Case
 
 data.top.base.Foo -u-|> data.top.Base
-data.top.base.Bar -u-|> data.top.base.Foo
+data.top.base.Bar -u-|> data.top.Base
 
 data.Top o- data.top.Base
 data.top.base.Foo o- data.top.base.foo.Foo
-....
+--
 
 == Specific rules
 
@@ -413,13 +641,13 @@ FIXME: Here should be Augmentable & Instantied & ChildDataNode
 === `grouping` Statement
 
 * `grouping` statement is represented by `interface`
-** class name is generated according to <<class-naming>> with suffix `Grouping`
+** interface name is generated according to <<class-naming>> with suffix `Grouping`
 * Representations of `grouping` statements are generated into <<grouping-namespace>>
-* data schema nodes under grouping are represented by `interface` and are generated
-  into <<grouping-namespace>>
+* schema nodes under grouping are represented by `interface` and are generated
+  into <<grouping-namespace>> + name of grouping
 ** getters (accessors) from parent nodes are generated according to <<accessor-rules>>
 ** class name is generated according to <<class-naming>> with suffix `Data`
-** data schema nodes does not follow <<instantiated-data-tree-rules>>, these interfaces
+** schema nodes does not follow <<instantiated-data-tree-rules>>, these interfaces
    are used only in instantiated data tree.
 
 .Simple Grouping
@@ -437,22 +665,31 @@ grouping simple  { <1>
     with signature `public grp.simple.FooData getFoo();`
 <3> Is represented by getter in `grp.SimpleGrouping` with signature `public String getBar()`
 
-[plantuml]
-....
+[uml, file="grouping1.png"]
+--
 interface grp.SimpleGrouping {
   + getBar() : String
   + getFoo() : grp.simple.FooData
 }
 interface grp.simple.FooData
 grp.SimpleGrouping o- grp.simple.FooData
-....
+--
 ====
 
 ==== Data Node substatements
 
 Representations of data node substatements are generated according to rules
 described in <<data-node-rules>> with following changes:
-
+////
+MS: proposed interface names:
+case - <NodeName>Case
+choice - <<NodeName>Choice
+container, list - <NodeName>
+////
+////
+MC: I would keep Data suffix, but idea about distinguishing cases and choices
+is to think about
+////
 * Interface names for `case`, `choice`, `container` and `list`, is suffixed by
   `Data` suffix, in order to not conflict with same named groupings inside same
   package
@@ -506,9 +743,8 @@ container top {
   uses simple;
 }
 ----
-
-[plantuml]
-....
+[uml, file="grouping2.png"]
+--
 set namespaceSeparator none
 
 interface grp.SimpleGrouping {
@@ -526,9 +762,9 @@ grp.SimpleGrouping o-- grp.simple.FooData
 data.Top o-- data.top.Foo
 data.Top -|> grp.SimpleGrouping
 data.top.Foo -|> grp.simple.FooData
-....
+--
 
-NOTE: Diagram does not show all details for `data.Top`  and `data.top.Foo`, which
+NOTE: Diagram does not show all details for `data.Top` and `data.top.Foo`, which
 are based on <<instantiated-data-tree-rules>>
 
 ====
@@ -539,9 +775,7 @@ are based on <<instantiated-data-tree-rules>>
 .YANG Snippet
 [source, yang]
 ----
-set namespaceSeparator none
 grouping with-inner {
-
   grouping inner {
     container cont;
   }
@@ -553,8 +787,8 @@ container top {
 }
 ----
 
-[plantuml]
-....
+[uml, file="grouping3.png"]
+--
 set namespaceSeparator none
 
 interface grp.withinner.inner.ContData
@@ -588,7 +822,7 @@ grp.withinner.InnerGrouping o-- grp.withinner.inner.ContData : contains
 
 grp.withinner.ContData -|> grp.withinner.inner.ContData : is concretization of (implements)
 
-....
+--
 
 NOTE: Diagram does not show all details for `data.Top`  and `data.top.Cont`, which
 are based on <<instantiated-data-tree-rules>>
@@ -621,8 +855,8 @@ container top {
 
 ----
 
-[plantuml]
-....
+[uml, file="grouping4.png"]
+--
 set namespaceSeparator none
 
 interface data.Top
@@ -640,7 +874,7 @@ grp.ExampleGrouping o-- grp.example.NestedData
 
 data.Top -|> grp.ExampleGrouping
 data.top.Nested -|> grp.example.NestedData
-....
+--
 
 NOTE: Diagram does not show all details for `data.Top`, `data.top.Nested` and
 `data.top.nested.Bar`, which are based on <<instantiated-data-tree-rules>>
@@ -672,8 +906,8 @@ grouping top {
 
 ----
 
-[plantuml]
-....
+[uml, file="grouping5.png"]
+--
 set namespaceSeparator none
 
 interface grp.TopGrouping
@@ -690,7 +924,7 @@ grp.ExampleGrouping o-- grp.example.NestedData
 
 grp.TopGrouping -|> grp.ExampleGrouping
 grp.top.NestedData -|> grp.example.NestedData
-....
+--
 
 ====
 
@@ -709,9 +943,8 @@ augment statement is defined
   augmentation is generated, child data nodes are generated by rules for
   <<instantiated-data-node-rules>>.
   See <<augment-other-module>> for details & examples.
-
-`augment` statement targets only instantiated data nodes, so child data node
-representation are always ge
+`augment` statement targets only instantiated data nodes, so child data nodes
+representation is always generated.
 
 [[augment-same-module]]
 ==== Augmentation target in same module
@@ -757,17 +990,29 @@ container top {
   }
 }
 
-.Java representation for both variants
 ----
-[plantuml]
-....
+.Same module written with grouping
+----
+grouping a {
+    container foo {
+    }
+}
+
+container top {
+    uses a;
+}
+
+----
+Java representation for all variants
+[uml, file="augment1.png"]
+--
 set namespaceSeparator none
 
 interface data.Top
 interface data.top.Foo
 
 data.Top o- data.top.Foo
-....
+--
 
 ====
 
@@ -799,8 +1044,8 @@ module foo {
 
 ----
 
-[plantuml]
-....
+[uml,file="augment2.png"]
+--
 set namespaceSeparator none
 
 interface Augmentable<T>
@@ -817,7 +1062,7 @@ top.data.Top -u-|> Augmentable : T = top.data.Top
 foo.data.FooTop -u-|> Augmentation : T = top.data.Top
 top.data.Top o-- foo.data.FooTop
 foo.data.FooTop o-- foo.data.top.Bar
-....
+--
 
 ====
 
@@ -852,8 +1097,8 @@ module foo {
 
 ----
 
-[plantuml]
-....
+[uml,file="augment3.png"]
+--
 set namespaceSeparator none
 
 interface Augmentable<T>
@@ -873,8 +1118,7 @@ foo.data.FooTop -u-|> Augmentation : T = top.data.Top
 top.data.Top o-- foo.data.FooTop
 foo.data.FooTop o-- foo.data.top.Bar
 foo.data.FooTop o-- foo.data.top.Baz
-
-....
+--
 
 ====
 
@@ -913,8 +1157,8 @@ module foo {
 
 ----
 
-[plantuml]
-....
+[uml, file="augment4.png"]
+--
 set namespaceSeparator none
 
 interface Augmentable<T>
@@ -945,6 +1189,23 @@ target.data.Second o-- foo.data.FooSecond
 
 foo.data.FooFirst o-- foo.data.first.Bar
 foo.data.FooSecond o-- foo.data.second.Baz
+--
+====
 
-....
+.Key in grouping
 ====
+[source,yang]
+----
+grouping nodes {
+    list node {
+        key id;
+        leaf id {
+            type string;
+        }
+    }
+}
+
+----
+grouping key.grp.nodes.node.<nodeidentifier>
+
+instantiated key.data.nodes.node.<nodeidentifier>