gpt4 book ai didi

java - 生成 Ant 构建文件

转载 作者:数据小太阳 更新时间:2023-10-29 02:05:53 25 4
gpt4 key购买 nike

我有以下项目结构:

root/
comp/
env/
version/
build.xml
build.xml
build.xml

root/comp/env/version/build.xml 是:

<project name="comp-env-version" basedir=".">
<import file="../build.xml" optional="true" />
<echo>Comp Env Version tasks</echo>
<target name="run">
<echo>Comp Env Version run task</echo>
</target>
</project>

root/comp/env/build.xml 是:

<project name="comp-env" basedir=".">
<import file="../build.xml" optional="true" />
<echo>Comp Env tasks</echo>
<target name="run">
<echo>Comp Env run task</echo>
</target>
</project>

root/comp/build.xml 是:

<project name="comp" basedir=".">
<echo>Comp tasks</echo>
</project>

每个构建文件都导入父构建文件,每个子构建文件继承覆盖父任务/属性。

我需要的是在不运行任何东西的情况下获取生成的构建 XML

例如,如果我在 root/comp/env/version/上运行“ant”(或类似的东西),我想获得以下输出:

<project name="comp-env-version" basedir=".">
<echo>Comp tasks</echo>
<echo>Comp Env tasks</echo>
<echo>Comp Env Version tasks</echo>
<target name="run">
<echo>Comp Env Version run task</echo>
</target>
</project>

是否有 Ant 插件可以执行此操作?与马文?如果没有,我有什么选择?

编辑:我需要 Ant 的“mvn help:effective-pom”之类的东西。

最佳答案

基于 import task 的描述,它的工作方式非常像一个包含两个附加功能的实体:

  • 目标覆盖
  • 特殊属性

为了查看“有效构建”,我认为不需要特殊属性处理(尽管可以通过迭代插入的目标来添加)。所以实现这个的处理就变成了。

  1. 将 build.xml 解析为 DOM
    • 对于找到的每个顶级包含标签(只允许顶级),找到引用的源文件。
    • 解析引用的build.xml
    • 插入引用的 build.xml 中不与当前文件中的内容冲突的任何内容。
    • 对引用的 build.xml 文件重复第 2 步,直到找不到更多
    • 输出结果DOM

您可以定义自定义 Ant 任务,以便可以在要从您的构建中运行的任务中定义此处理。看这个tutorial了解更多详情。

这是一个基本实现,它通过导入递归并从引用的文件中插入 DOM 元素。当我把它放在一起时,几乎可以肯定它有一些错误,但它应该主要完成你所追求的:

/**
* Reads the build.xml and outputs the resolved build to stdout
*/
public static void main(String[] args) {
try {
Element root = new EffectiveBuild().parse(new File(args[0]));

XMLOutputter outputter = new XMLOutputter(Format.getPrettyFormat());

outputter.output(root, System.out);
} catch (Exception e) {
// TODO handle errors
e.printStackTrace();
}

}

/**
* Get the DOM for the passed file and iterate all imports, replacing with
* non-duplicate referenced content
*/
private Element parse(File buildFile) throws JDOMException, IOException {
Element root = getRootElement(buildFile);

List<Element> imports = root.getChildren("import");

for (int i = 0; i < imports.size(); i++) {
Element element = imports.get(i);

List<Content> importContent = parseImport(element, root, buildFile);

int replaceIndex = root.indexOf(element);

root.addContent(replaceIndex, importContent);

root.removeContent(element);
}

root.removeChildren("import");

return root;
}

/**
* Get the imported file and merge it into the parent.
*/
private List<Content> parseImport(Element element, Element currentRoot,
File buildFile) throws JDOMException, IOException {
String importFileName = element.getAttributeValue("file");
File importFile = new File(buildFile.getParentFile(), importFileName)
.getAbsoluteFile();
if (importFileName != null) {
Element importRoot = getRootElement(importFile);

return getImportContent(element, currentRoot, importRoot,
importFile);
}

return Collections.emptyList();
}

/**
* Replace the passed element with the content of the importRoot
* (not the project tag)
*/
private List<Content> getImportContent(Element element,
Element currentRoot, Element importRoot, File buildFile)
throws JDOMException, IOException {

if (currentRoot != null) {
// copy all the reference import elements to the parent if needed
List<Content> childNodes = importRoot.cloneContent();
List<Content> importContent = new ArrayList<Content>();

for (Content content : childNodes) {
if (content instanceof Element
&& ((Element) content).getName().equals("import")) {
importContent.addAll(parseImport((Element) content,
currentRoot, buildFile));
}
if (!existsInParent(currentRoot, content)) {
importContent.add(content);
} else {
// TODO note the element was skipped
}
}

return importContent;
}

return Collections.emptyList();
}

/**
* Return true if the content already defined in the parent
*/
private boolean existsInParent(Element parent, Content content) {
if (content instanceof Text) {
if (((Text) content).getText().trim().length() == 0) {
// let the pretty printer deal with the whitespace
return false;
}
return true;
}
if (content instanceof Element) {
String id = ((Element) content).getAttributeValue("name");

String name = ((Element) content).getName();
List<Content> parentContent = parent.getChildren();

if (id != null) {
for (Content content2 : parentContent) {
if (content2 instanceof Element
&& ((Element) content2).getName().equals(name)) {
String parentId = ((Element) content2)
.getAttributeValue("name");

if (parentId != null && parentId.equals(id)) {
return true;
}
}
}
}
}
return false;
}

/**
* Parse the passed file.
*/
private Element getRootElement(File buildFile) throws JDOMException,
IOException {
SAXBuilder builder = new SAXBuilder();
builder.setValidation(false);
builder.setIgnoringElementContentWhitespace(true);
Document doc = builder.build(buildFile);

Element root = doc.getRootElement();
return root;
}

关于java - 生成 Ant 构建文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1469786/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com