Java 如何将maven构建文件的各个部分外部化?
我遇到了一个问题:如何将配置文件的版本设置为XML格式。最简单的方法是编写XSLT更新。应用程序的每个版本都有自己的XSLT更新。所有这些更新文件都足够小,可以由IDE管理,特别是它的DIFF工具 由于该项目已经作为Maven2开发,Java逻辑解决方案是通过maven构建文件触发这些更新 这是今天应用一组更新的部分的外观:Java 如何将maven构建文件的各个部分外部化?,java,maven-2,refactoring,maven-plugin,Java,Maven 2,Refactoring,Maven Plugin,我遇到了一个问题:如何将配置文件的版本设置为XML格式。最简单的方法是编写XSLT更新。应用程序的每个版本都有自己的XSLT更新。所有这些更新文件都足够小,可以由IDE管理,特别是它的DIFF工具 由于该项目已经作为Maven2开发,Java逻辑解决方案是通过maven构建文件触发这些更新 这是今天应用一组更新的部分的外观: <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<configuration>
<transformationSets>
<transformationSet>
<dir>config/xsltUpdates/input</dir>
<stylesheet>config/xsltUpdates/update1-8-3.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-8-3</outputDir>
</transformationSet>
<transformationSet>
<dir>config/xsltUpdates/update1-8-3</dir>
<stylesheet>config/xsltUpdates/update1-8-9.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-8-9</outputDir>
</transformationSet>
<transformationSet>
<dir>config/xsltUpdates/update1-8-9</dir>
<stylesheet>config/xsltUpdates/update1-9-0.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-9-0</outputDir>
</transformationSet>
<transformationSet>
<dir>config/xsltUpdates/update1-9-0</dir>
<stylesheet>config/xsltUpdates/update1-10-0.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-10-0</outputDir>
</transformationSet>
<transformationSet>
<dir>config/xsltUpdates/update1-10-0</dir>
<stylesheet>config/xsltUpdates/update1-10-0-1.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-10-0-1</outputDir>
</transformationSet>
<transformationSet>
<dir>config/xsltUpdates/update1-10-0-1</dir>
<stylesheet>config/xsltUpdates/update1-10-0-2.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-10-0-2</outputDir>
</transformationSet>
<transformationSet>
<dir>config/xsltUpdates/update1-10-0-2</dir>
<stylesheet>config/xsltUpdates/updateCurrent.xsl</stylesheet>
<outputDir>config/xsltUpdates/output</outputDir>
</transformationSet>
</transformationSets>
</configuration>
<dependencies>
<dependency>
<groupId>net.sf.saxon</groupId>
<artifactId>saxon</artifactId>
<version>8.7</version>
</dependency>
</dependencies>
</plugin>
org.codehaus.mojo
xml maven插件
编译
使改变
config/xsltUpdates/input
config/xsltUpdates/update1-8-3.xsl
config/xsltUpdates/update1-8-3
config/xsltUpdates/update1-8-3
config/xsltUpdates/update1-8-9.xsl
config/xsltUpdates/update1-8-9
config/xsltUpdates/update1-8-9
config/xsltUpdates/update1-9-0.xsl
config/xsltUpdates/update1-9-0
config/xsltUpdates/update1-9-0
config/xsltUpdates/update1-10-0.xsl
config/xsltUpdates/update1-10-0
config/xsltUpdates/update1-10-0
config/xsltUpdates/update1-10-0-1.xsl
config/xsltUpdates/update1-10-0-1
config/xsltUpdates/update1-10-0-1
config/xsltUpdates/update1-10-0-2.xsl
config/xsltUpdates/update1-10-0-2
config/xsltUpdates/update1-10-0-2
config/xsltUpdates/updateCurrent.xsl
config/xsltUpdates/output
net.sf.saxon
撒克逊人
8.7
我想在一些属性/xml文件导入中具体化有关transformationSet的信息。我的pom.xml文件将更清晰,外部化信息更易于维护
我该怎么做
我可以在构建文件中使用一些迭代控制语句吗?有没有从外部文件导入数据的方法?可能还有其他方法,但您可以在父pom中有一个节 pluginManagement:是一个可以在插件旁边看到的元素。插件管理包含插件元素的方式与此基本相同,不同之处在于它不是为这个特定的项目构建配置插件信息,而是配置从这个项目构建继承的项目构建。但是,这仅配置在子元素的plugins元素中实际引用的插件。孩子们完全有权推翻插件管理的定义 例如: 父项目POM(需要运行mvn安装,以确保您的子项目可见)
4.0.0
org.nkl
父母亲
聚甲醛
0.0.1-快照
org.codehaus.mojo
xml maven插件
编译
使改变
config/xsltUpdates/input
config/xsltUpdates/update1-8-3.xsl
config/xsltUpdates/update1-8-3
config/xsltUpdates/update1-8-3
config/xsltUpdates/update1-8-9.xsl
config/xsltUpdates/update1-8-9
config/xsltUpdates/update1-8-9
config/xsltUpdates/update1-9-0.xsl
config/xsltUpdates/update1-9-0
config/xsltUpdates/update1-9-0
config/xsltUpdates/update1-10-0.xsl
config/xsltUpdates/update1-10-0
config/xsltUpdates/update1-10-0
config/xsltUpdates/update1-10-0-1.xsl
config/xsltUpdates/update1-10-0-1
config/xsltUpdates/update1-10-0-1
config/xsltUpdates/update1-10-0-2.xsl
config/xsltUpdates/update1-10-0-2
config/xsltUpdates/update1-10-0-2
config/xsltUpdates/updateCurrent.xsl
config/xsltUpdates/output
net.sf.saxon
撒克逊人
8.7
儿童项目POM
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>parent</artifactId>
<groupId>org.nkl</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.nkl</groupId>
<artifactId>child</artifactId>
<version>0.0.1-SNAPSHOT</version>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
父母亲
org.nkl
0.0.1-快照
4.0.0
org.nkl
小孩
0.0.1-快照
org.codehaus.mojo
xml maven插件
一些插件允许您使用外部描述符(例如。不幸的是,XMLMaven插件还不是其中之一
一种选择是从XMLMaven插件复制相关目标,并将maven共享io的处理嵌入目标。我一直在寻找自己这样做,以期对各种插件提出请求,使用描述符文件和Locator策略方法来查找描述符。下面是一些修改XMLMaven插件以允许使用描述符的处理。注意,所涉及的文件几乎没有验证,所以它有点脆弱,但它确实有效
1) 创建一个新的maven插件项目(称为xml ext maven插件),该项目具有以下依赖项:
<dependencies>
<dependency>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<version>1.0-beta-2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-2</version>
</dependency>
</dependencies>
4) 修改execute()方法以读取TransformationSet的描述符
public void execute() throws MojoExecutionException, MojoFailureException {
//insert at start of method to resolve transformationSets fronm descriptors
if (descriptors != null && descriptors.length > 0) {
transformationSets = readDescriptors(descriptors);
}
...
5) 实现readDescriptors(),允许您在类路径上或项目中定位描述符(读卡器处理主要从程序集插件的DefaultAssemblyReader中提升)。注意在这个实现中几乎没有验证,一个合适的插件会检查是否设置了值等
private TransformationSet[] readDescriptors(String[] descriptors)
throws MojoExecutionException {
List descriptorSets = new ArrayList();
// add all the existing transformationSets
if (transformationSets != null && transformationSets.length != 0) {
descriptorSets.addAll(Arrays.asList(transformationSets));
}
for (int i = 0; i < descriptors.length; i++) {
getLog().info(
"Reading transformation descriptor: " + descriptors[i]);
Location location = getLocation(descriptors[i]);
Reader reader = null;
try {
reader = new InputStreamReader(location.getInputStream(),
"UTF-8");
Xpp3Dom dom = Xpp3DomBuilder.build(reader);
descriptorSets.addAll(parseTransformationSets(dom));
} catch (IOException e) {
throw new MojoExecutionException(
"Error reading transformation descriptor: "
+ descriptors[i], e);
} catch (XmlPullParserException e) {
throw new MojoExecutionException(
"Error parsing transformation descriptor: "
+ descriptors[i], e);
} finally {
IOUtil.close(reader);
}
}
return (TransformationSet[]) descriptorSets
.toArray(new TransformationSet[descriptorSets.size()]);
}
/**
* Create transformationSets from the Xpp3Dom.
* TODO use plexus utilities to resolve these elegantly?
*/
private List parseTransformationSets(Xpp3Dom dom) {
// TODO validation of the input files!
Xpp3Dom[] setDoms = dom.getChildren("transformationSet");
List sets = new ArrayList();
for (int i = 0; i < setDoms.length; i++) {
TransformationSet set = new TransformationSet();
set.setDir(new File(setDoms[i].getChild("dir").getValue()));
set.setStylesheet(new File(setDoms[i].getChild("stylesheet")
.getValue()));
Xpp3Dom outDom = setDoms[i].getChild("outputDir");
if (outDom != null) {
set.setOutputDir(new File(outDom.getValue()));
}
sets.add(set);
}
return sets;
}
7) 重写asAbsoluteFile()以使用定位器策略解析文件(也允许我们在描述符项目中定义xsl文件)
8) 将插件安装到您的存储库中
9) 创建一个新的maven项目
public void execute() throws MojoExecutionException, MojoFailureException {
//insert at start of method to resolve transformationSets fronm descriptors
if (descriptors != null && descriptors.length > 0) {
transformationSets = readDescriptors(descriptors);
}
...
private TransformationSet[] readDescriptors(String[] descriptors)
throws MojoExecutionException {
List descriptorSets = new ArrayList();
// add all the existing transformationSets
if (transformationSets != null && transformationSets.length != 0) {
descriptorSets.addAll(Arrays.asList(transformationSets));
}
for (int i = 0; i < descriptors.length; i++) {
getLog().info(
"Reading transformation descriptor: " + descriptors[i]);
Location location = getLocation(descriptors[i]);
Reader reader = null;
try {
reader = new InputStreamReader(location.getInputStream(),
"UTF-8");
Xpp3Dom dom = Xpp3DomBuilder.build(reader);
descriptorSets.addAll(parseTransformationSets(dom));
} catch (IOException e) {
throw new MojoExecutionException(
"Error reading transformation descriptor: "
+ descriptors[i], e);
} catch (XmlPullParserException e) {
throw new MojoExecutionException(
"Error parsing transformation descriptor: "
+ descriptors[i], e);
} finally {
IOUtil.close(reader);
}
}
return (TransformationSet[]) descriptorSets
.toArray(new TransformationSet[descriptorSets.size()]);
}
/**
* Create transformationSets from the Xpp3Dom.
* TODO use plexus utilities to resolve these elegantly?
*/
private List parseTransformationSets(Xpp3Dom dom) {
// TODO validation of the input files!
Xpp3Dom[] setDoms = dom.getChildren("transformationSet");
List sets = new ArrayList();
for (int i = 0; i < setDoms.length; i++) {
TransformationSet set = new TransformationSet();
set.setDir(new File(setDoms[i].getChild("dir").getValue()));
set.setStylesheet(new File(setDoms[i].getChild("stylesheet")
.getValue()));
Xpp3Dom outDom = setDoms[i].getChild("outputDir");
if (outDom != null) {
set.setOutputDir(new File(outDom.getValue()));
}
sets.add(set);
}
return sets;
}
private Location getLocation(String path) {
List strategies = new ArrayList();
strategies.add(new RelativeFileLocatorStrategy(getBasedir()));
strategies.add(new ClasspathResourceLocatorStrategy());
strategies.add(new FileLocatorStrategy());
strategies.add(new URLLocatorStrategy());
List refStrategies = new ArrayList();
refStrategies.add(classpathStrategy);
Locator locator = new Locator();
locator.setStrategies(strategies);
Location location = locator.resolve(path);
return location;
}
protected File asAbsoluteFile(File f) {
String path = f.getPath();
// ensure we're getting a path in the form that URL can handle
if (path != null) {
path = path.replaceAll("\\\\", "/");
}
Location location = getLocation(path);
if (location == null) {
//can't find the file, let the parent implementation have a try
return super.asAbsoluteFile(f);
}
try {
return location.getFile();
} catch (IOException e) {
throw new RuntimeException("unable to read file " + f.getPath(), e);
}
}
<transformationSets>
<transformationSet>
<!--the config directory is in the root of the project -->
<dir>config/xsltUpdates/input</dir>
<!-- the stylesheet can be in the descriptor project-->
<stylesheet>/stylesheets/update1-8-3.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-8-3</outputDir>
</transformationSet>
<transformationSet>
<dir>config/xsltUpdates/update1-8-3</dir>
<stylesheet>/stylesheets/update1-8-9.xsl</stylesheet>
<outputDir>config/xsltUpdates/update1-8-9</outputDir>
</transformationSet>
</transformationSets>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>xml-maven-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>transform</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>name.seller.rich</groupId>
<artifactId>xml-ext-test-descriptor</artifactId>
<version>0.0.1</version>
</dependency>
</dependencies>
<configuration>
<descriptors>
<!-- will be resolved from xml-ext-test-descriptor -->
<descriptor>/transformationSet1.xml</descriptor>
</descriptors>
</plugin>