[ONOS-5724],[ONOS-5725],[ONOS-5736] onos buck plugin modifications for support of private package property.

Change-Id: Ic3a2f13c14816e803debc208826445ef27b49a4f
diff --git a/apps/yms/app/BUCK b/apps/yms/app/BUCK
index 97bd7a4..be5b01b 100644
--- a/apps/yms/app/BUCK
+++ b/apps/yms/app/BUCK
@@ -7,5 +7,7 @@
 ]
 
 osgi_jar_with_tests(
+  name = 'onos-apps-yms-app',
   deps = COMPILE_DEPS,
+  #private_packages = 'org.onosproject.yangutils.datamodel.*,org.onosproject.yangutils.translator.*,org.onosproject.yangutils.linker.*,org.onosproject.yangutils.utils.*',
 )
diff --git a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java
index 0c4e22f..59d414f 100644
--- a/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java
+++ b/apps/yms/app/src/main/java/org/onosproject/yms/app/ysr/DefaultYangSchemaRegistry.java
@@ -140,26 +140,28 @@
 
     @Override
     public void registerApplication(Object appObject, Class<?> serviceClass) {
-        synchronized (serviceClass) {
+        synchronized (DefaultYangSchemaRegistry.class) {
             doPreProcessing(serviceClass, appObject);
             if (!verifyIfApplicationAlreadyRegistered(serviceClass)) {
                 BundleContext context = getBundle(serviceClass).getBundleContext();
-                Bundle[] bundles = context.getBundles();
-                Bundle bundle;
-                int len = bundles.length;
-                List<YangNode> curNodes;
-                String jarPath;
-                for (int i = len - 1; i >= 0; i--) {
-                    bundle = bundles[i];
-                    if (bundle.getSymbolicName().contains(ONOS)) {
-                        jarPath = getJarPathFromBundleLocation(
-                                bundle.getLocation(), context.getProperty(USER_DIRECTORY));
-                        curNodes = processJarParsingOperations(jarPath);
-                        // process application registration.
-                        if (curNodes != null && !curNodes.isEmpty()) {
-                            jarPathStore.put(serviceClass.getName(), jarPath);
-                            processRegistration(serviceClass, jarPath,
-                                                curNodes, appObject, false);
+                if (context != null) {
+                    Bundle[] bundles = context.getBundles();
+                    Bundle bundle;
+                    int len = bundles.length;
+                    List<YangNode> curNodes;
+                    String jarPath;
+                    for (int i = len - 1; i >= 0; i--) {
+                        bundle = bundles[i];
+                        if (bundle.getSymbolicName().contains(ONOS)) {
+                            jarPath = getJarPathFromBundleLocation(
+                                    bundle.getLocation(), context.getProperty(USER_DIRECTORY));
+                            curNodes = processJarParsingOperations(jarPath);
+                            // process application registration.
+                            if (curNodes != null && !curNodes.isEmpty()) {
+                                jarPathStore.put(serviceClass.getName(), jarPath);
+                                processRegistration(serviceClass, jarPath,
+                                                    curNodes, appObject, false);
+                            }
                         }
                     }
                 }
@@ -170,7 +172,7 @@
     @Override
     public void unRegisterApplication(Object managerObject,
                                       Class<?> serviceClass) {
-        synchronized (serviceClass) {
+        synchronized (DefaultYangSchemaRegistry.class) {
             YangSchemaNode curNode;
             String serviceName = serviceClass.getName();
 
@@ -296,7 +298,7 @@
 
     @Override
     public boolean verifyNotificationObject(Object appObj, Class<?> service) {
-        synchronized (service) {
+        synchronized (DefaultYangSchemaRegistry.class) {
             YangSchemaNode node = appNameKeyStore.get(service.getName());
             if (node == null) {
                 log.error("application is not registered with YMS {}",
@@ -336,7 +338,7 @@
     @Override
     public void processModuleLibrary(String serviceName,
                                      YangModuleLibrary library) {
-        synchronized (serviceName) {
+        synchronized (DefaultYangSchemaRegistry.class) {
             YangSchemaNode node = appNameKeyStore.get(serviceName);
             if (node != null) {
                 YangModuleInformation moduleInformation =
diff --git a/lib/BUCK b/lib/BUCK
index 45e155b..69e6afd 100644
--- a/lib/BUCK
+++ b/lib/BUCK
@@ -1,4 +1,4 @@
-# ***** This file was auto-generated at Mon, 27 Feb 2017 19:42:10 GMT. Do not edit this file manually. *****
+# ***** This file was auto-generated at Tue, 28 Feb 2017 04:50:50 GMT. Do not edit this file manually. *****
 # ***** Use onos-lib-gen *****
 
 pass_thru_pom(
@@ -1211,3 +1211,12 @@
   visibility = [ 'PUBLIC' ],
 )
 
+remote_jar (
+  name = 'plexus-utils',
+  out = 'plexus-utils-3.0.24.jar',
+  url = 'mvn:org.codehaus.plexus:plexus-utils:jar:3.0.24',
+  sha1 = 'b4ac9780b37cb1b736eae9fbcef27609b7c911ef',
+  maven_coords = 'org.codehaus.plexus:plexus-utils:jar:NON-OSGI:3.0.24',
+  visibility = [ 'PUBLIC' ],
+)
+
diff --git a/lib/deps.json b/lib/deps.json
index 5d50e76..f809e3f 100644
--- a/lib/deps.json
+++ b/lib/deps.json
@@ -213,6 +213,7 @@
     "openflowj-3.0": {
       "uri": "mvn:org.projectfloodlight:openflowj:3.0.0-SNAPSHOT",
       "repo": "https://oss.sonatype.org/content/repositories/snapshots"
-    }
+    },
+    "plexus-utils": "mvn:org.codehaus.plexus:plexus-utils:3.0.24"
   }
 }
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java
index aa529fc..8cf91af 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OSGiWrapper.java
@@ -20,8 +20,12 @@
 import aQute.bnd.header.Parameters;
 import aQute.bnd.osgi.Analyzer;
 import aQute.bnd.osgi.Builder;
+import aQute.bnd.osgi.Constants;
+import aQute.bnd.osgi.Descriptors;
 import aQute.bnd.osgi.FileResource;
 import aQute.bnd.osgi.Jar;
+import aQute.bnd.osgi.Packages;
+import aQute.bnd.osgi.Processor;
 import aQute.bnd.osgi.Resource;
 import com.facebook.buck.step.ExecutionContext;
 import com.facebook.buck.step.Step;
@@ -32,6 +36,7 @@
 import com.google.common.collect.Maps;
 import com.google.common.collect.Sets;
 import org.apache.felix.scrplugin.bnd.SCRDescriptorBndPlugin;
+import org.codehaus.plexus.util.DirectoryScanner;
 
 import java.io.File;
 import java.io.IOException;
@@ -45,6 +50,7 @@
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Properties;
 import java.util.Set;
 import java.util.jar.Manifest;
 import java.util.stream.Collectors;
@@ -68,6 +74,7 @@
     private String bundleVersion;
 
     private String importPackages;
+    private String privatePackages;
     private String dynamicimportPackages;
 
     private String exportPackages;
@@ -95,7 +102,8 @@
                        String includeResources,
                        String webContext,
                        String dynamicimportPackages,
-                       String bundleDescription) {
+                       String bundleDescription,
+                       String privatePackages) {
         this.inputJar = inputJar;
         this.sourcesDir = sourcesDir;
         this.classesDir = classesDir;
@@ -115,6 +123,7 @@
         this.bundleDescription = bundleDescription;
 
         this.importPackages = importPackages;
+        this.privatePackages = privatePackages;
         this.dynamicimportPackages = dynamicimportPackages;
         this.exportPackages = exportPackages;
         this.includeResources = includeResources;
@@ -140,11 +149,16 @@
 
         // There are no good defaults so make sure you set the Import-Package
         analyzer.setProperty(Analyzer.IMPORT_PACKAGE, importPackages);
+        if (privatePackages != null) {
+            analyzer.setProperty(Analyzer.PRIVATE_PACKAGE, privatePackages);
+        }
+        analyzer.setProperty(Analyzer.REMOVEHEADERS, "Private-Package,Include-Resource");
 
-        analyzer.setProperty(Analyzer.DYNAMICIMPORT_PACKAGE, dynamicimportPackages);
+        analyzer.setProperty(Analyzer.DYNAMICIMPORT_PACKAGE,
+                             dynamicimportPackages);
 
         // TODO include version in export, but not in import
-        analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages);
+        //    analyzer.setProperty(Analyzer.EXPORT_PACKAGE, exportPackages);
 
         // TODO we may need INCLUDE_RESOURCE, or that might be done by Buck
         if (includeResources != null) {
@@ -159,7 +173,7 @@
     }
 
     public boolean execute() {
-        Analyzer analyzer = new Builder();
+        Builder analyzer = new Builder();
         try {
 
             Jar jar = new Jar(inputJar.toFile());  // where our data is
@@ -179,17 +193,11 @@
 
             // ------------- let's begin... -------------------------
 
-            // Analyze the target JAR first
-            analyzer.analyze();
+            //Add local packges to jar file.
+            addLocalPackages(new File(classesDir.toString()), analyzer);
+//            analyzer.analyze();
 
-            // Scan the JAR for Felix SCR annotations and generate XML files
-            Map<String, String> properties = Maps.newHashMap();
-            properties.put("destdir", classesDir.toAbsolutePath().toString());
-            SCRDescriptorBndPlugin scrDescriptorBndPlugin = new SCRDescriptorBndPlugin();
-            scrDescriptorBndPlugin.setProperties(properties);
-            scrDescriptorBndPlugin.setReporter(analyzer);
-            scrDescriptorBndPlugin.analyzeJar(analyzer);
-
+            //add resources.
             if (includeResources != null) {
                 doIncludeResources(analyzer);
             }
@@ -198,13 +206,27 @@
             doWabStaging(analyzer);
 
             // Calculate the manifest
-            Manifest manifest = analyzer.calcManifest();
+//            Manifest manifest = analyzer.calcManifest();
             //OutputStream s = new FileOutputStream("/tmp/foo2.txt");
             //manifest.write(s);
             //s.close();
 
             if (analyzer.isOk()) {
+                //Build the jar files
+                analyzer.build();
+                Map<String, String> properties = Maps.newHashMap();
+
+                // Scan the JAR for Felix SCR annotations and generate XML files
+                properties.put("destdir", classesDir.toAbsolutePath().toString());
+                SCRDescriptorBndPlugin scrDescriptorBndPlugin = new SCRDescriptorBndPlugin();
+                scrDescriptorBndPlugin.setProperties(properties);
+                scrDescriptorBndPlugin.setReporter(analyzer);
+                scrDescriptorBndPlugin.analyzeJar(analyzer);
+
+                //add calculated manifest file.
+                Manifest manifest = analyzer.calcManifest();
                 analyzer.getJar().setManifest(manifest);
+
                 if (analyzer.save(outputJar.toFile(), true)) {
                     log("Saved!\n");
                 } else {
@@ -225,6 +247,75 @@
         }
     }
 
+    private static void addLocalPackages(File outputDirectory, Analyzer analyzer) throws IOException {
+        Packages packages = new Packages();
+
+        if (outputDirectory != null && outputDirectory.isDirectory()) {
+            // scan classes directory for potential packages
+            DirectoryScanner scanner = new DirectoryScanner();
+            scanner.setBasedir(outputDirectory);
+            scanner.setIncludes(new String[]
+                                        {"**/*.class"});
+
+            scanner.addDefaultExcludes();
+            scanner.scan();
+
+            String[] paths = scanner.getIncludedFiles();
+            for (int i = 0; i < paths.length; i++) {
+                packages.put(analyzer.getPackageRef(getPackageName(paths[i])));
+            }
+        }
+
+        Packages exportedPkgs = new Packages();
+        Packages privatePkgs = new Packages();
+
+        boolean noprivatePackages = "!*".equals(analyzer.getProperty(Analyzer.PRIVATE_PACKAGE));
+
+        for (Descriptors.PackageRef pkg : packages.keySet()) {
+            // mark all source packages as private by default (can be overridden by export list)
+            privatePkgs.put(pkg);
+
+            // we can't export the default package (".") and we shouldn't export internal packages
+            String fqn = pkg.getFQN();
+            if (noprivatePackages || !(".".equals(fqn) || fqn.contains(".internal") || fqn.contains(".impl"))) {
+                exportedPkgs.put(pkg);
+            }
+        }
+
+        Properties properties = analyzer.getProperties();
+        String exported = properties.getProperty(Analyzer.EXPORT_PACKAGE);
+        if (exported == null) {
+            if (!properties.containsKey(Analyzer.EXPORT_CONTENTS)) {
+                // no -exportcontents overriding the exports, so use our computed list
+                for (Attrs attrs : exportedPkgs.values()) {
+                    attrs.put(Constants.SPLIT_PACKAGE_DIRECTIVE, "merge-first");
+                }
+                properties.setProperty(Analyzer.EXPORT_PACKAGE, Processor.printClauses(exportedPkgs));
+            } else {
+                // leave Export-Package empty (but non-null) as we have -exportcontents
+                properties.setProperty(Analyzer.EXPORT_PACKAGE, "");
+            }
+        }
+
+        String internal = properties.getProperty(Analyzer.PRIVATE_PACKAGE);
+        if (internal == null) {
+            if (!privatePkgs.isEmpty()) {
+                for (Attrs attrs : privatePkgs.values()) {
+                    attrs.put(Constants.SPLIT_PACKAGE_DIRECTIVE, "merge-first");
+                }
+                properties.setProperty(Analyzer.PRIVATE_PACKAGE, Processor.printClauses(privatePkgs));
+            } else {
+                // if there are really no private packages then use "!*" as this will keep the Bnd Tool happy
+                properties.setProperty(Analyzer.PRIVATE_PACKAGE, "!*");
+            }
+        }
+    }
+
+    private static String getPackageName(String filename) {
+        int n = filename.lastIndexOf(File.separatorChar);
+        return n < 0 ? "." : filename.substring(0, n).replace(File.separatorChar, '.');
+    }
+
     private boolean isWab() {
         return webContext != null;
     }
@@ -238,7 +329,7 @@
 
         log("wab %s", wab);
         analyzer.setBundleClasspath("WEB-INF/classes," +
-                                    analyzer.getProperty(analyzer.BUNDLE_CLASSPATH));
+                                            analyzer.getProperty(analyzer.BUNDLE_CLASSPATH));
 
         Set<String> paths = new HashSet<>(dot.getResources().keySet());
 
@@ -368,7 +459,6 @@
                 .add("bundleDescription", bundleDescription)
                 .add("bundleLicense", bundleLicense)
                 .toString();
-
     }
 
     @Override
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java
index 6885c07..0f80bd5 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJar.java
@@ -21,7 +21,6 @@
 import com.facebook.buck.jvm.java.JavaLibrary;
 import com.facebook.buck.jvm.java.MavenPublishable;
 import com.facebook.buck.model.BuildTarget;
-import com.facebook.buck.model.Pair;
 import com.facebook.buck.rules.AddToRuleKey;
 import com.facebook.buck.rules.BuildRule;
 import com.facebook.buck.rules.BuildRuleParams;
@@ -29,7 +28,6 @@
 import com.facebook.buck.rules.SourcePathResolver;
 import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.ImmutableSortedMap;
 import com.google.common.collect.ImmutableSortedSet;
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java
index 6ba61cf..620182b 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarDescription.java
@@ -34,7 +34,6 @@
 import com.facebook.buck.model.Flavor;
 import com.facebook.buck.model.Flavored;
 import com.facebook.buck.model.ImmutableFlavor;
-import com.facebook.buck.model.Pair;
 import com.facebook.buck.parser.NoSuchBuildTargetException;
 import com.facebook.buck.rules.BuildRule;
 import com.facebook.buck.rules.BuildRuleParams;
@@ -58,8 +57,6 @@
 
 import java.nio.file.Path;
 import java.util.List;
-import java.util.function.BinaryOperator;
-import java.util.stream.Collectors;
 
 import static com.facebook.buck.jvm.common.ResourceValidator.validateResources;
 
@@ -250,7 +247,8 @@
                                                            args.apiPackage, args.apiDescription, args.resources,
                                                            args.groupId, args.bundleName, args.bundleVersion,
                                                            args.bundleLicense, args.bundleDescription, args.importPackages,
-                                                           args.exportPackages, includedResourcesString, args.dynamicimportPackages),
+                                                           args.exportPackages, includedResourcesString,
+                                                           args.dynamicimportPackages, args.privatePackages),
                                     args.resourcesRoot,
                                     args.manifestFile,
                                     args.mavenCoords,
@@ -327,6 +325,7 @@
         public Optional<String> bundleDescription;
 
         public Optional<String> importPackages;
+        public Optional<String> privatePackages;
         public Optional<String> exportPackages;
         public Optional<ImmutableSortedMap<String, SourcePath>> includeResources;
         public Optional<String> dynamicimportPackages;
diff --git a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java
index ae2853b..fff225e3 100644
--- a/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java
+++ b/tools/build/buck-plugin/src/main/java/org/onosproject/onosjar/OnosJarStepFactory.java
@@ -57,6 +57,7 @@
     private final String bundleLicense;
     private final String bundleDescription;
     private final String importPackages;
+    private final String privatePackages;
     private final String exportPackages;
     private final String includeResources;
     private final String dynamicimportPackages;
@@ -77,10 +78,12 @@
                               Optional<String> importPackages,
                               Optional<String> exportPackages,
                               Optional<String> includeResources,
-                              Optional<String> dynamicimportPackages) {
+                              Optional<String> dynamicimportPackages,
+                              Optional<String> privatePackages) {
         super(javacOptions, amender);
         this.bundleDescription = processParameter(bundleDescription);
         this.importPackages = processParameter(importPackages);
+        this.privatePackages = processParameter(privatePackages);
         this.exportPackages = processParameter(exportPackages);
         this.includeResources = processParameter(includeResources);
         this.dynamicimportPackages = processParameter(dynamicimportPackages);
@@ -194,7 +197,8 @@
                 includeResources, // include resources
                 webContext, // web context
                 dynamicimportPackages, // dynamic import packages
-                bundleDescription  // bundle description
+                bundleDescription,  // bundle description
+                privatePackages // private packages
         );
         steps.add(osgiStep);