@@ -347,16 +347,62 @@ public Path resolveRelativeToBaseDir(String path) {
347347 return resolveRelativeToBaseDir (path , null );
348348 }
349349
350- Path resolveRelativeToBaseDir (String path , String defaultPath ) {
351- return dir .resolve (path == null ? defaultPath : stripProjectBasedirPrefix (path , PROJECT_BASEDIR ));
350+ Path resolveRelativeToBaseDir (String pathStr , String defaultPath ) {
351+ if (pathStr == null ) {
352+ return dir .resolve (defaultPath );
353+ }
354+ var path = resolveProjectPropertyPathOrNull (pathStr );
355+ return path == null ? dir .resolve (pathStr ) : path ;
356+ }
357+
358+ private Path resolveRelativeToBuildDir (String pathStr , String defaultPath ) {
359+ if (pathStr == null ) {
360+ return getOutputDir ().resolve (defaultPath );
361+ }
362+ var path = resolveProjectPropertyPathOrNull (pathStr );
363+ return path == null ? getOutputDir ().resolve (pathStr ) : path ;
364+ }
365+
366+ private Path resolveRelativeToDir (Path baseDir , String pathStr ) {
367+ if (pathStr == null ) {
368+ return baseDir ;
369+ }
370+ var path = resolveProjectPropertyPathOrNull (pathStr );
371+ return path == null ? baseDir .resolve (pathStr ) : path ;
372+ }
373+
374+ Path resolveProjectPropertyPathOrNull (String pathStr ) {
375+ final int propertyStart = getProjectPropertySuffixIndex (pathStr );
376+ if (propertyStart >= 0 ) {
377+ String relativePath = getRelativePath (pathStr , propertyStart , "basedir}" );
378+ if (relativePath != null ) {
379+ return relativePath .isEmpty () ? dir : dir .resolve (relativePath );
380+ }
381+ relativePath = getRelativePath (pathStr , propertyStart , "build.directory}" );
382+ if (relativePath != null ) {
383+ return relativePath .isEmpty () ? getOutputDir () : getOutputDir ().resolve (relativePath );
384+ }
385+ relativePath = getRelativePath (pathStr , propertyStart , "build.outputDirectory}" );
386+ if (relativePath != null ) {
387+ return relativePath .isEmpty () ? getClassesDir () : getClassesDir ().resolve (relativePath );
388+ }
389+ }
390+ return null ;
352391 }
353392
354- private Path resolveRelativeToBuildDir (String path , String defaultPath ) {
355- return getOutputDir ().resolve (path == null ? defaultPath : stripProjectBasedirPrefix (path , PROJECT_BUILD_DIR ));
393+ private static String getRelativePath (String pathStr , int elementStart , String pathElement ) {
394+ if (!pathStr .regionMatches (elementStart , pathElement , 0 , pathElement .length ())) {
395+ return null ;
396+ }
397+ return pathStr .length () == elementStart + pathElement .length () ? ""
398+ : pathStr .substring (elementStart + pathElement .length () + 1 );
356399 }
357400
358- static String stripProjectBasedirPrefix (String path , String expr ) {
359- return path .startsWith (expr ) ? path .substring (expr .length () + 1 ) : path ;
401+ private static int getProjectPropertySuffixIndex (String pathStr ) {
402+ final String projectProdPrefix = "${project." ;
403+ // we are not using startWith here because, apparently, there could be preceding '/' characters, although it doesn't seem to make sense
404+ final int propertyStart = pathStr .indexOf (projectProdPrefix );
405+ return propertyStart < 0 ? propertyStart : propertyStart + projectProdPrefix .length ();
360406 }
361407
362408 private static String configuredBuildDir (LocalProject project , Function <Build , String > f ) {
@@ -368,11 +414,6 @@ private static String configuredBuildDir(LocalProject project, Function<Build, S
368414 }
369415 if (project .rawModel .getBuild () != null ) {
370416 dir = f .apply (project .rawModel .getBuild ());
371- // in case the "raw" model is passed in from the reactor by the QuarkusBootstrapProvider,
372- // the Build will contain an effective config, so we need to take the relative path
373- if (dir != null ) {
374- // TODO
375- }
376417 }
377418 }
378419 return dir ;
@@ -483,7 +524,7 @@ private boolean addSourceSetsFromPlugins(List<Plugin> plugins, WorkspaceModule.M
483524 final List <String > list = new ArrayList <>(elements .length );
484525 for (Xpp3Dom element : elements ) {
485526 for (String s : element .getValue ().split ("," )) {
486- list .add (stripProjectBasedirPrefix ( s , PROJECT_BASEDIR ));
527+ list .add (resolveRelativeToBaseDir ( s ). toString ( ));
487528 }
488529 }
489530 moduleBuilder .setAdditionalTestClasspathElements (list );
@@ -573,8 +614,9 @@ private static String getClassifier(Xpp3Dom dom, boolean test) {
573614 }
574615
575616 private Collection <SourceDir > collectMainResources (PathFilter filter ) {
576- final List <Resource > resources = rawModel .getBuild () == null ? List .of ()
577- : rawModel .getBuild ().getResources ();
617+ final Model model = effectiveModel == null ? rawModel : effectiveModel ;
618+ final List <Resource > resources = model .getBuild () == null ? List .of ()
619+ : model .getBuild ().getResources ();
578620 final Path classesDir = getClassesDir ();
579621 final Path generatedSourcesDir = getGeneratedSourcesDir ();
580622 if (resources .isEmpty ()) {
@@ -590,22 +632,21 @@ private Collection<SourceDir> collectMainResources(PathFilter filter) {
590632 new DefaultSourceDir (
591633 new DirectoryPathTree (resolveRelativeToBaseDir (r .getDirectory (), SRC_MAIN_RESOURCES )),
592634 new DirectoryPathTree ((r .getTargetPath () == null ? classesDir
593- : classesDir . resolve ( stripProjectBasedirPrefix ( r .getTargetPath (), PROJECT_OUTPUT_DIR ))),
635+ : resolveRelativeToDir ( classesDir , r .getTargetPath ())),
594636 filter ),
595637 new DirectoryPathTree ((r .getTargetPath () == null ? generatedSourcesDir
596- : generatedSourcesDir .resolve (
597- stripProjectBasedirPrefix (r .getTargetPath (), PROJECT_GENERATED_SOURCES_DIR ))),
638+ : resolveRelativeToDir (generatedSourcesDir , r .getTargetPath ())),
598639 filter ),
599640 Map .of ()));
600641 }
601642 return sourceDirs ;
602643 }
603644
604645 private Collection <SourceDir > collectTestResources (PathFilter filter ) {
605- final List <Resource > resources = rawModel .getBuild () == null ? List .of ()
606- : rawModel .getBuild ().getTestResources ();
646+ final Model model = effectiveModel == null ? rawModel : effectiveModel ;
647+ final List <Resource > resources = model .getBuild () == null ? List .of ()
648+ : model .getBuild ().getTestResources ();
607649 final Path testClassesDir = getTestClassesDir ();
608- final Path generatedSourcesDir = getGeneratedSourcesDir ();
609650 if (resources .isEmpty ()) {
610651 return List .of (new DefaultSourceDir (
611652 new DirectoryPathTree (resolveRelativeToBaseDir (null , SRC_TEST_RESOURCES )),
@@ -620,7 +661,7 @@ private Collection<SourceDir> collectTestResources(PathFilter filter) {
620661 new DefaultSourceDir (
621662 new DirectoryPathTree (resolveRelativeToBaseDir (r .getDirectory (), SRC_TEST_RESOURCES )),
622663 new DirectoryPathTree ((r .getTargetPath () == null ? testClassesDir
623- : testClassesDir . resolve ( stripProjectBasedirPrefix ( r .getTargetPath (), PROJECT_OUTPUT_DIR ))),
664+ : resolveRelativeToDir ( testClassesDir , r .getTargetPath ())),
624665 filter ),
625666 // FIXME: do tests have generated sources?
626667 null ,
0 commit comments