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