Skip to content

Commit bef10a1

Browse files
aschemanclaude
andcommitted
Extract shared method for main/test resource handling
Refactor duplicate resource handling code into a shared method: - Add ResourceHandlingContext record to group shared parameters - Add handleResourceConfiguration method (4 parameters vs 9) - Remove unused outputDirectory param from createModularResourceRoot - Replace ~120 lines of duplicate code with 7 lines This addresses PR review comment #1 about code duplication between main and test resource handling blocks. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <[email protected]>
1 parent 0c2451e commit bef10a1

File tree

1 file changed

+114
-130
lines changed

1 file changed

+114
-130
lines changed

impl/maven-core/src/main/java/org/apache/maven/project/DefaultProjectBuilder.java

Lines changed: 114 additions & 130 deletions
Original file line numberDiff line numberDiff line change
@@ -720,133 +720,13 @@ private void initProject(MavenProject project, ModelBuilderResult result) {
720720
modules,
721721
isModularProject);
722722

723-
/*
724-
* Handle main resources - modular project has highest priority:
725-
* 1. Modular project: use resources from <sources> if present, otherwise inject defaults
726-
* 2. Classic project: use resources from <sources> if present, otherwise use legacy <resources>
727-
*/
728-
List<Resource> resources = project.getBuild().getDelegate().getResources();
729-
if (isModularProject) {
730-
if (hasMainResources) {
731-
// Modular project with resources configured via <sources> - already added above
732-
if (hasExplicitLegacyResources(resources, baseDir, ProjectScope.MAIN.id())) {
733-
logger.warn("Legacy <resources> element is ignored because main resources are "
734-
+ "configured via <source><lang>resources</lang></source> in <sources>");
735-
}
736-
logger.debug(
737-
"Main resources configured via <sources> element, ignoring legacy <resources> element");
738-
} else {
739-
// Modular project without resources in <sources> - inject module-aware defaults
740-
if (hasExplicitLegacyResources(resources, baseDir, ProjectScope.MAIN.id())) {
741-
String message =
742-
"Legacy <resources> element is ignored because modular sources are configured. "
743-
+ "Use <source><lang>resources</lang></source> in <sources> for custom resource paths.";
744-
logger.warn(message);
745-
result.getProblemCollector()
746-
.reportProblem(new org.apache.maven.impl.model.DefaultModelProblem(
747-
message,
748-
Severity.WARNING,
749-
Version.V41,
750-
project.getModel().getDelegate(),
751-
-1,
752-
-1,
753-
null));
754-
}
755-
logger.debug("Injecting module-aware main resource roots for {} modules", modules.size());
756-
for (String module : modules) {
757-
Path resourcePath = baseDir.resolve("src")
758-
.resolve(module)
759-
.resolve(ProjectScope.MAIN.id())
760-
.resolve("resources");
761-
logger.debug(" - Adding main resource root: {} (module: {})", resourcePath, module);
762-
project.addSourceRoot(
763-
createModularResourceRoot(baseDir, module, ProjectScope.MAIN, outputDirectory));
764-
}
765-
}
766-
} else {
767-
// Classic (non-modular) project
768-
if (hasMainResources) {
769-
// Resources configured via <sources> - already added above
770-
if (hasExplicitLegacyResources(resources, baseDir, ProjectScope.MAIN.id())) {
771-
logger.warn("Legacy <resources> element is ignored because main resources are "
772-
+ "configured via <source><lang>resources</lang></source> in <sources>");
773-
}
774-
logger.debug(
775-
"Main resources configured via <sources> element, ignoring legacy <resources> element");
776-
} else {
777-
// Use legacy <resources> element
778-
logger.debug("Using explicit or default resources ({} resources configured)", resources.size());
779-
for (Resource resource : resources) {
780-
project.addSourceRoot(new DefaultSourceRoot(baseDir, ProjectScope.MAIN, resource));
781-
}
782-
}
783-
}
784-
785-
/*
786-
* Handle test resources - same priority as main resources:
787-
* 1. Modular project: use test resources from <sources> if present, otherwise inject defaults
788-
* 2. Classic project: use test resources from <sources> if present, otherwise use legacy <testResources>
789-
*/
790-
List<Resource> testResources = project.getBuild().getDelegate().getTestResources();
791-
if (isModularProject) {
792-
if (hasTestResources) {
793-
// Modular project with test resources configured via <sources> - already added above
794-
if (hasExplicitLegacyResources(testResources, baseDir, ProjectScope.TEST.id())) {
795-
logger.warn(
796-
"Legacy <testResources> element is ignored because test resources are "
797-
+ "configured via <source><lang>resources</lang><scope>test</scope></source> in <sources>");
798-
}
799-
logger.debug(
800-
"Test resources configured via <sources> element, ignoring legacy <testResources> element");
801-
} else {
802-
// Modular project without test resources in <sources> - inject module-aware defaults
803-
if (hasExplicitLegacyResources(testResources, baseDir, ProjectScope.TEST.id())) {
804-
String message =
805-
"Legacy <testResources> element is ignored because modular sources are configured. "
806-
+ "Use <source><lang>resources</lang><scope>test</scope></source> in <sources> for custom resource paths.";
807-
logger.warn(message);
808-
result.getProblemCollector()
809-
.reportProblem(new org.apache.maven.impl.model.DefaultModelProblem(
810-
message,
811-
Severity.WARNING,
812-
Version.V41,
813-
project.getModel().getDelegate(),
814-
-1,
815-
-1,
816-
null));
817-
}
818-
logger.debug("Injecting module-aware test resource roots for {} modules", modules.size());
819-
for (String module : modules) {
820-
Path resourcePath = baseDir.resolve("src")
821-
.resolve(module)
822-
.resolve(ProjectScope.TEST.id())
823-
.resolve("resources");
824-
logger.debug(" - Adding test resource root: {} (module: {})", resourcePath, module);
825-
project.addSourceRoot(
826-
createModularResourceRoot(baseDir, module, ProjectScope.TEST, outputDirectory));
827-
}
828-
}
829-
} else {
830-
// Classic (non-modular) project
831-
if (hasTestResources) {
832-
// Test resources configured via <sources> - already added above
833-
if (hasExplicitLegacyResources(testResources, baseDir, ProjectScope.TEST.id())) {
834-
logger.warn(
835-
"Legacy <testResources> element is ignored because test resources are "
836-
+ "configured via <source><lang>resources</lang><scope>test</scope></source> in <sources>");
837-
}
838-
logger.debug(
839-
"Test resources configured via <sources> element, ignoring legacy <testResources> element");
840-
} else {
841-
// Use legacy <testResources> element
842-
logger.debug(
843-
"Using explicit or default test resources ({} resources configured)",
844-
testResources.size());
845-
for (Resource resource : testResources) {
846-
project.addSourceRoot(new DefaultSourceRoot(baseDir, ProjectScope.TEST, resource));
847-
}
848-
}
849-
}
723+
// Handle main and test resources using shared method
724+
ResourceHandlingContext ctx =
725+
new ResourceHandlingContext(project, baseDir, modules, isModularProject, result);
726+
handleResourceConfiguration(
727+
ctx, project.getBuild().getDelegate().getResources(), hasMainResources, ProjectScope.MAIN);
728+
handleResourceConfiguration(
729+
ctx, project.getBuild().getDelegate().getTestResources(), hasTestResources, ProjectScope.TEST);
850730
}
851731

