/**
  * Process one item in the population
  *
  * @param index the index of items
  * @param item the item from the population to be processed
  * @param c2 the XPath evaluation context
  * @throws XPathException
  */
 protected void processItem(HashMap<ComparisonKey, List<Item>> index, Item item, XPathContext c2)
     throws XPathException {
   SequenceIterator keys = keyExpression.iterate(c2);
   boolean firstKey = true;
   while (true) {
     AtomicValue key = (AtomicValue) keys.next();
     if (key == null) {
       break;
     }
     ComparisonKey comparisonKey = comparer.getComparisonKey(key);
     List<Item> g = index.get(comparisonKey);
     if (g == null) {
       List<Item> newGroup = new ArrayList<Item>(20);
       newGroup.add(item);
       groups.add(newGroup);
       groupKeys.add(key);
       index.put(comparisonKey, newGroup);
     } else {
       if (firstKey) {
         g.add(item);
       } else {
         // if this is not the first key value for this item, we
         // check whether the item is already in this group before
         // adding it again. If it is in this group, then we know
         // it will be at the end.
         if (g.get(g.size() - 1) != item) {
           g.add(item);
         }
       }
     }
     firstKey = false;
   }
 }
Exemple #2
0
 /** Evaluate the function in a boolean context */
 public boolean effectiveBooleanValue(XPathContext c) throws XPathException {
   SequenceIterator iter = argument[0].iterate(c);
   boolean result;
   if ((iter.getProperties() & SequenceIterator.LOOKAHEAD) != 0) {
     result = !((LookaheadIterator) iter).hasNext();
   } else {
     result = iter.next() == null;
   }
   iter.close();
   return result;
 }
