From: Wolfgang M. M. <wol...@us...> - 2005-09-30 15:28:18
|
Update of /cvsroot/exist/eXist-1.0/src/org/exist/xquery/functions/transform In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv14445/src/org/exist/xquery/functions/transform Modified Files: TransformModule.java Transform.java Log Message: New function in transform module: stream-transform(). Writes the result of the XSL transformation directly to the servlet output stream. Index: Transform.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/functions/transform/Transform.java,v retrieving revision 1.15 retrieving revision 1.16 diff -C2 -d -r1.15 -r1.16 *** Transform.java 26 Jul 2005 07:15:38 -0000 1.15 --- Transform.java 30 Sep 2005 15:28:02 -0000 1.16 *************** *** 23,28 **** --- 23,31 ---- package org.exist.xquery.functions.transform; + import java.io.BufferedOutputStream; import java.io.File; import java.io.IOException; + import java.io.OutputStream; + import java.io.StringWriter; import java.net.MalformedURLException; import java.net.URL; *************** *** 36,39 **** --- 39,43 ---- import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.TransformerException; + import javax.xml.transform.TransformerFactoryConfigurationError; import javax.xml.transform.URIResolver; import javax.xml.transform.dom.DOMSource; *************** *** 42,45 **** --- 46,50 ---- import javax.xml.transform.sax.TemplatesHandler; import javax.xml.transform.sax.TransformerHandler; + import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; *************** *** 48,51 **** --- 53,57 ---- import org.exist.dom.NodeProxy; import org.exist.dom.QName; + import org.exist.http.servlets.ResponseWrapper; import org.exist.memtree.DocumentBuilderReceiver; import org.exist.memtree.MemTreeBuilder; *************** *** 57,66 **** --- 63,76 ---- import org.exist.xquery.Cardinality; import org.exist.xquery.FunctionSignature; + import org.exist.xquery.Variable; import org.exist.xquery.XPathException; import org.exist.xquery.XQueryContext; + import org.exist.xquery.functions.request.RequestModule; import org.exist.xquery.value.Item; + import org.exist.xquery.value.JavaObjectValue; import org.exist.xquery.value.NodeValue; import org.exist.xquery.value.Sequence; import org.exist.xquery.value.SequenceType; + import org.exist.xquery.value.StringValue; import org.exist.xquery.value.Type; import org.exist.xquery.value.ValueSequence; *************** *** 74,78 **** public class Transform extends BasicFunction { ! public final static FunctionSignature signature = new FunctionSignature( new QName("transform", TransformModule.NAMESPACE_URI, TransformModule.PREFIX), --- 84,88 ---- public class Transform extends BasicFunction { ! public final static FunctionSignature signatures[] = { new FunctionSignature( new QName("transform", TransformModule.NAMESPACE_URI, TransformModule.PREFIX), *************** *** 87,91 **** new SequenceType(Type.ITEM, Cardinality.EXACTLY_ONE), new SequenceType(Type.NODE, Cardinality.ZERO_OR_ONE)}, ! new SequenceType(Type.NODE, Cardinality.ZERO_OR_ONE)); private Map cache = new HashMap(); --- 97,113 ---- new SequenceType(Type.ITEM, Cardinality.EXACTLY_ONE), new SequenceType(Type.NODE, Cardinality.ZERO_OR_ONE)}, ! new SequenceType(Type.NODE, Cardinality.ZERO_OR_ONE)), ! new FunctionSignature( ! new QName("stream-transform", TransformModule.NAMESPACE_URI, TransformModule.PREFIX), ! "Applies an XSL stylesheet to the node tree passed as first argument. The parameters are the same " + ! "as for the transform function. stream-transform can only be used within a servlet context. Instead " + ! "of returning the transformed document fragment, it directly streams its output to the servlet's output stream. " + ! "It should thus be the last statement in the XQuery.", ! new SequenceType[] { ! new SequenceType(Type.NODE, Cardinality.ZERO_OR_ONE), ! new SequenceType(Type.ITEM, Cardinality.EXACTLY_ONE), ! new SequenceType(Type.NODE, Cardinality.ZERO_OR_ONE)}, ! new SequenceType(Type.ITEM, Cardinality.EMPTY)) ! }; private Map cache = new HashMap(); *************** *** 95,99 **** * @param signature */ ! public Transform(XQueryContext context) { super(context, signature); } --- 117,121 ---- * @param signature */ ! public Transform(XQueryContext context, FunctionSignature signature) { super(context, signature); } *************** *** 112,116 **** options = ((NodeValue)args[2].itemAt(0)).getNode(); ! SAXTransformerFactory factory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); TransformerHandler handler; try { --- 134,198 ---- options = ((NodeValue)args[2].itemAt(0)).getNode(); ! TransformerHandler handler = createHandler(stylesheetItem, options); ! if (isCalledAs("transform")) { ! ValueSequence seq = new ValueSequence(); ! context.pushDocumentContext(); ! MemTreeBuilder builder = context.getDocumentBuilder(); ! DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder); ! SAXResult result = new SAXResult(receiver); ! handler.setResult(result); ! try { ! handler.startDocument(); ! inputNode.toSAX(context.getBroker(), handler); ! handler.endDocument(); ! } catch (SAXException e) { ! throw new XPathException(getASTNode(), "SAX exception while transforming node: " + e.getMessage(), e); ! } ! Node next = builder.getDocument().getFirstChild(); ! while (next != null) { ! seq.add((NodeValue) next); ! next = next.getNextSibling(); ! } ! context.popDocumentContext(); ! return seq; ! } else { ! RequestModule myModule = (RequestModule)context.getModule(RequestModule.NAMESPACE_URI); ! // request object is read from global variable $request ! Variable respVar = myModule.resolveVariable(RequestModule.RESPONSE_VAR); ! if(respVar == null) ! throw new XPathException(getASTNode(), "No request object found in the current XQuery context."); ! if(respVar.getValue().getItemType() != Type.JAVA_OBJECT) ! throw new XPathException(getASTNode(), "Variable $response is not bound to an Java object."); ! JavaObjectValue respValue = (JavaObjectValue) ! respVar.getValue().itemAt(0); ! if (!"org.exist.http.servlets.HttpResponseWrapper".equals(respValue.getObject().getClass().getName())) ! throw new XPathException(getASTNode(), signatures[1].toString() + ! " can only be used within the EXistServlet or XQueryServlet"); ! ResponseWrapper response = (ResponseWrapper) respValue.getObject(); ! try { ! OutputStream os = new BufferedOutputStream(response.getOutputStream()); ! StreamResult result = new StreamResult(os); ! handler.setResult(result); ! handler.startDocument(); ! inputNode.toSAX(context.getBroker(), handler); ! handler.endDocument(); ! } catch (SAXException e) { ! throw new XPathException(getASTNode(), "SAX exception while transforming node: " + e.getMessage(), e); ! } catch (IOException e) { ! throw new XPathException(getASTNode(), "IO exception while transforming node: " + e.getMessage(), e); ! } ! return Sequence.EMPTY_SEQUENCE; ! } ! } ! ! /** ! * @param stylesheetItem ! * @param options ! * @return ! * @throws TransformerFactoryConfigurationError ! * @throws XPathException ! */ ! private TransformerHandler createHandler(Item stylesheetItem, Node options) throws TransformerFactoryConfigurationError, XPathException { ! SAXTransformerFactory factory = (SAXTransformerFactory)SAXTransformerFactory.newInstance(); TransformerHandler handler; try { *************** *** 129,154 **** throw new XPathException("Unable to set up transformer: " + e.getMessage(), e); } ! ! context.pushDocumentContext(); ! MemTreeBuilder builder = context.getDocumentBuilder(); ! DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder); ! SAXResult result = new SAXResult(receiver); ! handler.setResult(result); ! try { ! handler.startDocument(); ! inputNode.toSAX(context.getBroker(), handler); ! handler.endDocument(); ! } catch (SAXException e) { ! throw new XPathException("SAX exception while transforming node: " + e.getMessage(), e); ! } ! ValueSequence seq = new ValueSequence(); ! Node next = builder.getDocument().getFirstChild(); ! while (next != null) { ! seq.add((NodeValue) next); ! next = next.getNextSibling(); ! } ! context.popDocumentContext(); ! return seq; ! } private void parseParameters(Node options, Transformer handler) throws XPathException { --- 211,216 ---- throw new XPathException("Unable to set up transformer: " + e.getMessage(), e); } ! return handler; ! } private void parseParameters(Node options, Transformer handler) throws XPathException { Index: TransformModule.java =================================================================== RCS file: /cvsroot/exist/eXist-1.0/src/org/exist/xquery/functions/transform/TransformModule.java,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** TransformModule.java 15 Oct 2004 13:59:27 -0000 1.2 --- TransformModule.java 30 Sep 2005 15:28:02 -0000 1.3 *************** *** 36,40 **** private final static FunctionDef functions[] = { ! new FunctionDef(Transform.signature, Transform.class) }; --- 36,41 ---- private final static FunctionDef functions[] = { ! new FunctionDef(Transform.signatures[0], Transform.class), ! new FunctionDef(Transform.signatures[1], Transform.class) }; |