123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- // Copyright (c) 2003, 2013 Per M.A. Bothner.
- // This is free software; for terms and warranty disclaimer see ./COPYING.
- package gnu.kawa.xml;
- import gnu.mapping.Values;
- import gnu.lists.*;
- import gnu.xml.*;
- /* #ifdef use:org.w3c.dom.Node */
- import org.w3c.dom.*;
- /* #endif */
- /** Manages a sequence of node references.
- */
- public class Nodes extends Values.FromList<SeqPosition>
- implements PositionConsumer,
- /* #ifdef use:org.w3c.dom.Node */
- org.w3c.dom.NodeList,
- /* #endif */
- Consumer
- {
- protected NodeVector vector;
- private Nodes(NodeVector nvector) {
- super(nvector);
- this.vector = nvector;
- }
- public Nodes() {
- this(new NodeVector());
- }
- public Consumer append(char c) {
- maybeStartTextNode();
- curFragment.append(c);
- return this;
- }
- public Consumer append(CharSequence csq) {
- maybeStartTextNode();
- curFragment.append(csq);
- return this;
- }
- public boolean ignoring() {
- return false;
- }
- int nesting = 0;
- boolean inAttribute;
- NodeTree curNode;
- XMLFilter curFragment;
- public void writePosition (AbstractSequence seq, int ipos) {
- vector.writePosition(seq, ipos);
- }
-
- public void writePosition(SeqPosition position) {
- vector.writePosition(position);
- }
- public void writeObject(Object v) {
- if (curFragment != null) {
- if (nesting == 0
- && (v instanceof SeqPosition || v instanceof TreeList))
- finishFragment();
- else {
- curFragment.writeObject(v);
- return;
- }
- }
- if (v instanceof SeqPosition) {
- writePosition((SeqPosition) v);
- return;
- }
- if (v instanceof TreeList) {
- TreeList tlist = (TreeList) v;
- writePosition(tlist, 0);
- return;
- }
- handleNonNode();
- curFragment.writeObject(v);
- return;
- }
- void maybeStartTextNode ()
- {
- if (curFragment == null)
- {
- throw new IllegalArgumentException("non-node where node required");
- }
- }
- void handleNonNode ()
- {
- if (curFragment == null)
- {
- throw new ClassCastException("atomic value where node is required");
- }
- }
- public void writeFloat (float v)
- {
- handleNonNode();
- curFragment.writeFloat(v);
- }
- public void writeDouble (double v)
- {
- handleNonNode();
- curFragment.writeDouble(v);
- }
- public void writeLong(long v)
- {
- handleNonNode();
- curFragment.writeLong(v);
- }
- public void writeInt(int v)
- {
- handleNonNode();
- curFragment.writeInt(v);
- }
- public void writeBoolean (boolean v)
- {
- handleNonNode();
- curFragment.writeBoolean(v);
- }
- public void write (int v)
- {
- maybeStartTextNode();
- curFragment.write(v);
- }
- public Consumer append (CharSequence csq, int start, int end) {
- maybeStartTextNode();
- curFragment.append(csq, start, end);
- return this;
- }
- public void write(char[] buf, int off, int len)
- {
- maybeStartTextNode();
- curFragment.write(buf, off, len);
- }
- public void write(CharSequence str, int start, int length)
- {
- maybeStartTextNode();
- curFragment.write(str, start, length);
- }
- public void write (String str)
- {
- maybeStartTextNode();
- curFragment.write(str);
- }
- private void maybeStartNonTextNode ()
- {
- if (curFragment != null && nesting == 0)
- finishFragment();
- if (curFragment == null)
- startFragment();
- nesting++;
- }
- private void maybeEndNonTextNode ()
- {
- if (--nesting == 0)
- finishFragment();
- }
- public void startElement (Object type)
- {
- maybeStartNonTextNode();
- curFragment.startElement(type);
- }
- public void endElement ()
- {
- curFragment.endElement();
- maybeEndNonTextNode();
- }
- public void startAttribute(Object attrType)
- {
- maybeStartNonTextNode();
- curFragment.startAttribute(attrType);
- inAttribute = true;
- }
- public void endAttribute()
- {
- if (! inAttribute)
- return;
- inAttribute = false;
- curFragment.endAttribute();
- maybeEndNonTextNode();
- }
- public void writeComment(char[] chars, int offset, int length)
- {
- maybeStartNonTextNode();
- curFragment.writeComment(chars, offset, length);
- maybeEndNonTextNode();
- }
- public void writeCDATA(char[] chars, int offset, int length)
- {
- maybeStartNonTextNode();
- curFragment.writeCDATA(chars, offset, length);
- }
- public void writeProcessingInstruction(String target, char[] content,
- int offset, int length)
- {
- maybeStartNonTextNode();
- curFragment.writeProcessingInstruction(target, content, offset, length);
- maybeEndNonTextNode();
- }
- public void startDocument()
- {
- maybeStartNonTextNode();
- curFragment.startDocument();
- }
- public void endDocument()
- {
- curFragment.endDocument();
- maybeEndNonTextNode();
- }
- public void beginEntity(Object base)
- {
- maybeStartNonTextNode();
- curFragment.beginEntity(base);
- }
- public void endEntity()
- {
- curFragment.endEntity();
- maybeEndNonTextNode();
- }
- void startFragment ()
- {
- curNode = new NodeTree();
- curFragment = new XMLFilter(curNode);
- writePosition(curNode, 0);
- }
- void finishFragment ()
- {
- curNode = null;
- curFragment = null;
- }
- /*
- public int size()
- {
- return count;
- }
- */
- public int getLength()
- {
- return size();
- }
- /* #ifdef use:org.w3c.dom.Node */
- public Node item(int index)
- {
- if (index >= size())
- return null;
- else
- return (Node) get(index);
- }
- /* #endif */
- /** Optimization of {@code ((SeqPosition) get(index)).sequence}.
- * However returns null instead of throwing IndexOutOfBoundsException
- * if {@code index >= count}. */
- public AbstractSequence getSeq(int index) {
- if (index >= vector.size())
- return null;
- return vector.getSeq(index);
- }
- /** Optimization of ((SeqPosition) get(index)). ipos. */
- public int getPos(int index) {
- return vector.getPos(index);
- }
- public void consumePosRange (int iposStart, int iposEnd, Consumer out) {
- vector.consumePosRange(iposStart, iposEnd, out);
- }
- public static class NodeVector
- extends SimpleVector<SeqPosition>
- implements PositionConsumer {
- Object[] odata;
- int[] idata;
- int getLastIndex() { return getGapStart() - 1; }
- public int getBufferLength() {
- return odata == null ? 0 : odata.length;
- }
- public void copyBuffer(int length) {
- checkCanWrite();
- int oldLength = odata == null ? 0 : odata.length;
- if (length == -1)
- length = oldLength;
- if (oldLength != length) {
- if (oldLength > length)
- oldLength = length;
- Object[] otmp = new Object[length];
- int[] itmp = new int[length];
- if (oldLength != 0) {
- System.arraycopy(odata, 0, otmp, 0, oldLength);
- System.arraycopy(idata, 0, itmp, 0, oldLength);
- }
- odata = otmp;
- idata = itmp;
- }
- }
- protected Object getBuffer() { throw new Error(); }
- protected void setBuffer(Object buffer) { throw new Error(); }
- public SeqPosition getRaw(int index) {
- Object obj = odata[index];
- if (obj instanceof SeqPosition)
- return (SeqPosition) obj;
- return makeSeqPos((AbstractSequence) obj, idata[index]);
- }
- public AbstractSequence getSeq(int index) {
- return getSeqRaw(effectiveIndex(index));
- }
- public AbstractSequence getSeqRaw(int index) {
- Object obj = odata[index];
- if (obj instanceof SeqPosition)
- return ((SeqPosition) obj).sequence;
- return (AbstractSequence) obj;
- }
- public int getPos(int index) {
- return getPosRaw(effectiveIndex(index));
- }
- public int getPosRaw(int index) {
- Object obj = odata[index];
- if (obj instanceof SeqPosition)
- return ((SeqPosition) obj).ipos;
- return idata[index];
- }
- protected static SeqPosition makeSeqPos(AbstractSequence seq, int ipos) {
- if (seq instanceof NodeTree)
- return KNode.make((NodeTree) seq, ipos);
- else
- return new SeqPosition(seq, ipos);
- }
- public void setRaw(int index, SeqPosition value) {
- checkCanWrite();
- odata[index] = value;
- idata[index] = 0;
- }
- protected void setBuffer(int index, AbstractSequence seq, int ipos) {
- checkCanWrite();
- odata[index] = seq;
- idata[index] = ipos;
- }
- protected void clearBuffer(int start, int count) {
- checkCanWrite();
- Object[] d = odata;
- while (--count >= 0)
- d[start++] = null;
- }
- @Override
- protected NodeVector newInstance(int newLength) {
- NodeVector nvec = new NodeVector();
- if (newLength < 0) {
- nvec.odata = this.odata;
- nvec.idata = this.idata;
- } else {
- nvec.odata = new Object[newLength];
- nvec.idata = new int[newLength];
- }
- return nvec;
- }
- public void writePosition(SeqPosition seq) {
- add(seq);
- }
- public void writePosition(AbstractSequence seq, int ipos) {
- int sz = size();
- add((SeqPosition) null);
- odata[sz] = seq;
- idata[sz] = ipos;
- }
- public void shift(int srcStart, int dstStart, int count) {
- checkCanWrite();
- System.arraycopy(odata, srcStart, odata, dstStart, count);
- System.arraycopy(idata, srcStart, idata, dstStart, count);
- }
- public void consumePosRange (int iposStart, int iposEnd, Consumer out) {
- if (out.ignoring())
- return;
- int i = nextIndex(iposStart);
- int end = nextIndex(iposEnd);
- int size = size();
- if (end > size)
- end = size;
- for (; i < end; i++) {
- int ii = effectiveIndex(i);
- if (out instanceof PositionConsumer) {
- PositionConsumer pout = (PositionConsumer) out;
- Object obj = odata[ii];
- if (obj instanceof SeqPosition)
- pout.writePosition((SeqPosition) obj);
- else
- pout.writePosition((AbstractSequence) obj, idata[ii]);
- }
- else
- out.writeObject(getRaw(ii));
- }
- }
- }
- public static KNode root (NodeTree seq, int ipos)
- {
- int root;
- if (seq.gapStart > TreeList.BEGIN_ENTITY_SIZE
- && seq.data[0] == TreeList.BEGIN_ENTITY)
- root = TreeList.BEGIN_ENTITY_SIZE << 1;
- else
- root = 0;
- return KNode.make(seq, root);
- }
- }
|