使用MavenXpp3Writer编写pom文件时保留项目结构[元素顺序]

时间:2014-02-25 09:39:04

标签: git maven

在我的用例中,我需要在运行时更新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提交。

有没有办法实现这个目标。?

1 个答案:

答案 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);