Source for javax.swing.text.AbstractDocument

   1: /* AbstractDocument.java --
   2:    Copyright (C) 2002, 2004, 2005  Free Software Foundation, Inc.
   3: 
   4: This file is part of GNU Classpath.
   5: 
   6: GNU Classpath is free software; you can redistribute it and/or modify
   7: it under the terms of the GNU General Public License as published by
   8: the Free Software Foundation; either version 2, or (at your option)
   9: any later version.
  10: 
  11: GNU Classpath is distributed in the hope that it will be useful, but
  12: WITHOUT ANY WARRANTY; without even the implied warranty of
  13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14: General Public License for more details.
  15: 
  16: You should have received a copy of the GNU General Public License
  17: along with GNU Classpath; see the file COPYING.  If not, write to the
  18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  19: 02110-1301 USA.
  20: 
  21: Linking this library statically or dynamically with other modules is
  22: making a combined work based on this library.  Thus, the terms and
  23: conditions of the GNU General Public License cover the whole
  24: combination.
  25: 
  26: As a special exception, the copyright holders of this library give you
  27: permission to link this library with independent modules to produce an
  28: executable, regardless of the license terms of these independent
  29: modules, and to copy and distribute the resulting executable under
  30: terms of your choice, provided that you also meet, for each linked
  31: independent module, the terms and conditions of the license of that
  32: module.  An independent module is a module which is not derived from
  33: or based on this library.  If you modify this library, you may extend
  34: this exception to your version of the library, but you are not
  35: obligated to do so.  If you do not wish to do so, delete this
  36: exception statement from your version. */
  37: 
  38: 
  39: package javax.swing.text;
  40: 
  41: import java.io.PrintStream;
  42: import java.io.Serializable;
  43: import java.util.Dictionary;
  44: import java.util.Enumeration;
  45: import java.util.EventListener;
  46: import java.util.Hashtable;
  47: import java.util.Vector;
  48: 
  49: import javax.swing.event.DocumentEvent;
  50: import javax.swing.event.DocumentListener;
  51: import javax.swing.event.EventListenerList;
  52: import javax.swing.event.UndoableEditEvent;
  53: import javax.swing.event.UndoableEditListener;
  54: import javax.swing.tree.TreeNode;
  55: import javax.swing.undo.AbstractUndoableEdit;
  56: import javax.swing.undo.CompoundEdit;
  57: import javax.swing.undo.UndoableEdit;
  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:   /** The documents properties. */
  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:   // These still need to be implemented by a derived class:
  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:     // FIXME: make me thread-safe
 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:     // FIXME: make me thread-safe
 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:     // Just return when no text to insert was given.
 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:     // FIXME: make me thread-safe
 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:   /**
 301:    * Replaces some text in the document.
 302:    *
 303:    * @since 1.4
 304:    */
 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:   /**
 314:    * Adds a <code>DocumentListener</code> object to this document.
 315:    *
 316:    * @param listener the listener to add
 317:    */
 318:   public void addDocumentListener(DocumentListener listener)
 319:   {
 320:     listenerList.add(DocumentListener.class, listener);
 321:   }
 322: 
 323:   /**
 324:    * Removes a <code>DocumentListener</code> object from this document.
 325:    *
 326:    * @param listener the listener to remove
 327:    */
 328:   public void removeDocumentListener(DocumentListener listener)
 329:   {
 330:     listenerList.remove(DocumentListener.class, listener);
 331:   }
 332: 
 333:   /**
 334:    * Returns add added <code>DocumentListener</code> objects.
 335:    *
 336:    * @return an array of listeners
 337:    */
 338:   public DocumentListener[] getDocumentListeners()
 339:   {
 340:     return (DocumentListener[]) getListeners(DocumentListener.class);
 341:   }
 342: 
 343:   /**
 344:    * Adds a <code>UndoableEditListener</code> object to this document.
 345:    *
 346:    * @param listener the listener to add
 347:    */
 348:   public void addUndoableEditListener(UndoableEditListener listener)
 349:   {
 350:     listenerList.add(UndoableEditListener.class, listener);
 351:   }
 352: 
 353:   /**
 354:    * Removes a <code>UndoableEditListener</code> object from this document.
 355:    *
 356:    * @param listener the listener to remove
 357:    */
 358:   public void removeUndoableEditListener(UndoableEditListener listener)
 359:   {
 360:     listenerList.remove(UndoableEditListener.class, listener);
 361:   }
 362: 
 363:   /**
 364:    * Returns add added <code>UndoableEditListener</code> objects.
 365:    *
 366:    * @return an array of listeners
 367:    */
 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:     // FIXME: make me thread-safe
 388:     properties = x;
 389:   }
 390: 
 391:   protected void writeLock()
 392:   {
 393:   }
 394: 
 395:   protected void writeUnlock()
 396:   {
 397:   }
 398: 
 399:   /**
 400:    * @since 1.4
 401:    */
 402:   public DocumentFilter getDocumentFilter()
 403:   {
 404:     return documentFilter;
 405:   }
 406: 
 407:   /**
 408:    * @since 1.4
 409:    */
 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:     // TreeNode implementation
 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:     // MutableAttributeSet support
 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:     // AttributeSet interface support
 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:     // Element interface support
 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:       // XXX: There is surely a better algorithm
 696:       // as beginning from first element each time.
 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:       // XXX: There is surely a better algorithm
 732:       // as beginning from first element each time.
 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: }