1:
37:
38:
39: package ;
40:
41: import ;
42: import ;
43: import ;
44: import ;
45: import ;
46: import ;
47: import ;
48:
49: import ;
50: import ;
51: import ;
52: import ;
53: import ;
54: import ;
55: import ;
56: import ;
57: import ;
58:
59: public abstract class AbstractDocument
60: implements Document, Serializable
61: {
62: private static final long serialVersionUID = -116069779446114664L;
63:
64: protected static final String BAD_LOCATION = "document location failure";
65:
66: public static final String BidiElementName = "bidi level";
67: public static final String ContentElementName = "content";
68: public static final String ParagraphElementName = "paragraph";
69: public static final String SectionElementName = "section";
70: public static final String ElementNameAttribute = "$ename";
71:
72: Content content;
73: AttributeContext context;
74: DocumentFilter documentFilter;
75:
76:
77: Dictionary properties;
78:
79: protected EventListenerList listenerList = new EventListenerList();
80:
81: protected AbstractDocument(Content doc)
82: {
83: this(doc, StyleContext.getDefaultStyleContext());
84: }
85:
86: protected AbstractDocument(Content doc, AttributeContext ctx)
87: {
88: content = doc;
89: context = ctx;
90: }
91:
92:
93: public abstract Element getParagraphElement(int pos);
94:
95: public abstract Element getDefaultRootElement();
96:
97: protected Element createBranchElement(Element parent,
98: AttributeSet attributes)
99: {
100: return new BranchElement(parent, attributes);
101: }
102:
103: protected Element createLeafElement(Element parent, AttributeSet attributes,
104: int start, int end)
105: {
106: return new LeafElement(parent, attributes, start, end);
107: }
108:
109: public Position createPosition(final int offset) throws BadLocationException
110: {
111: if (offset < 0 || offset > getLength())
112: throw new BadLocationException(getText(0, getLength()), offset);
113:
114: return new Position()
115: {
116: public int getOffset()
117: {
118: return offset;
119: }
120: };
121: }
122:
123: protected void fireChangedUpdate(DocumentEvent event)
124: {
125: DocumentListener[] listeners = getDocumentListeners();
126:
127: for (int index = 0; index < listeners.length; ++index)
128: listeners[index].changedUpdate(event);
129: }
130:
131: protected void fireInsertUpdate(DocumentEvent event)
132: {
133: DocumentListener[] listeners = getDocumentListeners();
134:
135: for (int index = 0; index < listeners.length; ++index)
136: listeners[index].insertUpdate(event);
137: }
138:
139: protected void fireRemoveUpdate(DocumentEvent event)
140: {
141: DocumentListener[] listeners = getDocumentListeners();
142:
143: for (int index = 0; index < listeners.length; ++index)
144: listeners[index].removeUpdate(event);
145: }
146:
147: protected void fireUndoableEditUpdate(UndoableEditEvent event)
148: {
149: UndoableEditListener[] listeners = getUndoableEditListeners();
150:
151: for (int index = 0; index < listeners.length; ++index)
152: listeners[index].undoableEditHappened(event);
153: }
154:
155: public int getAsynchronousLoadPriority()
156: {
157: return 0;
158: }
159:
160: protected AttributeContext getAttributeContext()
161: {
162: return context;
163: }
164:
165: public Element getBidiRootElement()
166: {
167: return null;
168: }
169:
170: protected Content getContent()
171: {
172: return content;
173: }
174:
175: protected Thread getCurrentWriter()
176: {
177: return null;
178: }
179:
180: public Dictionary getDocumentProperties()
181: {
182:
183: if (properties == null)
184: properties = new Hashtable();
185:
186: return properties;
187: }
188:
189: public Position getEndPosition()
190: {
191: return new Position()
192: {
193: public int getOffset()
194: {
195: return getLength();
196: }
197: };
198: }
199:
200: public int getLength()
201: {
202: return content.length() - 1;
203: }
204:
205: public EventListener[] getListeners(Class listenerType)
206: {
207: return listenerList.getListeners(listenerType);
208: }
209:
210: public Object getProperty(Object key)
211: {
212:
213: Object value = null;
214: if (properties != null)
215: value = properties.get(key);
216:
217: return value;
218: }
219:
220: public Element[] getRootElements()
221: {
222: Element[] elements = new Element[1];
223: elements[0] = getDefaultRootElement();
224: return elements;
225: }
226:
227: public Position getStartPosition()
228: {
229: return new Position()
230: {
231: public int getOffset()
232: {
233: return 0;
234: }
235: };
236: }
237:
238: public String getText(int offset, int length) throws BadLocationException
239: {
240: return content.getString(offset, length);
241: }
242:
243: public void getText(int offset, int length, Segment segment)
244: throws BadLocationException
245: {
246: content.getChars(offset, length, segment);
247: }
248:
249: public void insertString(int offset, String text, AttributeSet attributes)
250: throws BadLocationException
251: {
252:
253: if (text == null || text.length() == 0)
254: return;
255:
256: DefaultDocumentEvent event =
257: new DefaultDocumentEvent(offset, text.length(),
258: DocumentEvent.EventType.INSERT);
259: content.insertString(offset, text);
260: insertUpdate(event, attributes);
261: fireInsertUpdate(event);
262: }
263:
264: protected void insertUpdate(DefaultDocumentEvent chng, AttributeSet attr)
265: {
266: }
267:
268: protected void postRemoveUpdate(DefaultDocumentEvent chng)
269: {
270: }
271:
272: public void putProperty(Object key, Object value)
273: {
274:
275: if (properties == null)
276: properties = new Hashtable();
277:
278: properties.put(key, value);
279: }
280:
281: public void readLock()
282: {
283: }
284:
285: public void readUnlock()
286: {
287: }
288:
289: public void remove(int offset, int length) throws BadLocationException
290: {
291: DefaultDocumentEvent event =
292: new DefaultDocumentEvent(offset, length,
293: DocumentEvent.EventType.REMOVE);
294: removeUpdate(event);
295: content.remove(offset, length);
296: postRemoveUpdate(event);
297: fireRemoveUpdate(event);
298: }
299:
300:
305: public void replace(int offset, int length, String text,
306: AttributeSet attributes)
307: throws BadLocationException
308: {
309: remove(offset, length);
310: insertString(offset, text, attributes);
311: }
312:
313:
318: public void addDocumentListener(DocumentListener listener)
319: {
320: listenerList.add(DocumentListener.class, listener);
321: }
322:
323:
328: public void removeDocumentListener(DocumentListener listener)
329: {
330: listenerList.remove(DocumentListener.class, listener);
331: }
332:
333:
338: public DocumentListener[] getDocumentListeners()
339: {
340: return (DocumentListener[]) getListeners(DocumentListener.class);
341: }
342:
343:
348: public void addUndoableEditListener(UndoableEditListener listener)
349: {
350: listenerList.add(UndoableEditListener.class, listener);
351: }
352:
353:
358: public void removeUndoableEditListener(UndoableEditListener listener)
359: {
360: listenerList.remove(UndoableEditListener.class, listener);
361: }
362:
363:
368: public UndoableEditListener[] getUndoableEditListeners()
369: {
370: return (UndoableEditListener[]) getListeners(UndoableEditListener.class);
371: }
372:
373: protected void removeUpdate(DefaultDocumentEvent chng)
374: {
375: }
376:
377: public void render(Runnable r)
378: {
379: }
380:
381: public void setAsynchronousLoadPriority(int p)
382: {
383: }
384:
385: public void setDocumentProperties(Dictionary x)
386: {
387:
388: properties = x;
389: }
390:
391: protected void writeLock()
392: {
393: }
394:
395: protected void writeUnlock()
396: {
397: }
398:
399:
402: public DocumentFilter getDocumentFilter()
403: {
404: return documentFilter;
405: }
406:
407:
410: public void setDocumentFilter(DocumentFilter filter)
411: {
412: this.documentFilter = filter;
413: }
414:
415: public void dump(PrintStream out)
416: {
417: ((AbstractElement) getDefaultRootElement()).dump(out, 0);
418: }
419:
420: public interface AttributeContext
421: {
422: AttributeSet addAttribute(AttributeSet old, Object name, Object value);
423:
424: AttributeSet addAttributes(AttributeSet old, AttributeSet attributes);
425:
426: AttributeSet getEmptySet();
427:
428: void reclaim(AttributeSet attributes);
429:
430: AttributeSet removeAttribute(AttributeSet old, Object name);
431:
432: AttributeSet removeAttributes(AttributeSet old, AttributeSet attributes);
433:
434: AttributeSet removeAttributes(AttributeSet old, Enumeration names);
435: }
436:
437: public interface Content
438: {
439: Position createPosition(int offset) throws BadLocationException;
440:
441: int length();
442:
443: UndoableEdit insertString(int where, String str)
444: throws BadLocationException;
445:
446: UndoableEdit remove(int where, int nitems) throws BadLocationException;
447:
448: String getString(int where, int len) throws BadLocationException;
449:
450: void getChars(int where, int len, Segment txt) throws BadLocationException;
451: }
452:
453: public abstract class AbstractElement
454: implements Element, MutableAttributeSet, TreeNode, Serializable
455: {
456: private static final long serialVersionUID = 1265312733007397733L;
457: int count;
458: int offset;
459:
460: AttributeSet attributes;
461:
462: Element element_parent;
463:
464: TreeNode tree_parent;
465: Vector tree_children;
466:
467: public AbstractElement(Element p, AttributeSet s)
468: {
469: element_parent = p;
470: attributes = s;
471: }
472:
473:
474:
475: public abstract Enumeration children();
476:
477: public abstract boolean getAllowsChildren();
478:
479: public TreeNode getChildAt(int index)
480: {
481: return (TreeNode) tree_children.get(index);
482: }
483:
484: public int getChildCount()
485: {
486: return tree_children.size();
487: }
488:
489: public int getIndex(TreeNode node)
490: {
491: return tree_children.indexOf(node);
492: }
493:
494: public TreeNode getParent()
495: {
496: return tree_parent;
497: }
498:
499: public abstract boolean isLeaf();
500:
501:
502:
503:
504: public void addAttribute(Object name, Object value)
505: {
506: attributes = getAttributeContext().addAttribute(attributes, name, value);
507: }
508:
509: public void addAttributes(AttributeSet attrs)
510: {
511: attributes = getAttributeContext().addAttributes(attributes, attrs);
512: }
513:
514: public void removeAttribute(Object name)
515: {
516: attributes = getAttributeContext().removeAttribute(attributes, name);
517: }
518:
519: public void removeAttributes(AttributeSet attrs)
520: {
521: attributes = getAttributeContext().removeAttributes(attributes, attrs);
522: }
523:
524: public void removeAttributes(Enumeration names)
525: {
526: attributes = getAttributeContext().removeAttributes(attributes, names);
527: }
528:
529: public void setResolveParent(AttributeSet parent)
530: {
531: attributes = getAttributeContext().addAttribute(attributes, ResolveAttribute, parent);
532: }
533:
534:
535:
536:
537: public boolean containsAttribute(Object name, Object value)
538: {
539: return attributes.containsAttribute(name, value);
540: }
541:
542: public boolean containsAttributes(AttributeSet attrs)
543: {
544: return attributes.containsAttributes(attrs);
545: }
546:
547: public AttributeSet copyAttributes()
548: {
549: return attributes.copyAttributes();
550: }
551:
552: public Object getAttribute(Object key)
553: {
554: return attributes.getAttribute(key);
555: }
556:
557: public int getAttributeCount()
558: {
559: return attributes.getAttributeCount();
560: }
561:
562: public Enumeration getAttributeNames()
563: {
564: return attributes.getAttributeNames();
565: }
566:
567: public AttributeSet getResolveParent()
568: {
569: return attributes.getResolveParent();
570: }
571:
572: public boolean isDefined(Object attrName)
573: {
574: return attributes.isDefined(attrName);
575: }
576:
577: public boolean isEqual(AttributeSet attrs)
578: {
579: return attributes.isEqual(attrs);
580: }
581:
582:
583:
584: public AttributeSet getAttributes()
585: {
586: return attributes;
587: }
588:
589: public Document getDocument()
590: {
591: return AbstractDocument.this;
592: }
593:
594: public abstract Element getElement(int index);
595:
596: public String getName()
597: {
598: return (String) getAttribute(NameAttribute);
599: }
600:
601: public Element getParentElement()
602: {
603: return element_parent;
604: }
605:
606: public abstract int getEndOffset();
607:
608: public abstract int getElementCount();
609:
610: public abstract int getElementIndex(int offset);
611:
612: public abstract int getStartOffset();
613:
614: private void dumpElement(PrintStream stream, String indent, Element element)
615: {
616: System.out.println(indent + "<" + element.getName() +">");
617:
618: if (element.isLeaf())
619: {
620: int start = element.getStartOffset();
621: int end = element.getEndOffset();
622: String text = "";
623: try
624: {
625: text = getContent().getString(start, end - start);
626: }
627: catch (BadLocationException e)
628: {
629: }
630: System.out.println(indent + " ["
631: + start + ","
632: + end + "]["
633: + text + "]");
634: }
635: else
636: {
637: for (int i = 0; i < element.getElementCount(); ++i)
638: dumpElement(stream, indent + " ", element.getElement(i));
639: }
640: }
641:
642: public void dump(PrintStream stream, int indent)
643: {
644: String indentStr = "";
645: for (int i = 0; i < indent; ++i)
646: indentStr += " ";
647: dumpElement(stream, indentStr, this);
648: }
649: }
650:
651: public class BranchElement extends AbstractElement
652: {
653: private static final long serialVersionUID = -8595176318868717313L;
654:
655: private Element[] children = new Element[0];
656:
657: public BranchElement(Element parent, AttributeSet attributes)
658: {
659: super(parent, attributes);
660: }
661:
662: public Enumeration children()
663: {
664: if (children.length == 0)
665: return null;
666:
667: Vector tmp = new Vector();
668:
669: for (int index = 0; index < children.length; ++index)
670: tmp.add(children[index]);
671:
672: return tmp.elements();
673: }
674:
675: public boolean getAllowsChildren()
676: {
677: return true;
678: }
679:
680: public Element getElement(int index)
681: {
682: if (index < 0 || index >= children.length)
683: return null;
684:
685: return children[index];
686: }
687:
688: public int getElementCount()
689: {
690: return children.length;
691: }
692:
693: public int getElementIndex(int offset)
694: {
695:
696:
697: for (int index = 0; index < children.length; ++index)
698: {
699: Element elem = children[index];
700:
701: if ((elem.getStartOffset() <= offset)
702: && (offset < elem.getEndOffset()))
703: return index;
704: }
705:
706: return 0;
707: }
708:
709: public int getEndOffset()
710: {
711: return children[children.length - 1].getEndOffset();
712: }
713:
714: public String getName()
715: {
716: return ParagraphElementName;
717: }
718:
719: public int getStartOffset()
720: {
721: return children[0].getStartOffset();
722: }
723:
724: public boolean isLeaf()
725: {
726: return false;
727: }
728:
729: public Element positionToElement(int position)
730: {
731:
732:
733: for (int index = 0; index < children.length; ++index)
734: {
735: Element elem = children[index];
736:
737: if ((elem.getStartOffset() <= position)
738: && (position < elem.getEndOffset()))
739: return elem;
740: }
741:
742: return null;
743: }
744:
745: public void replace(int offset, int length, Element[] elements)
746: {
747: Element[] target = new Element[children.length - length
748: + elements.length];
749: System.arraycopy(children, 0, target, 0, offset);
750: System.arraycopy(elements, 0, target, offset, elements.length);
751: System.arraycopy(children, offset + length, target,
752: offset + elements.length,
753: children.length - offset - length);
754: children = target;
755: }
756:
757: public String toString()
758: {
759: return ("BranchElement(" + getName() + ") "
760: + getStartOffset() + "," + getEndOffset() + "\n");
761: }
762: }
763:
764: public class DefaultDocumentEvent extends CompoundEdit
765: implements DocumentEvent
766: {
767: private static final long serialVersionUID = -7406103236022413522L;
768:
769: private int offset;
770: private int length;
771: private DocumentEvent.EventType type;
772:
773: public DefaultDocumentEvent(int offset, int length,
774: DocumentEvent.EventType type)
775: {
776: this.offset = offset;
777: this.length = length;
778: this.type = type;
779: }
780:
781: public Document getDocument()
782: {
783: return AbstractDocument.this;
784: }
785:
786: public int getLength()
787: {
788: return length;
789: }
790:
791: public int getOffset()
792: {
793: return offset;
794: }
795:
796: public DocumentEvent.EventType getType()
797: {
798: return type;
799: }
800:
801: public DocumentEvent.ElementChange getChange(Element elem)
802: {
803: return null;
804: }
805: }
806:
807: public static class ElementEdit extends AbstractUndoableEdit
808: implements DocumentEvent.ElementChange
809: {
810: private static final long serialVersionUID = -1216620962142928304L;
811:
812: private Element elem;
813: private int index;
814: private Element[] removed;
815: private Element[] added;
816:
817: public ElementEdit(Element elem, int index,
818: Element[] removed, Element[] added)
819: {
820: this.elem = elem;
821: this.index = index;
822: this.removed = removed;
823: this.added = added;
824: }
825:
826: public Element[] getChildrenAdded()
827: {
828: return added;
829: }
830:
831: public Element[] getChildrenRemoved()
832: {
833: return removed;
834: }
835:
836: public Element getElement()
837: {
838: return elem;
839: }
840:
841: public int getIndex()
842: {
843: return index;
844: }
845: }
846:
847: public class LeafElement extends AbstractElement
848: {
849: private static final long serialVersionUID = 5115368706941283802L;
850: int start;
851: int end;
852:
853: public LeafElement(Element parent, AttributeSet attributes, int start,
854: int end)
855: {
856: super(parent, attributes);
857: this.start = start;
858: this.end = end;
859: }
860:
861: public Enumeration children()
862: {
863: return null;
864: }
865:
866: public boolean getAllowsChildren()
867: {
868: return false;
869: }
870:
871: public Element getElement(int index)
872: {
873: return null;
874: }
875:
876: public int getElementCount()
877: {
878: return 0;
879: }
880:
881: public int getElementIndex(int offset)
882: {
883: return -1;
884: }
885:
886: public int getEndOffset()
887: {
888: return end;
889: }
890:
891: public String getName()
892: {
893: return ContentElementName;
894: }
895:
896: public int getStartOffset()
897: {
898: return start;
899: }
900:
901: public boolean isLeaf()
902: {
903: return true;
904: }
905:
906: public String toString()
907: {
908: return ("LeafElement(" + getName() + ") "
909: + getStartOffset() + "," + getEndOffset() + "\n");
910: }
911: }
912: }