示例#1
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;
  }
示例#2
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;
 }
示例#3
0
  private static String serialize(DBBroker broker, Item item) throws SAXException, XPathException {
    Serializer serializer = broker.getSerializer();

    serializer.reset();
    String value;
    if (Type.subTypeOf(item.getType(), Type.NODE)) {
      value = serializer.serialize((NodeValue) item);
    } else {
      value = item.getStringValue();
    }
    return value;
  }
示例#4
0
  @Override
  public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {

    NodeImpl report = null;
    try {
      // Only match documents that match these URLs
      List<String> toBeMatchedURIs = new ArrayList<>();

      Sequence pathSeq = getArgumentCount() == 2 ? args[0] : contextSequence;
      if (pathSeq == null) return Sequence.EMPTY_SEQUENCE;

      // Get first agument, these are the documents / collections to search in
      for (SequenceIterator i = pathSeq.iterate(); i.hasNext(); ) {
        String path;
        Item item = i.nextItem();
        if (Type.subTypeOf(item.getType(), Type.NODE)) {
          if (((NodeValue) item).isPersistentSet()) {
            path = ((NodeProxy) item).getDocument().getURI().toString();
          } else {
            path = item.getStringValue();
          }
        } else {
          path = item.getStringValue();
        }
        toBeMatchedURIs.add(path);
      }

      // Get second argument, this is the query
      String query;
      if (getArgumentCount() == 1) query = args[0].itemAt(0).getStringValue();
      else query = args[1].itemAt(0).getStringValue();

      // Get the lucene worker
      LuceneIndexWorker index =
          (LuceneIndexWorker)
              context.getBroker().getIndexController().getWorkerByIndexId(LuceneIndex.ID);

      // Perform search
      report = index.search(context, toBeMatchedURIs, query);

    } catch (XPathException ex) {
      // Log and rethrow
      logger.error(ex);
      throw ex;
    }

    // Return list of matching files.
    return report;
  }
