gNotification flag implementation in utils to optimize notification search and notification listener addition in YMS

Change-Id: Iea666ca7af9641869cba2a67e23a025cbc1b7317
diff --git a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java
index f04862e..94369d7 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/parser/impl/listeners/NotificationListener.java
@@ -16,6 +16,7 @@
 
 package org.onosproject.yangutils.parser.impl.listeners;
 
+import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
 import org.onosproject.yangutils.datamodel.YangModule;
 import org.onosproject.yangutils.datamodel.YangNode;
 import org.onosproject.yangutils.datamodel.YangNotification;
@@ -92,9 +93,11 @@
                                                 GeneratedYangParser.NotificationStatementContext ctx) {
 
         // Check for stack to be non empty.
-        checkStackIsNotEmpty(listener, MISSING_HOLDER, NOTIFICATION_DATA, ctx.identifier().getText(), ENTRY);
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, NOTIFICATION_DATA,
+                             ctx.identifier().getText(), ENTRY);
 
-        String identifier = getValidIdentifier(ctx.identifier().getText(), NOTIFICATION_DATA, ctx);
+        String identifier = getValidIdentifier(ctx.identifier().getText(),
+                                               NOTIFICATION_DATA, ctx);
 
         // Validate sub statement cardinality.
         validateSubStatementsCardinality(ctx);
@@ -102,13 +105,15 @@
         // Check for identifier collision
         int line = ctx.getStart().getLine();
         int charPositionInLine = ctx.getStart().getCharPositionInLine();
-        detectCollidingChildUtil(listener, line, charPositionInLine, identifier, NOTIFICATION_DATA);
+        detectCollidingChildUtil(listener, line, charPositionInLine, identifier,
+                                 NOTIFICATION_DATA);
 
         Parsable curData = listener.getParsedDataStack().peek();
         if (curData instanceof YangModule || curData instanceof YangSubModule) {
 
             YangNotification notification = getYangNotificationNode(JAVA_GENERATION);
             notification.setName(identifier);
+            ((RpcNotificationContainer) curData).setNotificationPresenceFlag(true);
             YangNode curNode = (YangNode) curData;
             try {
                 curNode.addChild(notification);
@@ -119,7 +124,7 @@
             listener.getParsedDataStack().push(notification);
         } else {
             throw new ParserException(constructListenerErrorMessage(INVALID_HOLDER, NOTIFICATION_DATA,
-                    ctx.identifier().getText(), ENTRY));
+                                                                    ctx.identifier().getText(), ENTRY));
         }
     }
 
@@ -134,13 +139,14 @@
                                                GeneratedYangParser.NotificationStatementContext ctx) {
 
         // Check for stack to be non empty.
-        checkStackIsNotEmpty(listener, MISSING_HOLDER, NOTIFICATION_DATA, ctx.identifier().getText(), EXIT);
+        checkStackIsNotEmpty(listener, MISSING_HOLDER, NOTIFICATION_DATA,
+                             ctx.identifier().getText(), EXIT);
 
         if (listener.getParsedDataStack().peek() instanceof YangNotification) {
             listener.getParsedDataStack().pop();
         } else {
             throw new ParserException(constructListenerErrorMessage(MISSING_CURRENT_HOLDER, NOTIFICATION_DATA,
-                    ctx.identifier().getText(), EXIT));
+                                                                    ctx.identifier().getText(), EXIT));
         }
     }
 
@@ -151,10 +157,13 @@
      */
     private static void validateSubStatementsCardinality(GeneratedYangParser.NotificationStatementContext ctx) {
 
-        validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA, NOTIFICATION_DATA, ctx.identifier().getText());
-        validateCardinalityMaxOne(ctx.descriptionStatement(), DESCRIPTION_DATA, NOTIFICATION_DATA,
-                ctx.identifier().getText());
-        validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA, NOTIFICATION_DATA,
-                ctx.identifier().getText());
+        validateCardinalityMaxOne(ctx.statusStatement(), STATUS_DATA,
+                                  NOTIFICATION_DATA, ctx.identifier().getText());
+        validateCardinalityMaxOne(ctx.descriptionStatement(),
+                                  DESCRIPTION_DATA, NOTIFICATION_DATA,
+                                  ctx.identifier().getText());
+        validateCardinalityMaxOne(ctx.referenceStatement(), REFERENCE_DATA,
+                                  NOTIFICATION_DATA,
+                                  ctx.identifier().getText());
     }
 }
