use of org.exist.storage.serializers.XIncludeFilter in project exist by eXist-db.
the class Transform method eval.
/* (non-Javadoc)
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
*/
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
final Properties attributes = new Properties();
final Properties serializationProps = new Properties();
final Properties stylesheetParams = new Properties();
// Parameter 1 & 2
final Sequence inputNode = args[0];
final Item stylesheetItem = args[1].itemAt(0);
// Parse 3rd parameter
final Node options = args[2].isEmpty() ? null : ((NodeValue) args[2].itemAt(0)).getNode();
if (options != null) {
stylesheetParams.putAll(parseParameters(options));
}
// Parameter 4 when present
if (getArgumentCount() >= 4) {
final Sequence attrs = args[3];
attributes.putAll(extractAttributes(attrs));
}
// Parameter 5 when present
if (getArgumentCount() >= 5) {
// extract serialization options
final Sequence serOpts = args[4];
serializationProps.putAll(extractSerializationProperties(serOpts));
} else {
context.checkOptions(serializationProps);
}
boolean expandXIncludes = "yes".equals(serializationProps.getProperty(EXistOutputKeys.EXPAND_XINCLUDES, "yes"));
final XSLTErrorsListener<XPathException> errorListener = new XSLTErrorsListener<XPathException>(stopOnError, stopOnWarn) {
@Override
protected void raiseError(String error, Exception ex) throws XPathException {
throw new XPathException(Transform.this, error, ex);
}
};
// Setup handler and error listener
final TransformerHandler handler = createHandler(stylesheetItem, stylesheetParams, attributes, errorListener);
if (isCalledAs("transform")) {
// transform:transform()
final ValueSequence seq = new ValueSequence();
context.pushDocumentContext();
try {
final MemTreeBuilder builder = context.getDocumentBuilder();
final DocumentBuilderReceiver builderReceiver = new DocumentBuilderReceiver(builder, true);
final SAXResult result = new SAXResult(builderReceiver);
// preserve comments etc... from xslt output
result.setLexicalHandler(builderReceiver);
handler.setResult(result);
final Receiver receiver = new ReceiverToSAX(handler);
final Serializer serializer = context.getBroker().borrowSerializer();
try {
serializer.setProperties(serializationProps);
serializer.setReceiver(receiver, true);
if (expandXIncludes) {
String xiPath = serializationProps.getProperty(EXistOutputKeys.XINCLUDE_PATH);
if (xiPath != null && !xiPath.startsWith(XmldbURI.XMLDB_URI_PREFIX)) {
final Path f = Paths.get(xiPath).normalize();
if (!f.isAbsolute()) {
xiPath = Paths.get(context.getModuleLoadPath(), xiPath).normalize().toAbsolutePath().toString();
}
} else {
xiPath = context.getModuleLoadPath();
}
serializer.getXIncludeFilter().setModuleLoadPath(xiPath);
}
serializer.toSAX(inputNode, 1, inputNode.getItemCount(), false, false, 0, 0);
} catch (final Exception e) {
throw new XPathException(this, "Exception while transforming node: " + e.getMessage(), e);
} finally {
context.getBroker().returnSerializer(serializer);
}
errorListener.checkForErrors();
Node next = builder.getDocument().getFirstChild();
while (next != null) {
seq.add((NodeValue) next);
next = next.getNextSibling();
}
return seq;
} finally {
context.popDocumentContext();
}
} else {
// transform:stream-transform()
final Optional<ResponseWrapper> maybeResponse = Optional.ofNullable(context.getHttpContext()).map(XQueryContext.HttpContext::getResponse);
if (!maybeResponse.isPresent()) {
throw new XPathException(this, ErrorCodes.XPDY0002, "No response object found in the current XQuery context.");
}
final ResponseWrapper response = maybeResponse.get();
if (!"org.exist.http.servlets.HttpResponseWrapper".equals(response.getClass().getName())) {
throw new XPathException(this, ErrorCodes.XPDY0002, signatures[1] + " can only be used within the EXistServlet or XQueryServlet");
}
// setup the response correctly
final String mediaType = handler.getTransformer().getOutputProperty("media-type");
final String encoding = handler.getTransformer().getOutputProperty("encoding");
if (mediaType != null) {
if (encoding == null) {
response.setContentType(mediaType);
} else {
response.setContentType(mediaType + "; charset=" + encoding);
}
}
// do the transformation
try {
final OutputStream os = new BufferedOutputStream(response.getOutputStream());
final StreamResult result = new StreamResult(os);
handler.setResult(result);
final Serializer serializer = context.getBroker().borrowSerializer();
Receiver receiver = new ReceiverToSAX(handler);
try {
serializer.setProperties(serializationProps);
if (expandXIncludes) {
XIncludeFilter xinclude = new XIncludeFilter(serializer, receiver);
String xiPath = serializationProps.getProperty(EXistOutputKeys.XINCLUDE_PATH);
if (xiPath != null) {
final Path f = Paths.get(xiPath).normalize();
if (!f.isAbsolute()) {
xiPath = Paths.get(context.getModuleLoadPath(), xiPath).normalize().toAbsolutePath().toString();
}
} else {
xiPath = context.getModuleLoadPath();
}
xinclude.setModuleLoadPath(xiPath);
receiver = xinclude;
}
serializer.setReceiver(receiver);
serializer.toSAX(inputNode);
} catch (final Exception e) {
throw new XPathException(this, "Exception while transforming node: " + e.getMessage(), e);
} finally {
context.getBroker().returnSerializer(serializer);
}
errorListener.checkForErrors();
os.close();
// commit the response
response.flushBuffer();
} catch (final IOException e) {
throw new XPathException(this, "IO exception while transforming node: " + e.getMessage(), e);
}
return Sequence.EMPTY_SEQUENCE;
}
}
use of org.exist.storage.serializers.XIncludeFilter in project exist by eXist-db.
the class XSLTServlet method doPost.
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
final String uri = (String) request.getAttribute(REQ_ATTRIBUTE_STYLESHEET);
if (uri == null) {
throw new ServletException("No stylesheet source specified!");
}
Item inputNode = null;
final String sourceAttrib = (String) request.getAttribute(REQ_ATTRIBUTE_INPUT);
if (sourceAttrib != null) {
Object sourceObj = request.getAttribute(sourceAttrib);
if (sourceObj != null) {
if (sourceObj instanceof ValueSequence) {
final ValueSequence seq = (ValueSequence) sourceObj;
if (seq.size() == 1) {
sourceObj = seq.itemAt(0);
}
}
if (sourceObj instanceof Item) {
inputNode = (Item) sourceObj;
if (!Type.subTypeOf(inputNode.getType(), Type.NODE)) {
throw new ServletException("Input for XSLT servlet is not a node. Read from attribute " + sourceAttrib);
}
if (LOG.isDebugEnabled()) {
LOG.debug("Taking XSLT input from request attribute {}", sourceAttrib);
}
} else {
throw new ServletException("Input for XSLT servlet is not a node. Read from attribute " + sourceAttrib);
}
}
}
try {
pool = BrokerPool.getInstance();
} catch (final EXistException e) {
throw new ServletException(e.getMessage(), e);
}
Subject user = pool.getSecurityManager().getGuestSubject();
Subject requestUser = HttpAccount.getUserFromServletRequest(request);
if (requestUser != null) {
user = requestUser;
}
// Retrieve username / password from HTTP request attributes
final String userParam = (String) request.getAttribute("xslt.user");
final String passwd = (String) request.getAttribute("xslt.password");
if (userParam != null) {
try {
user = pool.getSecurityManager().authenticate(userParam, passwd);
} catch (final AuthenticationException e1) {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Wrong password or user");
return;
}
}
final Stylesheet stylesheet = stylesheet(uri, request, response);
if (stylesheet == null) {
return;
}
// do the transformation
try (final DBBroker broker = pool.get(Optional.of(user))) {
final TransformerHandler handler = stylesheet.newTransformerHandler(broker, errorListener);
setTransformerParameters(request, handler.getTransformer());
final Properties properties = handler.getTransformer().getOutputProperties();
setOutputProperties(request, properties);
String encoding = properties.getProperty("encoding");
if (encoding == null) {
encoding = "UTF-8";
}
response.setCharacterEncoding(encoding);
final String mediaType = properties.getProperty("media-type");
if (mediaType != null) {
// check, do mediaType have "charset"
if (!mediaType.contains("charset")) {
response.setContentType(mediaType + "; charset=" + encoding);
} else {
response.setContentType(mediaType);
}
}
final SAXSerializer sax = (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class);
final Writer writer = new BufferedWriter(response.getWriter());
sax.setOutput(writer, properties);
final SAXResult result = new SAXResult(sax);
handler.setResult(result);
final Serializer serializer = broker.borrowSerializer();
Receiver receiver = new ReceiverToSAX(handler);
try {
XIncludeFilter xinclude = new XIncludeFilter(serializer, receiver);
receiver = xinclude;
String baseUri;
final String base = (String) request.getAttribute(REQ_ATTRIBUTE_BASE);
if (base != null) {
baseUri = getServletContext().getRealPath(base);
} else if (uri.startsWith("xmldb:exist://")) {
baseUri = XmldbURI.xmldbUriFor(uri).getCollectionPath();
} else {
baseUri = getCurrentDir(request).toAbsolutePath().toString();
}
xinclude.setModuleLoadPath(baseUri);
serializer.setReceiver(receiver);
if (inputNode != null) {
serializer.toSAX((NodeValue) inputNode);
} else {
final SAXToReceiver saxreceiver = new SAXToReceiver(receiver);
final XMLReader reader = pool.getParserPool().borrowXMLReader();
try {
reader.setContentHandler(saxreceiver);
// Handle gziped input stream
InputStream stream;
InputStream inStream = new BufferedInputStream(request.getInputStream());
inStream.mark(10);
try {
stream = new GZIPInputStream(inStream);
} catch (final IOException e) {
inStream.reset();
stream = inStream;
}
reader.parse(new InputSource(stream));
} finally {
pool.getParserPool().returnXMLReader(reader);
}
}
} catch (final SAXParseException e) {
LOG.error(e.getMessage());
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
} catch (final SAXException e) {
throw new ServletException("SAX exception while transforming node: " + e.getMessage(), e);
} finally {
SerializerPool.getInstance().returnObject(sax);
broker.returnSerializer(serializer);
}
writer.flush();
response.flushBuffer();
} catch (final IOException e) {
throw new ServletException("IO exception while transforming node: " + e.getMessage(), e);
} catch (final TransformerException e) {
throw new ServletException("Exception while transforming node: " + e.getMessage(), e);
} catch (final Throwable e) {
LOG.error(e);
throw new ServletException("An error occurred: " + e.getMessage(), e);
}
}
Aggregations