package org.xins.common.ant;
import java.io.FileInputStream;
import java.io.StringReader;
import java.io.StringWriter;
import java.io.Writer;
import java.net.URL;
import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Element;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Templates;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
import org.apache.tools.ant.Task;
import org.w3c.dom.Document;
import org.xins.common.io.IOReader;
import org.xins.common.text.URLEncoding;
import org.xins.common.xml.ElementFormatter;
public class CreateExampleTask extends Task {
private String _requestURL;
private String _exampleProperty;
private String _functionProperty;
private String _xslLocation;
private Document exampleDocument;
public void setRequestURL(String requestURL) {
_requestURL = requestURL;
}
public void setExampleProperty(String exampleProperty) {
_exampleProperty = exampleProperty;
}
public void setFunctionProperty(String functionProperty) {
_functionProperty = functionProperty;
}
public void setXslLocation(String xslLocation) {
_xslLocation = xslLocation;
}
@Override
public void init() throws BuildException {
try {
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
exampleDocument = builder.newDocument();
} catch (Exception ex) {
throw new BuildException(ex);
}
}
public void execute() throws BuildException {
checkAttributes();
try {
Element requestXML = getRequestAsXML();
log("request: " + requestXML.toString(), Project.MSG_VERBOSE);
Element resultXML = getResultAsXML(_requestURL);
log("result: " + resultXML.toString(), Project.MSG_VERBOSE);
Element combined = exampleDocument.createElement("combined");
combined.appendChild(requestXML);
combined.appendChild(resultXML);
String example = transformElement(combined);
getProject().setUserProperty(_exampleProperty, example);
} catch (Exception ex) {
throw new BuildException(ex);
}
}
private void checkAttributes() throws BuildException {
if (_requestURL == null) {
throw new BuildException("The \"requestUrl\" attribute needs to be specified.");
}
if (_exampleProperty == null) {
throw new BuildException("An \"exampleProperty\" attribute needs to be specified.");
}
if (_xslLocation == null) {
throw new BuildException("An \"xslLocation\" attribute needs to be specified.");
}
if (getProject().getUserProperty(_exampleProperty) != null) {
String message = "Override ignored for property \""
+ _exampleProperty
+ "\".";
log(message, Project.MSG_VERBOSE);
}
if (_functionProperty != null && getProject().getUserProperty(_functionProperty) != null) {
String message = "Override ignored for property \""
+ _functionProperty
+ "\".";
log(message, Project.MSG_VERBOSE);
}
}
private Element getRequestAsXML() throws Exception {
String queryString = _requestURL.substring(_requestURL.indexOf('?') + 1);
Element request = exampleDocument.createElement("request");
StringTokenizer stQuery = new StringTokenizer(queryString, "&");
while (stQuery.hasMoreTokens()) {
String nextParam = stQuery.nextToken();
int equalPos = nextParam.indexOf('=');
String paramName = nextParam.substring(0, equalPos);
String paramValue = (equalPos == nextParam.length() - 1) ? "" : nextParam.substring(equalPos + 1);
if (paramName.equals("_function")) {
request.setAttribute("function", paramValue);
if (_functionProperty != null) {
getProject().setUserProperty(_functionProperty, paramValue);
}
} else if (paramName.equals("_data")) {
String dataSectionXML = URLEncoding.decode(paramValue);
request.appendChild(ElementFormatter.parse(dataSectionXML));
} else if (paramName.charAt(0) != '_') {
String paramXML = "<param name=\"" + paramName + "\">" +
URLEncoding.decode(paramValue) + "</param>";
request.appendChild(ElementFormatter.parse(paramXML));
}
}
return request;
}
static Element getResultAsXML(String requestURL) throws Exception {
URL url = new URL(requestURL);
String result = IOReader.readFully(url.openStream());
Element resultXML = ElementFormatter.parse(result);
return resultXML;
}
private String transformElement(Element combined) throws Exception {
TransformerFactory factory = TransformerFactory.newInstance();
Templates templates = factory.newTemplates(new StreamSource(
new FileInputStream(_xslLocation)));
Transformer xformer = templates.newTransformer();
Source source = new StreamSource(new StringReader(combined.toString()));
Writer buffer = new StringWriter(1024);
Result resultExample = new StreamResult(buffer);
xformer.transform(source, resultExample);
return buffer.toString();
}
}