diff --git a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaNotificationTranslator.java b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaNotificationTranslator.java
index d6f81b9..a44164f 100644
--- a/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaNotificationTranslator.java
+++ b/plugin/src/main/java/org/onosproject/yangutils/translator/tojava/javamodel/YangJavaNotificationTranslator.java
@@ -17,23 +17,25 @@
 package org.onosproject.yangutils.translator.tojava.javamodel;
 
 import java.io.IOException;
-
+import org.onosproject.yangutils.datamodel.RpcNotificationContainer;
+import org.onosproject.yangutils.datamodel.YangLeavesHolder;
 import org.onosproject.yangutils.datamodel.YangNode;
-import org.onosproject.yangutils.translator.tojava.JavaFileInfoTranslator;
 import org.onosproject.yangutils.datamodel.javadatamodel.YangJavaNotification;
-import org.onosproject.yangutils.utils.io.YangPluginConfig;
 import org.onosproject.yangutils.translator.exception.TranslatorException;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGenerator;
 import org.onosproject.yangutils.translator.tojava.JavaCodeGeneratorInfo;
 import org.onosproject.yangutils.translator.tojava.JavaFileInfoContainer;
+import org.onosproject.yangutils.translator.tojava.JavaFileInfoTranslator;
 import org.onosproject.yangutils.translator.tojava.JavaQualifiedTypeInfoTranslator;
 import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFiles;
 import org.onosproject.yangutils.translator.tojava.TempJavaCodeFragmentFilesContainer;
 import org.onosproject.yangutils.translator.tojava.TempJavaServiceFragmentFiles;
 import org.onosproject.yangutils.translator.tojava.utils.JavaExtendsListHolder;
+import org.onosproject.yangutils.utils.io.YangPluginConfig;
 
 import static org.onosproject.yangutils.translator.tojava.GeneratedJavaFileType.GENERATE_INTERFACE_WITH_BUILDER;
 import static org.onosproject.yangutils.translator.tojava.YangJavaModelUtils.generateCodeOfAugmentableNode;
+import static org.onosproject.yangutils.translator.tojava.utils.JavaIdentifierSyntax.getEnumJavaAttribute;
 import static org.onosproject.yangutils.utils.UtilConstants.EVENT_LISTENER_STRING;
 import static org.onosproject.yangutils.utils.UtilConstants.EVENT_STRING;
 import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.getCapitalCase;
@@ -71,7 +73,8 @@
     public JavaFileInfoTranslator getJavaFileInfo() {
 
         if (javaFileInfo == null) {
-            throw new TranslatorException("Missing java info in java datamodel node");
+            throw new TranslatorException("Missing java info in java " +
+                                                  "datamodel node");
         }
         return (JavaFileInfoTranslator) javaFileInfo;
     }
@@ -114,11 +117,14 @@
      * @throws TranslatorException translator operation fail
      */
     @Override
-    public void generateCodeEntry(YangPluginConfig yangPlugin) throws TranslatorException {
+    public void generateCodeEntry(YangPluginConfig yangPlugin)
+            throws TranslatorException {
 
         /*
-         * As part of the notification support the following files needs to be generated.
-         * 1) Subject of the notification(event), this is simple interface with builder class.
+         * As part of the notification support the following files needs to
+         * be generated.
+         * 1) Subject of the notification(event), this is simple interface with
+         * builder class.
          * 2) Event class extending "AbstractEvent" and defining event type enum.
          * 3) Event listener interface extending "EventListener".
          *
@@ -132,7 +138,8 @@
             addNotificationToExtendsList();
         } catch (IOException e) {
             throw new TranslatorException(
-                    "Failed to prepare generate code entry for notification node " + getName());
+                    "Failed to prepare generate code entry for notification " +
+                            "node " + getName());
         }
     }
 
@@ -167,8 +174,34 @@
         try {
             getTempJavaCodeFragmentFiles().generateJavaFile(GENERATE_INTERFACE_WITH_BUILDER, this);
         } catch (IOException e) {
-            throw new TranslatorException("Failed to generate code for notification node " + getName());
+            throw new TranslatorException("Failed to generate code for " +
+                                                  "notification node " +
+                                                  getName());
         }
 
     }
+
+    @Override
+    public void setNameSpaceAndAddToParentSchemaMap() {
+        // Get parent namespace.
+        if (this.getParent() != null) {
+            String nameSpace = this.getParent().getNameSpace();
+            // Set namespace for self node.
+            setNameSpace(nameSpace);
+            // Process addition of leaf to the child schema map of parent.
+            processAdditionOfSchemaNodeToParentMap(getName(), getNameSpace());
+            // Obtain the notification name as per enum in notification.
+            String enumName = getEnumJavaAttribute(getJavaFileInfo().getJavaName()).toUpperCase();
+
+            ((RpcNotificationContainer) this.getParent()).addToNotificationEnumMap(enumName, this);
+
+        }
+        /*
+         * Check if node contains leaf/leaf-list, if yes add namespace for leaf
+         * and leaf list.
+         */
+        if (this instanceof YangLeavesHolder) {
+            ((YangLeavesHolder) this).setLeafNameSpaceAndAddToParentSchemaMap();
+        }
+    }
 }
