/** * 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; } }
/** 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; }
/** * 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; }
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; }