示例#5
0
  /* (non-Javadoc)
   * @see org.exist.xquery.Expression#eval(org.exist.xquery.StaticContext, org.exist.dom.DocumentSet, 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());
    }

    Sequence result = atomize(expression.eval(contextSequence, contextItem));

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

    return result;
  }
示例#6
0
  /* (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 {
    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;
    // return 0 if the argument sequence is empty
    // TODO : return empty sequence ?
    if (args[0].isEmpty()) result = IntegerValue.ZERO;
    else {
      int count = 0;
      for (SequenceIterator i = args[0].iterate(); i.hasNext(); ) {
        Item next = i.nextItem();
        if (Type.subTypeOf(next.getType(), Type.NODE)) {
          NodeValue nv = (NodeValue) next;
          if (nv.getImplementationType() != NodeValue.PERSISTENT_NODE)
            throw new XPathException(
                getASTNode(), getName() + " cannot be applied to in-memory nodes.");
          NodeProxy np = (NodeProxy) nv;
          Match match = np.getMatches();
          while (match != null) {
            if (match.getNodeId().isDescendantOrSelfOf(np.getNodeId())) {
              count += match.getFrequency();
            }
            match = match.getNextMatch();
          }
        }
      }
      result = new IntegerValue(count);
    }

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

    return result;
  }
示例#7
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());
      }
    }

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

    Sequence result;
    final String s1 = getArgument(0).eval(contextSequence).getStringValue();
    final String s2 = getArgument(1).eval(contextSequence).getStringValue();
    if (s1.length() == 0 || s2.length() == 0) {
      result = Sequence.EMPTY_SEQUENCE;
    } else {
      final Collator collator = getCollator(contextSequence, contextItem, 3);
      if (Collations.startsWith(collator, s1, s2)) {
        result = BooleanValue.TRUE;
      } else {
        result = BooleanValue.FALSE;
      }
    }

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

    return result;
  }
示例#8
0
 public boolean flag(String query, boolean defaultValue) {
   Item item = optional(query);
   if (item != Item.NULL) {
     try {
       return item.booleanValue();
     } catch (Exception e) {
       LOG.error(
           "illegal flag value '"
               + item
               + "' found for query "
               + query
               + "; using default '"
               + defaultValue
               + "'");
     }
   }
   return defaultValue;
 }
示例#9
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());
    }

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

    Sequence result;
    Sequence arg = null;
    if (getSignature().getArgumentCount() == 1) arg = getArgument(0).eval(contextSequence);
    else arg = contextSequence;

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

    if (arg.isEmpty()) result = DoubleValue.NaN;
    else {
      try {
        result = arg.convertTo(Type.DOUBLE);
      } catch (XPathException e) {
        result = DoubleValue.NaN;
      }
    }

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

    return result;
  }
  /* (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 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();

    Sequence result;
    Sequence seq = expression.eval(contextSequence, contextItem);
    if (seq.isEmpty()) result = Sequence.EMPTY_SEQUENCE;
    else {
      //    		seq.setSelfAsContext();
      result = seq;
      for (Iterator i = predicates.iterator(); i.hasNext(); ) {
        Predicate pred = (Predicate) i.next();
        result = pred.evalPredicate(contextSequence, result, Constants.DESCENDANT_SELF_AXIS);
      }
    }

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

    return result;
  }
示例#11
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 contextSequence, Item contextItem) throws XPathException {
    logger.error(
        "Use of deprecated function fn:doctype(). "
            + "It will be removed soon. Please "
            + "use util:doctype() instead.");
    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());
    }

    MutableDocumentSet docs = new DefaultDocumentSet();
    for (int i = 0; i < getArgumentCount(); i++) {
      Sequence seq = getArgument(i).eval(contextSequence, contextItem);
      for (SequenceIterator j = seq.iterate(); j.hasNext(); ) {
        String next = j.nextItem().getStringValue();
        context.getBroker().getXMLResourcesByDoctype(next, docs);
      }
    }

    NodeSet result = new ExtArrayNodeSet(1);
    for (Iterator i = docs.getDocumentIterator(); i.hasNext(); ) {
      result.add(new NodeProxy((DocumentImpl) i.next(), NodeId.DOCUMENT_NODE));
    }

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

    return result;
  }
示例#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 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());
    }

    ResponseModule myModule = (ResponseModule) context.getModule(ResponseModule.NAMESPACE_URI);

    // response object is read from global variable $response
    Variable var = myModule.resolveVariable(ResponseModule.RESPONSE_VAR);
    if (var == null || var.getValue() == null) throw new XPathException("Response not set");
    if (var.getValue().getItemType() != Type.JAVA_OBJECT)
      throw new XPathException("Variable $response is not bound to a Java object.");
    JavaObjectValue response = (JavaObjectValue) var.getValue().itemAt(0);

    // get parameter
    int code =
        ((IntegerValue) getArgument(0).eval(contextSequence, contextItem).convertTo(Type.INTEGER))
            .getInt();

    // set response status code
    if (response.getObject() instanceof ResponseWrapper)
      ((ResponseWrapper) response.getObject()).setStatusCode(code);
    else
      throw new XPathException("Type error: variable $response is not bound to a response object");

    return Sequence.EMPTY_SEQUENCE;
  }
示例#13
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 result;
    Sequence[] args = getArguments(contextSequence, contextItem);
    Collator collator = getCollator(contextSequence, contextItem, 3);
    int length = args[0].getItemCount();
    if (length != args[1].getItemCount()) result = BooleanValue.FALSE;
    else {
      result = BooleanValue.TRUE;
      for (int i = 0; i < length; i++) {
        if (!deepEquals(args[0].itemAt(i), args[1].itemAt(i), collator)) {
          result = BooleanValue.FALSE;
          break;
        }
      }
    }

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

    return result;
  }
  /** @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;
  }
示例#15
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;
  }
示例#16
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;
  }
示例#17
0
  private boolean deepEquals(Item a, Item b, Collator collator) {
    try {
      final boolean aAtomic = Type.subTypeOf(a.getType(), Type.ATOMIC);
      final boolean bAtomic = Type.subTypeOf(b.getType(), Type.ATOMIC);
      if (aAtomic || bAtomic) {
        if (!aAtomic || !bAtomic) return false;
        try {
          AtomicValue av = (AtomicValue) a;
          AtomicValue bv = (AtomicValue) b;
          if (Type.subTypeOf(av.getType(), Type.NUMBER)
              && Type.subTypeOf(bv.getType(), Type.NUMBER)) {
            // or if both values are NaN
            if (((NumericValue) a).isNaN() && ((NumericValue) b).isNaN()) return true;
          }
          return ValueComparison.compareAtomic(
              collator, av, bv, Constants.TRUNC_NONE, Constants.EQ);
        } catch (XPathException e) {
          return false;
        }
      }
      //		assert Type.subTypeOf(a.getType(), Type.NODE);
      //		assert Type.subTypeOf(b.getType(), Type.NODE);
      if (a.getType() != b.getType()) return false;
      NodeValue nva = (NodeValue) a, nvb = (NodeValue) b;
      if (nva == nvb) return true;
      try {
        // Don't use this shortcut for in-memory nodes since the symbol table is ignored.
        if (nva.getImplementationType() != NodeValue.IN_MEMORY_NODE && nva.equals(nvb))
          return true; // shortcut!
      } catch (XPathException e) {
        // apparently incompatible values, do manual comparison
      }
      Node na, nb;
      switch (a.getType()) {
        case Type.DOCUMENT:
          // NodeValue.getNode() doesn't seem to work for document nodes
          na = nva instanceof Node ? (Node) nva : ((NodeProxy) nva).getDocument();
          nb = nvb instanceof Node ? (Node) nvb : ((NodeProxy) nvb).getDocument();
          return compareContents(na, nb);
        case Type.ELEMENT:
          na = nva.getNode();
          nb = nvb.getNode();
          return compareElements(na, nb);
        case Type.ATTRIBUTE:
          na = nva.getNode();
          nb = nvb.getNode();
          return compareNames(na, nb) && safeEquals(na.getNodeValue(), nb.getNodeValue());
        case Type.PROCESSING_INSTRUCTION:
        case Type.NAMESPACE:
          na = nva.getNode();
          nb = nvb.getNode();
          return safeEquals(na.getNodeName(), nb.getNodeName())
              && safeEquals(nva.getStringValue(), nvb.getStringValue());
        case Type.TEXT:
        case Type.COMMENT:
          return safeEquals(nva.getStringValue(), nvb.getStringValue());

        default:
          {
            logger.error("unexpected item type " + Type.getTypeName(a.getType()));
            throw new RuntimeException("unexpected item type " + Type.getTypeName(a.getType()));
          }
      }
    } catch (XPathException e) {
      logger.error(e.getMessage());
      e.printStackTrace();
      return false;
    }
  }
示例#18
0
 /** Add a sequence item to the node set. The item has to be a subtype of node. */
 public void add(Item item) throws XPathException {
   if (!Type.subTypeOf(item.getType(), Type.NODE)) throw new XPathException("item has wrong type");
   add((NodeProxy) item);
 }
