use of org.exist.xquery.value.Item in project exist by eXist-db.
the class ApacheFopTest method simplePdf.
@Test
public void simplePdf() throws EXistException, PermissionDeniedException, XPathException {
final String fopConfig = "<fop version=\"1.0\">\n" + " <strict-configuration>true</strict-configuration>\n" + " <strict-validation>false</strict-validation>\n" + " <base>./</base>\n" + " <renderers>\n" + " <renderer mime=\"application/pdf\"></renderer>\n" + " </renderers>\n" + "</fop>";
final String fo = "<fo:root xmlns:fo=\"http://www.w3.org/1999/XSL/Format\">\n" + " <fo:layout-master-set>\n" + " <fo:simple-page-master master-name=\"page-left\" page-height=\"297mm\" page-width=\"210mm\" margin-bottom=\"10mm\" margin-top=\"10mm\" margin-left=\"36mm\" margin-right=\"18mm\">\n" + " <fo:region-body margin-bottom=\"10mm\" margin-top=\"16mm\"/>\n" + " <fo:region-before region-name=\"head-left\" extent=\"10mm\"/>\n" + " </fo:simple-page-master>\n" + " <fo:simple-page-master master-name=\"page-right\" page-height=\"297mm\" page-width=\"210mm\" margin-bottom=\"10mm\" margin-top=\"10mm\" margin-left=\"18mm\" margin-right=\"36mm\">\n" + " <fo:region-body margin-bottom=\"10mm\" margin-top=\"16mm\"/>\n" + " <fo:region-before region-name=\"head-right\" extent=\"10mm\"/>\n" + " </fo:simple-page-master>\n" + " <fo:page-sequence-master master-name=\"page-content\">\n" + " <fo:repeatable-page-master-alternatives>\n" + " <fo:conditional-page-master-reference master-reference=\"page-right\" odd-or-even=\"odd\"/>\n" + " <fo:conditional-page-master-reference master-reference=\"page-left\" odd-or-even=\"even\"/>\n" + " </fo:repeatable-page-master-alternatives>\n" + " </fo:page-sequence-master>\n" + " </fo:layout-master-set>\n" + " <fo:page-sequence master-reference=\"page-content\">\n" + " <fo:flow flow-name=\"xsl-region-body\" hyphenate=\"true\" language=\"en\" xml:lang=\"en\">\n" + " <fo:block id=\"A97060-t\" line-height=\"16pt\" font-size=\"11pt\">\n" + " <fo:block id=\"A97060-e0\" page-break-after=\"right\">\n" + " <fo:block id=\"A97060-e100\" text-align=\"justify\" space-before=\".5em\" text-indent=\"1.5em\" space-after=\".5em\">\n" + " Hello World!\n" + " </fo:block>\n" + " </fo:block>\n" + " </fo:block>\n" + " </fo:flow>\n" + " </fo:page-sequence>\n" + "</fo:root>";
final String xquery = "xquery version \"3.1\";\n" + "\n" + "import module namespace xslfo=\"http://exist-db.org/xquery/xslfo\";\n" + "\n" + "let $config := " + fopConfig + "\n" + "let $fo := " + fo + "\n" + "\n" + "let $pdf := xslfo:render($fo, \"application/pdf\", (), $config)\n" + "return $pdf";
final BrokerPool pool = server.getBrokerPool();
final XQuery xqueryService = pool.getXQueryService();
try (final DBBroker broker = pool.getBroker()) {
final Sequence result = xqueryService.execute(broker, xquery, null);
assertNotNull(result);
assertEquals(1, result.getItemCount());
final Item pdf = result.itemAt(0);
assertEquals(Type.BASE64_BINARY, pdf.getType());
}
}
use of org.exist.xquery.value.Item 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.xquery.value.Item in project exist by eXist-db.
the class CallFunction method eval.
/* (non-Javadoc)
* @see org.exist.xquery.BasicFunction#eval(org.exist.xquery.value.Sequence[], org.exist.xquery.value.Sequence)
*/
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
final Sequence arg0 = getArgument(0).eval(contextSequence, contextItem);
if (arg0.getCardinality() != Cardinality.EXACTLY_ONE) {
throw new XPathException(this, "Expected exactly one item for first argument");
}
final Item item0 = arg0.itemAt(0);
if (item0.getType() != Type.FUNCTION_REFERENCE) {
throw new XPathException(this, "Type error: expected function, got " + Type.getTypeName(item0.getType()));
}
try (final FunctionReference ref = (FunctionReference) item0) {
// pass the remaining parameters to the function call
final List<Expression> params = new ArrayList<>(getArgumentCount() - 1);
for (int i = 1; i < getArgumentCount(); i++) {
params.add(getArgument(i));
}
ref.setArguments(params);
ref.analyze(new AnalyzeContextInfo(this, 0));
// Evaluate the function
return ref.eval(contextSequence);
}
}
use of org.exist.xquery.value.Item in project exist by eXist-db.
the class Modification method deepCopy.
protected Sequence deepCopy(Sequence inSeq) throws XPathException {
context.pushDocumentContext();
final MemTreeBuilder builder = context.getDocumentBuilder();
final DocumentBuilderReceiver receiver = new DocumentBuilderReceiver(builder);
final Serializer serializer = context.getBroker().borrowSerializer();
serializer.setReceiver(receiver);
try {
final Sequence out = new ValueSequence();
for (final SequenceIterator i = inSeq.iterate(); i.hasNext(); ) {
Item item = i.nextItem();
if (item.getType() == Type.DOCUMENT) {
if (((NodeValue) item).getImplementationType() == NodeValue.PERSISTENT_NODE) {
final NodeHandle root = (NodeHandle) ((NodeProxy) item).getOwnerDocument().getDocumentElement();
item = new NodeProxy(root);
} else {
item = (Item) ((Document) item).getDocumentElement();
}
}
if (Type.subTypeOf(item.getType(), Type.NODE)) {
if (((NodeValue) item).getImplementationType() == NodeValue.PERSISTENT_NODE) {
final int last = builder.getDocument().getLastNode();
final NodeProxy p = (NodeProxy) item;
serializer.toReceiver(p, false, false);
if (p.getNodeType() == Node.ATTRIBUTE_NODE) {
item = builder.getDocument().getLastAttr();
} else {
item = builder.getDocument().getNode(last + 1);
}
} else {
((org.exist.dom.memtree.NodeImpl) item).deepCopy();
}
}
out.add(item);
}
return out;
} catch (final SAXException | DOMException e) {
throw new XPathException(this, e.getMessage(), e);
} finally {
context.getBroker().returnSerializer(serializer);
context.popDocumentContext();
}
}
use of org.exist.xquery.value.Item in project exist by eXist-db.
the class Update method eval.
/* (non-Javadoc)
* @see org.exist.xquery.AbstractExpression#eval(org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
*/
public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
if (context.getProfiler().isEnabled()) {
context.getProfiler().start(this);
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
if (contextSequence != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
}
if (contextItem != null) {
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
}
}
if (contextItem != null) {
contextSequence = contextItem.toSequence();
}
final Sequence contentSeq = value.eval(contextSequence);
if (contentSeq.isEmpty()) {
throw new XPathException(this, Messages.getMessage(Error.UPDATE_EMPTY_CONTENT));
}
final Sequence inSeq = select.eval(contextSequence);
/* If we try and Update a node at an invalid location,
* trap the error in a context variable,
* this is then accessible from xquery via. the context extension module - deliriumsky
* TODO: This trapping could be expanded further - basically where XPathException is thrown from thiss class
* TODO: Maybe we could provide more detailed messages in the trap, e.g. couldnt update node `xyz` into `abc` becuase... this would be nicer for the end user of the xquery application
*/
if (!Type.subTypeOf(inSeq.getItemType(), Type.NODE)) {
// Indicate the failure to perform this update by adding it to the sequence in the context variable XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR
ValueSequence prevUpdateErrors = null;
final XPathException xpe = new XPathException(this, Messages.getMessage(Error.UPDATE_SELECT_TYPE));
final Object ctxVarObj = context.getAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR);
if (ctxVarObj == null) {
prevUpdateErrors = new ValueSequence();
} else {
prevUpdateErrors = (ValueSequence) XPathUtil.javaObjectToXPath(ctxVarObj, context);
}
prevUpdateErrors.add(new StringValue(xpe.getMessage()));
context.setAttribute(XQueryContext.XQUERY_CONTEXTVAR_XQUERY_UPDATE_ERROR, prevUpdateErrors);
if (!inSeq.isEmpty()) {
// TODO: should we trap this instead of throwing an exception - deliriumsky?
throw xpe;
}
}
if (!inSeq.isEmpty()) {
context.pushInScopeNamespaces();
// start a transaction
try (final Txn transaction = getTransaction()) {
final NotificationService notifier = context.getBroker().getBrokerPool().getNotificationService();
final StoredNode[] ql = selectAndLock(transaction, inSeq);
for (final StoredNode node : ql) {
final DocumentImpl doc = node.getOwnerDocument();
if (!doc.getPermissions().validate(context.getSubject(), Permission.WRITE)) {
throw new XPathException(this, "User '" + context.getSubject().getName() + "' does not have permission to write to the document '" + doc.getDocumentURI() + "'!");
}
// update the document
switch(node.getNodeType()) {
case Node.ELEMENT_NODE:
final NodeListImpl content = new NodeListImpl();
for (final SequenceIterator j = contentSeq.iterate(); j.hasNext(); ) {
final Item next = j.nextItem();
if (Type.subTypeOf(next.getType(), Type.NODE)) {
content.add(((NodeValue) next).getNode());
} else {
final TextImpl text = new TextImpl(next.getStringValue());
content.add(text);
}
}
((ElementImpl) node).update(transaction, content);
break;
case Node.TEXT_NODE:
final ElementImpl textParent = (ElementImpl) node.getParentNode();
final TextImpl text = new TextImpl(contentSeq.getStringValue());
text.setOwnerDocument(doc);
textParent.updateChild(transaction, node, text);
break;
case Node.ATTRIBUTE_NODE:
final ElementImpl attrParent = (ElementImpl) ((Attr) node).getOwnerElement();
if (attrParent == null) {
LOG.warn("parent node not found for {}", node.getNodeId());
break;
}
final AttrImpl attr = (AttrImpl) node;
final AttrImpl attribute = new AttrImpl(attr.getQName(), contentSeq.getStringValue(), context.getBroker().getBrokerPool().getSymbols());
attribute.setOwnerDocument(doc);
attrParent.updateChild(transaction, node, attribute);
break;
default:
throw new XPathException(this, "unsupported node-type");
}
doc.setLastModified(System.currentTimeMillis());
modifiedDocuments.add(doc);
context.getBroker().storeXMLResource(transaction, doc);
notifier.notifyUpdate(doc, UpdateListener.UPDATE);
}
finishTriggers(transaction);
// commit the transaction
transaction.commit();
} catch (final LockException | EXistException | TriggerException e) {
throw new XPathException(this, e.getMessage(), e);
} finally {
unlockDocuments();
context.popInScopeNamespaces();
}
}
if (context.getProfiler().isEnabled()) {
context.getProfiler().end(this, "", Sequence.EMPTY_SEQUENCE);
}
return Sequence.EMPTY_SEQUENCE;
}
Aggregations