Exemple #3
0
  /**
   * Show a query producing a sequence as its result and returning the sequence to the Java
   * application in the form of an iterator. For each item in the result, its string value is
   * output.
   */
  public static void exampleToSequence() throws XPathException {
    final Configuration config = new Configuration();
    final StaticQueryContext sqc = config.newStaticQueryContext();
    final XQueryExpression exp = sqc.compileQuery("for $i in 1 to 10 return ($i * $i)");

    final DynamicQueryContext dynamicContext = new DynamicQueryContext(config);
    final SequenceIterator iter = exp.iterator(dynamicContext);
    while (true) {
      Item item = iter.next();
      if (item == null) {
        break;
      }
      System.out.println(item.getStringValue());
    }
  }
 /**
  * Build the grouping table forming groups of items with equal keys. This form of grouping allows
  * a member of the population to be present in zero or more groups, one for each value of the
  * grouping key.
  */
 private void buildIndexedGroups() throws XPathException {
   HashMap index = new HashMap(40);
   XPathContext c2 = keyContext.newMinorContext();
   c2.setCurrentIterator(population);
   while (true) {
     Item item = population.next();
     if (item == null) {
       break;
     }
     processItem(index, item, c2);
   }
 }
 /**
  * Returns <tt>true</tt> if the iteration has more elements. (In other words, returns
  * <tt>true</tt> if <tt>next</tt> would return an element rather than throwing an exception.)
  *
  * @return <tt>true</tt> if the iterator has more elements.
  * @throws SaxonApiUncheckedException if a dynamic error occurs during XPath evaluation that is
  *     detected at this point.
  */
 public boolean hasNext() throws SaxonApiUncheckedException {
   switch (state) {
     case ON_ITEM:
       return true;
     case FINISHED:
       return false;
     case BEFORE_ITEM:
       try {
         next = XdmItem.wrapItem(base.next());
         if (next == null) {
           state = FINISHED;
           return false;
         } else {
           state = ON_ITEM;
           return true;
         }
       } catch (XPathException err) {
         throw new SaxonApiUncheckedException(err);
       }
     default:
       throw new IllegalStateException();
   }
 }
  /**
   * Convert an XPath value to an object in this object model. If the supplied value can be
   * converted to an object in this model, of the specified class, then the conversion should be
   * done and the resulting object returned. If the value cannot be converted, the method should
   * return null. Note that the supplied class might be a List, in which case the method should
   * inspect the contents of the Value to see whether they belong to this object model.
   *
   * @throws XPathException if the target class is explicitly associated with this object model, but
   *     the supplied value cannot be converted to the appropriate class
   */
  public Object convertXPathValueToObject(Value value, Class target, XPathContext context)
      throws XPathException {
    // We accept the object if (a) the target class is Node, Node[], or NodeList,
    // or (b) the supplied object is a node, or sequence of nodes, that wrap DOM nodes,
    // provided that the target class is Object or a collection class
    boolean requireDOM =
        (Node.class.isAssignableFrom(target)
            || (target == NodeList.class)
            || (target.isArray() && Node.class.isAssignableFrom(target.getComponentType())));

    // Note: we allow the declared type of the method argument to be a subclass of Node. If the
    // actual
    // node supplied is the wrong kind of node, this will result in a Java exception.

    boolean allowDOM =
        (target == Object.class
            || target.isAssignableFrom(ArrayList.class)
            || target.isAssignableFrom(HashSet.class)
            || (target.isArray() && target.getComponentType() == Object.class));
    if (!(requireDOM || allowDOM)) {
      return null;
    }
    List nodes = new ArrayList(20);

    SequenceIterator iter = value.iterate(context);
    while (true) {
      Item item = iter.next();
      if (item == null) {
        break;
      }
      if (item instanceof VirtualNode) {
        Object o = ((VirtualNode) item).getUnderlyingNode();
        if (o instanceof Node) {
          nodes.add(o);
        } else {
          if (requireDOM) {
            DynamicError err =
                new DynamicError(
                    "Extension function required class "
                        + target.getName()
                        + "; supplied value of class "
                        + item.getClass().getName()
                        + " could not be converted");
            throw err;
          }
          ;
        }
      } else if (requireDOM) {
        if (item instanceof NodeInfo) {
          nodes.add(NodeOverNodeInfo.wrap((NodeInfo) item));
        } else {
          DynamicError err =
              new DynamicError(
                  "Extension function required class "
                      + target.getName()
                      + "; supplied value of class "
                      + item.getClass().getName()
                      + " could not be converted");
          throw err;
        }
      } else {
        return null; // DOM Nodes are not actually required; let someone else try the conversion
      }
    }

    if (nodes.size() == 0 && !requireDOM) {
      return null; // empty sequence supplied - try a different mapping
    }
    if (Node.class.isAssignableFrom(target)) {
      if (nodes.size() != 1) {
        DynamicError err =
            new DynamicError(
                "Extension function requires a single DOM Node"
                    + "; supplied value contains "
                    + nodes.size()
                    + " nodes");
        throw err;
      }
      return nodes.get(0);
      // could fail if the node is of the wrong kind
    } else if (target == NodeList.class) {
      return new DOMNodeList(nodes);
    } else if (target.isArray() && target.getComponentType() == Node.class) {
      Node[] array = new Node[nodes.size()];
      nodes.toArray(array);
      return array;
    } else if (target.isAssignableFrom(ArrayList.class)) {
      return nodes;
    } else if (target.isAssignableFrom(HashSet.class)) {
      return new HashSet(nodes);
    } else {
      // after all this work, give up
      return null;
    }
  }
 /*@NotNull*/
 public SequenceIterator getAnother() throws XPathException {
   XPathContext c2 = keyContext.newMinorContext();
   return new GroupByIterator(population.getAnother(), keyExpression, c2, collator);
 }
  private void runAdjacent() throws SaxonApiException {
    TreeWriter treeWriter = null;
    String last = null;
    boolean open = false;

    int count = 0;
    while (source.moreDocuments()) {
      count++;
      source.read();
    }
    source.resetReader();

    DocumentSequenceIterator xsi = new DocumentSequenceIterator(); // See below
    xsi.setLast(count);

    int pos = 0;
    while (source.moreDocuments()) {
      XdmNode node = source.read();
      pos++;

      Item item = null;

      try {
        XPathCompiler xcomp = runtime.getProcessor().newXPathCompiler();
        xcomp.setBaseURI(step.getNode().getBaseURI());

        for (String prefix : groupAdjacent.getNamespaceBindings().keySet()) {
          xcomp.declareNamespace(prefix, groupAdjacent.getNamespaceBindings().get(prefix));
        }

        XPathExecutable xexec = xcomp.compile(groupAdjacent.getString());

        // From Michael Kay: http://markmail.org/message/vkb2vaq2miylgndu
        //
        // Underneath the s9api XPathExecutable is a net.sf.saxon.sxpath.XPathExpression.

        XPathExpression xexpr = xexec.getUnderlyingExpression();

        // Call createDynamicContext() on this to get an XPathDynamicContext object;

        XPathDynamicContext xdc = xexpr.createDynamicContext(node.getUnderlyingNode());

        // call getXPathContextObject() on that to get the underlying XPathContext.

        XPathContext xc = xdc.getXPathContextObject();

        // Then call XPathContext.setCurrentIterator()
        // to supply a SequenceIterator whose current() and position() methods return
        // the context item and position respectively. If there's any risk that the
        // expression will call the last() method, then it's simplest to make your
        // iterator's getProperties() return LAST_POSITION_FINDER, and implement the
        // LastPositionFinder interface, in which case last() will be implemented by
        // calling the iterator's getLastPosition() method. (Otherwise last() is
        // implemented by calling getAnother() to clone the iterator and calling next()
        // on the clone until the end of the sequence is reached).

        xsi.setPosition(pos);
        xsi.setItem(node.getUnderlyingNode());
        xc.setCurrentIterator(xsi);

        // Then evaluate the expression by calling iterate() on the
        // net.sf.saxon.sxpath.XPathExpression object.

        SequenceIterator results = xexpr.iterate(xdc);
        item = results.next();

        if (item == null) {
          throw new XProcException(
              step.getNode(), "The group-adjacent expression returned nothing.");
        }

        if (results.next() != null) {
          throw new XProcException(
              step.getNode(), "Didn't expect group-adjacent to return a sequence!");
        }
      } catch (XPathException xe) {
        throw new XProcException(xe);
      }

      //
      //  Good luck!
      //

      // FIXME: Compute effective boolean value in a more robust way
      String cur = item.getStringValue();

      if (last != null) {
        if (last.equals(cur)) {
          treeWriter.addSubtree(node);
        } else {
          if (open) {
            open = false;
            treeWriter.addEndElement();
            treeWriter.endDocument();
            result.write(treeWriter.getResult());
          }
        }
      }

      if (last == null || !last.equals(cur)) {
        last = cur;
        open = true;
        treeWriter = new TreeWriter(runtime);
        treeWriter.startDocument(step.getNode().getBaseURI());
        treeWriter.addStartElement(wrapper);
        treeWriter.startContent();
        treeWriter.addSubtree(node);
      }
    }

    if (open) {
      open = false;
      treeWriter.addEndElement();
      treeWriter.endDocument();
      result.write(treeWriter.getResult());
    }
  }
 private static List<String> sequenceToList(Sequence seq) throws XPathException {
   List<String> list = new ArrayList<String>();
   for (SequenceIterator<?> i = seq.iterate(); i.next() != null; )
     list.add(i.current().getStringValue());
   return list;
 }
