Пример #1
0
  public void getEntryById(DBBroker broker, String path, String id, OutgoingMessage response)
      throws EXistException, BadRequestException {
    XQuery xquery = broker.getXQueryService();
    CompiledXQuery feedQuery = xquery.getXQueryPool().borrowCompiledXQuery(broker, entryByIdSource);

    XQueryContext context;
    if (feedQuery == null) {
      context = xquery.newContext(AccessContext.REST);
      try {
        feedQuery = xquery.compile(context, entryByIdSource);
      } catch (XPathException ex) {
        throw new EXistException("Cannot compile xquery " + entryByIdSource.getURL(), ex);
      } catch (IOException ex) {
        throw new EXistException(
            "I/O exception while compiling xquery " + entryByIdSource.getURL(), ex);
      }
    } else {
      context = feedQuery.getContext();
    }
    context.setStaticallyKnownDocuments(
        new XmldbURI[] {XmldbURI.create(path).append(AtomProtocol.FEED_DOCUMENT_NAME)});

    try {
      context.declareVariable("id", id);
      Sequence resultSequence = xquery.execute(feedQuery, null);
      if (resultSequence.isEmpty()) {
        throw new BadRequestException("No topic was found.");
      }
      String charset = getContext().getDefaultCharset();
      response.setContentType("application/atom+xml; charset=" + charset);
      Serializer serializer = broker.getSerializer();
      serializer.reset();
      try {
        Writer w = new OutputStreamWriter(response.getOutputStream(), charset);
        SAXSerializer sax =
            (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class);
        Properties outputProperties = new Properties();
        sax.setOutput(w, outputProperties);
        serializer.setProperties(outputProperties);
        serializer.setSAXHandlers(sax, sax);

        serializer.toSAX(resultSequence, 1, 1, false);

        SerializerPool.getInstance().returnObject(sax);
        w.flush();
        w.close();
      } catch (IOException ex) {
        LOG.fatal("Cannot read resource " + path, ex);
        throw new EXistException("I/O error on read of resource " + path, ex);
      } catch (SAXException saxe) {
        LOG.warn(saxe);
        throw new BadRequestException("Error while serializing XML: " + saxe.getMessage());
      }
      resultSequence.itemAt(0);
    } catch (XPathException ex) {
      throw new EXistException("Cannot execute xquery " + entryByIdSource.getURL(), ex);
    } finally {
      xquery.getXQueryPool().returnCompiledXQuery(entryByIdSource, feedQuery);
    }
  }
Пример #2
0
  public Sequence eval(Sequence contextSequence, Item contextItem) throws XPathException {
    Sequence querySeq = getArgument(1).eval(contextSequence);
    if (querySeq.isEmpty()) {
      return Sequence.EMPTY_SEQUENCE;
    }
    String query = querySeq.itemAt(0).getStringValue();

    String[] terms = getSearchTerms(query);
    NodeSet hits[] = new NodeSet[terms.length];
    NodeSet contextSet = contextSequence.toNodeSet();
    for (int k = 0; k < terms.length; k++) {
      hits[k] =
          context
              .getBroker()
              .getTextEngine()
              .getNodesContaining(
                  context,
                  contextSet.getDocumentSet(),
                  null,
                  NodeSet.DESCENDANT,
                  null,
                  terms[k],
                  DBBroker.MATCH_EXACT);
      hits[k] = getArgument(0).eval(hits[k]).toNodeSet();
    }

    NodeSet result = hits[0];
    for (int k = 1; k < hits.length; k++) {
      if (hits[k] != null) result = result.deepIntersection(hits[k]);
    }
    if (LOG.isDebugEnabled()) LOG.debug("FOUND: " + result.getLength());
    return result;
  }
Пример #3
0
  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());
    }

    Sequence seq;
    Sequence result;

    if (contextItem != null) contextSequence = contextItem.toSequence();

    /*
    if (contextSequence == null || contextSequence.isEmpty())
    	result = Sequence.EMPTY_SEQUENCE;
    */

    // If we have one argument, we take it into account
    if (getSignature().getArgumentCount() > 0)
      seq = getArgument(0).eval(contextSequence, contextItem);
    // Otherwise, we take the context sequence and we iterate over it
    else seq = contextSequence;

    if (seq == null) throw new XPathException(this, "XPDY0002: Undefined context item");

    if (seq.isEmpty())
      // Bloody specs !
      result = StringValue.EMPTY_STRING;
    else {
      Item item = seq.itemAt(0);
      if (!Type.subTypeOf(item.getType(), Type.NODE))
        throw new XPathException(
            this, "XPTY0004: item is not a node; got '" + Type.getTypeName(item.getType()) + "'");
      // TODO : how to improve performance ?
      Node n = ((NodeValue) item).getNode();
      if (n instanceof QNameable)
        result = new StringValue(((QNameable) n).getQName().getStringValue());
      else result = StringValue.EMPTY_STRING;
    }

    if (context.getProfiler().isEnabled()) context.getProfiler().end(this, "", result);

    return result;
  }
