Repository: porscheinformatik/sonarqube-licensecheck (java)

Issue:
License is empty for Maven dependencies with classifier
When a module has a Maven dependency with a classifier then the licenses get not filled even though the license is set in the pom.xml and a valid license mapping is defined.

The classifier is displayed in the license check dashboard instead of the version.



Pull request description:
Check for classifier in Maven dependencies, closes #86
 - Changed implementation from RegEx to simple String split
 - When split string contains more items it is the classifier

Patch:
diff --git a/src/main/java/at/porscheinformatik/sonarqube/licensecheck/Dependency.java b/src/main/java/at/porscheinformatik/sonarqube/licensecheck/Dependency.java
index 48c35ee..3412d17 100644
--- a/src/main/java/at/porscheinformatik/sonarqube/licensecheck/Dependency.java
+++ b/src/main/java/at/porscheinformatik/sonarqube/licensecheck/Dependency.java
@@ -20,7 +20,7 @@ public class Dependency implements Comparable<Dependency>
     private String version;
     private String license;
     private String status;
-    private String localPath;
+    private String pomPath;
 
     public Dependency(String name, String version, String license)
     {
@@ -70,14 +70,14 @@ public class Dependency implements Comparable<Dependency>
         return status;
     }
 
-    public String getLocalPath()
+    public String getPomPath()
     {
-        return localPath;
+        return pomPath;
     }
 
-    public void setLocalPath(String localPath)
+    public void setPomPath(String pomPath)
     {
-        this.localPath = localPath;
+        this.pomPath = pomPath;
     }
 
     @Override
diff --git a/src/main/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScanner.java b/src/main/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScanner.java
index 31b6af8..f52b63c 100644
--- a/src/main/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScanner.java
+++ b/src/main/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScanner.java
@@ -21,6 +21,7 @@ import org.apache.commons.cli.CommandLine;
 import org.apache.commons.cli.CommandLineParser;
 import org.apache.commons.cli.DefaultParser;
 import org.apache.commons.cli.Options;
+import org.apache.commons.lang3.ArrayUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.maven.model.License;
 import org.apache.maven.shared.invoker.DefaultInvocationRequest;
@@ -42,7 +43,6 @@ public class MavenDependencyScanner implements Scanner
 {
     private static final Logger LOGGER = LoggerFactory.getLogger(MavenDependencyScanner.class);
     private static final String MAVEN_REPO_LOCAL = "maven.repo.local";
-    private static final Pattern DEPENDENCY_PATTERN = Pattern.compile("\\s*([^:]*):([^:]*):[^:]*:([^:]*):[^:]*:(.*)");
 
     private final MavenLicenseService mavenLicenseService;
     private final MavenDependencyService mavenDependencyService;
@@ -170,23 +170,62 @@ public class MavenDependencyScanner implements Scanner
         }
     }
 
