英文:
Maven extension for adding profile
问题
Maven扩展是否能在构建过程中向POM添加额外的配置文件(profile)?
还是说在Maven扩展运行时,配置文件已经被解析?
请注意,我不是在谈论Maven插件,而是Maven扩展。
英文:
Can a Maven extension add an additional profile to a POM (during the build)?
Or are profiles already resolved when Maven extensions run?
Note that I am not talking about Maven plugins, but about Maven extensions.
答案1
得分: 2
以下是您提供的代码的翻译部分:
// 这是一个示例代码片段
@Component(role = ModelBuilder.class, hint = Hints.DEFAULT_HINT)
public class IMHModelBuilder extends DefaultModelBuilder implements ModelBuilder {
@Override
public ModelBuildingResult build(ModelBuildingRequest request) throws ModelBuildingException {
injectProfiles(request);
return super.build(request);
}
@Override
public ModelBuildingResult build(ModelBuildingRequest request, ModelBuildingResult result) throws ModelBuildingException {
injectProfiles(request);
return super.build(request, result);
}
@Override
public Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking) {
return super.buildRawModel(pomFile, validationLevel, locationTracking);
}
protected void injectProfiles(ModelBuildingRequest request) {
// 代码部分...
}
protected InputStream injectProfiles(InputStream inputStream) throws XmlPullParserException, IOException {
// 代码部分...
}
protected String buildProfile() {
// 代码部分...
}
class ProfileAwareSource implements ModelSource2 {
// 代码部分...
}
}
请注意,这是您提供的代码的翻译部分,不包括代码的详细描述或评论。如果您需要其他帮助,请随时告诉我。
英文:
I do see following option there: try to modify raw xml prior building project object model, something like:
@Component(role = ModelBuilder.class, hint = Hints.DEFAULT_HINT)
public class IMHModelBuilder extends DefaultModelBuilder implements ModelBuilder {
@Override
public ModelBuildingResult build(ModelBuildingRequest request) throws ModelBuildingException {
injectProfiles(request);
return super.build(request);
}
@Override
public ModelBuildingResult build(ModelBuildingRequest request, ModelBuildingResult result) throws ModelBuildingException {
injectProfiles(request);
return super.build(request, result);
}
@Override
public Result<? extends Model> buildRawModel(File pomFile, int validationLevel, boolean locationTracking) {
return super.buildRawModel(pomFile, validationLevel, locationTracking);
}
protected void injectProfiles(ModelBuildingRequest request) {
File pomFile = request.getPomFile();
if (pomFile == null) {
// todo: does the absence of pom file means
// we encountered parent/dependency pom?
return;
}
// todo: do we need to pay attention to request#getRawModel?
// todo: do we need to pay attention to request#getModelSource?
request.setModelSource(new ProfileAwareSource(new FileModelSource(pomFile)));
}
protected InputStream injectProfiles(InputStream inputStream) throws XmlPullParserException, IOException {
MavenXpp3Reader reader = new MavenXpp3Reader();
Model projectModel = reader.read(inputStream);
Model profileModel = reader.read(new StringReader(buildProfile()), false);
Profile profile = profileModel.getProfiles().get(0);
// todo: merge with the existing ones
projectModel.getProfiles().add(profile);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
MavenXpp3Writer writer = new MavenXpp3Writer();
writer.write(baos, projectModel);
return new ByteArrayInputStream(baos.toByteArray());
}
protected String buildProfile() {
return "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
"<project>\n" +
" <modelVersion>4.0.0</modelVersion>\n" +
" <groupId>org.apache.maven</groupId>\n" +
" <artifactId>standalone-pom</artifactId>\n" +
" <version>1</version>\n" +
" <packaging>pom</packaging>\n" +
" <name>Maven Stub Project (No POM)</name>\n" +
" <profiles>\n" +
" <profile>\n" +
" <id>myprofile</id>\n" +
" </profile>\n" +
" </profiles>\n" +
"</project>\n";
}
class ProfileAwareSource implements ModelSource2 {
private final ModelSource2 origSource;
public ProfileAwareSource(ModelSource2 origSource) {
this.origSource = origSource;
}
@Override
public ModelSource2 getRelatedSource(String relPath) {
return new ProfileAwareSource(origSource.getRelatedSource(relPath));
}
@Override
public URI getLocationURI() {
return origSource.getLocationURI();
}
@Override
public InputStream getInputStream() throws IOException {
try (InputStream stream = origSource.getInputStream()) {
return injectProfiles(stream);
} catch (XmlPullParserException ex) {
throw new IOException(ex);
}
}
@Override
public String getLocation() {
return origSource.getLocation();
}
}
}
IMO, in case of this approach there are following challenging parts:
- need figure out what type of model is currently being built: module, parent, aggregator or dependency
- need somehow merge profile to be injected with the existing ones
- I have no idea how that will work with other plugins which are "modifying" POM (
flatten-maven-plugin
, for example)
pros: such approach seems to be less invasive - even IntelliJ
recognises new profile, although it's maven support is very poor.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论