[NO ISSUE][HYR][LIC] += <extraDependencies/> to license plugin

- Add ability to include extra maven dependencies (i.e. those not in the
  project model) in generated license output
- Extra maven dependencies can be the same groupId/artifactId as an
  exisiting dependency

(cherry picked from commit e0928c85ba)

Change-Id: Ic8f37d0eca6f4e745305b31d74682ca7e62ead27
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/14983
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Michael Blow <mblow@apache.org>
diff --git a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java
index 89993fd..2206621 100644
--- a/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java
+++ b/hyracks-fullstack/hyracks/hyracks-maven-plugins/license-automation-plugin/src/main/java/org/apache/hyracks/maven/license/LicenseMojo.java
@@ -41,13 +41,19 @@
 import java.util.stream.Collectors;
 
 import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.mutable.MutableBoolean;
 import org.apache.commons.lang3.tuple.ImmutablePair;
 import org.apache.commons.lang3.tuple.Pair;
 import org.apache.hyracks.maven.license.project.LicensedProjects;
 import org.apache.hyracks.maven.license.project.Project;
 import org.apache.maven.artifact.Artifact;
+import org.apache.maven.artifact.DefaultArtifact;
+import org.apache.maven.artifact.handler.ArtifactHandler;
+import org.apache.maven.artifact.handler.DefaultArtifactHandler;
 import org.apache.maven.artifact.repository.ArtifactRepository;
+import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
+import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 import org.apache.maven.artifact.resolver.ArtifactResolver;
 import org.apache.maven.execution.MavenSession;
 import org.apache.maven.model.License;
@@ -121,6 +127,9 @@
     @Parameter
     protected boolean failOnWarning;
 
+    @Parameter
+    protected List<String> extraDependencies = new ArrayList<>();
+
     private Map<String, MavenProject> projectCache = new HashMap<>();
 
     private Map<String, Model> supplementModels;
@@ -393,24 +402,47 @@
     private void gatherProjectDependencies(MavenProject project,
             Map<MavenProject, List<Pair<String, String>>> dependencyLicenseMap,
             Map<String, MavenProject> dependencyGavMap) throws ProjectBuildingException {
-        final Set dependencyArtifacts = project.getArtifacts();
+        final Set<Artifact> dependencyArtifacts = project.getArtifacts();
         if (dependencyArtifacts != null) {
-            for (Object depArtifactObj : dependencyArtifacts) {
-                final Artifact depArtifact = (Artifact) depArtifactObj;
-                if (!excludedScopes.contains(depArtifact.getScope())) {
-                    MavenProject dep = resolveDependency(depArtifact);
-                    dep.setArtifact(depArtifact);
-                    dependencyGavMap.put(toGav(dep), dep);
-                    List<Pair<String, String>> licenseUrls = new ArrayList<>();
-                    for (Object license : dep.getLicenses()) {
-                        final License license1 = (License) license;
-                        String url = license1.getUrl() != null ? license1.getUrl()
-                                : (license1.getName() != null ? license1.getName() : "LICENSE_EMPTY_NAME_URL");
-                        licenseUrls.add(new ImmutablePair<>(url, license1.getName()));
-                    }
-                    dependencyLicenseMap.put(dep, licenseUrls);
+            for (Artifact depArtifact : dependencyArtifacts) {
+                processArtifact(depArtifact, dependencyLicenseMap, dependencyGavMap);
+            }
+        }
+        for (String gav : extraDependencies) {
+            ArtifactHandler handler = new DefaultArtifactHandler("jar");
+            String[] gavParts = StringUtils.split(gav, ':');
+            Artifact manualDep = new DefaultArtifact(gavParts[0], gavParts[1], gavParts[2], Artifact.SCOPE_COMPILE,
+                    "jar", null, handler);
+            processArtifact(manualDep, dependencyLicenseMap, dependencyGavMap);
+        }
+    }
+
+    private void processArtifact(Artifact depArtifact,
+            Map<MavenProject, List<Pair<String, String>>> dependencyLicenseMap,
+            Map<String, MavenProject> dependencyGavMap) throws ProjectBuildingException {
+        if (!excludedScopes.contains(depArtifact.getScope())) {
+            MavenProject dep = resolveDependency(depArtifact);
+            if (!depArtifact.isResolved()) {
+                ArtifactResolutionRequest arr = new ArtifactResolutionRequest();
+                arr.setLocalRepository(localRepository);
+                arr.setRemoteRepositories(remoteRepositories);
+                arr.setArtifact(depArtifact);
+                ArtifactResolutionResult result = artifactResolver.resolve(arr);
+                if (!result.isSuccess()) {
+                    throw new ProjectBuildingException(project.getId(),
+                            "Unable to resolve " + depArtifact + ": " + result.getExceptions(), (Throwable) null);
                 }
             }
+            dep.setArtifact(depArtifact);
+            dependencyGavMap.put(toGav(dep), dep);
+            List<Pair<String, String>> licenseUrls = new ArrayList<>();
+            for (Object license : dep.getLicenses()) {
+                final License license1 = (License) license;
+                String url = license1.getUrl() != null ? license1.getUrl()
+                        : (license1.getName() != null ? license1.getName() : "LICENSE_EMPTY_NAME_URL");
+                licenseUrls.add(new ImmutablePair<>(url, license1.getName()));
+            }
+            dependencyLicenseMap.put(dep, licenseUrls);
         }
     }
 
@@ -430,7 +462,7 @@
                     .get(SupplementalModelHelper.generateSupplementMapKey(depObj.getGroupId(), depObj.getArtifactId()));
             registerVerified(depProj, supplement);
             if (supplement != null) {
-                Model merged = SupplementalModelHelper.mergeModels(assembler, depProj.getModel(), supplement);
+                Model merged = SupplementalModelHelper.mergeModels(assembler, depProj.getModel(), supplement).clone();
                 Set<String> origLicenses =
                         depProj.getModel().getLicenses().stream().map(License::getUrl).collect(Collectors.toSet());
                 Set<String> newLicenses =