From a12a9b6435c517a8bdae47893b346ef0d543cd6f Mon Sep 17 00:00:00 2001
From: tim_graves <28924492+atimgraves@users.noreply.github.com>
Date: Fri, 17 May 2024 11:01:02 +0100
Subject: [PATCH 1/2] removed some of the eclipse prefs and updated lombok
---
.gitignore | 6 +++++-
functions-hmac/.classpath | 17 +++++++++++++++++
.../.settings/org.eclipse.jdt.core.prefs | 1 +
functions-hmac/pom.xml | 2 +-
functions-hmac/tester-hello-java/func.yaml | 4 ++--
5 files changed, 26 insertions(+), 4 deletions(-)
diff --git a/.gitignore b/.gitignore
index 4e16e08..4ebbc60 100644
--- a/.gitignore
+++ b/.gitignore
@@ -30,4 +30,8 @@ Temporary Items
.key
.crt
.csr
-.pem
\ No newline at end of file
+.pem
+functions-hmac/.settings/org.eclipse.jdt.core.prefs
+functions-hmac/.settings/org.eclipse.jdt.apt.core.prefs
+functions-hmac/.factorypath
+functions-hmac/.classpath
diff --git a/functions-hmac/.classpath b/functions-hmac/.classpath
index 7a9a105..df66b20 100644
--- a/functions-hmac/.classpath
+++ b/functions-hmac/.classpath
@@ -36,5 +36,22 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/functions-hmac/.settings/org.eclipse.jdt.core.prefs b/functions-hmac/.settings/org.eclipse.jdt.core.prefs
index cf2cd45..87f474b 100644
--- a/functions-hmac/.settings/org.eclipse.jdt.core.prefs
+++ b/functions-hmac/.settings/org.eclipse.jdt.core.prefs
@@ -4,5 +4,6 @@ org.eclipse.jdt.core.compiler.compliance=17
org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.processAnnotations=enabled
org.eclipse.jdt.core.compiler.release=disabled
org.eclipse.jdt.core.compiler.source=17
diff --git a/functions-hmac/pom.xml b/functions-hmac/pom.xml
index 60a0129..99682b9 100644
--- a/functions-hmac/pom.xml
+++ b/functions-hmac/pom.xml
@@ -46,7 +46,7 @@ SOFTWARE. -->
UTF-8
1.5.0
1.0.177
- 1.18.28
+ 1.18.30
3.17.0
1.7.33
1.15
diff --git a/functions-hmac/tester-hello-java/func.yaml b/functions-hmac/tester-hello-java/func.yaml
index 221c94b..aa8def9 100644
--- a/functions-hmac/tester-hello-java/func.yaml
+++ b/functions-hmac/tester-hello-java/func.yaml
@@ -1,7 +1,7 @@
schema_version: 20180708
name: hello-java
-version: 0.0.5
+version: 0.0.7
runtime: java
build_image: fnproject/fn-java-fdk-build:jdk17-1.0.177
run_image: fnproject/fn-java-fdk:jre17-1.0.177
-cmd: com.example.fn.HelloFunction::handleAPIGWAuthenticationRequest
+cmd: com.example.fn.HelloFunction::handleRequest
From 6ce27d19a45976a54301acaf7cfcec8f30f8270b Mon Sep 17 00:00:00 2001
From: tim_graves <28924492+atimgraves@users.noreply.github.com>
Date: Mon, 20 May 2024 15:01:55 +0100
Subject: [PATCH 2/2] Initial put back of example code
---
dependencyanalyser/.gitignore | 4 +
dependencyanalyser/.settings/.gitignore | 3 +
dependencyanalyser/README.md | 128 ++
dependencyanalyser/pom.xml | 88 +
.../demo/dependencyanalyser/Dependency.java | 61 +
.../DependencyLoadTester.java | 102 +
.../DependencyProcessorException.java | 63 +
.../dependencyanalyser/DependencyScanner.java | 117 ++
.../dependencyanalyser/IdentifiedJarFile.java | 108 +
.../IdentifiedJarVersion.java | 182 ++
.../timg/demo/dependencyanalyser/JarTree.java | 165 ++
.../dependencyanalyser/JarTreeCombiner.java | 186 ++
.../demo/dependencyanalyser/OptionsData.java | 67 +
.../demo/dependencyanalyser/ScopeType.java | 49 +
.../importers/GetSourceLoader.java | 79 +
.../importers/JarFIleProcessorException.java | 65 +
.../importers/JarFileLoader.java | 186 ++
.../importers/MavenGraphLoader.java | 295 +++
.../MavenGraphProcessorException.java | 65 +
.../importers/MavenPomDetailsBuilder.java | 56 +
.../MavenPomPropertiesExtractor.java | 92 +
.../MavenPomPropertiesProcessorException.java | 65 +
.../importers/MavenPomXMLExtractor.java | 181 ++
.../importers/MavenPomXMLLoader.java | 239 +++
.../MavenPomXMLProcessorException.java | 65 +
.../importers/MavenProcessorException.java | 65 +
.../importers/SourceLoader.java | 66 +
.../importers/XMLLoader.java | 161 ++
.../importers/XMLProcessorException.java | 65 +
.../testdata/filereader.mvn-graphml.xml | 1857 +++++++++++++++++
.../testdata/filewriter.mvn-graphml.xml | 1842 ++++++++++++++++
dependencyanalyser/testdata/pom.xml | 87 +
32 files changed, 6854 insertions(+)
create mode 100644 dependencyanalyser/.gitignore
create mode 100644 dependencyanalyser/.settings/.gitignore
create mode 100644 dependencyanalyser/README.md
create mode 100644 dependencyanalyser/pom.xml
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/Dependency.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyLoadTester.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyProcessorException.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyScanner.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarFile.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarVersion.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTree.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTreeCombiner.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/OptionsData.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/ScopeType.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/GetSourceLoader.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFIleProcessorException.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFileLoader.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenGraphLoader.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenGraphProcessorException.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenPomDetailsBuilder.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenPomPropertiesExtractor.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenPomPropertiesProcessorException.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenPomXMLExtractor.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenPomXMLLoader.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenPomXMLProcessorException.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenProcessorException.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/SourceLoader.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/XMLLoader.java
create mode 100644 dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/XMLProcessorException.java
create mode 100644 dependencyanalyser/testdata/filereader.mvn-graphml.xml
create mode 100644 dependencyanalyser/testdata/filewriter.mvn-graphml.xml
create mode 100644 dependencyanalyser/testdata/pom.xml
diff --git a/dependencyanalyser/.gitignore b/dependencyanalyser/.gitignore
new file mode 100644
index 0000000..029cbfe
--- /dev/null
+++ b/dependencyanalyser/.gitignore
@@ -0,0 +1,4 @@
+/target/
+/.classpath
+/.factorypath
+/.project
diff --git a/dependencyanalyser/.settings/.gitignore b/dependencyanalyser/.settings/.gitignore
new file mode 100644
index 0000000..d726907
--- /dev/null
+++ b/dependencyanalyser/.settings/.gitignore
@@ -0,0 +1,3 @@
+/org.eclipse.jdt.apt.core.prefs
+/org.eclipse.jdt.core.prefs
+/org.eclipse.m2e.core.prefs
diff --git a/dependencyanalyser/README.md b/dependencyanalyser/README.md
new file mode 100644
index 0000000..2569a5f
--- /dev/null
+++ b/dependencyanalyser/README.md
@@ -0,0 +1,128 @@
+# Dependency Scanner
+
+This program will scan the dependency sources it is given and build a combined dependency tree combining the separate dependency trees for the inputs. This allows the detection of conflicting dependencies. While maven (and other build tools) can of course determine conflicting dependencies in the jar files they manage (and copy into the resulting targets) this only applies at compile time, not run time, where a jar file is provided by the end user (or the end user replaces a jar file in the inputs). The goal of this program is to enable the provision of a set of the top level input jar files and the dependency trees for each will be checked for conflicting versions. For example a developer may build an application against what will ultimately be a user supplied library (the maven `provided` scope). At the compile stage the application will be compiled against the version in that build, however a user may subsequently use a different version of that library (and the jar files associated with it) If the original compiled version had a different version of the library which was replaced (or the provided version was replaced by the developer mandated version) then conflicts may occur.
+
+## Usage
+The class `com.oracle.timg.demo.dependencyanalyser.DependencyScanner` is the main class. is supports the following arguments:
+
+ `-d`/`--directory` followed by working directory location - required when doing something that generates an intermediate file, for example extracting a pom.xml or generating a graph-xml file. In practice (with the current loaders) this basically means in all situation. Defaults to the current directory and can be absolute or relative, it must exist and of course you must be able to read and write it.
+
+ `-g`/`--groupid` followed by groupid - Optional and used for setting the groupid at the root of the combined dependency tree, defaults to `my.company` if not set. Recommended if listing jar files or similar so you can determine what the actual tree root will be in the output
+
+ `-a`/`--artifactid` followed by artifactid - Optional and used for setting the artifact at the root of the combined dependency tree, defaults to `myartifact` if not set. Recommended if listing jar files or similar so you can determine what the actual tree root will be in the output
+
+ `-v`/`--version` followed by version string - Optional and used for setting the version at the root of the combined dependency tree, defaults to `0.0.0` if not set. Recommended if listing jar files or similar so you can determine what the actual tree root will be in the output
+
+ `-m`/`--maven-path` followed by path - Required for all sources that are maven based (so pom.xmnl files of jar files with a ponm.xml contents. Specified the location of the mvn executabler. Note that this **MUST** be the full absolute path, there is no default as this is system dependent.
+
+ `-r`/`--resolve-dependencies` - If set will call any pre-resolving task needed before generating dependency data, used for example to ensure that the local mavan repo has ll of the dependencies downloaded. Defaults to false.
+
+ `-i`/`--retain-intermediates` - If set will retain the intermediate files (e.g. extracted pom.xml) used for the processing stages, this can be useful for debugging purposes. Defaults to false.
+
+ `-V`/`--Verbose` - outputs info re the sub processes that are run (e.g. command lines being used, output from the sub processes)
+
+
+ The remaining arguments are treated as input sources. Currently the following are supported.
+
+ Files with the suffix `.mvn-graphml.xml` These are assumed to contain a GraphML "dump" of the dependencies in the format that Maven outputs. The file will be directly loaded and to locate the root of the dependency tree all loaded jars are scanned to find a jar version which does not depend on any other source. This resulting tree will be added to the combined dependencies tree. The root of this source will be created as a sub node under the combined root tree and will have it's scope set to 'ROOT',
+
+ Files with the name `pom.xml` - These files will be passed to maven to create a maven dependency graqph file (with the suffix `.mvn-graphml.xml`) which will then be loaded and added to the combined dependencies tree using the process above if the `-r` flag is set then maven will be asked to do a dependency resolve stage before processing. The .mvn-graplml.xml file will be generated using a temporary name based on thye grupid, artifactid and version located in the ponm.xml file and will be written to the location specified by the `-d` flag, if the `-i` flag is set this temporary file will be retained, otherwise it will be deleted when the jvm exits. If the `-V` flag is set the the command(s) used to run maven and any maven output will be displayed.
+
+ Files with the suffix `.jar` are examined to see if they contain a `pom.xml` file and optionally a `pom.properties` file. These are expected to be under the `META-INF/maven//` "directory" in the jar file (If Maven is packaging the jar file it will copy the files there automatically, Gradle seem to also generate at least a `pom.xml` file which is places there as well). If present the `pom.properties` file will be used to get the groupid, artifactid and version, if `pom.properties` is not present these will be extracted from the `pom.xml` entri. The `META-INF/maven///pom.xml` entry in the jar file will then be extracted and copied into a temporaty file and then the process above is done as with a "normal" pom.xml file.
+
+## Outputs
+
+ The DependencyScanner class is provided as an example, it loads each of the source arguments in turn and then generates the output. There are a number of utility medhods in the JarTree class that can be used to locate jar file versions based on different criteria and also to dump the dependeny tree.
+
+ Count of the number of Jar files where there are two or move versions in the combined dependency tree
+
+ Information on each oif the jar files with multiple versions including the jar file versions that depend in this version, any jar file versions that they depend on and also details of the original source jar file version to help identify wherte conflicting versions originate from (this maps to the input sources).
+
+ It will also list the number of jar file versions that have no dependencies (i.e. "leaf" jar file versions) and also the bymber of jar file versions. Depending on the other flags and arguments other output may of course be provided.
+
+ Below is the core output from test code. This is deliberately using different versions of Lombok, please note that the number of jar file versions with nothign depending should always be one (this being the "root / project" dependency.
+
+ ```text
+ May 20, 2024 2:42:23 PM com.oracle.timg.demo.dependencyanalyser.DependencyScanner main
+INFO: Count of combined Jar files with two or more versions
+3
+May 20, 2024 2:42:23 PM com.oracle.timg.demo.dependencyanalyser.DependencyScanner main
+INFO: Details of jar files with multiple versions
+org.projectlombok:lombok
+ 1.18.30 refs = 1
+ Depends on
+ Depended on by
+ com.oracle.labs.helidon.fileio:filewriter:1.0.0 (PROVIDED)
+ In source
+ com.oracle.labs.helidon.fileio:filewriter:1.0.0 from origional source testdata/filewriter.mvn-graphml.xml
+
+ 1.18.32 refs = 2
+ Depends on
+ Depended on by
+ com.oracle.timg.demo:dependencyanalyser:0.0.1-SNAPSHOT (PROVIDED)
+ com.oracle.labs.helidon.fileio:filereader:1.0.0 (PROVIDED)
+ In source
+ com.oracle.timg.demo:dependencyanalyser:0.0.1-SNAPSHOT from origional source testdata/pom.xml
+ com.oracle.labs.helidon.fileio:filereader:1.0.0 from origional source testdata/filereader.mvn-graphml.xml
+
+org.apiguardian:apiguardian-api
+ 1.0.0 refs = 1
+ Depends on
+ Depended on by
+ com.oracle.labs.helidon.fileio:filereader:1.0.0 (COMPILE)
+ In source
+ com.oracle.labs.helidon.fileio:filereader:1.0.0 from origional source testdata/filereader.mvn-graphml.xml
+
+ 1.1.2 refs = 1
+ Depends on
+ Depended on by
+ org.junit.jupiter:junit-jupiter-api:5.9.3 (TEST)
+ In source
+ com.oracle.labs.helidon.fileio:filewriter:1.0.0 from origional source testdata/filewriter.mvn-graphml.xml
+
+jakarta.activation:jakarta.activation-api
+ 1.2.2 refs = 1
+ Depends on
+ Depended on by
+ jakarta.xml.bind:jakarta.xml.bind-api:2.3.3 (COMPILE)
+ In source
+ com.oracle.timg.demo:dependencyanalyser:0.0.1-SNAPSHOT from origional source testdata/pom.xml
+
+ 2.1.1 refs = 2
+ Depends on
+ Depended on by
+ com.oracle.labs.helidon.fileio:filewriter:1.0.0 (COMPILE)
+ com.oracle.labs.helidon.fileio:filereader:1.0.0 (COMPILE)
+ In source
+ com.oracle.labs.helidon.fileio:filewriter:1.0.0 from origional source testdata/filewriter.mvn-graphml.xml
+
+
+May 20, 2024 2:42:23 PM com.oracle.timg.demo.dependencyanalyser.DependencyScanner main
+INFO: Combined Jar versions with no dependencies 87
+May 20, 2024 2:42:23 PM com.oracle.timg.demo.dependencyanalyser.DependencyScanner main
+INFO: Combined Jar versions with no depended on 1
+```
+
+
+
+## Known limitations
+
+This program uses Mavan to build the per project tree, the program then loads the maven dependency output and combines it with all other supplied outputs. Of course this means that the mvn command needs to be available. it also means that it is subject to mavens restrictions and limitations. Known factors that may cause a problem are :
+
+1. You need to have resolved all the dependencies in any pom.xml (or jar file containing it) to do that the program has the option of running a maven resolve stage (set the `-r` flag), this can take a while and you will need a network connection and enough space on the machine you are using to download the dependencies.
+
+2. Maven supports the operation of relative parent pom.xml, for some projects where the jar file (or pom.xml) is not in the local maven repository this may be a problem as the parent pom may not be in the right place in the directory tree, in some situations where there happens to be a pom.xml (not not the expected one) in the location specified by the relativePath this will result in maven loading the incorrect parent pom.
+
+3. Of course if mvn output changes (or the mvn command and flags change) then this will be a problem.
+
+## Extending the code
+
+Is is architecturally possible to add additional sources of dependency information. The new loader needs to implement the SourceLoader interface, the GetSourceLoader class needs to be updated to recognize (by whatever means you like) the new source type and return an instance of the appropriate loader.
+
+The loadDependencied method needs to return a new Jar Tree which will then be combined with all of the others that have been built. The new Jar Tree has the following criteria.
+
+The getRoot method must return an IdenfitiedJarFileVersion which is the root of the new dependency structure, this must not have anything depending on it.
+
+This must be a tree, no loops are allowed (this is really a limitation of the output mechanisms)
+
+Every IdenfitiedJarFileVersion in the tree must contain the tree being built in the sourceProjecxtrs set (this will be combined with the other sources later and used in the output to trace the source of multiple dependencies
diff --git a/dependencyanalyser/pom.xml b/dependencyanalyser/pom.xml
new file mode 100644
index 0000000..47def5e
--- /dev/null
+++ b/dependencyanalyser/pom.xml
@@ -0,0 +1,88 @@
+
+
+
+ 4.0.0
+ com.oracle.timg.demo
+ dependencyanalyser
+ 0.0.1-SNAPSHOT
+ dependencyanalyser
+ analysies mvn output file looking for conflicting dependencies
+
+ 1.18.32
+ 2.37
+
+
+
+
+
+
+
+
+
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+ 2.3.3
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ runtime
+ 2.3.3
+
+
+
+ org.projectlombok
+ lombok
+ ${version.lombok}
+ provided
+
+
+ com.kazurayam
+ subprocessj
+ 0.3.7
+
+
+ args4j
+ args4j
+ ${version.args4j}
+
+
+
\ No newline at end of file
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/Dependency.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/Dependency.java
new file mode 100644
index 0000000..a3f02f2
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/Dependency.java
@@ -0,0 +1,61 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+@Data
+@EqualsAndHashCode
+
+public class Dependency implements Comparable {
+ @EqualsAndHashCode.Exclude
+ private final IdentifiedJarVersion source;
+ @EqualsAndHashCode.Include
+ private final IdentifiedJarVersion target;
+ @EqualsAndHashCode.Include
+ private final ScopeType scope;
+
+ @Override
+ public int compareTo(Dependency dependency) {
+ return (target.toString() + scope).compareTo(dependency.target.toString() + dependency.scope);
+ }
+
+ public Dependency dupeCore(IdentifiedJarVersion newSource, IdentifiedJarVersion newTarget) {
+ return new Dependency(newSource, newTarget, this.scope);
+ }
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyLoadTester.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyLoadTester.java
new file mode 100644
index 0000000..fdf6694
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyLoadTester.java
@@ -0,0 +1,102 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import java.io.File;
+import java.util.stream.Collectors;
+
+import com.oracle.timg.demo.dependencyanalyser.importers.MavenGraphLoader;
+
+import lombok.extern.java.Log;
+
+@Log
+public class DependencyLoadTester {
+
+ public final static void main(String args[]) throws Exception {
+// JarTree jarTreeReader = new JarTree("com.oracle.labs.helidon.fileio", "filereader", "1.0.0", "jar",
+// ScopeType.ROOT);
+ MavenGraphLoader loader = new MavenGraphLoader(new OptionsData());
+ JarTree jarTreeReader = loader.loadDependencyTree(new File(args[0]));
+// log.info("JarFiles list is :\n" + jarTreeReader.listJarFiles());
+// log.info("JarFiles details list is :\n" + jarTreeReader.listJarFileDetails());
+ log.info("Jar files with no versions " + jarTreeReader.getJarFilesWithNoVersions().size());
+ log.info("Jar files with two or more versions "
+ + jarTreeReader.getJarFilesWithMoreThanSpecifiedVersions(1).size());
+ log.info("Jar versions with no dependencies " + jarTreeReader.getJarVersionsWithNoDependencies().size());
+ log.info("Jar versions with no depended on " + jarTreeReader.getJarVersionsWithNoDependOn().size());
+ log.info("Root jar version details \n" + jarTreeReader.getRoot().getParent().toVersionDetails(""));
+ JarTreeCombiner combiner = new JarTreeCombiner("com.oracle.timg", "filehandling", "1.0.0");
+// log.warning(
+// "Combiner root pre combine is\n" + combiner.getProjectTop().getRoot().getParent().toVersionDetails(""));
+// log.warning("combined jar versions pre combine " + combiner.getProjectJarVersions().keySet());
+// // bring in the tree we just loaded
+ combiner.addJarTree(jarTreeReader);
+// log.warning("Combiner root post combine is\n"
+// + combiner.getProjectTop().getRoot().getParent().toVersionDetails(""));
+// log.warning("combined jar versions post combine " + combiner.getProjectJarVersions().keySet());
+// // get the first dependency in ther first version, then dump the target
+ JarTree combinedTree = combiner.getProjectTop();
+// IdentifiedJarVersion firstTarget = new ArrayList<>(combinedTree.getRoot().getDependsOn()).get(0).getTarget();
+// log.info("combined first dependency (should be file reader)\n" + firstTarget.getParent().toVersionDetails(""));
+//// log.info("Combined JarFiles list is :\n" + combinedTree.listJarFiles());
+//// log.info("Combined JarFiles details list is :\n" + combinedTree.listJarFileDetails());
+// log.info("Combined Jar files with no versions " + combinedTree.getJarFilesWithNoVersions().size());
+// log.info("Combined Jar files with two or more versions "
+// + combinedTree.getJarFilesWithMoreThanSpecifiedVersions(1).size());
+// log.info(
+// "Combined Jar versions with no dependencies " + combinedTree.getJarVersionsWithNoDependencies().size());
+// log.info("Combined Jar versions with no depended on " + combinedTree.getJarVersionsWithNoDependOn().size());
+//// log.info("Combined Root jar version details \n" + combinedTree.getRoot().getParent().toVersionDetails(""));
+// log.info("Scanning second tree");
+//
+ JarTree jarTreeWriter = loader.loadDependencyTree(new File(args[1]));
+
+// log.warning("doing second combine");
+ combiner.addJarTree(jarTreeWriter);
+////
+ log.warning("Combiner root post second combine is\n"
+ + combiner.getProjectTop().getRoot().getParent().toVersionDetails(""));
+ log.warning("combined jar versions post second combine " + combiner.getProjectJarVersions().keySet());
+ log.info("Combined final jar tree is :\n" + combinedTree.dumpTree(""));
+ log.info("Combined final keys \n" + combinedTree.keySet());
+ log.info("Project root final jar version dependencies " + combinedTree.getRoot().getDependsOn());
+ log.info("Combined Jar files with two or more versions "
+ + combinedTree.getJarFilesWithMoreThanSpecifiedVersions(1).stream()
+ .map(jarversion -> jarversion.toVersionDetails("", true)).collect(Collectors.joining("\n")));
+ }
+
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyProcessorException.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyProcessorException.java
new file mode 100644
index 0000000..dcaad3a
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyProcessorException.java
@@ -0,0 +1,63 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+public class DependencyProcessorException extends Exception {
+
+ private static final long serialVersionUID = 529077741205885816L;
+
+ public DependencyProcessorException() {
+ super();
+ }
+
+ public DependencyProcessorException(String arg0) {
+ super(arg0);
+ }
+
+ public DependencyProcessorException(Throwable arg0) {
+ super(arg0);
+ }
+
+ public DependencyProcessorException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+ public DependencyProcessorException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
+ super(arg0, arg1, arg2, arg3);
+ }
+
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyScanner.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyScanner.java
new file mode 100644
index 0000000..669ca35
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/DependencyScanner.java
@@ -0,0 +1,117 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import java.io.File;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.kohsuke.args4j.CmdLineException;
+import org.kohsuke.args4j.CmdLineParser;
+import org.kohsuke.args4j.spi.Messages;
+
+import com.oracle.timg.demo.dependencyanalyser.importers.GetSourceLoader;
+import com.oracle.timg.demo.dependencyanalyser.importers.SourceLoader;
+
+import lombok.extern.java.Log;
+
+@Log
+public class DependencyScanner {
+
+ public final static void main(String args[]) throws Exception {
+ // process the args
+ OptionsData options = new OptionsData();
+ CmdLineParser parser = new CmdLineParser(options);
+ try {
+ // parse the arguments.
+ parser.parseArgument(args);
+ if (options.sources.isEmpty()) {
+ throw new CmdLineException(parser, Messages.DEFAULT_META_REST_OF_ARGUMENTS_HANDLER,
+ "No sources provided");
+ }
+ } catch (CmdLineException e) {
+ // if there's a problem in the command line,
+ // you'll get this exception. this will report
+ // an error message.
+ System.err.println(e.getMessage());
+ // print the list of available options
+ parser.printUsage(System.err);
+ System.err.println();
+ return;
+ }
+ log.fine("Processed options are :\n" + options);
+ // place to put the results
+ JarTreeCombiner combiner = new JarTreeCombiner(options.getGroupid(), options.getArtifactid(),
+ options.getVersion());
+ // let's process the args
+ options.getSources().stream().forEach(source -> processSource(options, source, combiner));
+
+ log.fine("Combiner root post combine is\n"
+ + combiner.getProjectTop().getRoot().getParent().toVersionDetails(""));
+ JarTree combinedTree = combiner.getProjectTop();
+ Set multiVersionJarFiles = combinedTree.getJarFilesWithMoreThanSpecifiedVersions(1);
+ log.info("Count of combined Jar files with two or more versions\n" + multiVersionJarFiles.size());
+ log.info("Details of jar files with multiple versions\n" + multiVersionJarFiles.stream()
+ .map(jarFile -> jarFile.toVersionDetails("", true)).collect(Collectors.joining("\n", "", "\n")));
+ log.info(
+ "Combined Jar versions with no dependencies " + combinedTree.getJarVersionsWithNoDependencies().size());
+ log.info("Combined Jar versions with no depended on " + combinedTree.getJarVersionsWithNoDependOn().size());
+ }
+
+ private static void processSource(OptionsData options, File source, JarTreeCombiner combiner) {
+ log.info("Loading source " + source.getPath());
+ SourceLoader loader;
+ try {
+ loader = GetSourceLoader.getSourceLoader(options, source);
+ } catch (DependencyProcessorException e) {
+ log.warning(
+ "SourceLoader cannot process source " + source.getPath() + " due to " + e.getLocalizedMessage());
+ return;
+ }
+ JarTree loadedJarTree;
+ try {
+ loadedJarTree = loader.loadDependencyTree(source);
+ } catch (DependencyProcessorException e) {
+ log.warning("SourceLoader cannot load source " + source.getPath() + " due to " + e.getLocalizedMessage());
+ return;
+ }
+ log.info("Combining source " + source.getPath() + " with " + combiner.getProjectJarVersions().size()
+ + " jar versions already loaded");
+ // now add it to the tree wew're building up
+ combiner.addJarTree(loadedJarTree);
+ }
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarFile.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarFile.java
new file mode 100644
index 0000000..95228b0
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarFile.java
@@ -0,0 +1,108 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+import lombok.RequiredArgsConstructor;
+
+@Data
+@RequiredArgsConstructor
+@EqualsAndHashCode(callSuper = false)
+public class IdentifiedJarFile extends TreeMap implements Comparable {
+ private static final long serialVersionUID = 7088951357215826846L;
+ @EqualsAndHashCode.Include
+ @NonNull
+ private final String groupId;
+ @EqualsAndHashCode.Include
+ @NonNull
+ private final String artifactId;
+ @EqualsAndHashCode.Exclude
+ private boolean fromSource = true;
+ @EqualsAndHashCode.Exclude
+ private int refCount = 0;
+
+ public IdentifiedJarFile duplicateCore() {
+ IdentifiedJarFile newJarFile = new IdentifiedJarFile(this.groupId, this.artifactId);
+ newJarFile.setFromSource(false);
+ return newJarFile;
+ }
+
+ public int incrRefCount() {
+ refCount++;
+ return refCount;
+ }
+
+ public int decrCount() {
+ refCount--;
+ return refCount;
+ }
+
+ @Override
+ public String toString() {
+ return processString(groupId, artifactId);
+ }
+
+ public static String processString(String groupId, String artifactId) {
+ return groupId + ":" + artifactId;
+ }
+
+ public String toVersionList(String indentString) {
+ return indentString + toString() + "\n" + this.values().stream()
+ .map(version -> indentString + " " + version.getVersion()).collect(Collectors.joining("\n"));
+ }
+
+ public String toVersionDetails(String indentString) {
+ return toVersionDetails(indentString, false);
+ }
+
+ public String toVersionDetails(String indentString, boolean includeSources) {
+ return indentString + toString() + "\n"
+ + this.values().stream().map(version -> version.toFullString(indentString + " ", includeSources))
+ .collect(Collectors.joining("\n"));
+ }
+
+ @Override
+ public int compareTo(IdentifiedJarFile other) {
+ return this.toString().compareTo(other.toString());
+ }
+
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarVersion.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarVersion.java
new file mode 100644
index 0000000..e105d4e
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/IdentifiedJarVersion.java
@@ -0,0 +1,182 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.TreeSet;
+import java.util.stream.Collectors;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NonNull;
+
+@Data
+public class IdentifiedJarVersion implements Comparable {
+ @EqualsAndHashCode.Include
+ @NonNull
+ private final String version;
+ @EqualsAndHashCode.Exclude
+ @NonNull
+ private final IdentifiedJarFile parent;
+ @EqualsAndHashCode.Exclude
+ @NonNull
+ private final String type;
+ @EqualsAndHashCode.Exclude
+ @NonNull
+ private final ScopeType scope;
+ // what depends on us - assumes that a dependency of say
+ // com.fred.test.program:1.2.1 is always the same actual target of a dependency
+ @EqualsAndHashCode.Exclude
+ private final Set dependsOn = new TreeSet<>();
+ // the things that depend on us (for reporting on conflict trees)
+ @EqualsAndHashCode.Exclude
+ private final LinkedList dependsOnThis = new LinkedList<>();
+ // used to track the source projects this jar version came from
+ @EqualsAndHashCode.Exclude
+ private final Set sourceProjects = new TreeSet<>();
+ @EqualsAndHashCode.Exclude
+ private int refCount = 0;
+ @EqualsAndHashCode.Exclude
+ private boolean fromSource = true;
+
+ public IdentifiedJarVersion() {
+ this.version = "";
+ this.parent = null;
+ this.type = "";
+ this.scope = ScopeType.ERROR;
+
+ }
+
+ public IdentifiedJarVersion(@NonNull String version, @NonNull IdentifiedJarFile parent, @NonNull String type,
+ @NonNull ScopeType scope) {
+ this(version, parent, type, scope, null);
+ }
+
+ public IdentifiedJarVersion(String version, IdentifiedJarFile parent, String type, ScopeType scope,
+ JarTree sourceProject) {
+ this.version = version;
+ this.parent = parent;
+ this.type = type;
+ this.scope = scope;
+ if (sourceProject != null) {
+ this.sourceProjects.add(sourceProject);
+ }
+ }
+
+ public IdentifiedJarVersion duplicateCore(@NonNull IdentifiedJarFile newParent) {
+ IdentifiedJarVersion newJarVersion = new IdentifiedJarVersion(version, newParent, type, scope);
+ newJarVersion.addSourceProjects(sourceProjects);
+ // duplicates are by definition not from the core
+ newJarVersion.setFromSource(false);
+ return newJarVersion;
+ }
+
+ public boolean equals(@NonNull IdentifiedJarVersion other) {
+ return version.equals(other.version);
+ }
+
+ public int hashCode() {
+ return version.hashCode();
+ }
+
+ public int incrRefCount() {
+ refCount++;
+ return refCount;
+ }
+
+ public int decrCount() {
+ refCount--;
+ return refCount;
+ }
+
+ public void addSourceProjects(@NonNull Collection sourceProjectToAdd) {
+ this.sourceProjects.addAll(sourceProjectToAdd);
+ }
+
+ @Override
+ public String toString() {
+ return processString(parent.getGroupId(), parent.getArtifactId(), version);
+ }
+
+ public String toFullerString(String indentString) {
+ return indentString + processString(parent.getGroupId(), parent.getArtifactId(), version) + "Has "
+ + dependsOn.size() + " Dependencies and " + dependsOnThis.size() + " that depend on it";
+ }
+
+ public static String processString(String groupId, String artifactId, String version) {
+ return groupId + ":" + artifactId + ":" + version;
+ }
+
+ public String toFullString(String indentString) {
+ return toFullString(indentString, false);
+ }
+
+ public String toFullString(String indentString, boolean includeSources) {
+ String vsn = indentString + version + " refs = " + getRefCount() + "\n";
+ String dependsOnString = indentString + " " + "Depends on\n";
+ if (dependsOn.size() > 0) {
+ dependsOnString += dependsOn.stream()
+ .map(dependency -> dependency.getTarget().toString() + " (" + dependency.getScope() + ")")
+ .collect(Collectors.joining("\n" + indentString + " ", indentString + " ", "\n"));
+ }
+ String dependsOnThisString = indentString + " " + "Depended on by\n";
+ if (dependsOnString.length() > 0) {
+ dependsOnThisString += dependsOnThis.stream()
+ .map(depender -> depender.getSource().toString() + " (" + depender.getScope() + ")")
+ .collect(Collectors.joining("\n" + indentString + " ", indentString + " ", "\n"));
+ }
+ String resp = vsn + dependsOnString + dependsOnThisString;
+ if (includeSources) {
+ String sources = indentString + " " + "In source\n";
+ sources += sourceProjects.stream().map(sourceTree -> sourceTree.getRootDescription())
+ .collect(Collectors.joining("\n" + indentString + " ", indentString + " ", "\n"));
+ resp = resp += sources;
+ }
+ return resp;
+ }
+
+ @Override
+ public int compareTo(IdentifiedJarVersion target) {
+ return this.version.compareTo(target.version);
+ }
+
+ public void addSourceProject(@NonNull JarTree sourceProject) {
+ this.sourceProjects.add(sourceProject);
+ }
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTree.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTree.java
new file mode 100644
index 0000000..80e655d
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTree.java
@@ -0,0 +1,165 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+import java.util.TreeMap;
+import java.util.stream.Collectors;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.RequiredArgsConstructor;
+
+@Data
+@EqualsAndHashCode(callSuper = false)
+@RequiredArgsConstructor
+public class JarTree extends TreeMap implements Comparable {
+ private static final long serialVersionUID = -1545900389748317346L;
+ private IdentifiedJarVersion root = new IdentifiedJarVersion();
+ private final File origionalSourceFile;
+
+ public JarTree(String groupId, String artifactId, String jarFileVersionString, String jarFileType,
+ ScopeType jarScope) {
+ this(groupId, artifactId, jarFileVersionString, jarFileType, jarScope, null);
+ }
+
+ public JarTree(String groupId, String artifactId, String jarFileVersionString, String jarFileType,
+ ScopeType jarScope, File origionalSourceFile) {
+ this.origionalSourceFile = origionalSourceFile;
+ IdentifiedJarFile identifiedJarFile = new IdentifiedJarFile(groupId, artifactId);
+ IdentifiedJarVersion identifiedJarVersion = new IdentifiedJarVersion(jarFileVersionString.trim(),
+ identifiedJarFile, jarFileType, jarScope);
+ identifiedJarFile.put(jarFileVersionString.trim(), identifiedJarVersion);
+ this.root = identifiedJarVersion;
+ this.put(IdentifiedJarFile.processString(groupId, artifactId).trim(), identifiedJarFile);
+ identifiedJarVersion.addSourceProject(this);
+ }
+
+ public String dumpTree(IdentifiedJarVersion jarVersionCurrent, String indent, ScopeType scopeType, int depth) {
+ // do a depth first dump with indentation
+ String resp = indent;
+ String subIndent = indent + "|---";
+ // try to get the dependency link scope types
+ List dependentScopes;
+ if (jarVersionCurrent.getDependsOnThis().size() == 0) {
+ dependentScopes = new ArrayList<>(1);
+ dependentScopes.add(ScopeType.ROOT);
+ } else {
+ dependentScopes = jarVersionCurrent.getDependsOnThis().stream().map(dependecyOn -> dependecyOn.getScope())
+ .collect(Collectors.toList());
+ }
+ resp += jarVersionCurrent.toString() + " (" + dependentScopes + " refs = " + jarVersionCurrent.getRefCount()
+ + ")\n";
+ if (depth == 0) {
+ return resp + "\n" + "Reached specified depth\n";
+ }
+ int newDepth;
+ if (depth > 0) {
+ newDepth = depth - 1;
+ } else {
+ newDepth = depth;
+ }
+ // process the dependencies
+ String dependencyString = jarVersionCurrent.getDependsOn().stream()
+ .map(dependency -> dumpTree(dependency.getTarget(), subIndent, dependency.getScope(), newDepth))
+ .collect(Collectors.joining());
+ return resp + dependencyString;
+
+ }
+
+ public String dumpTree() {
+ return this.dumpTree("", -1);
+ }
+
+ public String dumpTree(String indent) {
+ return this.dumpTree(indent, -1);
+ }
+
+ public String dumpTree(String indent, int depth) {
+ return this.dumpTree(root, indent, root.getScope(), depth);
+ }
+
+ @Override
+ public int compareTo(JarTree other) {
+ return this.root.compareTo(other.root);
+ }
+
+ public String listJarFiles() {
+ return this.entrySet().stream().map(entry -> entry.getValue().toVersionList(""))
+ .collect(Collectors.joining("\n"));
+ }
+
+ public String listJarFileDetails() {
+ return listJarFileDetails(false);
+ }
+
+ public String listJarFileDetails(boolean includeSources) {
+ return this.entrySet().stream().map(entry -> entry.getValue().toVersionDetails("", includeSources))
+ .collect(Collectors.joining("\n"));
+ }
+
+ public Set getJarFilesWithNoVersions() {
+ return this.values().stream().filter(jarFile -> jarFile.isEmpty()).collect(Collectors.toSet());
+ }
+
+ public Set getJarFilesWithMoreThanSpecifiedVersions(int maxVersionCount) {
+ return this.values().stream().filter(jarFile -> jarFile.size() > maxVersionCount).collect(Collectors.toSet());
+ }
+
+ public Set getJarVersionsWithNoDependencies() {
+ return this.values().stream().flatMap(jarFile -> jarFile.values().stream())
+ .filter(version -> version.getDependsOn().size() == 0).collect(Collectors.toSet());
+ }
+
+ public Set getJarVersionsWithNoDependOn() {
+ return this.values().stream().flatMap(jarFile -> jarFile.values().stream())
+ .filter(version -> version.getDependsOnThis().size() == 0).collect(Collectors.toSet());
+ }
+
+ public String getRootDescription() {
+ String resp = this.getRoot().toString();
+ if (origionalSourceFile == null) {
+ resp += " no origional source file available";
+ } else {
+ resp += " from origional source " + origionalSourceFile.getPath();
+ }
+ return resp;
+ }
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTreeCombiner.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTreeCombiner.java
new file mode 100644
index 0000000..731efa7
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/JarTreeCombiner.java
@@ -0,0 +1,186 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import java.util.Map;
+import java.util.TreeMap;
+
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.extern.java.Log;
+
+@Log
+@Data
+public class JarTreeCombiner {
+ public final static String PROJECT_FILE_TYPE = "project";
+ public final static ScopeType PROJECT_SCOPE_TYPE = ScopeType.PROJECT;
+ private JarTree projectTop;
+ @EqualsAndHashCode.Exclude
+ private Map projectJarVersions = new TreeMap<>();
+
+ public JarTreeCombiner(String groupId, String artifactId, String projectVersionString) {
+ this.projectTop = new JarTree(groupId, artifactId, projectVersionString, PROJECT_FILE_TYPE, PROJECT_SCOPE_TYPE);
+ projectTop.getRoot().getParent().setFromSource(false);
+ projectTop.getRoot().setFromSource(false);
+ // get the "root" project jar version we just created and stash it for later
+ // access
+ projectJarVersions.put(projectTop.getRoot().toString().trim(), projectTop.getRoot());
+
+ }
+
+ public void addJarTree(JarTree jarTree) {
+ // force up the root connection to our project
+ IdentifiedJarVersion incomingRootJarVersion = jarTree.getRoot();
+ // if the jar file is already processed then no need to setup the new one
+ String incommingRoofJarFileName = incomingRootJarVersion.getParent().toString();
+ IdentifiedJarFile newRootJarFile = projectTop.get(incommingRoofJarFileName.trim());
+ if (newRootJarFile == null) {
+ log.finer("Cannot locate incomming root jar file " + incommingRoofJarFileName + ", creating");
+ newRootJarFile = incomingRootJarVersion.getParent().duplicateCore();
+ // stash it in the new jar tree
+ projectTop.put(newRootJarFile.toString().trim(), newRootJarFile);
+ // in this case the jar file will (should) also be in the incoming tree, so
+ // reduce the ref count
+ // to reflect we've set it up already
+ newRootJarFile.decrCount();
+ } else {
+ log.finer("Located an existing jar file for the project root of " + incommingRoofJarFileName);
+ }
+ // sort out the jar version
+ String incomingRootJarVersionName = incomingRootJarVersion.getVersion();
+ IdentifiedJarVersion newRootJarVersion = newRootJarFile.get(incomingRootJarVersionName.trim());
+ if (newRootJarVersion == null) {
+ log.finer("Cannot locate incomming root jar version " + incomingRootJarVersionName + ", creating");
+ newRootJarVersion = incomingRootJarVersion.duplicateCore(newRootJarFile);
+ // add the new version info to the new jar file
+ newRootJarFile.put(incomingRootJarVersionName.trim(), newRootJarVersion);
+ // put the new jar version in the main stash so we can get it later when setting
+ // up the dependencies
+ projectJarVersions.put(newRootJarVersion.toString().trim(), newRootJarVersion);
+ } else {
+ log.finer("Located incomming root jar version " + incomingRootJarVersionName + ", reusing");
+ }
+ newRootJarVersion.incrRefCount();
+ // setup the dependency, this will link the project root to the incoming tree
+ // root duplicate
+ Dependency dependency = new Dependency(projectTop.getRoot(), newRootJarVersion, PROJECT_SCOPE_TYPE);
+ // add the dependencies in place
+ projectTop.getRoot().getDependsOn().add(dependency);
+ newRootJarVersion.getDependsOnThis().add(dependency);
+ // copy over all of the jar files and version details
+ addAllJarFilesAndVersions(jarTree);
+ // now we have everything we need for the dependencies
+ addAllDependencies(jarTree);
+ }
+
+ private void addAllJarFilesAndVersions(JarTree incommingJarTree) {
+ // for every incoming jar file get the jar file from the main tree, creating if
+ // needed
+ incommingJarTree.entrySet().stream().forEach(jarFileEntry -> {
+ String jarName = jarFileEntry.getKey();
+ IdentifiedJarFile incommingJarFile = jarFileEntry.getValue();
+ IdentifiedJarFile mainJarFile = projectTop.get(jarName.trim());
+ // we don't have this yet create a new one
+ if (mainJarFile == null) {
+ mainJarFile = incommingJarFile.duplicateCore();
+ projectTop.put(jarName.trim(), mainJarFile);
+ }
+ mainJarFile.incrRefCount();
+ // for the next stream to work the jar file must be final so
+ IdentifiedJarFile finalMainJarFile = mainJarFile;
+ // for every version of that jar file add it to the main tree version (the jar
+ // file itself must exist as we have just created it if needed)
+ incommingJarFile.entrySet().stream().forEach(jarVersionEntry -> {
+ String versionName = jarVersionEntry.getKey();
+ IdentifiedJarVersion incommingJarVersion = jarVersionEntry.getValue();
+ IdentifiedJarVersion mainJarVersion = finalMainJarFile.get(versionName.trim());
+ // if the version does not exist in the main jar version then create and add it
+ // then add the original jar versions source projects (the source JarTree) to
+ // the
+ // main trees version source projects (let's us identify the source of a
+ // conflict)
+ if (mainJarVersion == null) {
+ // this will copy over the original source project
+ mainJarVersion = incommingJarVersion.duplicateCore(finalMainJarFile);
+ finalMainJarFile.put(versionName.trim(), mainJarVersion);
+ // stash a direct link to the version to speed up access later
+ projectJarVersions.put(mainJarVersion.toString().trim(), mainJarVersion);
+ } else {
+ // the version exists, but we need to add the source projects to the existing
+ // version
+ mainJarVersion.addSourceProjects(incommingJarVersion.getSourceProjects());
+ }
+ // increment the ref count
+ mainJarVersion.incrRefCount();
+ });
+ });
+ }
+
+ private void addAllDependencies(JarTree incommingJarTree) {
+ // for every incoming jar file get the jar file from the main tree, then the
+ // versions, then the dependencies
+ incommingJarTree.values().stream().flatMap(incommingJarFile -> incommingJarFile.values().stream())
+ .flatMap(incommingJarVersion -> incommingJarVersion.getDependsOn().stream())
+ .forEach(incommingTreeDependency -> {
+ // the dependency will reference the original jar tree jar versions, but we need
+ // the main tree versions
+ // so need to get the main tree version entries
+ String incommingSourceJarVersionName = incommingTreeDependency.getSource().toString();
+ IdentifiedJarVersion mainTreeSourceJarVersion = projectJarVersions
+ .get(incommingSourceJarVersionName.trim());
+ if (mainTreeSourceJarVersion == null) {
+ log.severe("Cannot locate the version " + incommingSourceJarVersionName
+ + " in the main tree, but it should be there");
+ return;
+ }
+ String incommingTargetJarVersionName = incommingTreeDependency.getTarget().toString();
+ IdentifiedJarVersion mainTreeTargetJarVersion = projectJarVersions
+ .get(incommingTargetJarVersionName.trim());
+ if (mainTreeTargetJarVersion == null) {
+ log.severe("Cannot locate the version " + incommingTargetJarVersionName
+ + " in the main tree, but it should be there");
+ return;
+ }
+ // we have the matching source and dest, let's create a new dependency for them
+ Dependency mainTreeDependency = incommingTreeDependency.dupeCore(mainTreeSourceJarVersion,
+ mainTreeTargetJarVersion);
+ // add the dependency
+ mainTreeSourceJarVersion.getDependsOn().add(mainTreeDependency);
+ mainTreeTargetJarVersion.getDependsOnThis().add(mainTreeDependency);
+ });
+ }
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/OptionsData.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/OptionsData.java
new file mode 100644
index 0000000..1fee8c3
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/OptionsData.java
@@ -0,0 +1,67 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+import java.io.File;
+import java.util.List;
+
+import org.kohsuke.args4j.Argument;
+import org.kohsuke.args4j.Option;
+
+import lombok.Data;
+
+@Data
+public class OptionsData {
+ @Option(name = "-V", aliases = "--Verbose", usage = "Set to true to enable verpose output of intermediate stages (e.g. the mvn sub processes). Defaults to false", metaVar = "true or false")
+ public boolean verboseOutput = false;
+ @Option(name = "-d", aliases = "--directory", usage = "Name of the temporary directory to use when generating temp files. Defaults to the current directory if not specified")
+ public File workingDirectory = new File(".");
+ @Option(name = "-g", aliases = "--groupid", usage = "The group Id to use for in the root of the combined dependency tree", metaVar = "my.group.id")
+ public String groupid = "my.company";
+ @Option(name = "-a", aliases = "--artifactid", usage = "The artifact Id to use for in the root of the combined dependency tree", metaVar = "codeproject")
+ public String artifactid = "myartifact";
+ @Option(name = "-v", aliases = "--version", usage = "The version to use for in the root of the combined dependency tree", metaVar = "1.2.3+SP2")
+ public String version = "0.0.0";
+ @Option(name = "-m", aliases = "--maven-path", usage = "The version to use for in the root of the combined dependency tree", metaVar = "1.2.3+SP2")
+ public File mvnPath = null;
+ @Option(name = "-r", aliases = "--resolve-dependencies", usage = "Set to enable mvn dependency resolution before building the dependency tree, default to false.", metaVar = "true or false")
+ public boolean resolveDependencies = false;
+ @Option(name = "-i", aliases = "--retain-intermediates", usage = "Set to true to retain the intermediate files, default to false", metaVar = "true or false")
+ public boolean retainIntermediateFiles = false;
+ @Argument(required = true, usage = "Input(s) can be pom.xml, mvn graph outputs (suffix .mvn-graphml)")
+ public List sources;
+}
\ No newline at end of file
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/ScopeType.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/ScopeType.java
new file mode 100644
index 0000000..4519a8d
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/ScopeType.java
@@ -0,0 +1,49 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser;
+
+public enum ScopeType {
+ ROOT, PROJECT, COMPILE, PROVIDED, RUNTIME, TEST, SYSTEM, IMPORT, UNKNOWN, ERROR, INPUT;
+
+ public static ScopeType getScope(String scopeName) {
+ ScopeType scope = ScopeType.valueOf(scopeName.toUpperCase());
+ if (scope == null) {
+ scope = UNKNOWN;
+ }
+ return scope;
+ }
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/GetSourceLoader.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/GetSourceLoader.java
new file mode 100644
index 0000000..b128ede
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/GetSourceLoader.java
@@ -0,0 +1,79 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser.importers;
+
+import java.io.File;
+
+import com.oracle.timg.demo.dependencyanalyser.DependencyProcessorException;
+import com.oracle.timg.demo.dependencyanalyser.OptionsData;
+
+public class GetSourceLoader {
+
+ public static final String POM_XML = "pom.xml";
+ public final static String MAVEN_GRAPH_FILE_SUFFIX = ".mvn-graphml.xml";
+ public final static String JAR_FILE_SUFFIX = ".jar";
+
+ public static SourceLoader getSourceLoader(OptionsData options, File source) throws DependencyProcessorException {
+ if (!source.exists()) {
+ throw new DependencyProcessorException(
+ "Source file " + source.getAbsolutePath() + " does not exist, cannot process it");
+ }
+ if (!source.isFile()) {
+ throw new DependencyProcessorException(
+ "Source file " + source.getAbsolutePath() + " is not a file, cannot process it");
+ }
+ if (!source.canRead()) {
+ throw new DependencyProcessorException(
+ "Source file " + source.getAbsolutePath() + " is not readable, cannot process it");
+ }
+ // need to work out what type of source this is.
+ String sourceName = source.getName();
+ if (sourceName.equalsIgnoreCase(POM_XML)) {
+ return new MavenPomXMLLoader(options);
+ }
+ // if it's a graphml file we can process it instantly
+ if (source.getName().endsWith(MAVEN_GRAPH_FILE_SUFFIX)) {
+ return new MavenGraphLoader(options);
+ }
+ // if it's a graphml file we can process it instantly
+ if (source.getName().endsWith(JAR_FILE_SUFFIX)) {
+ return new JarFileLoader(options);
+ }
+ throw new DependencyProcessorException("Unable to locate a loader for file type " + sourceName);
+ }
+
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFIleProcessorException.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFIleProcessorException.java
new file mode 100644
index 0000000..7c356de
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFIleProcessorException.java
@@ -0,0 +1,65 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser.importers;
+
+import com.oracle.timg.demo.dependencyanalyser.DependencyProcessorException;
+
+public class JarFIleProcessorException extends DependencyProcessorException {
+
+ private static final long serialVersionUID = 529077741205885816L;
+
+ public JarFIleProcessorException() {
+ super();
+ }
+
+ public JarFIleProcessorException(String arg0) {
+ super(arg0);
+ }
+
+ public JarFIleProcessorException(Throwable arg0) {
+ super(arg0);
+ }
+
+ public JarFIleProcessorException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ }
+
+ public JarFIleProcessorException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
+ super(arg0, arg1, arg2, arg3);
+ }
+
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFileLoader.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFileLoader.java
new file mode 100644
index 0000000..298c4d6
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/JarFileLoader.java
@@ -0,0 +1,186 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser.importers;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Optional;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+
+import com.oracle.timg.demo.dependencyanalyser.DependencyProcessorException;
+import com.oracle.timg.demo.dependencyanalyser.IdentifiedJarVersion;
+import com.oracle.timg.demo.dependencyanalyser.JarTree;
+import com.oracle.timg.demo.dependencyanalyser.OptionsData;
+
+import lombok.extern.java.Log;
+
+@Log
+public class JarFileLoader extends MavenPomXMLLoader {
+ public final static String ALLOWABLE_CHARACTERS = "[\\w\\.]";
+
+ public JarFileLoader(OptionsData optionsData) throws DependencyProcessorException {
+ super(optionsData);
+ }
+
+ @Override
+ public JarTree loadDependencyTree(File sourceFile, File origionalSourceFile) throws DependencyProcessorException {
+ // will need this later
+ File tempPomXMLFile;
+ // try and locate the pom.properties in the jar file, this is the simplest
+ // option
+ try (JarFile jarFile = new JarFile(sourceFile);) {
+ // regexp to locate the pom.properties it will be named along the lines of
+ // META-INF/maven///pom.properties
+ // make this final so the lambda doesn't get upset
+ final Pattern pomPropertiesPattern = Pattern.compile(
+ "META-INF/maven/" + ALLOWABLE_CHARACTERS + "*/" + ALLOWABLE_CHARACTERS + "*/pom.properties",
+ Pattern.CASE_INSENSITIVE);
+ // try to locate the pom.properties file entry
+ Optional pomPropertiesEntry = jarFile.stream().filter(entry -> {
+ Matcher matcher = pomPropertiesPattern.matcher(entry.getName());
+ return matcher.find();
+ }).findFirst();
+ // the pom.xml will be similar
+ final Pattern pomXMLPattern = Pattern.compile(
+ "META-INF/maven/" + ALLOWABLE_CHARACTERS + "*/" + ALLOWABLE_CHARACTERS + "*/pom.xml",
+ Pattern.CASE_INSENSITIVE);
+ // try to locate the pom.properties file entry
+ Optional pomXMLEntry = jarFile.stream().filter(entry -> {
+ Matcher matcher = pomXMLPattern.matcher(entry.getName());
+ return matcher.find();
+ }).findFirst();
+ // if we have the pom.properties then get the pom info form that, it's "safer"
+ IdentifiedJarVersion jarFileIdentifiedJarVerion = null;
+ if (pomPropertiesEntry.isPresent()) {
+ ZipEntry pomPropertiesZipFile = pomPropertiesEntry.get();
+ try {
+ MavenPomPropertiesExtractor pomPropertiesExtractor = new MavenPomPropertiesExtractor(
+ jarFile.getInputStream(pomPropertiesZipFile));
+ jarFileIdentifiedJarVerion = pomPropertiesExtractor.getJarVersion();
+ log.fine("Extracted pom info " + jarFileIdentifiedJarVerion + " from pom.properties in jar file "
+ + sourceFile.getPath());
+ } catch (MavenPomPropertiesProcessorException e) {
+ log.fine("Problem loading the pom properties because " + e.getLocalizedMessage());
+ }
+ }
+ // if we loaded the jar details then we will use them later, but if we didn't
+ // then fall back to trying to get them from the pom
+ if (jarFileIdentifiedJarVerion == null) {
+ if (pomXMLEntry.isEmpty()) {
+ throw new JarFIleProcessorException("Unfortunately jar file " + sourceFile.getPath()
+ + " does not containe a usable pom.properties file or pom.xml file, cannot process this jar file");
+ }
+ ZipEntry pomXMLZipFile = pomXMLEntry.get();
+ try {
+ MavenPomXMLExtractor pomXMLExtractor = new MavenPomXMLExtractor(
+ jarFile.getInputStream(pomXMLZipFile));
+ jarFileIdentifiedJarVerion = pomXMLExtractor.getJarVersion();
+ log.fine("Extracted pom info " + jarFileIdentifiedJarVerion + " from pom.xml in jar file "
+ + sourceFile.getPath());
+ } catch (XMLProcessorException e) {
+ throw new JarFIleProcessorException("Unfortunately jar file " + sourceFile.getPath()
+ + " does not have a usable pom.xml file, cannot process this jar file");
+ }
+ }
+
+ if (jarFileIdentifiedJarVerion == null) {
+ throw new JarFIleProcessorException("Unfortunately jar file " + sourceFile.getPath()
+ + " does not have a usable pom.xml or pom.properties file, cannot process this jar file");
+ }
+ // have to check for the pom file directly as we may have gotten the info from
+ // the pom.properties file
+ if (pomXMLEntry.isEmpty()) {
+ throw new JarFIleProcessorException("Unfortunately jar file " + sourceFile.getPath()
+ + " does not containe a pom.xml file, cannot process this jar file");
+ }
+ // build a name for the pom.xml file to cache
+ String prefix = jarFileIdentifiedJarVerion.getParent().getGroupId() + "."
+ + jarFileIdentifiedJarVerion.getParent().getArtifactId() + "-"
+ + jarFileIdentifiedJarVerion.getVersion() + "-";
+ Path pomXMLPath;
+ try {
+ pomXMLPath = Files.createTempFile(optionsData.getWorkingDirectory().toPath(), prefix,
+ "." + GetSourceLoader.POM_XML);
+ } catch (IOException e) {
+ throw new JarFIleProcessorException(
+ "Can't create temp file for pom.xml output in " + optionsData.getWorkingDirectory()
+ + " using prefix " + prefix + " and suffix " + "." + GetSourceLoader.POM_XML);
+ }
+
+ tempPomXMLFile = pomXMLPath.toFile();
+ String tempPomXMLFileName = tempPomXMLFile.getAbsolutePath();
+ // if needed mark this as something to delete when the JVM closes
+ if (!optionsData.isRetainIntermediateFiles()) {
+ tempPomXMLFile.deleteOnExit();
+ log.info("Will delete temp pom.xml file " + tempPomXMLFileName + " on exit");
+ } else {
+ log.info("Will retain temp pom.xml file " + tempPomXMLFileName + " on exit");
+ }
+ ZipEntry pomXMLZipFile = pomXMLEntry.get();
+ log.finer("Pom.xml file in " + pomXMLZipFile + " is of path " + pomXMLZipFile.getName() + " and "
+ + pomXMLZipFile.getSize() + " bytes long when uncompressed");
+ InputStream pomXmlInputStream;
+ try {
+ pomXmlInputStream = jarFile.getInputStream(pomXMLZipFile);
+ } catch (IOException e) {
+ throw new JarFIleProcessorException(
+ "Unable to get the pom.xml input stream from " + sourceFile.getPath()
+ + " because of IO problem " + e.getMessage() + ", cannot process this jar file");
+ }
+ try {
+ Files.copy(pomXmlInputStream, pomXMLPath, StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException e) {
+ throw new JarFIleProcessorException("Unable to extract the pom.xml file from " + sourceFile.getPath()
+ + " because of IO problem " + e.getMessage() + ", cannot process this jar file");
+ }
+ } catch (IOException e) {
+ throw new JarFIleProcessorException(
+ "IO problem loading the jar file " + sourceFile.getPath() + ", " + e.getLocalizedMessage());
+ }
+ // we have the pom.xml extracted in the temp files. now get the superclass to
+ // process it
+ return super.loadDependencyTree(tempPomXMLFile);
+ }
+}
diff --git a/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenGraphLoader.java b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenGraphLoader.java
new file mode 100644
index 0000000..d6cfc50
--- /dev/null
+++ b/dependencyanalyser/src/main/java/com/oracle/timg/demo/dependencyanalyser/importers/MavenGraphLoader.java
@@ -0,0 +1,295 @@
+/*Copyright (c) 2024 Oracle and/or its affiliates.
+
+The Universal Permissive License (UPL), Version 1.0
+
+Subject to the condition set forth below, permission is hereby granted to any
+person obtaining a copy of this software, associated documentation and/or data
+(collectively the "Software"), free of charge and under any and all copyright
+rights in the Software, and any and all patent rights owned or freely
+licensable by each licensor hereunder covering either (i) the unmodified
+Software as contributed to or provided by such licensor, or (ii) the Larger
+Works (as defined below), to deal in both
+
+(a) the Software, and
+(b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
+one is included with the Software (each a "Larger Work" to which the Software
+is contributed by such licensors),
+
+without restriction, including without limitation the rights to copy, create
+derivative works of, display, perform, and distribute the Software and make,
+use, sell, offer for sale, import, export, have made, and have sold the
+Software and the Larger Work(s), and to sublicense the foregoing rights on
+either these or other terms.
+
+This license is subject to the following condition:
+The above copyright notice and either this complete permission notice or at
+a minimum a reference to the UPL must be included in all copies or
+substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+ */
+package com.oracle.timg.demo.dependencyanalyser.importers;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+import javax.xml.xpath.XPathExpression;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import com.oracle.timg.demo.dependencyanalyser.Dependency;
+import com.oracle.timg.demo.dependencyanalyser.DependencyProcessorException;
+import com.oracle.timg.demo.dependencyanalyser.IdentifiedJarFile;
+import com.oracle.timg.demo.dependencyanalyser.IdentifiedJarVersion;
+import com.oracle.timg.demo.dependencyanalyser.JarTree;
+import com.oracle.timg.demo.dependencyanalyser.OptionsData;
+import com.oracle.timg.demo.dependencyanalyser.ScopeType;
+
+import lombok.NonNull;
+import lombok.extern.java.Log;
+
+/**
+ * Loads the graph output of maven into the jartree to generate the mvn grapu :
+ * 'mvn -f dependency:tree -DoutputType=graphml -DoutputFile=