Class PomEditor.Dependencies

java.lang.Object
eu.maveniverse.domtrip.maven.PomEditor.Dependencies
Enclosing class:
PomEditor

public class PomEditor.Dependencies extends Object
Helper for managing regular and managed Maven dependencies within a POM.

Provides high-level operations for adding, updating, deleting, aligning, and inspecting dependencies, including support for exclusions, dependencyManagement, and convention detection.

By default, operations resolve relative to the project root (<project>). Use forProfile(String) or forProfile(Element) to obtain a profile-scoped instance whose operations resolve relative to a specific <profile> element.

Since:
0.3.0
  • Method Details

    • forProfile

      public PomEditor.Dependencies forProfile(String profileId)
      Returns a Dependencies instance scoped to the specified Maven profile.

      All dependency operations on the returned instance will resolve paths relative to the profile element instead of the project root. For example, addAligned will target project/profiles/profile[id=X]/dependencies instead of project/dependencies.

      Parameters:
      profileId - the <id> of the profile to scope to
      Returns:
      a Dependencies instance scoped to the profile
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the profile is not found
      Since:
      1.1.0
    • forProfile

      public PomEditor.Dependencies forProfile(eu.maveniverse.domtrip.Element profileElement)
      Returns a Dependencies instance scoped to the given profile element.

      This overload accepts a pre-resolved <profile> element, which can be obtained via PomEditor.Profiles.findProfile(String). This is useful when the caller has already located the profile or wants to check its existence before scoping.

      Example:

      Element profile = editor.profiles().findProfile("my-profile");
      if (profile != null) {
          editor.dependencies().forProfile(profile).addAligned(coords);
      }
      
      Parameters:
      profileElement - the <profile> element to scope to
      Returns:
      a Dependencies instance scoped to the profile
      Since:
      1.1.0
    • addDependency

      public eu.maveniverse.domtrip.Element addDependency(eu.maveniverse.domtrip.Element dependenciesElement, String groupId, String artifactId, String version) throws eu.maveniverse.domtrip.DomTripException
      Adds a dependency element with the specified coordinates.
      Parameters:
      dependenciesElement - the dependencies container element
      groupId - the dependency groupId
      artifactId - the dependency artifactId
      version - the dependency version (can be null)
      Returns:
      the newly created dependency element
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the dependency cannot be added
    • updateManagedDependency

      public boolean updateManagedDependency(boolean upsert, Coordinates coordinates) throws eu.maveniverse.domtrip.DomTripException
      Updates or inserts a managed dependency in project/dependencyManagement/dependencies/dependency[].

      If the dependency exists (matched by GATC), its version is updated. If the version is a property reference (${...}), the property value is updated instead. If upsert is true and the dependency doesn't exist, it will be created.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates junit = Coordinates.of("org.junit.jupiter", "junit-jupiter", "5.10.0");
      editor.updateManagedDependency(true, junit);
      
      Parameters:
      upsert - whether to create the dependency if it doesn't exist
      coordinates - the artifact coordinates
      Returns:
      true if the dependency was updated or created, false otherwise
      Throws:
      eu.maveniverse.domtrip.DomTripException - if an error occurs during editing
      Since:
      0.3.0
    • updateManagedDependencyAligned

      public boolean updateManagedDependencyAligned(boolean upsert, Coordinates coordinates) throws eu.maveniverse.domtrip.DomTripException
      Convention-aware version of updateManagedDependency(boolean, Coordinates).

      Detects the project's version conventions and, when the convention calls for property-backed versions, creates (or updates) a version property and stores a ${propName} reference in the managed dependency element instead of the raw version string.

      This is equivalent to calling updateManagedDependencyAligned(upsert, coordinates, AlignOptions.defaults()).

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates jackson = Coordinates.of("com.fasterxml.jackson.core", "jackson-databind", "2.15.0");
      // Auto-detects conventions; creates a property if the project uses property-backed versions
      editor.dependencies().updateManagedDependencyAligned(true, jackson);
      
      Parameters:
      upsert - whether to create the dependency if it doesn't exist
      coordinates - the artifact coordinates (version is required)
      Returns:
      true if the dependency was updated or created, false otherwise
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the coordinates are invalid or version is null
      Since:
      1.4.0
    • updateManagedDependencyAligned

      public boolean updateManagedDependencyAligned(boolean upsert, Coordinates coordinates, AlignOptions options) throws eu.maveniverse.domtrip.DomTripException
      Convention-aware version of updateManagedDependency(boolean, Coordinates) with explicit alignment options.

      Resolves conventions (auto-detecting any fields left null in options) and, when the effective version source is AlignOptions.VersionSource.PROPERTY, creates or updates a version property and uses its ${...} reference as the version in the managed dependency element.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates jackson = Coordinates.of("com.fasterxml.jackson.core", "jackson-databind", "2.15.0");
      editor.dependencies().updateManagedDependencyAligned(true, jackson,
          AlignOptions.builder()
              .versionSource(AlignOptions.VersionSource.PROPERTY)
              .namingConvention(AlignOptions.PropertyNamingConvention.DOT_SUFFIX)
              .build());
      
      Parameters:
      upsert - whether to create the dependency if it doesn't exist
      coordinates - the artifact coordinates (version is required)
      options - alignment options (null fields are auto-detected from the POM)
      Returns:
      true if the dependency was updated or created, false otherwise
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the coordinates are invalid or version is null
      Since:
      1.4.0
    • deleteManagedDependency

      public boolean deleteManagedDependency(Coordinates coordinates) throws eu.maveniverse.domtrip.DomTripException
      Removes a managed dependency from project/dependencyManagement/dependencies/dependency[].

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates junit = Coordinates.of("org.junit.jupiter", "junit-jupiter", "5.10.0");
      editor.deleteManagedDependency(junit);
      
      Parameters:
      coordinates - the artifact to remove (matched by GATC)
      Returns:
      true if the dependency was removed, false if it didn't exist
      Throws:
      eu.maveniverse.domtrip.DomTripException
      Since:
      0.3.0
    • updateDependency

      public boolean updateDependency(boolean upsert, Coordinates coordinates) throws eu.maveniverse.domtrip.DomTripException
      Updates or inserts a dependency in project/dependencies/dependency[].

      If the dependency exists (matched by GATC), its version is updated. If the version is a property reference (${...}), the property value is updated instead. If the dependency has no version element, the managed dependency is updated instead. If upsert is true and the dependency doesn't exist, it will be created.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates junit = Coordinates.of("org.junit.jupiter", "junit-jupiter", "5.10.0");
      editor.updateDependency(true, junit);
      
      Parameters:
      upsert - whether to create the dependency if it doesn't exist
      coordinates - the artifact coordinates
      Returns:
      true if the dependency was updated or created, false otherwise
      Throws:
      eu.maveniverse.domtrip.DomTripException - if an error occurs during editing
      Since:
      0.3.0
    • deleteDependency

      public boolean deleteDependency(Coordinates coordinates) throws eu.maveniverse.domtrip.DomTripException
      Removes a dependency from project/dependencies/dependency[].

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates junit = Coordinates.of("org.junit.jupiter", "junit-jupiter", "5.10.0");
      editor.deleteDependency(junit);
      
      Parameters:
      coordinates - the Coordinates to remove (matched by GATC)
      Returns:
      true if the dependency was removed, false if it didn't exist
      Throws:
      eu.maveniverse.domtrip.DomTripException
      Since:
      0.3.0
    • deleteDependencyVersion

      public boolean deleteDependencyVersion(Coordinates coordinates) throws eu.maveniverse.domtrip.DomTripException
      Removes a dependency version from project/dependencies/dependency[]. This call is usually combined with adding dependency management for same dependency.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates junit = Coordinates.of("org.junit.jupiter", "junit-jupiter", "5.10.0");
      editor.deleteDependencyVersion(junit);
      editor.updateManagedDependency(true, junit);
      
      Parameters:
      coordinates - the Coordinates to remove (matched by GATC)
      Returns:
      true if the dependency was removed, false if it didn't exist
      Throws:
      eu.maveniverse.domtrip.DomTripException
      Since:
      0.3.1
    • addExclusion

      public eu.maveniverse.domtrip.Element addExclusion(Coordinates dependency, Coordinates exclusion) throws eu.maveniverse.domtrip.DomTripException
      Adds an exclusion to a dependency. Creates the <exclusions> wrapper if absent. The dependency is found by matching on groupId:artifactId (GA).

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates dep = Coordinates.of("org.example", "my-lib", "1.0.0");
      Coordinates excl = Coordinates.of("commons-logging", "commons-logging", null);
      editor.dependencies().addExclusion(dep, excl);
      
      Parameters:
      dependency - the dependency coordinates (matched by GA)
      exclusion - the exclusion coordinates (groupId and artifactId)
      Returns:
      the newly created exclusion element
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the dependency is not found or an error occurs
      Since:
      1.0.0
    • deleteExclusion

      public boolean deleteExclusion(Coordinates dependency, Coordinates exclusion) throws eu.maveniverse.domtrip.DomTripException
      Removes an exclusion from a dependency. Removes the <exclusions> wrapper if it becomes empty.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates dep = Coordinates.of("org.example", "my-lib", "1.0.0");
      Coordinates excl = Coordinates.of("commons-logging", "commons-logging", null);
      editor.dependencies().deleteExclusion(dep, excl);
      
      Parameters:
      dependency - the dependency coordinates (matched by GA)
      exclusion - the exclusion coordinates (matched by GA)
      Returns:
      true if the exclusion was removed, false if it didn't exist
      Throws:
      eu.maveniverse.domtrip.DomTripException
      Since:
      1.0.0
    • hasExclusion

      public boolean hasExclusion(Coordinates dependency, Coordinates exclusion)
      Checks whether a dependency has a specific exclusion.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates dep = Coordinates.of("org.example", "my-lib", "1.0.0");
      Coordinates excl = Coordinates.of("commons-logging", "commons-logging", null);
      boolean has = editor.dependencies().hasExclusion(dep, excl);
      
      Parameters:
      dependency - the dependency coordinates (matched by GA)
      exclusion - the exclusion coordinates (matched by GA)
      Returns:
      true if the dependency has the specified exclusion
      Since:
      1.0.0
    • addManagedExclusion

      public eu.maveniverse.domtrip.Element addManagedExclusion(Coordinates dependency, Coordinates exclusion) throws eu.maveniverse.domtrip.DomTripException
      Adds an exclusion to a managed dependency. Creates the <exclusions> wrapper if absent. The dependency is found by matching on groupId:artifactId (GA).

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates dep = Coordinates.of("org.example", "my-lib", "1.0.0");
      Coordinates excl = Coordinates.of("commons-logging", "commons-logging", null);
      editor.dependencies().addManagedExclusion(dep, excl);
      
      Parameters:
      dependency - the dependency coordinates (matched by GA)
      exclusion - the exclusion coordinates (groupId and artifactId)
      Returns:
      the newly created exclusion element
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the dependency is not found or an error occurs
      Since:
      1.0.0
    • deleteManagedExclusion

      public boolean deleteManagedExclusion(Coordinates dependency, Coordinates exclusion) throws eu.maveniverse.domtrip.DomTripException
      Removes an exclusion from a managed dependency. Removes the <exclusions> wrapper if it becomes empty.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates dep = Coordinates.of("org.example", "my-lib", "1.0.0");
      Coordinates excl = Coordinates.of("commons-logging", "commons-logging", null);
      editor.dependencies().deleteManagedExclusion(dep, excl);
      
      Parameters:
      dependency - the dependency coordinates (matched by GA)
      exclusion - the exclusion coordinates (matched by GA)
      Returns:
      true if the exclusion was removed, false if it didn't exist
      Throws:
      eu.maveniverse.domtrip.DomTripException
      Since:
      1.0.0
    • hasManagedExclusion

      public boolean hasManagedExclusion(Coordinates dependency, Coordinates exclusion)
      Checks whether a managed dependency has a specific exclusion.

      Example:

      PomEditor editor = new PomEditor(document);
      Coordinates dep = Coordinates.of("org.example", "my-lib", "1.0.0");
      Coordinates excl = Coordinates.of("commons-logging", "commons-logging", null);
      boolean has = editor.dependencies().hasManagedExclusion(dep, excl);
      
      Parameters:
      dependency - the dependency coordinates (matched by GA)
      exclusion - the exclusion coordinates (matched by GA)
      Returns:
      true if the managed dependency has the specified exclusion
      Since:
      1.0.0
    • detectVersionStyle

      public AlignOptions.VersionStyle detectVersionStyle()
      Detects whether most dependencies use managed versions (version-less) or inline versions.

      Analyzes project/dependencies/dependency[] to count how many have inline versions versus how many delegate to dependencyManagement. Returns AlignOptions.VersionStyle.MANAGED if the strict majority of dependencies are version-less.

      Returns:
      the detected version style
      Since:
      1.1.0
    • detectVersionSource

      public AlignOptions.VersionSource detectVersionSource()
      Determine whether dependency versions predominantly use property references or literal values.

      Analyzes `/dependencies` and `/dependencyManagement/dependencies`. If a strict majority of observed `` elements are property references of the form `${...}`, the method returns AlignOptions.VersionSource.PROPERTY; otherwise it returns AlignOptions.VersionSource.LITERAL.

      Returns:
      AlignOptions.VersionSource.PROPERTY if strictly more versioned dependencies use `${...}` property references, AlignOptions.VersionSource.LITERAL otherwise
      Since:
      1.1.0
    • detectPropertyNamingConvention

      public AlignOptions.PropertyNamingConvention detectPropertyNamingConvention()
      Detects the dominant property naming convention from existing version property references.

      Analyzes ${...} version references in both regular and managed dependencies to determine the naming pattern. Falls back to AlignOptions.PropertyNamingConvention.DOT_SUFFIX if no pattern can be detected.

      Returns:
      the detected naming convention
      Since:
      1.1.0
    • detectConventions

      public AlignOptions detectConventions()
      Detects the project's dominant dependency version style, version source, and property naming convention and returns an AlignOptions instance with all corresponding fields populated.
      Returns:
      an AlignOptions populated with the detected version style, version source, and naming convention
      Since:
      1.1.0
    • addAligned

      public boolean addAligned(Coordinates coords)
      Adds a dependency aligned with the project's auto-detected conventions.

      Detects the project's dependency management style (managed vs inline, property vs literal, property naming convention) and adds the dependency accordingly. If the dependency already exists, returns false.

      Parameters:
      coords - the dependency coordinates (version is required)
      Returns:
      true if the dependency was added, false if it already existed
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the coordinates are invalid or version is null
      Since:
      1.1.0
    • addAligned

      public boolean addAligned(Coordinates coords, AlignOptions options)
      Adds a dependency aligned with the specified options, auto-detecting any unspecified conventions.

      Example usage:

      PomEditor editor = new PomEditor(document);
      Coordinates guava = Coordinates.of("com.google.guava", "guava", "32.1.2-jre");
      
      // Auto-detect all conventions
      editor.dependencies().addAligned(guava);
      
      // Force managed + property with explicit property name
      editor.dependencies().addAligned(guava, AlignOptions.builder()
          .versionStyle(AlignOptions.VersionStyle.MANAGED)
          .versionSource(AlignOptions.VersionSource.PROPERTY)
          .propertyName("guava.version")
          .build());
      
      // Add as test dependency
      editor.dependencies().addAligned(junit, AlignOptions.builder()
          .scope("test")
          .build());
      
      Parameters:
      coords - the dependency coordinates (version is required)
      options - alignment options (null fields are auto-detected)
      Returns:
      true if the dependency was added, false if it already existed
      Throws:
      eu.maveniverse.domtrip.DomTripException - if the coordinates are invalid or version is null
      Since:
      1.1.0
    • alignDependency

      public boolean alignDependency(Coordinates coords)
      Aligns the specified dependency to the project's detected dependency/version conventions.

      Applies the project's inferred version style and source (property vs literal) to the dependency's version handling. Only dependencies that currently have a `` element may be modified; dependencies without a `` are left unchanged.

      Parameters:
      coords - the dependency coordinates matched by groupId and artifactId
      Returns:
      `true` if the dependency was modified; `false` if the dependency was not found or no change was necessary
      Since:
      1.1.0
    • alignDependency

      public boolean alignDependency(Coordinates coords, AlignOptions options)
      Aligns an existing dependency to match the specified options, auto-detecting any unspecified conventions.

      This method transforms the version management of an existing dependency to match the target style. The following transformations may be applied:

      • Literal → Property: creates a version property and replaces the literal version with a ${property} reference
      • Inline → Managed: moves the version to dependencyManagement and removes the version element from the dependency

      Dependencies that are already version-less (managed) are not modified.

      Example usage:

      // Align a specific dependency to use managed + property style
      editor.dependencies().alignDependency(
          Coordinates.of("com.google.guava", "guava"),
          AlignOptions.builder()
              .versionStyle(AlignOptions.VersionStyle.MANAGED)
              .versionSource(AlignOptions.VersionSource.PROPERTY)
              .build());
      
      Parameters:
      coords - the dependency coordinates (matched by groupId and artifactId)
      options - alignment options (null fields are auto-detected from the POM)
      Returns:
      true if the dependency was modified, false if not found or no change was needed
      Since:
      1.1.0
      See Also:
    • alignAllDependencies

      public int alignAllDependencies()
      Aligns all existing dependencies to match the project's auto-detected conventions.

      Equivalent to calling alignAllDependencies(AlignOptions.defaults()).

      Returns:
      the number of dependencies that were modified
      Since:
      1.1.0
      See Also:
    • alignAllDependencies

      public int alignAllDependencies(AlignOptions options)
      Aligns all existing dependencies to match the specified options.

      Conventions are detected once before aligning, then applied consistently to all dependencies. This avoids convention drift that could occur if conventions were re-detected after each individual alignment.

      Example usage:

      // Align all dependencies to use managed + property style
      int changed = editor.dependencies().alignAllDependencies(
          AlignOptions.builder()
              .versionStyle(AlignOptions.VersionStyle.MANAGED)
              .versionSource(AlignOptions.VersionSource.PROPERTY)
              .build());
      System.out.println(changed + " dependencies aligned");
      
      Parameters:
      options - alignment options (null fields are auto-detected from the POM)
      Returns:
      the number of dependencies that were modified
      Since:
      1.1.0
      See Also:
    • alignToParent

      public boolean alignToParent(Coordinates coords, PomEditor parentEditor, AlignOptions options)
      Moves a single dependency's version from this (child) POM to the parent POM's <dependencyManagement>, making the child dependency version-less.

      If the child's version is a property reference, the property definition is migrated to the parent POM. When the target version source is PROPERTY and the child uses a literal version, a new property is created in the parent using the naming convention.

      Example usage:

      PomEditor child = new PomEditor(childDoc);
      PomEditor parent = new PomEditor(parentDoc);
      child.dependencies().alignToParent(
          Coordinates.of("com.google.guava", "guava"),
          parent,
          AlignOptions.builder()
              .versionSource(AlignOptions.VersionSource.PROPERTY)
              .build());
      
      Parameters:
      coords - the dependency coordinates (matched by groupId and artifactId)
      parentEditor - the parent POM editor where the managed dependency will be created
      options - alignment options controlling version source and property naming in the parent
      Returns:
      true if the dependency was moved, false if not found or already version-less
      Since:
      1.4.0
    • alignAllToParent

      public int alignAllToParent(PomEditor parentEditor, AlignOptions options)
      Moves all dependency versions from this (child) POM to the parent POM's <dependencyManagement>, making all child dependencies version-less.

      Conventions are resolved from the parent POM once before processing, then applied consistently. Property definitions are migrated or created in the parent as needed.

      Example usage:

      PomEditor child = new PomEditor(childDoc);
      PomEditor parent = new PomEditor(parentDoc);
      int moved = child.dependencies().alignAllToParent(parent,
          AlignOptions.builder()
              .versionSource(AlignOptions.VersionSource.PROPERTY)
              .namingConvention(AlignOptions.PropertyNamingConvention.DOT_SUFFIX)
              .build());
      
      Parameters:
      parentEditor - the parent POM editor where managed dependencies will be created
      options - alignment options controlling version source and property naming in the parent
      Returns:
      the number of dependencies that were moved to the parent
      Since:
      1.4.0
    • findManagedVersion

      public String findManagedVersion(Coordinates coords)
      Looks up the version text of a managed dependency matching the given coordinates.
      Parameters:
      coords - the dependency coordinates (matched by groupId/artifactId/type/classifier)
      Returns:
      the version text from the managed dependency, or null if not found
      Since:
      1.4.0