diff --git a/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/SchemaNodeTest.java b/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/SchemaNodeTest.java
index 88a4e2d..5d77724 100644
--- a/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/SchemaNodeTest.java
+++ b/plugin/src/test/java/org/onosproject/yangutils/plugin/manager/SchemaNodeTest.java
@@ -22,6 +22,7 @@
 import java.util.Map;
 import org.apache.maven.plugin.MojoExecutionException;
 import org.junit.Test;
+import org.onosproject.yangutils.datamodel.exceptions.DataModelException;
 import org.onosproject.yangutils.datamodel.YangLeaf;
 import org.onosproject.yangutils.datamodel.YangLeavesHolder;
 import org.onosproject.yangutils.datamodel.YangNode;
@@ -32,6 +33,7 @@
 import org.onosproject.yangutils.utils.io.impl.YangFileScanner;
 
 import static org.hamcrest.CoreMatchers.notNullValue;
+import static org.hamcrest.CoreMatchers.nullValue;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.core.Is.is;
 import static org.onosproject.yangutils.utils.io.impl.YangIoUtils.deleteDirectory;
@@ -46,10 +48,14 @@
     /**
      * Checks method to get schema node from map.
      *
-     * @throws MojoExecutionException
+     * @throws IOException a violation in IO rule
+     * @throws ParserException a violation in parser rule
+     * @throws MojoExecutionException a violation in mojo rule
+     * @throws DataModelException a violation in data model rule
      */
     @Test