-    private static Dependency findDependency(String line)
+    static Dependency findDependency(String line)
+    {
+        String[] items = getItems(line);
+        if (items == null)
+            return null;
+
+        String groupId = items[0];
+        String artifactId = items[1];
+        String version = items[3];
+        String path = items[5];
+
+        String classifier = null;
+        if (items.length > 6)
+        {
+            classifier = items[3];
+            version = items[4];
+            path = items[6];
+        }
+
+        if (classifier != null)
+        {
+            path = path.replace("-" + classifier, "");
+        }
+        int lastDotIndex = path.lastIndexOf('.');
+        if (lastDotIndex > 0)
+        {
+            path = path.substring(0, lastDotIndex) + ".pom";
+        }
+
+        Dependency dependency = new Dependency(groupId + ":" + artifactId, version, null);
+        if (new File(path).exists())
+        {
+            dependency.setPomPath(path);
+        }
+        return dependency;
+    }
+
+    private static String[] getItems(String line)
     {
         // Remove module info introduced with Maven Dependency Plugin 3.0 (and JDK > 9)
         line = line.replaceFirst(" -- module .*", "");
 
-        Matcher matcher = DEPENDENCY_PATTERN.matcher(line);
-        if (matcher.find())
+        String[] items = line.trim().split(":");
+        if (items.length < 4)
         {
-            String groupId = matcher.group(1);
-            String artifactId = matcher.group(2);
-            String version = matcher.group(3);
-            String path = matcher.group(4);
-            Dependency dependency = new Dependency(groupId + ":" + artifactId, version, null);
-            dependency.setLocalPath(path);
-            return dependency;
+            return null;
         }
-        return null;
+
+        // Windows-specific absolute path "C:\my\path"
+        if (items[items.length - 2].length() == 1)
+        {
+            items[items.length - 2] += ":" + items[items.length - 1];
+            items = ArrayUtils.remove(items, items.length - 1);
+        }
+
+        return items;
     }
 
     private Function<Dependency, Dependency> loadLicenseFromPom(Map<Pattern, String> licenseMap, String userSettings,
@@ -195,7 +234,7 @@ public class MavenDependencyScanner implements Scanner
         return (Dependency dependency) ->
         {
             if (StringUtils.isNotBlank(dependency.getLicense())
-                || dependency.getLocalPath() == null)
+                || dependency.getPomPath() == null)
             {
                 return dependency;
             }
@@ -207,11 +246,9 @@ public class MavenDependencyScanner implements Scanner
     private static Dependency loadLicense(Map<Pattern, String> licenseMap, String userSettings, String globalSettings,
         Dependency dependency)
     {
-        String path = dependency.getLocalPath();
-        int lastDotIndex = path.lastIndexOf('.');
-        if (lastDotIndex > 0)
+        String pomPath = dependency.getPomPath();
+        if (pomPath != null)
         {
-            String pomPath = path.substring(0, lastDotIndex) + ".pom";
             List<License> licenses = LicenseFinder.getLicenses(new File(pomPath), userSettings, globalSettings);
             if (licenses.isEmpty())
             {


Test patch:
diff --git a/src/test/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScannerTest.java b/src/test/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScannerTest.java
index 265b93d..f54f034 100644
--- a/src/test/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScannerTest.java
+++ b/src/test/java/at/porscheinformatik/sonarqube/licensecheck/maven/MavenDependencyScannerTest.java
@@ -1,6 +1,7 @@
 package at.porscheinformatik.sonarqube.licensecheck.maven;
 
 import static java.util.Collections.singletonList;
+import static org.hamcrest.CoreMatchers.endsWith;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertThat;
 import static org.mockito.Mockito.when;
@@ -96,4 +97,28 @@ public class MavenDependencyScannerTest
 
         assertThat(commonsLang.getLicense(), is("TEST"));
     }
+
+    @Test
+    public void testFindDependency()
+    {
+        String jarFilePath = new File("src/test/resources/test.jar").getAbsolutePath();
+        Dependency dependency = MavenDependencyScanner.findDependency(
+            "at.porscheinformatik.test:test:jar:1.2.3:compile:" + jarFilePath + " -- module test (auto)");
+
+        assertThat(dependency.getName(), is("at.porscheinformatik.test:test"));
+        assertThat(dependency.getVersion(), is("1.2.3"));
+        assertThat(dependency.getPomPath(), endsWith("test.pom"));
+    }
+
+    @Test
+    public void testFindDependencyWithClassifier()
+    {
+        String jarFilePath = new File("src/test/resources/test-sources.jar").getAbsolutePath();
+        Dependency dependency = MavenDependencyScanner.findDependency(
+            "at.porscheinformatik.test:test:jar:sources:2.2:compile:" + jarFilePath + " -- module test (auto)");
+
+        assertThat(dependency.getName(), is("at.porscheinformatik.test:test"));
+        assertThat(dependency.getVersion(), is("2.2"));
+        assertThat(dependency.getPomPath(), endsWith("test.pom"));
+    }
 }
diff --git a/src/test/resources/test.pom b/src/test/resources/test.pom
new file mode 100644
index 0000000..7f7204c
--- /dev/null
+++ b/src/test/resources/test.pom
@@ -0,0 +1,1 @@
+EMPTY