|
27 | 27 | import org.apache.maven.execution.MavenSession; |
28 | 28 | import org.apache.maven.model.MailingList; |
29 | 29 | import org.apache.maven.model.building.ModelBuildingRequest; |
| 30 | +import org.apache.maven.project.DefaultProjectBuildingRequest; |
30 | 31 | import org.apache.maven.project.MavenProject; |
31 | 32 | import org.apache.maven.project.ProjectBuilder; |
32 | 33 | import org.apache.maven.project.ProjectBuildingException; |
| 34 | +import org.apache.maven.project.ProjectBuildingRequest; |
33 | 35 | import org.apache.maven.project.ProjectBuildingResult; |
34 | 36 | import org.apache.maven.repository.RepositorySystem; |
35 | 37 | import org.cyclonedx.Version; |
|
56 | 58 | import java.net.URISyntaxException; |
57 | 59 | import java.util.Arrays; |
58 | 60 | import java.util.Collections; |
| 61 | +import java.util.HashSet; |
59 | 62 | import java.util.List; |
60 | 63 | import java.util.Properties; |
| 64 | +import java.util.Set; |
61 | 65 | import java.util.TreeMap; |
62 | 66 | import java.util.stream.Collectors; |
63 | 67 | import org.apache.maven.model.Plugin; |
@@ -443,4 +447,130 @@ private static boolean isBlank(String s) { |
443 | 447 | private static boolean isLicenseBlank(org.apache.maven.model.License license) { |
444 | 448 | return isBlank(license.getName()) && isBlank(license.getUrl()); |
445 | 449 | } |
| 450 | + |
| 451 | + @Override |
| 452 | + public boolean hasParentPom(Artifact artifact) { |
| 453 | + try { |
| 454 | + final Artifact pomArtifact = repositorySystem.createProjectArtifact(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()); |
| 455 | + final ProjectBuildingResult build = mavenProjectBuilder.build(pomArtifact, |
| 456 | + session.getProjectBuildingRequest() |
| 457 | + .setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL) |
| 458 | + .setProcessPlugins(false) |
| 459 | + .setResolveDependencies(false) |
| 460 | + ); |
| 461 | + final MavenProject project = build.getProject(); |
| 462 | + return project.hasParent() && project.getParent() != null; |
| 463 | + } catch (ProjectBuildingException e) { |
| 464 | + logger.debug("Unable to check parent for " + artifact.getId(), e); |
| 465 | + return false; |
| 466 | + } |
| 467 | + } |
| 468 | + |
| 469 | + @Override |
| 470 | + public Artifact getParentArtifact(Artifact artifact) { |
| 471 | + try { |
| 472 | + final Artifact pomArtifact = repositorySystem.createProjectArtifact(artifact.getGroupId(), artifact.getArtifactId(), artifact.getVersion()); |
| 473 | + final ProjectBuildingResult build = mavenProjectBuilder.build(pomArtifact, |
| 474 | + session.getProjectBuildingRequest() |
| 475 | + .setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL) |
| 476 | + .setProcessPlugins(false) |
| 477 | + .setResolveDependencies(false) |
| 478 | + ); |
| 479 | + final MavenProject project = build.getProject(); |
| 480 | + if (project.hasParent() && project.getParent() != null) { |
| 481 | + final MavenProject parent = project.getParent(); |
| 482 | + // Create an artifact for the parent POM |
| 483 | + return new DefaultArtifact( |
| 484 | + parent.getGroupId(), |
| 485 | + parent.getArtifactId(), |
| 486 | + parent.getVersion(), |
| 487 | + null, // scope |
| 488 | + "pom", // type |
| 489 | + null, // classifier |
| 490 | + new DefaultArtifactHandler("pom") |
| 491 | + ); |
| 492 | + } |
| 493 | + } catch (ProjectBuildingException e) { |
| 494 | + logger.debug("Unable to get parent for " + artifact.getId(), e); |
| 495 | + } |
| 496 | + return null; |
| 497 | + } |
| 498 | + |
| 499 | + @Override |
| 500 | + public Set<String> getDirectDependencyPurls(Artifact artifact) { |
| 501 | + final Set<String> directDeps = new HashSet<>(); |
| 502 | + |
| 503 | + try { |
| 504 | + // Build the artifact's POM to get its model |
| 505 | + final DefaultArtifact pomArtifact = new DefaultArtifact( |
| 506 | + artifact.getGroupId(), |
| 507 | + artifact.getArtifactId(), |
| 508 | + artifact.getVersion(), |
| 509 | + null, // scope |
| 510 | + "pom", |
| 511 | + null, // classifier |
| 512 | + new DefaultArtifactHandler("pom") |
| 513 | + ); |
| 514 | + |
| 515 | + final ProjectBuildingRequest buildingRequest = new DefaultProjectBuildingRequest(session.getProjectBuildingRequest()); |
| 516 | + buildingRequest.setValidationLevel(ModelBuildingRequest.VALIDATION_LEVEL_MINIMAL); |
| 517 | + buildingRequest.setResolveDependencies(false); |
| 518 | + buildingRequest.setProcessPlugins(false); |
| 519 | + |
| 520 | + final ProjectBuildingResult build = mavenProjectBuilder.build(pomArtifact, buildingRequest); |
| 521 | + final MavenProject project = build.getProject(); |
| 522 | + |
| 523 | + // Get dependencies from the original model |
| 524 | + if (project.getOriginalModel() != null && project.getOriginalModel().getDependencies() != null) { |
| 525 | + for (org.apache.maven.model.Dependency dep : project.getOriginalModel().getDependencies()) { |
| 526 | + try { |
| 527 | + // Skip if essential coordinates are missing |
| 528 | + if (dep.getGroupId() == null || dep.getArtifactId() == null) { |
| 529 | + continue; |
| 530 | + } |
| 531 | + |
| 532 | + // Version might be null if inherited from dependencyManagement |
| 533 | + String version = dep.getVersion(); |
| 534 | + if (version == null) { |
| 535 | + // Try to find the version from the effective dependencies |
| 536 | + for (org.apache.maven.model.Dependency effectiveDep : project.getDependencies()) { |
| 537 | + if (dep.getGroupId().equals(effectiveDep.getGroupId()) && |
| 538 | + dep.getArtifactId().equals(effectiveDep.getArtifactId())) { |
| 539 | + version = effectiveDep.getVersion(); |
| 540 | + break; |
| 541 | + } |
| 542 | + } |
| 543 | + } |
| 544 | + |
| 545 | + // If we still don't have a version, skip this dependency |
| 546 | + if (version == null) { |
| 547 | + logger.debug("Skipping dependency without version: " + dep.getGroupId() + ":" + dep.getArtifactId()); |
| 548 | + continue; |
| 549 | + } |
| 550 | + |
| 551 | + // Create an artifact to generate the pURL |
| 552 | + final DefaultArtifact depArtifact = new DefaultArtifact( |
| 553 | + dep.getGroupId(), |
| 554 | + dep.getArtifactId(), |
| 555 | + version, |
| 556 | + dep.getScope(), |
| 557 | + dep.getType() != null ? dep.getType() : "jar", |
| 558 | + dep.getClassifier(), |
| 559 | + new DefaultArtifactHandler(dep.getType() != null ? dep.getType() : "jar") |
| 560 | + ); |
| 561 | + final String purl = generatePackageUrl(depArtifact); |
| 562 | + if (purl != null) { |
| 563 | + directDeps.add(purl); |
| 564 | + } |
| 565 | + } catch (Exception e) { |
| 566 | + logger.warn("Error processing dependency " + dep.getGroupId() + ":" + dep.getArtifactId(), e); |
| 567 | + } |
| 568 | + } |
| 569 | + } |
| 570 | + } catch (Exception e) { |
| 571 | + logger.warn("Error loading POM for artifact " + artifact.getId(), e); |
| 572 | + } |
| 573 | + |
| 574 | + return directDeps; |
| 575 | + } |
446 | 576 | } |
0 commit comments