Skip to content
Permalink
Browse files

Fix #211 by adding an allow-text-results extension and turning text o…

…utput into encoded XML that's decoded by p:store
  • Loading branch information
ndw committed May 22, 2015
1 parent 64d2152 commit 693224b6e876a94507d9211e9ae664c611e43f52
@@ -112,6 +112,7 @@
public String jsonFlavor = JSONtoXML.MARKLOGIC;
public boolean useXslt10 = false;
public boolean htmlSerializer = false;
public boolean allowTextResults = false;
public Vector<String> catalogs = new Vector<String> ();

public int piperackPort = 8088;
@@ -387,6 +388,7 @@ private void loadConfiguration() {
extensionValues = "true".equals(System.getProperty("com.xmlcalabash.general-values", ""+extensionValues));
xpointerOnText = "true".equals(System.getProperty("com.xmlcalabash.xpointer-on-text", ""+xpointerOnText));
transparentJSON = "true".equals(System.getProperty("com.xmlcalabash.transparent-json", ""+transparentJSON));
allowTextResults = "true".equals(System.getProperty("com.xmlcalabash.allow-text-results", ""+allowTextResults));
safeMode = "true".equals(System.getProperty("com.xmlcalabash.safe-mode", ""+safeMode));
jsonFlavor = System.getProperty("com.xmlcalabash.json-flavor", jsonFlavor);
useXslt10 = "true".equals(System.getProperty("com.xmlcalabash.use-xslt-10", ""+useXslt10));
@@ -721,6 +723,8 @@ private void parseExtension(XdmNode node) {
if (! JSONtoXML.knownFlavor(jsonFlavor)) {
throw new XProcException("Unrecognized JSON flavor: " + jsonFlavor);
}
} else if ("allow-text-results".equals(name)) {
allowTextResults = "true".equals(value);
} else if ("use-xslt-1.0".equals(name) || "use-xslt-10".equals(name)) {
useXslt10 = "true".equals(value);
} else if ("html-serializer".equals(name)) {
@@ -134,6 +134,7 @@
private URI baseURI = null;
private boolean allowGeneralExpressions = true;
private boolean allowXPointerOnText = true;
private boolean allowTextResults = true;
private boolean transparentJSON = false;
private String jsonFlavor = JSONtoXML.MARKLOGIC;
private boolean useXslt10 = false;
@@ -225,6 +226,7 @@ public XProcRuntime(XProcConfiguration config) {

allowGeneralExpressions = config.extensionValues;
allowXPointerOnText = config.xpointerOnText;
allowTextResults = config.allowTextResults;
transparentJSON = config.transparentJSON;
jsonFlavor = config.jsonFlavor;
useXslt10 = config.useXslt10;
@@ -459,6 +461,10 @@ public boolean getAllowXPointerOnText() {
return allowXPointerOnText;
}

public boolean getAllowTextResults() {
return allowTextResults;
}

public boolean transparentJSON() {
return transparentJSON;
}
@@ -661,6 +661,20 @@ public void setXPointerOnText(boolean xPointerOnText) {
}
}

/**
* Set whether non-XML (text) results can be returned from p:xslt and p:xquery steps,
* default is false.
*
* @param allowTextResults true if text results are allowed
*/
public void setAllowTextResults(boolean allowTextResults) {
try {
userArgs.setAllowTextResults(allowTextResults);
} catch (Exception e) {
handleError(e);
}
}

/**
* Set whether to enable use of XSLT 1.0;
* optional, default is false.
@@ -126,6 +126,8 @@ public Sequence call(XPathContext xPathContext, Sequence[] sequences) throws XPa
value = runtime.jsonFlavor();
} else if ("general-values".equals(local)) {
value = runtime.getAllowGeneralExpressions() ? "true" : "false";
} else if ("allow-text-results".equals(local)) {
value = runtime.getAllowTextResults() ? "true" : "false";
} else if ("xpointer-on-text".equals(local)) {
value = runtime.getAllowXPointerOnText() ? "true" : "false";
} else if ("use-xslt-1.0".equals(local) || "use-xslt-10".equals(local)) {
@@ -55,7 +55,6 @@

public class Store extends DefaultStep {
private static final QName _href = new QName("href");
private static final QName _encoding = new QName("encoding");
private static final QName _content_type = new QName("content-type");
private static final QName c_encoding = new QName("c", XProcConstants.NS_XPROC_STEP, "encoding");
private static final QName c_body = new QName("c", XProcConstants.NS_XPROC_STEP, "body");
@@ -116,8 +115,13 @@ public void run() throws SaxonApiException {
logger.trace(MessageFormatter.nodeMessage(hrefOpt.getNode(), "Storing to \"" + href + "\"."));
}

String decode = step.getExtensionAttribute(cx_decode);
XdmNode root = S9apiUtils.getDocumentElement(doc);

String decode = step.getExtensionAttribute(cx_decode);
if (decode == null) {
decode = root.getAttributeValue(cx_decode);
}

String contentType = root.getAttributeValue(_content_type);
URI contentId;
if (("true".equals(decode) || "1".equals(decode) || method != CompressionMethod.NONE)
@@ -50,6 +50,7 @@

public class XQuery extends DefaultStep {
private static final QName _content_type = new QName("content-type");
private static final QName cx_decode = new QName("cx", XProcConstants.NS_CALABASH_EX, "decode");

private ReadablePipe source = null;
private Hashtable<QName,RuntimeValue> params = new Hashtable<QName,RuntimeValue> ();
@@ -140,10 +141,48 @@ public void run() throws SaxonApiException {
Iterator<XdmItem> iter = xqeval.iterator();
while (iter.hasNext()) {
XdmItem item = iter.next();
XdmNode node = null;

if (item.isAtomicValue()) {
throw new XProcException(step.getNode(), "Not expecting atomic values back from XQuery!");
if (runtime.getAllowTextResults()) {
TreeWriter tree = new TreeWriter(runtime);
tree.startDocument(step.getNode().getBaseURI());
tree.addStartElement(XProcConstants.c_result);
tree.addAttribute(_content_type, "text/plain");
tree.addAttribute(cx_decode,"true");
tree.startContent();
tree.addText(item.getStringValue());
tree.addEndElement();
tree.endDocument();
node = tree.getResult();
} else {
throw new XProcException(step.getNode(), "p:xquery returned atomic value");
}
} else {
node = (XdmNode) item;

// If the document isn't well-formed XML, encode it as text
try {
S9apiUtils.assertDocument(node);
} catch (XProcException e) {
// If the document isn't well-formed XML, encode it as text
if (runtime.getAllowTextResults()) {
// Document is apparently not well-formed XML.
TreeWriter tree = new TreeWriter(runtime);
tree.startDocument(step.getNode().getBaseURI());
tree.addStartElement(XProcConstants.c_result);
tree.addAttribute(_content_type, "text/plain");
tree.addAttribute(cx_decode,"true");
tree.startContent();
tree.addText(node.toString());
tree.addEndElement();
tree.endDocument();
node = tree.getResult();
} else {
throw new XProcException(step.getStep(), "p:xquery returned non-XML result", e.getCause());
}
}
}
XdmNode node = (XdmNode) item;

if (node.getNodeKind() != XdmNodeKind.DOCUMENT) {
// Make a document for this node...is this the right thing to do?
@@ -77,6 +77,8 @@
private static final QName _template_name = new QName("", "template-name");
private static final QName _output_base_uri = new QName("", "output-base-uri");
private static final QName _version = new QName("", "version");
private static final QName _content_type = new QName("content-type");
private static final QName cx_decode = new QName("cx", XProcConstants.NS_CALABASH_EX, "decode");
private ReadablePipe sourcePipe = null;
private ReadablePipe stylesheetPipe = null;
private WritablePipe resultPipe = null;
@@ -254,7 +256,29 @@ public void run() throws SaxonApiException {
String sysId = document.getBaseURI().toASCIIString();
xformed.getUnderlyingNode().setSystemId(sysId);
}
resultPipe.write(xformed);

// If the document isn't well-formed XML, encode it as text
try {
S9apiUtils.assertDocument(xformed);
resultPipe.write(xformed);
} catch (XProcException e) {
// If the document isn't well-formed XML, encode it as text
if (runtime.getAllowTextResults()) {
// Document is apparently not well-formed XML.
TreeWriter tree = new TreeWriter(runtime);
tree.startDocument(xformed.getBaseURI());
tree.addStartElement(XProcConstants.c_result);
tree.addAttribute(_content_type, "text/plain");
tree.addAttribute(cx_decode,"true");
tree.startContent();
tree.addText(xformed.toString());
tree.addEndElement();
tree.endDocument();
resultPipe.write(tree.getResult());
} else {
throw new XProcException(step.getStep(), "p:xslt returned non-XML result", e.getCause());
}
}
}
}

@@ -333,7 +357,28 @@ public void close(Result result) throws TransformerException {
String href = result.getSystemId();
XdmDestination xdmResult = secondaryResults.get(href);
XdmNode doc = xdmResult.getXdmNode();
secondaryPipe.write(doc);

try {
S9apiUtils.assertDocument(doc);
secondaryPipe.write(doc);
} catch (XProcException e) {
// If the document isn't well-formed XML, encode it as text
if (runtime.getAllowTextResults()) {
// Document is apparently not well-formed XML.
TreeWriter tree = new TreeWriter(runtime);
tree.startDocument(doc.getBaseURI());
tree.addStartElement(XProcConstants.c_result);
tree.addAttribute(_content_type, "text/plain");
tree.addAttribute(cx_decode,"true");
tree.startContent();
tree.addText(doc.toString());
tree.addEndElement();
tree.endDocument();
secondaryPipe.write(tree.getResult());
} else {
throw new XProcException(step.getStep(), "p:xslt returned non-XML secondary result", e.getCause());
}
}
}
}

@@ -149,6 +149,8 @@ public UserArgs parse(String[] args) {
userArgs.setExtensionValues(true);
} else if ("xpointer-on-text".equals(ext)) {
userArgs.setAllowXPointerOnText(true);
} else if ("allow-text-results".equals(ext)) {
userArgs.setAllowTextResults(true);
} else if ("use-xslt-1.0".equals(ext) || "use-xslt-10".equals(ext)) {
userArgs.setUseXslt10(true);
} else if ("html-serializer".equals(ext)) {
@@ -85,6 +85,7 @@
protected StepArgs lastStep = null;
protected boolean extensionValues = false;
protected boolean allowXPointerOnText = false;
protected boolean allowTextResults = false;
protected boolean useXslt10 = false;
protected boolean htmlSerializer = false;
protected boolean transparentJSON = false;
@@ -404,6 +405,10 @@ public void setAllowXPointerOnText(boolean allowXPointerOnText) {
this.allowXPointerOnText = allowXPointerOnText;
}

public void setAllowTextResults(boolean allowTextResults) {
this.allowTextResults = allowTextResults;
}

public void setUseXslt10(boolean useXslt10) {
this.useXslt10 = useXslt10;
}
@@ -556,6 +561,7 @@ public XProcConfiguration createConfiguration() throws SaxonApiException {
if ((jsonFlavor != null) && !knownFlavor(jsonFlavor)) {
config.jsonFlavor = jsonFlavor;
}
config.allowTextResults |= allowTextResults;
config.useXslt10 |= useXslt10;
config.htmlSerializer |= htmlSerializer;

0 comments on commit 693224b

Please sign in to comment.
You can’t perform that action at this time.