Exemple #10
0
 private List<?> processRow()
     throws ExpressionEvaluationException, BlockedException, TeiidComponentException,
         TeiidProcessingException {
   List<Object> tuple = new ArrayList<Object>(projectedColumns.size());
   for (XMLColumn proColumn : projectedColumns) {
     if (proColumn.isOrdinal()) {
       if (rowCount > Integer.MAX_VALUE) {
         throw new TeiidRuntimeException(
             new TeiidProcessingException(
                 QueryPlugin.Event.TEIID31174, QueryPlugin.Util.gs(QueryPlugin.Event.TEIID31174)));
       }
       tuple.add((int) rowCount);
     } else {
       try {
         XPathExpression path = proColumn.getPathExpression();
         XPathDynamicContext dynamicContext = path.createDynamicContext(item);
         SequenceIterator pathIter = path.iterate(dynamicContext);
         Item colItem = pathIter.next();
         if (colItem == null) {
           if (proColumn.getDefaultExpression() != null) {
             tuple.add(
                 getEvaluator(Collections.emptyMap())
                     .evaluate(proColumn.getDefaultExpression(), null));
           } else {
             tuple.add(null);
           }
           continue;
         }
         if (proColumn.getSymbol().getType() == DataTypeManager.DefaultDataClasses.XML) {
           XMLType value =
               table
                   .getXQueryExpression()
                   .createXMLType(
                       pathIter.getAnother(), this.getBufferManager(), false, getContext());
           tuple.add(value);
           continue;
         }
         Item next = pathIter.next();
         if (next != null) {
           if (proColumn.getSymbol().getType().isArray()) {
             ArrayList<Object> vals = new ArrayList<Object>();
             vals.add(
                 getValue(
                     proColumn.getSymbol().getType().getComponentType(),
                     colItem,
                     this.table.getXQueryExpression().getConfig(),
                     getContext()));
             vals.add(
                 getValue(
                     proColumn.getSymbol().getType().getComponentType(),
                     next,
                     this.table.getXQueryExpression().getConfig(),
                     getContext()));
             while ((next = pathIter.next()) != null) {
               vals.add(
                   getValue(
                       proColumn.getSymbol().getType().getComponentType(),
                       next,
                       this.table.getXQueryExpression().getConfig(),
                       getContext()));
             }
             Object value =
                 new ArrayImpl(
                     vals.toArray(
                         (Object[])
                             Array.newInstance(
                                 proColumn.getSymbol().getType().getComponentType(),
                                 vals.size())));
             tuple.add(value);
             continue;
           }
           throw new TeiidProcessingException(
               QueryPlugin.Event.TEIID30171,
               QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30171, proColumn.getName()));
         }
         Object value =
             getValue(
                 proColumn.getSymbol().getType(),
                 colItem,
                 this.table.getXQueryExpression().getConfig(),
                 getContext());
         tuple.add(value);
       } catch (XPathException e) {
         throw new TeiidProcessingException(
             QueryPlugin.Event.TEIID30172,
             e,
             QueryPlugin.Util.gs(QueryPlugin.Event.TEIID30172, proColumn.getName()));
       }
     }
   }
   item = null;
   return tuple;
 }