Class DependencyUtils

java.lang.Object
com.ultikits.ultitools.utils.DependencyUtils

public class DependencyUtils extends Object
Utility class for handling plugin dependency and package scanning operations. This class helps determine which packages should be scanned for components based on annotations like ComponentScan and EnableAutoRegister.

@UltiToolsModule carries both ComponentScan and EnableAutoRegister as meta-annotations, and its scanBasePackages()/scanBasePackageClasses() attributes declare @AliasFor onto ComponentScan's basePackages()/ basePackageClasses(). Resolution therefore goes through MergedAnnotationResolver.find(java.lang.Class<?>, java.lang.Class<A>) rather than the JDK's own direct-annotation-only reflection (a bare Class lookup, which only sees an annotation declared directly on the class and misses that merge entirely) -- before @since 6.3.0 a class annotated only @UltiToolsModule(scanBasePackages = {...}) silently fell through to the plugin class's own package, discarding its declared value (SILENT-22).

Since:
6.0.0
Author:
wisdomme
See Also:
  • Constructor Details

    • DependencyUtils

      public DependencyUtils()
  • Method Details

    • getPluginPackages

      public static String[] getPluginPackages(UltiToolsPlugin plugin)
      Get plugin packages.

      Additive, not first-match: every declared source -- ComponentScan.value(), ComponentScan.basePackages(), ComponentScan.basePackageClasses(), and EnableAutoRegister.scanPackage() -- contributes packages, in declaration order, with duplicates collapsed to their first occurrence, mirroring PluginManager.getPluginScanPackages's shape. Falls back to the plugin class's own package only when no source contributes anything.

      Parameters:
      plugin - UltiTools plugin instance
      Returns:
      Plugin packages
    • dedupeNestedPackages

      static Set<String> dedupeNestedPackages(Set<String> packages)
      Drops any package that is a strict, segment-wise subpackage of another package already present in packages (#362). A scanner that recurses from the parent package already reaches every @ConfigEntity class the nested entry would find again, so keeping both means ConfigManager.registerAll initialises - and validates - the same class once per matching scan package instead of once overall.

      "Strict subpackage" is tested by segment, not by string prefix: com.example.modular is NOT a subpackage of com.example.mod, even though the raw string starts with it - the comparison always appends a trailing "." before testing String.startsWith(String).

      Parameters:
      packages - candidate packages, in declaration order; never mutated
      Returns:
      a new set containing only the packages with no ancestor also present in packages, in the same relative order. Empty in, empty out - nothing throws.