Пример #4
0
 public static Sequence atomize(Sequence input) throws XPathException {
   if (input.hasOne()) return input.itemAt(0).atomize();
   Item next;
   ValueSequence result = new ValueSequence();
   for (SequenceIterator i = input.iterate(); i.hasNext(); ) {
     next = i.nextItem();
     result.add(next.atomize());
   }
   return result;
 }
Пример #5
0
  private static Sequence executeQuery(
      DBBroker broker, String query, int expected, String expectedResult)
      throws XPathException, SAXException, PermissionDeniedException {
    XQuery xquery = broker.getXQueryService();
    Sequence seq = xquery.execute(query, null, AccessContext.TEST);
    assertEquals(expected, seq.getItemCount());

    if (expectedResult != null) {
      Item item = seq.itemAt(0);
      String value = serialize(broker, item);
      assertEquals(expectedResult, value);
    }
    return seq;
  }
Пример #6
0
  public Sequence eval(Sequence[] args, Sequence contextSequence) 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);
    }

    Sequence result;
    if (args.length == 0 || args[0].isEmpty()) {
      result = Sequence.EMPTY_SEQUENCE;
    } else {
      Sequence arg = args[0];
      AbstractDateTimeValue date = (AbstractDateTimeValue) arg.itemAt(0);
      if (isCalledAs("day-from-dateTime") || isCalledAs("day-from-date")) {
        result = new IntegerValue(date.getPart(DateValue.DAY), Type.INTEGER);
      } else if (isCalledAs("month-from-dateTime") || isCalledAs("month-from-date")) {
        result = new IntegerValue(date.getPart(DateValue.MONTH), Type.INTEGER);
      } else if (isCalledAs("year-from-dateTime") || isCalledAs("year-from-date")) {
        result = new IntegerValue(date.getPart(DateValue.YEAR), Type.INTEGER);
      } else if (isCalledAs("hours-from-dateTime") || isCalledAs("hours-from-time")) {
        result = new IntegerValue(date.getPart(DateValue.HOUR), Type.INTEGER);
      } else if (isCalledAs("minutes-from-dateTime") || isCalledAs("minutes-from-time")) {
        result = new IntegerValue(date.getPart(DateValue.MINUTE), Type.INTEGER);
      } else if (isCalledAs("seconds-from-dateTime") || isCalledAs("seconds-from-time")) {
        result = new IntegerValue(date.calendar.getSecond()).convertTo(Type.DECIMAL);
        if (date.calendar.getFractionalSecond() != null)
          result =
              ((DecimalValue) result).plus(new DecimalValue(date.calendar.getFractionalSecond()));
      } else if (isCalledAs("timezone-from-dateTime")
          || isCalledAs("timezone-from-date")
          || isCalledAs("timezone-from-time")) {
        result = date.getTimezone();
      } else {
        throw new Error("can't handle function " + mySignature.getName().getLocalName());
      }
    }

    if (context.getProfiler().isEnabled()) context.getProfiler().end(this, "", result);

    return result;
  }
Пример #7
0
  @Test
  public void nodeProxy_getParents()
      throws XPathException, SAXException, PermissionDeniedException {
    Sequence smallSet =
        executeQuery(
            broker, "//SPEECH/LINE[fn:contains(., 'perturbed spirit')]/ancestor::SPEECH", 1, null);

    NodeProxy proxy = (NodeProxy) smallSet.itemAt(0);

    NodeSet result = proxy.getParents(-1);
    assertEquals(1, result.getLength());

    NameTest test = new NameTest(Type.ELEMENT, new QName("SPEAKER", ""));
    NodeSet speakers =
        broker
            .getStructuralIndex()
            .findElementsByTagName(ElementValue.ELEMENT, docs, test.getName(), null);

    result = speakers.selectParentChild(proxy, NodeSet.DESCENDANT, -1);
    assertEquals(1, result.getLength());
  }
