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: notifications@ant.apache.org
          Reporter: jfm0...@gmail.com
  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.

Reply via email to