-    public void processSchemaNodeMap() throws IOException, ParserException, MojoExecutionException {
+    public void processSchemaNodeMap() throws IOException, ParserException,
+            MojoExecutionException, DataModelException {
 
         String searchDir = "src/test/resources/schemaMap";
         utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
@@ -63,13 +69,23 @@
         Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
         YangNode rootNode = yangNodeIterator.next();
 
+        // Validate the notification enum map
+        assertThat(rootNode.getChild().getNextSibling(),
+                   is(rootNode.getNotificationSchemaNode("TESTNOTIFICATION1")));
+
+        // Validate the notification enum map shouldn't have container
+        assertThat(rootNode.getNotificationSchemaNode("TESTCONTAINER"),
+                   is(nullValue()));
+
         assertThat(rootNode.getYsnContextInfoMap(), is(notNullValue()));
-        Map<YangSchemaNodeIdentifier, YangSchemaNodeContextInfo> schemaMap = rootNode.getYsnContextInfoMap();
+        Map<YangSchemaNodeIdentifier, YangSchemaNodeContextInfo> schemaMap =
+                rootNode.getYsnContextInfoMap();
         YangSchemaNodeIdentifier yangSchemaNodeIdentifier = new YangSchemaNodeIdentifier();
         yangSchemaNodeIdentifier.setName("testcontainer");
         yangSchemaNodeIdentifier.setNameSpace("http://huawei.com");
         assertThat(schemaMap.get(yangSchemaNodeIdentifier), is(notNullValue()));
-        YangSchemaNodeContextInfo yangSchemaNodeContextInfo = schemaMap.get(yangSchemaNodeIdentifier);
+        YangSchemaNodeContextInfo yangSchemaNodeContextInfo =
+                schemaMap.get(yangSchemaNodeIdentifier);
         assertThat(yangSchemaNodeContextInfo.getSchemaNode(), is(rootNode.getChild()));
 
         assertThat(rootNode.getChild().getYsnContextInfoMap(), is(notNullValue()));
@@ -84,21 +100,26 @@
         assertThat(schemaMap2.get(yangSchemaNodeIdentifier), is(notNullValue()));
 
         assertThat(rootNode.getChild().getChild().getYsnContextInfoMap(), is(notNullValue()));
-        Map<YangSchemaNodeIdentifier, YangSchemaNodeContextInfo> schemaMap3 = rootNode.getChild().getChild()
+        Map<YangSchemaNodeIdentifier, YangSchemaNodeContextInfo> schemaMap3 =
+                rootNode.getChild().getChild()
                 .getYsnContextInfoMap();
         yangSchemaNodeIdentifier.setName("pretzel");
         yangSchemaNodeIdentifier.setNameSpace("http://huawei.com");
         assertThat(schemaMap3.get(yangSchemaNodeIdentifier), is(notNullValue()));
-        YangSchemaNodeContextInfo yangSchemaNodeContextInfo3 = schemaMap3.get(yangSchemaNodeIdentifier);
+        YangSchemaNodeContextInfo yangSchemaNodeContextInfo3 =
+                schemaMap3.get(yangSchemaNodeIdentifier);
 
-        assertThat(rootNode.getChild().getChild().getChild().getYsnContextInfoMap(), is(notNullValue()));
-        Map<YangSchemaNodeIdentifier, YangSchemaNodeContextInfo> schemaMap4 = rootNode.getChild().getChild().getChild()
+        assertThat(rootNode.getChild().getChild().getChild().getYsnContextInfoMap(),
+                   is(notNullValue()));
+        Map<YangSchemaNodeIdentifier, YangSchemaNodeContextInfo> schemaMap4 =
+                rootNode.getChild().getChild().getChild()
                 .getYsnContextInfoMap();
         yangSchemaNodeIdentifier.setName("pretzel");
         yangSchemaNodeIdentifier.setNameSpace("http://huawei.com");
         assertThat(schemaMap4.get(yangSchemaNodeIdentifier), is(notNullValue()));
 
-        YangSchemaNodeContextInfo yangSchemaNodeContextInfo2 = schemaMap4.get(yangSchemaNodeIdentifier);
+        YangSchemaNodeContextInfo yangSchemaNodeContextInfo2 =
+                schemaMap4.get(yangSchemaNodeIdentifier);
         List<YangLeaf> yangListOfLeaf = ((YangLeavesHolder) rootNode.getChild().getChild().getChild()).getListOfLeaf();
         YangLeaf yangLeaf = yangListOfLeaf.get(0);
         assertThat(yangSchemaNodeContextInfo2.getSchemaNode(), is(yangLeaf));
@@ -109,4 +130,33 @@
         deleteDirectory("target/schemaMap/");
     }
 
+    /**
+     * Checks that notification map shouldn't be present in other YANG node.
+     *
+     * @throws IOException a violation in IO rule
+     * @throws ParserException a violation in parser rule
+     * @throws MojoExecutionException a violation in mojo rule
+     * @throws DataModelException a violation in data model rule
+     */
+    @Test(expected = DataModelException.class)
+    public void processNotificationEnumMapInvalidScenario() throws IOException,
+            ParserException, MojoExecutionException,
+            DataModelException {
+
+        String searchDir = "src/test/resources/schemaMap";
+        utilManager.createYangFileInfoSet(YangFileScanner.getYangFiles(searchDir));
+        utilManager.parseYangFileInfoSet();
+        utilManager.createYangNodeSet();
+        utilManager.resolveDependenciesUsingLinker();
+        YangPluginConfig yangPluginConfig = new YangPluginConfig();
+        yangPluginConfig.setCodeGenDir("target/schemaMap/");
+        utilManager.translateToJava(yangPluginConfig);
+
+        Iterator<YangNode> yangNodeIterator = utilManager.getYangNodeSet().iterator();
+        YangNode rootNode = yangNodeIterator.next();
+
+        deleteDirectory("target/schemaMap/");
+
+        rootNode.getChild().getNotificationSchemaNode("TESTNOTIFICATION1");
+    }
 }
diff --git a/plugin/src/test/resources/schemaMap/SchemaMap.yang b/plugin/src/test/resources/schemaMap/SchemaMap.yang
index b8b5c48..34c989c 100644
--- a/plugin/src/test/resources/schemaMap/SchemaMap.yang
+++ b/plugin/src/test/resources/schemaMap/SchemaMap.yang
@@ -14,4 +14,12 @@
              }
         }
     }
+    notification testnotification1 {
+        leaf type {
+            type string;
+        }
+        leaf severity {
+            type string;
+        }
+    }
 }