/[classpath]/classpath/javax/swing/text/AbstractDocument.java
ViewVC logotype

Diff of /classpath/javax/swing/text/AbstractDocument.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.9.2.10 by tromey, Thu Oct 6 00:32:40 2005 UTC revision 1.9.2.11 by gnu_andrew, Wed Nov 2 00:44:02 2005 UTC
# Line 127  public abstract class AbstractDocument i Line 127  public abstract class AbstractDocument i
127     * Manages event listeners for this <code>Document</code>.     * Manages event listeners for this <code>Document</code>.
128     */     */
129    protected EventListenerList listenerList = new EventListenerList();    protected EventListenerList listenerList = new EventListenerList();
130      
131      /**
132       * Stores the current writer thread.  Used for locking.
133       */
134      private Thread currentWriter = null;
135      
136      /**
137       * The number of readers.  Used for locking.
138       */
139      private int numReaders = 0;
140      
141      /**
142       * Tells if there are one or more writers waiting.
143       */
144      private int numWritersWaiting = 0;  
145    
146    /**    /**
147       * A condition variable that readers and writers wait on.
148       */
149      Object documentCV = new Object();
150    
151      
152      /**
153     * Creates a new <code>AbstractDocument</code> with the specified     * Creates a new <code>AbstractDocument</code> with the specified
154     * {@link Content} model.     * {@link Content} model.
155     *     *
# Line 347  public abstract class AbstractDocument i Line 368  public abstract class AbstractDocument i
368     */     */
369    protected Thread getCurrentWriter()    protected Thread getCurrentWriter()
370    {    {
371      // FIXME: Implement locking!      return currentWriter;
     return null;  
372    }    }
373    
374    /**    /**
# Line 515  public abstract class AbstractDocument i Line 535  public abstract class AbstractDocument i
535      // Just return when no text to insert was given.      // Just return when no text to insert was given.
536      if (text == null || text.length() == 0)      if (text == null || text.length() == 0)
537        return;        return;
       
538      DefaultDocumentEvent event =      DefaultDocumentEvent event =
539        new DefaultDocumentEvent(offset, text.length(),        new DefaultDocumentEvent(offset, text.length(),
540                                 DocumentEvent.EventType.INSERT);                                 DocumentEvent.EventType.INSERT);
541      content.insertString(offset, text);      
542        writeLock();
543        UndoableEdit undo = content.insertString(offset, text);
544      insertUpdate(event, attributes);      insertUpdate(event, attributes);
545        writeUnlock();
546    
547      fireInsertUpdate(event);      fireInsertUpdate(event);
548        if (undo != null)
549          fireUndoableEditUpdate(new UndoableEditEvent(this, undo));
550    }    }
551    
552    /**    /**
# Line 565  public abstract class AbstractDocument i Line 590  public abstract class AbstractDocument i
590    }    }
591    
592    /**    /**
593     * Blocks until a read lock can be obtained.     * Blocks until a read lock can be obtained.  Must block if there is
594       * currently a writer modifying the <code>Document</code>.
595     */     */
596    public void readLock()    public void readLock()
597    {    {
598        if (currentWriter != null && currentWriter.equals(Thread.currentThread()))
599          return;
600        synchronized (documentCV)
601          {
602            while (currentWriter != null || numWritersWaiting > 0)
603              {
604                try
605                  {
606                    documentCV.wait();
607                  }
608                catch (InterruptedException ie)
609                  {
610                    throw new Error("interrupted trying to get a readLock");
611                  }
612              }
613              numReaders++;
614          }
615    }    }
616    
617    /**    /**
# Line 577  public abstract class AbstractDocument i Line 620  public abstract class AbstractDocument i
620     */     */
621    public void readUnlock()    public void readUnlock()
622    {    {
623        // Note we could have a problem here if readUnlock was called without a
624        // prior call to readLock but the specs simply warn users to ensure that
625        // balance by using a finally block:
626        // readLock()
627        // try
628        // {
629        //   doSomethingHere
630        // }
631        // finally
632        // {
633        //   readUnlock();
634        // }
635        
636        // All that the JDK seems to check for is that you don't call unlock
637        // more times than you've previously called lock, but it doesn't make
638        // sure that the threads calling unlock were the same ones that called lock
639    
640        // FIXME: the reference implementation throws a
641        // javax.swing.text.StateInvariantError here
642        if (numReaders == 0)
643          throw new IllegalStateException("document lock failure");
644        
645        synchronized (documentCV)
646        {
647          // If currentWriter is not null, the application code probably had a
648          // writeLock and then tried to obtain a readLock, in which case
649          // numReaders wasn't incremented
650          if (currentWriter == null)
651            {
652              numReaders --;
653              if (numReaders == 0 && numWritersWaiting != 0)
654                documentCV.notify();
655            }
656        }
657    }    }
658    
659    /**    /**
# Line 594  public abstract class AbstractDocument i Line 671  public abstract class AbstractDocument i
671      DefaultDocumentEvent event =      DefaultDocumentEvent event =
672        new DefaultDocumentEvent(offset, length,        new DefaultDocumentEvent(offset, length,
673                                 DocumentEvent.EventType.REMOVE);                                 DocumentEvent.EventType.REMOVE);
674        
675        // Here we set up the parameters for an ElementChange, if one
676        // needs to be added to the DocumentEvent later
677        Element root = getDefaultRootElement();
678        int start = root.getElementIndex(offset);
679        int end = root.getElementIndex(offset + length);
680        
681        Element[] removed = new Element[end - start + 1];
682        for (int i = start; i <= end; i++)
683          removed[i - start] = root.getElement(i);
684        
685      removeUpdate(event);      removeUpdate(event);
686      content.remove(offset, length);  
687        Element[] added = new Element[1];
688        added[0] = root.getElement(start);
689        boolean shouldFire = content.getString(offset, length).length() != 0;
690        
691        writeLock();
692        UndoableEdit temp = content.remove(offset, length);
693        writeUnlock();
694        
695      postRemoveUpdate(event);      postRemoveUpdate(event);
696      fireRemoveUpdate(event);      
697        GapContent.UndoRemove changes = null;
698        if (content instanceof GapContent)
699          changes = (GapContent.UndoRemove) temp;
700    
701        if (changes != null && !(start == end))
702          {
703            // We need to add an ElementChange to our DocumentEvent
704            ElementEdit edit = new ElementEdit (root, start, removed, added);
705            event.addEdit(edit);
706          }
707        
708        if (shouldFire)
709          fireRemoveUpdate(event);
710    }    }
711    
712    /**    /**
# Line 712  public abstract class AbstractDocument i Line 821  public abstract class AbstractDocument i
821     */     */
822    public void render(Runnable runnable)    public void render(Runnable runnable)
823    {    {
824      // FIXME: Implement me!      readLock();
825        try
826        {
827          runnable.run();
828        }
829        finally
830        {
831          readUnlock();
832        }
833    }    }
834    
835    /**    /**
# Line 724  public abstract class AbstractDocument i Line 841  public abstract class AbstractDocument i
841     */     */
842    public void setAsynchronousLoadPriority(int p)    public void setAsynchronousLoadPriority(int p)
843    {    {
844        // TODO: Implement this properly.
845    }    }
846    
847    /**    /**
# Line 738  public abstract class AbstractDocument i Line 856  public abstract class AbstractDocument i
856    }    }
857    
858    /**    /**
859     * Blocks until a write lock can be obtained.     * Blocks until a write lock can be obtained.  Must wait if there are
860       * readers currently reading or another thread is currently writing.
861     */     */
862    protected void writeLock()    protected void writeLock()
863    {    {
864      // FIXME: Implement me.      if (currentWriter!= null && currentWriter.equals(Thread.currentThread()))
865          return;
866        synchronized (documentCV)
867          {
868            numWritersWaiting++;
869            while (numReaders > 0)
870              {
871                try
872                  {
873                    documentCV.wait();
874                  }
875                catch (InterruptedException ie)
876                  {
877                    throw new Error("interruped while trying to obtain write lock");
878                  }
879              }
880            numWritersWaiting --;
881            currentWriter = Thread.currentThread();
882          }
883    }    }
884    
885    /**    /**
# Line 751  public abstract class AbstractDocument i Line 888  public abstract class AbstractDocument i
888     */     */
889    protected void writeUnlock()    protected void writeUnlock()
890    {    {
891      // FIXME: Implement me.      synchronized (documentCV)
892        {
893            if (Thread.currentThread().equals(currentWriter))
894              {
895                currentWriter = null;
896                documentCV.notifyAll();
897              }
898        }
899    }    }
900    
901    /**    /**
# Line 1230  public abstract class AbstractDocument i Line 1374  public abstract class AbstractDocument i
1374    
1375      /**      /**
1376       * Returns the resolve parent of this element.       * Returns the resolve parent of this element.
1377         * This is taken from the AttributeSet, but if this is null,
1378         * this method instead returns the Element's parent's
1379         * AttributeSet
1380       *       *
1381       * @return the resolve parent of this element       * @return the resolve parent of this element
1382       *       *
# Line 1237  public abstract class AbstractDocument i Line 1384  public abstract class AbstractDocument i
1384       */       */
1385      public AttributeSet getResolveParent()      public AttributeSet getResolveParent()
1386      {      {
1387        return attributes.getResolveParent();        if (attributes.getResolveParent() != null)
1388            return attributes.getResolveParent();
1389          return element_parent.getAttributes();
1390      }      }
1391    
1392      /**      /**
# Line 1407  public abstract class AbstractDocument i Line 1556  public abstract class AbstractDocument i
1556                                                        + "must not be thrown "                                                        + "must not be thrown "
1557                                                        + "here.");                                                        + "here.");
1558                err.initCause(ex);                err.initCause(ex);
1559                  throw err;
1560              }              }
1561            b.append("]\n");            b.append("]\n");
1562          }          }
# Line 1514  public abstract class AbstractDocument i Line 1664  public abstract class AbstractDocument i
1664       */       */
1665      public int getElementIndex(int offset)      public int getElementIndex(int offset)
1666      {      {
1667        // If we have no children, return -1.        // If offset is less than the start offset of our first child,
1668        if (getElementCount() == 0)        // return 0
1669          return - 1;        if (offset < getStartOffset())
1670            return 0;
1671          
1672        // XXX: There is surely a better algorithm        // XXX: There is surely a better algorithm
1673        // as beginning from first element each time.        // as beginning from first element each time.
1674        for (int index = 0; index < children.length; ++index)        for (int index = 0; index < children.length - 1; ++index)
1675          {          {
1676            Element elem = children[index];            Element elem = children[index];
1677    
1678            if ((elem.getStartOffset() <= offset)            if ((elem.getStartOffset() <= offset)
1679                 && (offset < elem.getEndOffset()))                 && (offset < elem.getEndOffset()))
1680              return index;              return index;
1681              // If the next element's start offset is greater than offset
1682              // then we have to return the closest Element, since no Elements
1683              // will contain the offset
1684              if (children[index + 1].getStartOffset() > offset)
1685                {
1686                  if ((offset - elem.getEndOffset()) > (children[index + 1].getStartOffset() - offset))
1687                    return index + 1;
1688                  else
1689                    return index;
1690                }
1691          }          }
1692    
1693        // If offset is greater than the index of the last element, return        // If offset is greater than the index of the last element, return
# Line 1759  public abstract class AbstractDocument i Line 1920  public abstract class AbstractDocument i
1920        return (DocumentEvent.ElementChange) changes.get(elem);        return (DocumentEvent.ElementChange) changes.get(elem);
1921      }      }
1922    }    }
1923      
1924    /**    /**
1925     * An implementation of {@link DocumentEvent.ElementChange} to be added     * An implementation of {@link DocumentEvent.ElementChange} to be added
1926     * to {@link DefaultDocumentEvent}s.     * to {@link DefaultDocumentEvent}s.

Legend:
Removed from v.1.9.2.10  
changed lines
  Added in v.1.9.2.11

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26