Пример #8
0
  /** @see org.exist.xquery.Expression#eval(Sequence, 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());
    }

    Sequence result;
    Sequence arg = getArgument(0).eval(contextSequence, contextItem);
    if (arg.isEmpty()) result = BooleanValue.FALSE;
    else {
      String path = arg.itemAt(0).getStringValue();
      try {
        result = BooleanValue.valueOf(DocUtils.isDocumentAvailable(this.context, path));
      } catch (Exception e) {
        throw new XPathException(getASTNode(), e.getMessage());
      }
    }

    if (context.getProfiler().isEnabled()) context.getProfiler().end(this, "", result);

    return result;
  }
Пример #9
0
  /*
   * (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 {

    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());
    }

    Expression arg1 = getArgument(0);
    Sequence s1 = arg1.eval(contextSequence, contextItem);

    Expression arg2 = getArgument(1);
    context.pushDocumentContext();
    Sequence s2 = arg2.eval(contextSequence, contextItem);
    context.popDocumentContext();

    if (s1.isEmpty()) {
      return BooleanValue.valueOf(s2.isEmpty());
    } else if (s2.isEmpty()) {
      return BooleanValue.valueOf(s1.isEmpty());
    }

    Sequence result = null;
    StringBuffer v1 = new StringBuffer();
    StringBuffer v2 = new StringBuffer();
    try {
      if (s1.hasMany()) {
        for (int i = 0; i < s1.getItemCount(); i++) {
          v1.append(serialize((NodeValue) s1.itemAt(i)));
        }
      } else {
        v1.append(serialize((NodeValue) s1.itemAt(0)));
      }
      if (s2.hasMany()) {
        for (int i = 0; i < s2.getItemCount(); i++) {
          v2.append(serialize((NodeValue) s2.itemAt(i)));
        }
      } else {
        v2.append(serialize((NodeValue) s2.itemAt(0)));
      }
      Diff d = new Diff(v1.toString(), v2.toString());
      boolean identical = d.identical();
      if (!identical) {
        logger.warn("Diff result: " + d.toString());
      }
      result = new BooleanValue(identical);
    } catch (Exception e) {
      throw new XPathException(
          this,
          "An exception occurred while serializing node " + "for comparison: " + e.getMessage(),
          e);
    }

    if (context.getProfiler().isEnabled()) context.getProfiler().end(this, "", result);

    return result;
  }
Пример #10
0
  /* (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 (requiredType == Type.ATOMIC
        || (requiredType == Type.NOTATION && expression.returnsType() != Type.NOTATION))
      throw new XPathException(
          this, "err:XPST0080: cannot convert to " + Type.getTypeName(requiredType));

    if (requiredType == Type.ANY_SIMPLE_TYPE
        || expression.returnsType() == Type.ANY_SIMPLE_TYPE
        || requiredType == Type.UNTYPED
        || expression.returnsType() == Type.UNTYPED)
      throw new XPathException(
          this, "err:XPST0051: cannot convert to " + Type.getTypeName(requiredType));

    Sequence result;
    // See : http://article.gmane.org/gmane.text.xml.xquery.general/1413
    // ... for the rationale
    // may be more complicated : let's see with following XQTS versions
    if (requiredType == Type.QNAME && Dependency.dependsOnVar(expression))
      result = BooleanValue.FALSE;
    else {
      Sequence seq = expression.eval(contextSequence, contextItem);
      if (seq.isEmpty()) {
        // If ? is specified after the target type, the result of the cast expression is an empty
        // sequence.
        if (Cardinality.checkCardinality(requiredCardinality, Cardinality.ZERO))
          result = BooleanValue.TRUE;
        // If ? is not specified after the target type, a type error is raised [err:XPTY0004].
        else
          // TODO : raise the error ?
          result = BooleanValue.FALSE;
      } else {
        try {
          seq.itemAt(0).convertTo(requiredType);
          // If ? is specified after the target type, the result of the cast expression is an empty
          // sequence.
          if (Cardinality.checkCardinality(requiredCardinality, seq.getCardinality()))
            result = BooleanValue.TRUE;
          // If ? is not specified after the target type, a type error is raised [err:XPTY0004].
          else result = BooleanValue.FALSE;
          // TODO : improve by *not* using a costly exception ?
        } catch (XPathException e) {
          result = BooleanValue.FALSE;
        }
      }
    }

    if (context.getProfiler().isEnabled()) context.getProfiler().end(this, "", result);

    return result;
  }
Пример #11
0
  /**
   * Processes a compressed entry from an archive
   *
   * @param name The name of the entry
   * @param isDirectory true if the entry is a directory, false otherwise
   * @param is an InputStream for reading the uncompressed data of the entry
   * @param filterParam is an additional param for entry filtering function
   * @param storeParam is an additional param for entry storing function
   * @throws XMLDBException
   */
  protected Sequence processCompressedEntry(
      String name, boolean isDirectory, InputStream is, Sequence filterParam, Sequence storeParam)
      throws IOException, XPathException, XMLDBException {
    String dataType = isDirectory ? "folder" : "resource";

    // call the entry-filter function
    Sequence filterParams[] = new Sequence[3];
    filterParams[0] = new StringValue(name);
    filterParams[1] = new StringValue(dataType);
    filterParams[2] = filterParam;
    Sequence entryFilterFunctionResult =
        entryFilterFunction.evalFunction(contextSequence, null, filterParams);

    if (BooleanValue.FALSE == entryFilterFunctionResult.itemAt(0)) {
      return Sequence.EMPTY_SEQUENCE;
    } else {
      Sequence entryDataFunctionResult;
      Sequence uncompressedData = Sequence.EMPTY_SEQUENCE;

      // copy the input data
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      byte buf[] = new byte[1024];
      int read = -1;
      while ((read = is.read(buf)) != -1) {
        baos.write(buf, 0, read);
      }
      byte[] entryData = baos.toByteArray();

      if (entryDataFunction.getSignature().getArgumentCount() == 3) {

        Sequence dataParams[] = new Sequence[3];
        System.arraycopy(filterParams, 0, dataParams, 0, 2);
        dataParams[2] = storeParam;
        entryDataFunctionResult = entryDataFunction.evalFunction(contextSequence, null, dataParams);

        String path = entryDataFunctionResult.itemAt(0).getStringValue();

        Collection root =
            new LocalCollection(
                context.getUser(),
                context.getBroker().getBrokerPool(),
                new AnyURIValue("/db").toXmldbURI(),
                context.getAccessContext());

        if (isDirectory) {

          XMLDBAbstractCollectionManipulator.createCollection(root, path);

        } else {

          Resource resource;

          File file = new File(path);
          name = file.getName();
          path = file.getParent();

          Collection target =
              (path == null)
                  ? root
                  : XMLDBAbstractCollectionManipulator.createCollection(root, path);

          MimeType mime = MimeTable.getInstance().getContentTypeFor(name);

          try {
            NodeValue content =
                ModuleUtils.streamToXML(context, new ByteArrayInputStream(baos.toByteArray()));
            resource = target.createResource(name, "XMLResource");
            ContentHandler handler = ((XMLResource) resource).setContentAsSAX();
            handler.startDocument();
            content.toSAX(context.getBroker(), handler, null);
            handler.endDocument();
          } catch (SAXException e) {
            resource = target.createResource(name, "BinaryResource");
            resource.setContent(baos.toByteArray());
          }

          if (resource != null) {
            if (mime != null) {
              ((EXistResource) resource).setMimeType(mime.getName());
            }
            target.storeResource(resource);
          }
        }

      } else {

        // try and parse as xml, fall back to binary
        try {
          uncompressedData = ModuleUtils.streamToXML(context, new ByteArrayInputStream(entryData));
        } catch (SAXException saxe) {
          if (entryData.length > 0)
            uncompressedData =
                BinaryValueFromInputStream.getInstance(
                    context, new Base64BinaryValueType(), new ByteArrayInputStream(entryData));
        }

        // call the entry-data function
        Sequence dataParams[] = new Sequence[4];
        System.arraycopy(filterParams, 0, dataParams, 0, 2);
        dataParams[2] = uncompressedData;
        dataParams[3] = storeParam;
        entryDataFunctionResult = entryDataFunction.evalFunction(contextSequence, null, dataParams);
      }

      return entryDataFunctionResult;
    }
  }
