Skip to content

Commit 8ca2d74

Browse files
authored
Allow forced alignment of groupId, artifactId and version (#361)
* Allow forced alignment of groupId, artifactId and version to PackageURL when reading component data with Readers * Fix spellcheck findings.
1 parent b90c9a7 commit 8ca2d74

18 files changed

Lines changed: 341 additions & 0 deletions
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
package com.devonfw.tools.solicitor.common;
2+
3+
/**
4+
* This class represents the coordinates of an application component.
5+
*/
6+
public class ApplicationComponentCoordinates {
7+
8+
private final String groupId;
9+
10+
private final String artifactId;
11+
12+
private final String version;
13+
14+
/**
15+
* Creates a new instance of {@link ApplicationComponentCoordinates} with the given values.
16+
*
17+
* @param groupId the groupId
18+
* @param artifactId the artifactId
19+
* @param version the version
20+
*/
21+
public ApplicationComponentCoordinates(String groupId, String artifactId, String version) {
22+
23+
super();
24+
this.groupId = groupId;
25+
this.artifactId = artifactId;
26+
this.version = version;
27+
}
28+
29+
/**
30+
* This method gets the field <code>groupId</code>.
31+
*
32+
* @return the field groupId
33+
*/
34+
public String getGroupId() {
35+
36+
return this.groupId;
37+
}
38+
39+
/**
40+
* This method gets the field <code>artifactId</code>.
41+
*
42+
* @return the field artifactId
43+
*/
44+
public String getArtifactId() {
45+
46+
return this.artifactId;
47+
}
48+
49+
/**
50+
* This method gets the field <code>version</code>.
51+
*
52+
* @return the field version
53+
*/
54+
public String getVersion() {
55+
56+
return this.version;
57+
}
58+
59+
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/PackageURLHandler.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.devonfw.tools.solicitor.common.packageurl;
22

3+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
34
import com.github.packageurl.PackageURL;
45

56
/**
@@ -45,4 +46,15 @@ public interface PackageURLHandler {
4546
*/
4647
String sourceArchiveSuffixFor(PackageURL packageUrl) throws SolicitorPackageURLUnavailableOperationException;
4748

49+
/**
50+
* Returns the coordinates of the application component represented by the given package URL.
51+
*
52+
* @param packageUrl the package URL of the package
53+
* @return the coordinates of the application component represented by the given package URL
54+
* @throws SolicitorPackageURLUnavailableOperationException if the method is unavailable in the implementing
55+
* {@link PackageURLHandler} or for the given {@link PackageURL}.
56+
*/
57+
ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl)
58+
throws SolicitorPackageURLUnavailableOperationException;
59+
4860
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/impl/CranPackageURLHandlerImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.springframework.beans.factory.annotation.Value;
55
import org.springframework.stereotype.Component;
66

7+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
78
import com.github.packageurl.PackageURL;
89

910
/**
@@ -88,4 +89,10 @@ protected String doSourceArchiveSuffixFor(PackageURL purl) {
8889

8990
return "tar.gz";
9091
}
92+
93+
@Override
94+
public ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl) {
95+
96+
return new ApplicationComponentCoordinates(null, packageUrl.getName(), packageUrl.getVersion());
97+
}
9198
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/impl/DelegatingPackageURLHandlerImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import org.springframework.beans.factory.annotation.Autowired;
88
import org.springframework.stereotype.Component;
99

10+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
1011
import com.devonfw.tools.solicitor.common.packageurl.AllKindsPackageURLHandler;
1112
import com.devonfw.tools.solicitor.common.packageurl.PackageURLHandler;
1213
import com.devonfw.tools.solicitor.common.packageurl.SolicitorPackageURLUnavailableOperationException;
@@ -60,4 +61,10 @@ public String sourceArchiveSuffixFor(PackageURL packageUrl) throws SolicitorPack
6061
return findApplicableDelegateHandler(packageUrl).sourceArchiveSuffixFor(packageUrl);
6162
}
6263

64+
@Override
65+
public ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl)
66+
throws SolicitorPackageURLUnavailableOperationException {
67+
68+
return findApplicableDelegateHandler(packageUrl).coordinatesFor(packageUrl);
69+
}
6370
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/impl/FallbackPackageURLHandlerImpl.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import org.springframework.stereotype.Component;
44

5+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
56
import com.devonfw.tools.solicitor.common.packageurl.SolicitorPackageURLUnavailableOperationException;
67
import com.github.packageurl.PackageURL;
78

@@ -42,4 +43,12 @@ public String sourceArchiveSuffixFor(PackageURL packageUrl) throws SolicitorPack
4243
"No package suffix can be determined for PackageUrl '" + packageUrl + "'");
4344
}
4445

46+
@Override
47+
public ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl)
48+
throws SolicitorPackageURLUnavailableOperationException {
49+
50+
throw new SolicitorPackageURLUnavailableOperationException(
51+
"No coordinates can be determined for PackageUrl '" + packageUrl + "'");
52+
}
53+
4554
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/impl/MavenPackageURLHandlerImpl.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.springframework.beans.factory.annotation.Value;
55
import org.springframework.stereotype.Component;
66

7+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
78
import com.github.packageurl.PackageURL;
89

910
/**
@@ -64,4 +65,14 @@ public String doSourceArchiveSuffixFor(PackageURL purl) {
6465
return "jar";
6566
}
6667

68+
@Override
69+
public ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl) {
70+
71+
if (packageUrl.getNamespace() == null) {
72+
throw new IllegalArgumentException("A maven package URL must have a namespace (groupId) : " + packageUrl);
73+
}
74+
return new ApplicationComponentCoordinates(packageUrl.getNamespace(), packageUrl.getName(),
75+
packageUrl.getVersion());
76+
}
77+
6778
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/impl/NpmPackageURLHandlerImpl.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.springframework.beans.factory.annotation.Value;
55
import org.springframework.stereotype.Component;
66

7+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
78
import com.github.packageurl.PackageURL;
89

910
/**
@@ -66,4 +67,20 @@ protected String doSourceArchiveSuffixFor(PackageURL packageURL) {
6667
return "tgz";
6768
}
6869

70+
@Override
71+
public ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl) {
72+
73+
if (packageUrl.getNamespace() == null) {
74+
return new ApplicationComponentCoordinates(null, packageUrl.getName(), packageUrl.getVersion());
75+
} else {
76+
// due to historical reasons the namespace is not mapped to groupId in Solicitor, but instead is part of the
77+
// artifactId. So we need to merge namespace and name here. From todays standpoint this does not follow the
78+
// standard mapping of packageURL to coordinates, but we need to do this for npm to not break existing usage of
79+
// npm package URLs in Solicitor. In the future we should consider to change this and map namespace to groupId and
80+
// name to artifactId, but that would be a breaking change.
81+
return new ApplicationComponentCoordinates(null, packageUrl.getNamespace() + "/" + packageUrl.getName(),
82+
packageUrl.getVersion());
83+
}
84+
}
85+
6986
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/impl/NugetPackageURLHandlerImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.springframework.beans.factory.annotation.Value;
55
import org.springframework.stereotype.Component;
66

7+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
78
import com.github.packageurl.PackageURL;
89

910
@Component
@@ -53,4 +54,10 @@ public String doSourceArchiveSuffixFor(PackageURL packageURL) {
5354
return "nupkg";
5455
}
5556

57+
@Override
58+
public ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl) {
59+
60+
return new ApplicationComponentCoordinates(null, packageUrl.getName(), packageUrl.getVersion());
61+
}
62+
5663
}

core/src/main/java/com/devonfw/tools/solicitor/common/packageurl/impl/PyPIPackageURLHandlerImpl.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import org.springframework.beans.factory.annotation.Value;
55
import org.springframework.stereotype.Component;
66

7+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
78
import com.github.packageurl.PackageURL;
89

910
/**
@@ -65,4 +66,10 @@ public String doSourceArchiveSuffixFor(PackageURL purl) {
6566
return "tar.gz";
6667
}
6768

69+
@Override
70+
public ApplicationComponentCoordinates coordinatesFor(PackageURL packageUrl) {
71+
72+
return new ApplicationComponentCoordinates(null, packageUrl.getName(), packageUrl.getVersion());
73+
}
74+
6875
}

core/src/main/java/com/devonfw/tools/solicitor/reader/AbstractReader.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,11 @@
1111
import org.slf4j.LoggerFactory;
1212
import org.springframework.beans.factory.annotation.Autowired;
1313

14+
import com.devonfw.tools.solicitor.common.ApplicationComponentCoordinates;
1415
import com.devonfw.tools.solicitor.common.InputStreamFactory;
1516
import com.devonfw.tools.solicitor.common.LogMessages;
17+
import com.devonfw.tools.solicitor.common.packageurl.AllKindsPackageURLHandler;
18+
import com.devonfw.tools.solicitor.common.packageurl.SolicitorPackageURLUnavailableOperationException;
1619
import com.devonfw.tools.solicitor.model.ModelFactory;
1720
import com.devonfw.tools.solicitor.model.inventory.ApplicationComponent;
1821
import com.devonfw.tools.solicitor.model.inventory.RawLicense;
@@ -59,6 +62,8 @@ public static class ReaderStatistics {
5962

6063
private ModelFactory modelFactory;
6164

65+
private AllKindsPackageURLHandler packageURLHandler;
66+
6267
@Autowired
6368
protected InputStreamFactory inputStreamFactory;
6469

@@ -189,10 +194,41 @@ public boolean addComponentToApplicationIfNotFiltered(Application application, A
189194
statistics.filteredComponentCount++;
190195
return false;
191196
}
197+
possiblyCorrectCoordinatesViaPurlData(appComponent, configuration);
192198
appComponent.setApplication(application);
193199
return true;
194200
}
195201

202+
/**
203+
* Checks if the configuration contains the parameter "deriveCoordinatesFromPurl" set to "true" and if so tries to
204+
* obtain coordinates for the appComponent from the purl data and overwrite the previously set coordinates with the
205+
* ones obtained from the purl as they map better to the naming convention used by Solicitor.
206+
*
207+
* @param appComponent the appComponent for which the coordinates should potentially be corrected based on purl data
208+
* @param configuration the configuration which might contain the parameter "deriveCoordinatesFromPurl" set to
209+
* "true"
210+
*/
211+
private void possiblyCorrectCoordinatesViaPurlData(ApplicationComponent appComponent,
212+
Map<String, String> configuration) {
213+
214+
if (configuration != null && "true".equals(configuration.get("deriveCoordinatesFromPurl"))) {
215+
if (appComponent.getPackageUrl() != null) {
216+
try {
217+
ApplicationComponentCoordinates coordinates = this.packageURLHandler
218+
.coordinatesFor(appComponent.getPackageUrl());
219+
// if we can map the purl to coordinates then we overwrite the previously set coordinates with the
220+
// ones
221+
// obtained from the purl as they map better to the naming convention used by Solicitor
222+
appComponent.setGroupId(coordinates.getGroupId());
223+
appComponent.setArtifactId(coordinates.getArtifactId());
224+
appComponent.setVersion(coordinates.getVersion());
225+
} catch (SolicitorPackageURLUnavailableOperationException e) {
226+
// if we do not know how to map to coordinates then we silently skip this
227+
}
228+
}
229+
}
230+
}
231+
196232
/**
197233
* This method gets the field <code>modelFactory</code>.
198234
*
@@ -232,4 +268,15 @@ public void setModelFactory(ModelFactory modelFactory) {
232268
this.modelFactory = modelFactory;
233269
}
234270

271+
/**
272+
* This method gets the field <code>packageURLHandler</code>.
273+
*
274+
* @param packageURLHandler the packageURLHandler to set
275+
*/
276+
@Autowired
277+
public void setPackageURLHandler(AllKindsPackageURLHandler packageURLHandler) {
278+
279+
this.packageURLHandler = packageURLHandler;
280+
}
281+
235282
}

0 commit comments

Comments
 (0)