示例#19
0
  /*
   * Actual implementation of the rendering process. When a function in this
   * module is called, this method is executed with the given inputs. @param
   * Sequence[] args (XSL-FO, mime-type, parameters) @param Sequence
   * contextSequence (default sequence)
   *
   * @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 {
    // gather input XSL-FO document
    // if no input document (empty), return empty result as we need data to
    // process
    if (args[0].isEmpty()) return Sequence.EMPTY_SEQUENCE;
    Item inputNode = args[0].itemAt(0);

    // get mime-type
    String mimeType = args[1].getStringValue();

    // get parameters
    Properties parameters = new Properties();
    if (!args[2].isEmpty()) {
      parameters = ModuleUtils.parseParameters(((NodeValue) args[2].itemAt(0)).getNode());
    }

    try {
      // setup a transformer handler
      TransformerHandler handler =
          TransformerFactoryAllocator.getTransformerFactory(context.getBroker())
              .newTransformerHandler();
      Transformer transformer = handler.getTransformer();

      // set the parameters if any
      if (parameters.size() > 0) {
        Enumeration keys = parameters.keys();
        while (keys.hasMoreElements()) {
          String name = (String) keys.nextElement();
          String value = parameters.getProperty(name);
          transformer.setParameter(name, value);
        }
      }

      // setup the FopFactory
      FopFactory fopFactory = FopFactory.newInstance();
      if (args.length == 4 && args[3] != null && !args[3].isEmpty()) {
        FopConfigurationBuilder cfgBuilder = new FopConfigurationBuilder(context.getBroker());
        Configuration cfg = cfgBuilder.buildFromItem(args[3].itemAt(0));
        fopFactory.setUserConfig(cfg);
      }

      // setup the foUserAgent, using given parameters held in the
      // transformer handler
      FOUserAgent foUserAgent =
          setupFOUserAgent(fopFactory.newFOUserAgent(), parameters, transformer);

      // create new instance of FOP using the mimetype, the created user
      // agent, and the output stream
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      Fop fop = fopFactory.newFop(mimeType, foUserAgent, baos);

      // Obtain FOP's DefaultHandler
      DefaultHandler dh = fop.getDefaultHandler();

      // process the XSL-FO
      dh.startDocument();
      inputNode.toSAX(context.getBroker(), dh, new Properties());
      dh.endDocument();

      // return the result
      return new Base64Binary(baos.toByteArray());
    } catch (TransformerException te) {
      throw new XPathException(te);
    } catch (SAXException se) {
      throw new XPathException(se);
    }
  }
示例#20
0
 public Configuration buildFromItem(Item item) throws SAXException {
   SAXConfigurationHandler handler = getHandler();
   handler.clear();
   item.toSAX(broker, handler, new Properties());
   return handler.getConfiguration();
 }
示例#21
0
  /**
   * @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String,
   *     java.lang.String, org.xml.sax.Attributes)
   */
  public void startElement(String namespaceURI, String localName, String qName, Attributes atts)
      throws SAXException {
    // save accumulated character content
    if (inModification && charBuf.length() > 0) {
      //            String normalized = charBuf.toString();
      final String normalized =
          preserveWhitespace
              ? charBuf.toString()
              : charBuf.getNormalizedString(FastStringBuffer.SUPPRESS_BOTH);

      if (normalized.length() > 0) {
        final Text text = doc.createTextNode(charBuf.toString());
        if (stack.isEmpty()) {
          // LOG.debug("appending text to fragment: " + text.getData());
          contents.add(text);
        } else {
          final Element last = stack.peek();
          last.appendChild(text);
        }
      }
      charBuf.setLength(0);
    }
    if (namespaceURI.equals(XUPDATE_NS)) {
      String select = null;
      if (localName.equals(MODIFICATIONS)) {
        startModifications(atts);
        return;
      } else if (localName.equals(VARIABLE)) {
        // variable declaration
        startVariableDecl(atts);
        return;
      } else if (IF.equals(localName)) {
        if (inModification) {
          throw new SAXException("xupdate:if is not allowed inside a modification");
        }
        select = atts.getValue("test");
        final Conditional cond =
            new Conditional(broker, documentSet, select, namespaces, variables);
        cond.setAccessContext(accessCtx);
        conditionals.push(cond);
        return;
      } else if (VALUE_OF.equals(localName)) {
        if (!inModification) {
          throw new SAXException("xupdate:value-of is not allowed outside a modification");
        }

      } else if (APPEND.equals(localName)
          || INSERT_BEFORE.equals(localName)
          || INSERT_AFTER.equals(localName)
          || REMOVE.equals(localName)
          || RENAME.equals(localName)
          || UPDATE.equals(localName)
          || REPLACE.equals(localName)) {
        if (inModification) {
          throw new SAXException("nested modifications are not allowed");
        }
        select = atts.getValue("select");
        if (select == null) {
          throw new SAXException(localName + " requires a select attribute");
        }
        doc = builder.newDocument();
        contents = new NodeListImpl();
        inModification = true;
      } else if ((ELEMENT.equals(localName)
          || ATTRIBUTE.equals(localName)
          || TEXT.equals(localName)
          || PROCESSING_INSTRUCTION.equals(localName)
          || COMMENT.equals(localName))) {
        if (!inModification) {
          throw new SAXException("creation elements are only allowed inside " + "a modification");
        }
        charBuf.setLength(0);
      } else {
        throw new SAXException("Unknown XUpdate element: " + qName);
      }

      // start a new modification section
      if (APPEND.equals(localName)) {
        final String child = atts.getValue("child");
        modification = new Append(broker, documentSet, select, child, namespaces, variables);
      } else if (UPDATE.equals(localName)) {
        modification = new Update(broker, documentSet, select, namespaces, variables);
      } else if (INSERT_BEFORE.equals(localName)) {
        modification =
            new Insert(broker, documentSet, select, Insert.INSERT_BEFORE, namespaces, variables);
      } else if (INSERT_AFTER.equals(localName)) {
        modification =
            new Insert(broker, documentSet, select, Insert.INSERT_AFTER, namespaces, variables);
      } else if (REMOVE.equals(localName)) {
        modification = new Remove(broker, documentSet, select, namespaces, variables);
      } else if (RENAME.equals(localName)) {
        modification = new Rename(broker, documentSet, select, namespaces, variables);
      } else if (REPLACE.equals(localName)) {
        modification = new Replace(broker, documentSet, select, namespaces, variables);
      }

      // process commands for node creation
      else if (ELEMENT.equals(localName)) {
        String name = atts.getValue("name");
        if (name == null) {
          throw new SAXException("element requires a name attribute");
        }
        final int p = name.indexOf(':');
        String namespace = null;
        String prefix = "";
        if (p != Constants.STRING_NOT_FOUND) {
          prefix = name.substring(0, p);
          if (name.length() == p + 1) {
            throw new SAXException("illegal prefix in qname: " + name);
          }
          name = name.substring(p + 1);
          namespace = atts.getValue("namespace");
          if (namespace == null) {
            namespace = (String) namespaces.get(prefix);
          }
          if (namespace == null) {
            throw new SAXException("no namespace defined for prefix " + prefix);
          }
        }
        Element elem;
        if (namespace != null && namespace.length() > 0) {
          elem = doc.createElementNS(namespace, name);
          elem.setPrefix(prefix);
        } else {
          elem = doc.createElement(name);
        }

        if (stack.isEmpty()) {
          contents.add(elem);
        } else {
          final Element last = stack.peek();
          last.appendChild(elem);
        }
        this.setWhitespaceHandling((Element) stack.push(elem));
      } else if (ATTRIBUTE.equals(localName)) {
        final String name = atts.getValue("name");
        if (name == null) {
          throw new SAXException("attribute requires a name attribute");
        }
        final int p = name.indexOf(':');
        String namespace = null;
        if (p != Constants.STRING_NOT_FOUND) {
          final String prefix = name.substring(0, p);
          if (name.length() == p + 1) {
            throw new SAXException("illegal prefix in qname: " + name);
          }
          namespace = atts.getValue("namespace");
          if (namespace == null) {
            namespace = (String) namespaces.get(prefix);
          }
          if (namespace == null) {
            throw new SAXException("no namespace defined for prefix " + prefix);
          }
        }
        Attr attrib =
            namespace != null && namespace.length() > 0
                ? doc.createAttributeNS(namespace, name)
                : doc.createAttribute(name);
        if (stack.isEmpty()) {
          for (int i = 0; i < contents.getLength(); i++) {
            final Node n = contents.item(i);
            String ns = n.getNamespaceURI();
            final String nname = ns == null ? n.getNodeName() : n.getLocalName();
            if (ns == null) {
              ns = "";
            }
            // check for duplicate attributes
            if (n.getNodeType() == Node.ATTRIBUTE_NODE
                && nname.equals(name)
                && ns.equals(namespace)) {
              throw new SAXException(
                  "The attribute " + attrib.getNodeName() + " cannot be specified twice");
            }
          }
          contents.add(attrib);
        } else {
          final Element last = (Element) stack.peek();
          if (namespace != null && last.hasAttributeNS(namespace, name)
              || namespace == null && last.hasAttribute(name)) {
            throw new SAXException(
                "The attribute "
                    + attrib.getNodeName()
                    + " cannot be specified "
                    + "twice on the same element");
          }
          if (namespace != null) {
            last.setAttributeNodeNS(attrib);
          } else {
            last.setAttributeNode(attrib);
          }
        }
        inAttribute = true;
        currentNode = attrib;

        // process value-of
      } else if (VALUE_OF.equals(localName)) {
        select = atts.getValue("select");
        if (select == null) {
          throw new SAXException("value-of requires a select attribute");
        }
        final Sequence seq = processQuery(select);
        if (LOG.isDebugEnabled()) {
          LOG.debug("Found " + seq.getItemCount() + " items for value-of");
        }
        Item item;
        try {
          for (final SequenceIterator i = seq.iterate(); i.hasNext(); ) {
            item = i.nextItem();
            if (Type.subTypeOf(item.getType(), Type.NODE)) {
              final Node node = NodeSetHelper.copyNode(doc, ((NodeValue) item).getNode());
              if (stack.isEmpty()) {
                contents.add(node);
              } else {
                final Element last = (Element) stack.peek();
                last.appendChild(node);
              }
            } else {
              final String value = item.getStringValue();
              characters(value.toCharArray(), 0, value.length());
            }
          }
        } catch (final XPathException e) {
          throw new SAXException(e.getMessage(), e);
        }
      }
    } else if (inModification) {
      final Element elem =
          namespaceURI != null && namespaceURI.length() > 0
              ? doc.createElementNS(namespaceURI, qName)
              : doc.createElement(qName);
      Attr a;
      for (int i = 0; i < atts.getLength(); i++) {
        final String name = atts.getQName(i);
        final String nsURI = atts.getURI(i);
        if (name.startsWith("xmlns")) {
          // Why are these showing up? They are supposed to be stripped out?
        } else {
          a = nsURI != null ? doc.createAttributeNS(nsURI, name) : doc.createAttribute(name);
          a.setValue(atts.getValue(i));
          if (nsURI != null) {
            elem.setAttributeNodeNS(a);
          } else {
            elem.setAttributeNode(a);
          }
        }
      }
      if (stack.isEmpty()) {
        contents.add(elem);
      } else {
        final Element last = (Element) stack.peek();
        last.appendChild(elem);
      }
      this.setWhitespaceHandling((Element) stack.push(elem));
    }
  }