Пример #12
0
  /*
   * (non-Javadoc)
   *
   * @see org.exist.xquery.Expression#eval(org.exist.dom.DocumentSet,
   * org.exist.xquery.value.Sequence, org.exist.xquery.value.Item)
   */
  public Sequence eval(Sequence args[], Sequence contextSequence) throws XPathException {

    if (!context.getSubject().hasDbaRole()) {
      final XPathException xPathException =
          new XPathException(
              this,
              "Permission denied, calling user '"
                  + context.getSubject().getName()
                  + "' must be a DBA to call this function.");
      logger.error("Invalid user", xPathException);
      throw xPathException;
    }

    final String user = args[0].getStringValue();
    final String pass = args[1].getStringValue();

    logger.info("Attempting to create user " + user);

    final UserAider userObj = new UserAider(user);
    userObj.setPassword(pass);

    // changed by wolf: the first group is always the primary group, so we
    // don't need
    // an additional argument
    final Sequence groups = args[2];
    final int len = groups.getItemCount();
    for (int x = 0; x < len; x++) {
      userObj.addGroup(groups.itemAt(x).getStringValue());
    }

    Collection collection = null;
    try {
      collection =
          new LocalCollection(
              context.getSubject(),
              context.getBroker().getBrokerPool(),
              XmldbURI.ROOT_COLLECTION_URI,
              context.getAccessContext());
      final UserManagementService ums =
          (UserManagementService) collection.getService("UserManagementService", "1.0");
      ums.addAccount(userObj);

    } catch (final XMLDBException xe) {
      logger.error("Failed to create user: "******"Failed to create user: "******"Failed to create new user '" + user + "' by " + context.getSubject().getName(),
          xe);
    } finally {
      if (null != collection)
        try {
          collection.close();
        } catch (final XMLDBException e) {
          /* ignore */
        }
    }
    return Sequence.EMPTY_SEQUENCE;
  }