package droid;
import com.sun.org.apache.xpath.internal.XPathAPI;
import java.io.*;
import java.util.regex.PatternSyntaxException;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.apache.log4j.xml.Log4jEntityResolver;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
public class UpdateToken extends org.apache.tools.ant.Task
{
private String token;
private String replace;
private String[] xpath;
private File fileSrc;
private String divider;
private boolean isLog;
private String dtdFilePath;
private String dtdDefPath;
public void execute()
throws BuildException
{
try
{
Document dom = parseXML(getFileSrc(), this.isLog);
if ((getString() == null) || (getReplace() == null) || (getXpath()[0] == null) || (getFileSrc() == null) || (dom == null))
{
throw new Exception("Required attribute(s) is(are) missing or file parsed unsuccessfully.");
}
if (getDivider() == null) {
this.divider = "~";
System.out.println("Using default divider.");
}
int multiple;
try {
multiple = multipleParse(getXpath());
} catch (PatternSyntaxException e) {
throw new Exception("Invalid character or string for the divider");
}
if (multiple > 1) {
pluralReplace(getXpath(), dom, getString(), getReplace());
}
else {
singleReplace(getXpath(), dom, getString(), getReplace());
}
transformXML(dom, getFileSrc(), this.isLog);
}
catch (Exception e) {
throw new BuildException(e.getMessage(), e);
}
}
private void singleReplace(String[] xpath, Document dom, String token, String replace)
{
System.out.println(xpath[0]);
try
{
replace(xpath[0], dom, token, replace);
} catch (TransformerException e) {
System.err.println("Transformer exception thrown.");
}
}
private void pluralReplace(String[] xpath, Document dom, String token, String replace)
throws TransformerException
{
try
{
for (int j = 0; j < xpath.length; ++j) {
System.out.println(xpath[j]);
replace(xpath[j], dom, token, replace);
}
} catch (TransformerException e) {
throw new TransformerException("Replace in pluralReplace has thrown Transformer Exception.", e);
}
}
private Document parseXML(File f, boolean isLog)
throws Exception
{
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
try
{
DocumentBuilder build;
if (this.dtdFilePath != null) {
factory.setValidating(true);
factory.setNamespaceAware(true);
build = factory.newDocumentBuilder();
build.setEntityResolver( new EntityResolver() {
public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
return new InputSource(new InputStreamReader(new FileInputStream(dtdFilePath)));
}
}
);
}
else
{
factory.setValidating(false);
factory.setExpandEntityReferences(false);
build = factory.newDocumentBuilder();
if (isLog)
{
build.setEntityResolver(new Log4jEntityResolver());
}
}
Document doc = build.parse(f);
return doc;
}
catch (Exception e) {
throw new Exception(e.getClass().getName() + " is thrown from parseXML for file '" + f.getName() + "'", e);
}
}
private void transformXML(Document doc, File f, boolean isLog)
throws TransformerConfigurationException, TransformerException
{
TransformerFactory factory = TransformerFactory.newInstance();
try
{
Source src = new DOMSource(doc);
Result dest = new StreamResult(f);
Transformer trans = factory.newTransformer();
if (isLog)
trans.setOutputProperty("doctype-system", "log4j.dtd");
else if (null != this.dtdDefPath) {
trans.setOutputProperty("doctype-system", this.dtdDefPath);
}
trans.transform(src, dest);
}
catch (TransformerConfigurationException e) {
throw new TransformerConfigurationException("Transformer Configuration Exception thrown from transformXML.");
}
catch (TransformerException e2) {
throw new TransformerException("Transformer Exception thrown from transformXML");
}
}
private int multipleParse(String[] s)
throws PatternSyntaxException
{
String tmp = this.xpath[0];
this.xpath = tmp.split(this.divider);
return this.xpath.length;
}
private void replace(String xpath, Document dom, String token, String replace)
throws TransformerException
{
try
{
NodeList nodes = XPathAPI.selectNodeList(dom, xpath);
System.out.println("Node List retrieved.");
for (int i = 0; i < nodes.getLength(); ++i)
{
Node node = nodes.item(i);
if (node.getNodeType() == 2) {
Attr atr = (Attr)nodes.item(i);
String buffer = atr.getFirstChild().getNodeValue();
if (-1 != buffer.indexOf(token)) {
String oldBuffer = buffer;
buffer = buffer.replace(token, replace);
atr.getFirstChild().setNodeValue(buffer);
}
}
else {
Element elem = (Element)nodes.item(i);
if (elem.getFirstChild() != null) {
String buffer = elem.getFirstChild().getNodeValue();
if (-1 != buffer.indexOf(token)) {
String oldBuffer = buffer;
buffer = buffer.replace(token, replace);
elem.getFirstChild().setNodeValue(buffer);
}
}
}
}
}
catch (TransformerException e) {
throw new TransformerException("Transformer Exception thrown from replace method.", e);
}
}
public void setString(String s)
{
this.token = s;
}
public void setReplace(String s)
{
this.replace = s;
}
public void setSrc(File f)
{
this.fileSrc = f;
}
public void setXpath(String s)
{
this.xpath = new String[1];
this.xpath[0] = s;
}
public void setDivider(String s)
{
this.divider = s;
}
public String getReplace() {
return this.replace;
}
public String[] getXpath() {
return this.xpath;
}
public String getString() {
return this.token;
}
public File getFileSrc() {
return this.fileSrc;
}
public String getDivider() {
return this.divider;
}
public void setLog(boolean b) {
this.isLog = b;
}
public String getDtdFilePath() {
return this.dtdFilePath;
}
public void setDtdFilePath(String dtdFilePath) {
this.dtdFilePath = dtdFilePath;
}
public String getDtdDefPath() {
return this.dtdDefPath;
}
public void setDtdDefPath(String dtdDefPath) {
this.dtdDefPath = dtdDefPath;
}
}