https://bz.apache.org/bugzilla/show_bug.cgi?id=65327
Bug ID: 65327
Summary: XMLProperties
Product: Ant
Version: unspecified
Hardware: Other
OS: All
Status: NEW
Severity: enhancement
Priority: P2
Component: Props Antlib
Assignee: [email protected]
Reporter: [email protected]
Target Milestone: ---
=====================================
File Test.java
import org.apache.tools.ant.Project;
import junix.ant.tasks.XmlPropsTask;
public class Test {
public static void main(String[] args) {
XmlPropsTask t = new XmlPropsTask();
t.setFile("properties.xml");
t.setPrefix("a.");
t.setExpression("/properties/a/@*");
t.setVerbose("true");
Project p = new Project();
t.setProject(p);
t.execute();
}
}
======================================
File XmlPropsTask.java
/*
* Copyright (c) 2021 Jean-Francois Martel v202105151146. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* http://www.opensource.org/licenses/mit-license.php
*/
package junix.ant.tasks;
import java.io.File;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.tools.ant.Task;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import junix.xml.XPathParser;
public class XmlPropsTask extends Task {
private String file;
private String prefix;
private String expression;
private boolean verbose;
HashMap<String, String> propsList = new HashMap<String, String>();
public void setVerbose(String verbose) {
this.verbose = Boolean.parseBoolean(verbose);
}
public void setFile(String file) {
this.file = file;
}
public void setPrefix(String prefix) {
this.prefix = prefix;
}
public void setExpression(String expression) {
this.expression = expression;
}
public void execute() {
Hashtable<String, Object> props = getProject().getProperties();
props.forEach((k, v) -> {
propsList.put(k.toString(), v.toString());
});
if(verbose)
getProject().log(this.getTaskName()+" parse:"+new
File(file).getAbsolutePath());
setXMLProps();
propsList.forEach((k, v) -> {
getProject().setNewProperty(k.toString(),
v.toString());
});
}
private void setXMLProps() {
final Pattern pattern = Pattern.compile("[$][{](.+?)[}]",
Pattern.DOTALL);
HashSet<String> replaceList = new HashSet<String>();
XPathParser xpp = new XPathParser();
Document doc = xpp.getDocument(file);
NodeList nodeList = xpp.getNodeList(expression, doc);
if (prefix != null)
for (int i = 0; i < nodeList.getLength(); i++) {
Node value = nodeList.item(i);
propsList.put(prefix + value.getNodeName(),
value.getNodeValue());
}
propsList.forEach((k, v) -> {
Matcher matcher = pattern.matcher(v.toString());
while (matcher.find()) {
replaceList.add(matcher.group(1));
}
});
int limit = 3;
int count = 0;
while (replaceList.size() != 0) {
replaceVariables(pattern, replaceList, propsList);
if (count > limit)
break;
count++;
}
}
private void replaceVariables(final Pattern pattern, HashSet<String>
replaceList,
HashMap<String, String> propsList) {
propsList.forEach((k, v) -> {
String oldValue = v.toString();
if (oldValue.contains("${")) {
Matcher matcher =
pattern.matcher(v.toString());
while (matcher.find()) {
String matche = matcher.group(1);
String replacement =
propsList.get(matche);
if (replacement != null)
if
(!replacement.contains("${")) {
String newValue =
oldValue.replace("${" + matche + "}", replacement);
if(verbose) {
System.out.println("M:"+ matche );
System.out.println("V:"+k.toString());
System.out.println("N:"+newValue);
}
propsList.put(k.toString(), newValue);
}
}
} else {
replaceList.remove(k.toString());
}
});
}
}
=========================
File XPathParser.java
/*
* Copyright (c) 2021 Jean-Francois Martel v202105151146. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the MIT License which is available at
* http://www.opensource.org/licenses/mit-license.php
*/
package junix.xml;
import static java.util.stream.Collectors.toList;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class XPathParser {
public static String[] getValues(XPathParser xpathParser, Document doc,
String expression, String itemName)
throws XPathExpressionException {
List<String> valuesList = new ArrayList<>();
NodeList nodeList = xpathParser.getNodeList(expression, doc);
for (int i = 0; i < nodeList.getLength(); i++) {
String value = xpathParser.getNodeValue(itemName, i,
nodeList);
valuesList.add(value);
}
return valuesList.toArray(new String[valuesList.size()]);
}
public Document getDocument(String fileName) {
DocumentBuilderFactory factory =
DocumentBuilderFactory.newInstance();
DocumentBuilder builder;
Document doc = null;
try {
builder = factory.newDocumentBuilder();
doc = builder.parse(new File(fileName));
} catch (ParserConfigurationException | SAXException |
IOException e) {
e.printStackTrace();
}
return doc;
}
public String[] getNode(String itemName, NodeList nodeList) throws
XPathExpressionException {
String[] results = new String[nodeList.getLength()];
for (int index = 0; index < nodeList.getLength(); index++) {
Node node = nodeList.item(index);
Node name =
node.getAttributes().getNamedItem(itemName);
results[index] = name.getNodeValue();
}
return results;
}
public NodeList getNodeList(String expression, Document doc) {
XPath xPath = XPathFactory.newInstance().newXPath();
NodeList nodeList = null;
try {
nodeList = (NodeList) xPath.compile(expression).evaluate(doc,
XPathConstants.NODESET);
} catch (Exception e) {
e.printStackTrace();
}
return nodeList;
}
public String getNodeValue(String itemName, int index, NodeList
nodeList) {
Node node = nodeList.item(index);
Node name = node.getAttributes().getNamedItem(itemName);
if (name == null)
return "";
return name.getNodeValue();
}
public static List<String> getValues(String path, String expression,
String itemName)
throws XPathExpressionException {
XPathParser xpathParser = new XPathParser();
Document doc = xpathParser.getDocument(path);
return Arrays.stream(XPathParser.getValues(xpathParser, doc,
expression, itemName)).map(String::valueOf)
.collect(toList());
}
}
==============
File: build.xml
<project name="test xmlprops" default="default"
xmlns:if="ant:if"
xmlns:unless="ant:unless"
basedir="."
>
<taskdef name="xmlprops" classname="junix.ant.tasks.XmlPropsTask"
onerror="ignore">
<classpath>
<pathelement path="target/classes/"/>
</classpath>
</taskdef>
<target name="default">
<xmlproperty file="properties.xml" keeproot="false"
rootdirectory="properties" collapseattributes="true" />
<echoproperties format="text" prefix="a."/>
</target>
<target name="custom xml xmlproperty">
<xmlprops file="properties.xml" prefix="a."
expression="/properties/a/@*" verbose="false" />
<echoproperties format="text" prefix="a." />
</target>
</project>
=================
File: properties.xml
<?xml version="1.0" encoding="UTF-8"?>
<properties><a
c= "C"
b= "B ${a.a}"
a= "A"
d= "D ${a.c}"
g= "G ${a.c}"
/>
</properties>
--
You are receiving this mail because:
You are the assignee for the bug.