001: package net.sf.saxon.functions;
002:
003: import net.sf.saxon.expr.XPathContext;
004: import net.sf.saxon.om.Item;
005: import net.sf.saxon.om.SequenceIterator;
006: import net.sf.saxon.trans.XPathException;
007: import net.sf.saxon.value.AtomicValue;
008: import net.sf.saxon.value.NumericValue;
009:
010: /**
011: * The XPath 2.0 insert-before() function
012: */
013:
014: public class Insert extends SystemFunction {
015:
016: /**
017: * Evaluate the function to return an iteration of selected nodes.
018: */
019:
020: public SequenceIterator iterate(XPathContext context)
021: throws XPathException {
022: SequenceIterator seq = argument[0].iterate(context);
023: AtomicValue n0 = (AtomicValue) argument[1]
024: .evaluateItem(context);
025: NumericValue n = (NumericValue) n0.getPrimitiveValue();
026: int pos = (int) n.longValue();
027: SequenceIterator ins = argument[2].iterate(context);
028: return new InsertIterator(seq, ins, pos);
029: }
030:
031: public static class InsertIterator implements SequenceIterator {
032:
033: private SequenceIterator base;
034: private SequenceIterator insert;
035: private int insertPosition;
036: private int position = 0;
037: private Item current = null;
038: private boolean inserting = false;
039:
040: public InsertIterator(SequenceIterator base,
041: SequenceIterator insert, int insertPosition) {
042: this .base = base;
043: this .insert = insert;
044: this .insertPosition = (insertPosition < 1 ? 1
045: : insertPosition);
046: this .inserting = (insertPosition == 1);
047: }
048:
049: public Item next() throws XPathException {
050: Item nextItem;
051: if (inserting) {
052: nextItem = insert.next();
053: if (nextItem == null) {
054: inserting = false;
055: nextItem = base.next();
056: }
057: } else {
058: if (position == insertPosition - 1) {
059: nextItem = insert.next();
060: if (nextItem == null) {
061: nextItem = base.next();
062: } else {
063: inserting = true;
064: }
065: } else {
066: nextItem = base.next();
067: if (nextItem == null
068: && position < insertPosition - 1) {
069: inserting = true;
070: nextItem = insert.next();
071: }
072: }
073: }
074: if (nextItem == null) {
075: current = null;
076: position = -1;
077: return null;
078: } else {
079: current = nextItem;
080: position++;
081: return current;
082: }
083: }
084:
085: public Item current() {
086: return current;
087: }
088:
089: public int position() {
090: return position;
091: }
092:
093: public SequenceIterator getAnother() throws XPathException {
094: return new InsertIterator(base.getAnother(), insert
095: .getAnother(), insertPosition);
096: }
097:
098: /**
099: * Get properties of this iterator, as a bit-significant integer.
100: *
101: * @return the properties of this iterator. This will be some combination of
102: * properties such as {@link GROUNDED}, {@link LAST_POSITION_FINDER},
103: * and {@link LOOKAHEAD}. It is always
104: * acceptable to return the value zero, indicating that there are no known special properties.
105: * It is acceptable for the properties of the iterator to change depending on its state.
106: */
107:
108: public int getProperties() {
109: return 0;
110: }
111:
112: }
113:
114: }
115:
116: //
117: // The contents of this file are subject to the Mozilla Public License Version 1.0 (the "License");
118: // you may not use this file except in compliance with the License. You may obtain a copy of the
119: // License at http://www.mozilla.org/MPL/
120: //
121: // Software distributed under the License is distributed on an "AS IS" basis,
122: // WITHOUT WARRANTY OF ANY KIND, either express or implied.
123: // See the License for the specific language governing rights and limitations under the License.
124: //
125: // The Original Code is: all this file.
126: //
127: // The Initial Developer of the Original Code is Michael H. Kay
128: //
129: // Portions created by (your name) are Copyright (C) (your legal entity). All Rights Reserved.
130: //
131: // Contributor(s): none.
132: //
|