852732
project.setActiveProfiles(
@@ -1240,6 +1120,112 @@ public Set<Entry<K, V>> entrySet() {
12401120
}
12411121
}
12421122

1123+
/**
1124+
* Context object for resource handling configuration.
1125+
* Groups parameters shared between main and test resource handling to reduce method parameter count.
1126+
*/
1127+
private record ResourceHandlingContext(
1128+
MavenProject project,
1129+
Path baseDir,
1130+
Set<String> modules,
1131+
boolean modularProject,
1132+
ModelBuilderResult result) {}
1133+
1134+
/**
1135+
* Handles resource configuration for a given scope (main or test).
1136+
* This method applies the resource priority rules:
1137+
* <ol>
1138+
* <li>Modular project: use resources from &lt;sources&gt; if present, otherwise inject defaults</li>
1139+
* <li>Classic project: use resources from &lt;sources&gt; if present, otherwise use legacy resources</li>
1140+
* </ol>
1141+
*
1142+
* @param ctx the resource handling context containing project info
1143+
* @param resources the legacy resource list (from &lt;resources&gt; or &lt;testResources&gt;)
1144+
* @param hasResourcesInSources whether resources are configured via &lt;sources&gt;
1145+
* @param scope the project scope (MAIN or TEST)
1146+
*/
1147+
private void handleResourceConfiguration(
1148+
ResourceHandlingContext ctx, List<Resource> resources, boolean hasResourcesInSources, ProjectScope scope) {
1149+
1150+
String scopeId = scope.id();
1151+
String scopeName = scope == ProjectScope.MAIN ? "Main" : "Test";
1152+
String legacyElement = scope == ProjectScope.MAIN ? "<resources>" : "<testResources>";
1153+
String sourcesConfig = scope == ProjectScope.MAIN
1154+
? "<source><lang>resources</lang></source>"
1155+
: "<source><lang>resources</lang><scope>test</scope></source>";
1156+
1157+
if (ctx.modularProject()) {
1158+
if (hasResourcesInSources) {
1159+
// Modular project with resources configured via <sources> - already added above
1160+
if (hasExplicitLegacyResources(resources, ctx.baseDir(), scopeId)) {
1161+
logger.warn(
1162+
"Legacy {} element is ignored because {} resources are configured via {} in <sources>",
1163+
legacyElement,
1164+
scopeId,
1165+
sourcesConfig);
1166+
}
1167+
logger.debug(
1168+
"{} resources configured via <sources> element, ignoring legacy {} element",
1169+
scopeName,
1170+
legacyElement);
1171+
} else {
1172+
// Modular project without resources in <sources> - inject module-aware defaults
1173+
if (hasExplicitLegacyResources(resources, ctx.baseDir(), scopeId)) {
1174+
String message = "Legacy " + legacyElement
1175+
+ " element is ignored because modular sources are configured. "
1176+
+ "Use " + sourcesConfig + " in <sources> for custom resource paths.";
1177+
logger.warn(message);
1178+
ctx.result()
1179+
.getProblemCollector()
1180+
.reportProblem(new org.apache.maven.impl.model.DefaultModelProblem(
1181+
message,
1182+
Severity.WARNING,
1183+
Version.V41,
1184+
ctx.project().getModel().getDelegate(),
1185+
-1,
1186+
-1,
1187+
null));
1188+
}
1189+
logger.debug(
1190+
"Injecting module-aware {} resource roots for {} modules",
1191+
scopeId,
1192+
ctx.modules().size());
1193+
for (String module : ctx.modules()) {
1194+
Path resourcePath = ctx.baseDir()
1195+
.resolve("src")
1196+
.resolve(module)
1197+
.resolve(scopeId)
1198+
.resolve("resources");
1199+
logger.debug(" - Adding {} resource root: {} (module: {})", scopeId, resourcePath, module);
1200+
ctx.project().addSourceRoot(createModularResourceRoot(ctx.baseDir(), module, scope));
1201+
}
1202+
}
1203+
} else {
1204+
// Classic (non-modular) project
1205+
if (hasResourcesInSources) {
1206+
// Resources configured via <sources> - already added above
1207+
if (hasExplicitLegacyResources(resources, ctx.baseDir(), scopeId)) {
1208+
logger.warn(
1209+
"Legacy {} element is ignored because {} resources are configured via {} in <sources>",
1210+
legacyElement,
1211+
scopeId,
1212+
sourcesConfig);
1213+
}
1214+
logger.debug(
1215+
"{} resources configured via <sources> element, ignoring legacy {} element",
1216+
scopeName,
1217+
legacyElement);
1218+
} else {
1219+
// Use legacy resources element
1220+
logger.debug(
1221+
"Using explicit or default {} resources ({} resources configured)", scopeId, resources.size());
1222+
for (Resource resource : resources) {
1223+
ctx.project().addSourceRoot(new DefaultSourceRoot(ctx.baseDir(), scope, resource));
1224+
}
1225+
}
1226+
}
1227+
}
1228+
12431229
/**
12441230
* Extracts unique module names from the given list of source elements.
12451231
* A project is considered modular if it has at least one module name.
@@ -1263,11 +1249,9 @@ private static Set<String> extractModules(List<org.apache.maven.api.model.Source
12631249
* @param baseDir base directory of the project
12641250
* @param module module name
12651251
* @param scope project scope (main or test)
1266-
* @param outputDirectory function providing output directory for the scope
12671252
* @return configured DefaultSourceRoot for the module's resources
12681253
*/
1269-
private DefaultSourceRoot createModularResourceRoot(
1270-
Path baseDir, String module, ProjectScope scope, Function<ProjectScope, String> outputDirectory) {
1254+
private DefaultSourceRoot createModularResourceRoot(Path baseDir, String module, ProjectScope scope) {
12711255
Path resourceDir =
12721256
baseDir.resolve("src").resolve(module).resolve(scope.id()).resolve("resources");
12731257

0 commit comments

Comments
 (0)