use of org.exist.util.serializer.XQuerySerializer in project exist by eXist-db.
the class XQueryURLRewrite method response.
private void response(final DBBroker broker, final HttpServletResponse response, final Properties outputProperties, final Sequence resultSequence) throws IOException {
final String encoding = outputProperties.getProperty(OutputKeys.ENCODING);
try (final OutputStream os = response.getOutputStream();
final Writer writer = new OutputStreamWriter(os, encoding);
final PrintWriter printWriter = new PrintWriter(writer)) {
if (!response.containsHeader("Content-Type")) {
String mimeType = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
if (mimeType != null) {
final int semicolon = mimeType.indexOf(';');
if (semicolon != Constants.STRING_NOT_FOUND) {
mimeType = mimeType.substring(0, semicolon);
}
response.setContentType(mimeType + "; charset=" + encoding);
}
}
try {
final XQuerySerializer serializer = new XQuerySerializer(broker, outputProperties, printWriter);
serializer.serialize(resultSequence);
} catch (final SAXException | XPathException e) {
throw new IOException(e);
}
printWriter.flush();
}
}
use of org.exist.util.serializer.XQuerySerializer in project exist by eXist-db.
the class Eval method doEval.
private Sequence doEval(final XQueryContext evalContext, final Sequence contextSequence, final Sequence[] args) throws XPathException {
if (evalContext.getProfiler().isEnabled()) {
evalContext.getProfiler().start(this);
evalContext.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
evalContext.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
}
int argCount = 0;
Sequence exprContext = null;
if (isCalledAs(FS_EVAL_INLINE_NAME)) {
// the current expression context
exprContext = args[argCount++];
}
// get the query expression
final Item expr = args[argCount++].itemAt(0);
final Source querySource;
if (Type.subTypeOf(expr.getType(), Type.ANY_URI)) {
querySource = loadQueryFromURI(expr);
} else {
final String queryStr = expr.getStringValue();
if (queryStr.trim().isEmpty()) {
return new EmptySequence();
}
querySource = new StringSource(queryStr);
}
final NodeValue contextInit;
if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME)) {
// set the context initialization param for later use
contextInit = (NodeValue) args[argCount++].itemAt(0);
} else {
contextInit = null;
}
// should the compiled query be cached?
final boolean cache;
if (isCalledAs(FS_EVAL_AND_SERIALIZE_NAME)) {
cache = true;
} else if (argCount < getArgumentCount()) {
cache = ((BooleanValue) args[argCount++].itemAt(0)).effectiveBooleanValue();
} else {
cache = false;
}
// save some context properties
evalContext.pushNamespaceContext();
final LocalVariable mark = evalContext.markLocalVariables(false);
// save the static document set of the current context, so it can be restored later
final DocumentSet oldDocs = evalContext.getStaticDocs();
if (exprContext != null) {
evalContext.setStaticallyKnownDocuments(exprContext.getDocumentSet());
}
if (evalContext.isProfilingEnabled(2)) {
evalContext.getProfiler().start(this, "eval: " + expr);
}
// fixme! - hook for debugger here /ljo
final XQuery xqueryService = evalContext.getBroker().getBrokerPool().getXQueryService();
final XQueryContext innerContext;
final Sequence initContextSequence;
if (contextInit != null) {
// eval-with-context: initialize a new context
innerContext = new XQueryContext(context.getBroker().getBrokerPool());
initContextSequence = initContext(contextInit.getNode(), innerContext);
} else {
// use the existing outer context
// TODO: check if copying the static context would be sufficient???
innerContext = evalContext.copyContext();
innerContext.setShared(true);
// innerContext = context;
initContextSequence = null;
}
// set module load path
if (Type.subTypeOf(expr.getType(), Type.ANY_URI)) {
String uri = null;
if (querySource instanceof DBSource) {
final XmldbURI documentPath = ((DBSource) querySource).getDocumentPath();
uri = XmldbURI.EMBEDDED_SERVER_URI.append(documentPath).removeLastSegment().toString();
} else if (querySource instanceof FileSource) {
uri = ((FileSource) querySource).getPath().getParent().toString();
}
if (uri != null) {
innerContext.setModuleLoadPath(uri);
}
}
// bind external vars?
if (isCalledAs(FS_EVAL_NAME) && getArgumentCount() >= 3) {
final Sequence externalVars = args[argCount++];
for (int i = 0; i < externalVars.getItemCount(); i++) {
final Item varName = externalVars.itemAt(i);
if (varName.getType() == Type.QNAME) {
final Item varValue = externalVars.itemAt(++i);
innerContext.declareVariable(((QNameValue) varName).getQName(), varValue);
}
}
}
// determine if original line/column number are passed on
final boolean pass;
if (isCalledAs(FS_EVAL_NAME) && getArgumentCount() == 4) {
pass = args[3].itemAt(0).toJavaObject(Boolean.class);
} else if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME) && getArgumentCount() == 5) {
pass = args[4].itemAt(0).toJavaObject(Boolean.class);
} else if (isCalledAs(FS_EVAL_INLINE_NAME) && getArgumentCount() == 4) {
pass = args[3].itemAt(0).toJavaObject(Boolean.class);
} else if (isCalledAs(FS_EVAL_AND_SERIALIZE_NAME) && getArgumentCount() == 5) {
pass = args[4].itemAt(0).toJavaObject(Boolean.class);
} else {
// default
pass = false;
}
// fixme! - hook for debugger here /ljo
try {
if (isCalledAs(FS_EVAL_WITH_CONTEXT_NAME) && getArgumentCount() >= 4) {
final Item contextItem = args[argCount++].itemAt(0);
if (contextItem != null) {
// TODO : sort this out
if (exprContext != null) {
LOG.warn("exprContext and contextItem are not null");
}
exprContext = contextItem.toSequence();
}
}
if (initContextSequence != null) {
exprContext = initContextSequence;
}
Sequence result = null;
try {
if (!isCalledAs(FS_EVAL_AND_SERIALIZE_NAME)) {
result = execute(evalContext.getBroker(), xqueryService, querySource, innerContext, exprContext, cache, null);
return result;
} else {
// get the default serialization options
final Properties defaultOutputOptions;
if (getArgumentCount() >= 2 && !args[1].isEmpty()) {
defaultOutputOptions = FunSerialize.getSerializationProperties(this, args[1].itemAt(0));
} else {
defaultOutputOptions = new Properties();
}
// execute the query, XQuery prolog serialization options are collected into `xqueryOutputProperties`
final Properties xqueryOutputProperties = new Properties();
result = execute(evalContext.getBroker(), xqueryService, querySource, innerContext, exprContext, cache, xqueryOutputProperties);
// do we need to subsequence the results?
if (getArgumentCount() > 2) {
result = FunSubSequence.subsequence(result, ((DoubleValue) getArgument(2).eval(contextSequence, null).convertTo(Type.DOUBLE)), getArgumentCount() == 3 ? null : ((DoubleValue) getArgument(3).eval(contextSequence, null).convertTo(Type.DOUBLE)));
}
// override the default options with the ones from the xquery prolog
final Properties serializationProperties = new Properties();
serializationProperties.putAll(defaultOutputOptions);
serializationProperties.putAll(xqueryOutputProperties);
// serialize the results
try (final StringWriter writer = new StringWriter()) {
final XQuerySerializer xqSerializer = new XQuerySerializer(context.getBroker(), serializationProperties, writer);
final Sequence seq;
if (xqSerializer.normalize()) {
seq = FunSerialize.normalize(this, context, result);
} else {
seq = result;
}
xqSerializer.serialize(seq);
return new StringValue(writer.toString());
} catch (final IOException | SAXException e) {
throw new XPathException(this, FnModule.SENR0001, e.getMessage());
}
}
} finally {
cleanup(evalContext, innerContext, oldDocs, mark, expr, result);
}
} catch (final XPathException e) {
try {
e.prependMessage("Error while evaluating expression: " + querySource.getContent() + ". ");
} catch (final IOException e1) {
}
if (!pass) {
e.setLocation(line, column);
}
throw e;
}
}
use of org.exist.util.serializer.XQuerySerializer in project exist by eXist-db.
the class RestXqServiceSerializerImpl method serializeNodeBody.
@Override
protected void serializeNodeBody(final Sequence result, final HttpResponse response, final Map<SerializationProperty, String> serializationProperties) throws RestXqServiceException {
try (final DBBroker broker = getBrokerPool().getBroker();
final Writer writer = new OutputStreamWriter(response.getOutputStream(), serializationProperties.get(SerializationProperty.ENCODING))) {
final Properties outputProperties = serializationPropertiesToProperties(serializationProperties);
final XQuerySerializer xqSerializer = new XQuerySerializer(broker, outputProperties, writer);
xqSerializer.serialize(((SequenceAdapter) result).getExistSequence());
writer.flush();
} catch (IOException | XPathException | SAXException | EXistException ioe) {
throw new RestXqServiceException("Error while serializing xml: " + ioe.toString(), ioe);
}
}
use of org.exist.util.serializer.XQuerySerializer in project exist by eXist-db.
the class XQueryServlet method process.
/**
* Processes incoming HTTP requests for XQuery.
*
* @param request the http request
* @param response the http response
*
* @throws ServletException if the servlet raises an exception
* @throws IOException if an I/O error occurs
*/
protected void process(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// first, adjust the path
String path = request.getPathTranslated();
if (path == null) {
path = request.getRequestURI().substring(request.getContextPath().length());
final int p = path.lastIndexOf(';');
if (p != Constants.STRING_NOT_FOUND) {
path = path.substring(0, p);
}
path = getServletContext().getRealPath(path);
}
// second, perform descriptor actions
final Descriptor descriptor = Descriptor.getDescriptorSingleton();
if (descriptor != null && !descriptor.requestsFiltered()) {
// logs the request if specified in the descriptor
descriptor.doLogRequestInReplayLog(request);
// map's the path if a mapping is specified in the descriptor
path = descriptor.mapPath(path);
}
// if (request.getCharacterEncoding() == null)
// try {
// request.setCharacterEncoding(formEncoding);
// } catch (IllegalStateException e) {
// }
final ServletOutputStream sout = response.getOutputStream();
final PrintWriter output = new PrintWriter(new OutputStreamWriter(sout, getFormEncoding()));
// response.setContentType(contentType + "; charset=" + formEncoding);
response.addHeader("pragma", "no-cache");
response.addHeader("Cache-Control", "no-cache");
String requestPath = request.getRequestURI();
final int p = requestPath.lastIndexOf('/');
if (p != Constants.STRING_NOT_FOUND) {
requestPath = requestPath.substring(0, p);
}
String moduleLoadPath;
final Object loadPathAttrib = request.getAttribute(ATTR_MODULE_LOAD_PATH);
if (loadPathAttrib != null) {
moduleLoadPath = getValue(loadPathAttrib);
} else {
moduleLoadPath = getServletContext().getRealPath(requestPath.substring(request.getContextPath().length()));
}
Subject user = getDefaultUser();
// to determine the user, first check the request attribute "xquery.user", then
// the current session attribute "user"
final Object userAttrib = request.getAttribute(ATTR_XQUERY_USER);
final HttpSession session = request.getSession(false);
if (userAttrib != null || (session != null && request.isRequestedSessionIdValid())) {
final Object passwdAttrib = request.getAttribute(ATTR_XQUERY_PASSWORD);
String username;
String password;
if (userAttrib != null) {
username = getValue(userAttrib);
password = getValue(passwdAttrib);
} else {
username = getSessionAttribute(session, "user");
password = getSessionAttribute(session, "password");
}
// TODO authentication should use super.authenticate(...) !!!
try {
if (username != null && password != null) {
Subject newUser = getPool().getSecurityManager().authenticate(username, password);
if (newUser != null && newUser.isAuthenticated()) {
user = newUser;
}
}
} catch (final AuthenticationException e) {
getLog().error("User can not be authenticated ({}).", username);
}
}
if (user == getDefaultUser()) {
Subject requestUser = HttpAccount.getUserFromServletRequest(request);
if (requestUser != null) {
user = requestUser;
} else {
requestUser = getAuthenticator().authenticate(request, response, false);
if (requestUser != null) {
user = requestUser;
}
}
}
Source source = null;
final Object sourceAttrib = request.getAttribute(ATTR_XQUERY_SOURCE);
final Object urlAttrib = request.getAttribute(ATTR_XQUERY_URL);
if (sourceAttrib != null) {
String s;
if (sourceAttrib instanceof Item)
try {
s = ((Item) sourceAttrib).getStringValue();
} catch (final XPathException e) {
throw new ServletException("Failed to read XQuery source string from " + "request attribute '" + ATTR_XQUERY_SOURCE + "': " + e.getMessage(), e);
}
else {
s = sourceAttrib.toString();
}
source = new StringSource(s);
} else if (urlAttrib != null) {
try (final DBBroker broker = getPool().get(Optional.ofNullable(user))) {
source = SourceFactory.getSource(broker, moduleLoadPath, urlAttrib.toString(), true);
if (source == null) {
final String msg = "Could not read source: context=" + moduleLoadPath + ", location=" + urlAttrib.toString();
getLog().error(msg);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
sendError(output, "Error", msg);
}
} catch (final Exception e) {
getLog().error(e.getMessage(), e);
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
sendError(output, "Error", e.getMessage());
}
} else {
final Path f = Paths.get(path);
if (!Files.isReadable(f)) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
sendError(output, "Cannot read source file", path);
return;
}
source = new FileSource(f, Charset.forName(encoding), true);
}
if (source == null) {
response.setStatus(HttpServletResponse.SC_NOT_FOUND);
sendError(output, "Source not found", path);
}
boolean reportErrors = false;
final String errorOpt = (String) request.getAttribute(ATTR_XQUERY_REPORT_ERRORS);
if (errorOpt != null) {
reportErrors = errorOpt.equalsIgnoreCase("YES");
}
// allow source viewing for GET?
if ("GET".equals(request.getMethod().toUpperCase())) {
String option;
boolean allowSource = false;
if ((option = request.getParameter("_source")) != null)
allowSource = "yes".equals(option);
// Should we display the source of the XQuery or execute it
if (allowSource && descriptor != null) {
// System.out.println("path="+path);
if (descriptor.allowSource(path)) {
if (source instanceof DBSource) {
try {
((DBSource) source).validate(user, Permission.READ);
} catch (final PermissionDeniedException e) {
if (getDefaultUser().equals(user)) {
getAuthenticator().sendChallenge(request, response);
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Permission to view XQuery source for: " + path + " denied. (no read access)");
}
return;
}
}
// Show the source of the XQuery
// writeResourceAs(resource, broker, stylesheet, encoding, "text/plain", outputProperties, response);
response.setContentType("text/plain; charset=" + getFormEncoding());
output.write(source.getContent());
output.flush();
return;
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "Permission to view XQuery source for: " + path + " denied. Must be explicitly defined in descriptor.xml");
return;
}
}
}
// -------------------------------
// URI baseUri;
// try {
// baseUri = new URI(request.getScheme(),
// null/*user info?*/, request.getLocalPart(), request.getLocalPort(),
// request.getRequestURI(), null, null);
// } catch(URISyntaxException e) {
// baseUri = null;
// }
final String requestAttr = (String) request.getAttribute(ATTR_XQUERY_ATTRIBUTE);
try (final DBBroker broker = getPool().get(Optional.ofNullable(user))) {
final XQuery xquery = broker.getBrokerPool().getXQueryService();
CompiledXQuery query = getPool().getXQueryPool().borrowCompiledXQuery(broker, source);
XQueryContext context;
if (query == null) {
context = new XQueryContext(getPool());
context.setModuleLoadPath(moduleLoadPath);
try {
query = xquery.compile(context, source);
} catch (final XPathException ex) {
throw new EXistException("Cannot compile xquery: " + ex.getMessage(), ex);
} catch (final IOException ex) {
throw new EXistException("I/O exception while compiling xquery: " + ex.getMessage(), ex);
}
} else {
context = query.getContext();
context.setModuleLoadPath(moduleLoadPath);
context.prepareForReuse();
}
final Properties outputProperties = new Properties();
outputProperties.put("base-uri", collectionURI.toString());
final HttpRequestWrapper reqw = new HttpRequestWrapper(request, getFormEncoding(), getContainerEncoding());
final ResponseWrapper respw = new HttpResponseWrapper(response);
context.setHttpContext(new XQueryContext.HttpContext(reqw, respw, session != null ? new HttpSessionWrapper(session) : null));
final String timeoutOpt = (String) request.getAttribute(ATTR_TIMEOUT);
if (timeoutOpt != null) {
try {
final long timeout = Long.parseLong(timeoutOpt);
context.getWatchDog().setTimeout(timeout);
} catch (final NumberFormatException e) {
throw new EXistException("Bad timeout option: " + timeoutOpt);
}
}
final String maxNodesOpt = (String) request.getAttribute(ATTR_MAX_NODES);
if (maxNodesOpt != null) {
try {
final int maxNodes = Integer.parseInt(maxNodesOpt);
context.getWatchDog().setMaxNodes(maxNodes);
} catch (final NumberFormatException e) {
throw new EXistException("Bad max-nodes option: " + maxNodesOpt);
}
}
DebuggeeFactory.checkForDebugRequest(request, context);
Sequence resultSequence;
try {
resultSequence = xquery.execute(broker, query, null, outputProperties);
} finally {
context.runCleanupTasks();
getPool().getXQueryPool().returnCompiledXQuery(source, query);
}
final String mediaType = outputProperties.getProperty(OutputKeys.MEDIA_TYPE);
if (mediaType != null) {
if (!response.isCommitted()) {
if (MimeTable.getInstance().isTextContent(mediaType)) {
response.setContentType(mediaType + "; charset=" + getFormEncoding());
response.setCharacterEncoding(getFormEncoding());
} else
response.setContentType(mediaType);
}
} else {
String contentType = this.contentType;
try {
contentType = getServletContext().getMimeType(path);
if (contentType == null) {
contentType = this.contentType;
}
} catch (final Throwable e) {
contentType = this.contentType;
} finally {
if (MimeTable.getInstance().isTextContent(contentType)) {
contentType += "; charset=" + getFormEncoding();
}
response.setContentType(contentType);
}
}
if (requestAttr != null && (XmldbURI.API_LOCAL.equals(collectionURI.getApiName()))) {
request.setAttribute(requestAttr, resultSequence);
} else {
XQuerySerializer serializer = new XQuerySerializer(broker, outputProperties, output);
serializer.serialize(resultSequence);
}
} catch (final PermissionDeniedException e) {
if (getDefaultUser().equals(user)) {
getAuthenticator().sendChallenge(request, response);
} else {
response.sendError(HttpServletResponse.SC_FORBIDDEN, "No permission to execute XQuery for: " + path + " denied.");
}
return;
} catch (final XPathException e) {
final Logger logger = getLog();
if (logger.isDebugEnabled()) {
logger.debug(e.getMessage(), e);
}
if (reportErrors) {
writeError(output, e);
} else {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
sendError(output, "Error", e.getMessage());
}
} catch (final Throwable e) {
getLog().error(e.getMessage(), e);
if (reportErrors) {
writeError(output, e);
} else {
response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
sendError(output, "Error", e.getMessage());
}
}
output.flush();
output.close();
}
use of org.exist.util.serializer.XQuerySerializer in project exist by eXist-db.
the class ExtTestFailureFunction method errorMapToString.
private String errorMapToString(final Sequence seqErrorMap) throws IOException, XPathException, SAXException {
try (final StringWriter writer = new StringWriter()) {
final Properties properties = new Properties();
properties.setProperty(OutputKeys.METHOD, "adaptive");
final XQuerySerializer xquerySerializer = new XQuerySerializer(context.getBroker(), properties, writer);
xquerySerializer.serialize(seqErrorMap);
return writer.toString();
}
}
Aggregations