在我的用例中,我需要在运行时更新pom文件中的某些项目属性值。 因此我使用的代码是这样的。
MavenXpp3Reader reader = new MavenXpp3Reader();
pomStream = new FileInputStream(pomF);
Model model = reader.read(pomStream);
// update properties
model.setProperties(modelProperties);
MavenXpp3Writer writer = new MavenXpp3Writer();
writer.write(new FileWriter(pomF), model);
当我这样做时,pom文件的元素被完全重新排列。我需要保留结构并简单地更新属性,因为我需要执行更改文件的git提交。
有没有办法实现这个目标。?
答案 0 :(得分:1)
问题在于属性是在java.util.Properties
内读取的,并且由于它是基于哈希表的,因此写入文件时特定属性的顺序不是“读取优先顺序”,而是由以下项的确定哈希表的哈希值,它是确定性的,但很可能不是xml文件中定义的顺序。
作为一种解决方法,类MavenXpp3ReaderEx
维护从XML文件读取的内容InputLocation
:保存标记的行号和列号。
此groovy脚本显示了如何使用行号强制以与原始pom.xml文件相同的顺序写入属性(此脚本的Java版本应易于调整):
import org.apache.maven.model.Model;
import org.apache.maven.model.io.xpp3.*;
@Grapes(
@Grab(group='org.apache.maven', module='maven-model', version='3.3.9')
)
def f = new File(args[0]);
def reader = new MavenXpp3ReaderEx();
def model = reader.read(f.newInputStream(), true, null);
// your modifications
model.getProperties().put("plexusVersion","99.99");
// reorder properties keys by line number
def locations = model.getLocation( "properties" );
def mapByLine = new TreeMap();
model.getProperties().each { key, val ->
def loc = locations.getLocation(key);
mapByLine.put(loc.getLineNumber(), key);
}
def newProps = new Properties() {
public Set keySet() {
return new LinkedHashSet(mapByLine.values());
}
}
newProps.putAll(model.getProperties());
model.setProperties(newProps);
def writer = new MavenXpp3Writer();
def fout = new File("output-pom.xml");
writer.write(fout.newOutputStream(), model);