diff options
Diffstat (limited to 'libjava/classpath/javax/swing/text/StringContent.java')
-rw-r--r-- | libjava/classpath/javax/swing/text/StringContent.java | 569 |
1 files changed, 0 insertions, 569 deletions
diff --git a/libjava/classpath/javax/swing/text/StringContent.java b/libjava/classpath/javax/swing/text/StringContent.java deleted file mode 100644 index a017de1..0000000 --- a/libjava/classpath/javax/swing/text/StringContent.java +++ /dev/null @@ -1,569 +0,0 @@ -/* StringContent.java -- - Copyright (C) 2005, 2006 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ - - -package javax.swing.text; - -import java.io.Serializable; -import java.lang.ref.Reference; -import java.lang.ref.ReferenceQueue; -import java.lang.ref.WeakReference; -import java.util.Iterator; -import java.util.Vector; - -import javax.swing.undo.AbstractUndoableEdit; -import javax.swing.undo.CannotRedoException; -import javax.swing.undo.CannotUndoException; -import javax.swing.undo.UndoableEdit; - -/** - * An implementation of the <code>AbstractDocument.Content</code> - * interface useful for small documents or debugging. The character - * content is a simple character array. It's not really efficient. - * - * <p>Do not use this class for large size.</p> - */ -public final class StringContent - implements AbstractDocument.Content, Serializable -{ - /** - * Stores a reference to a mark that can be resetted to the original value - * after a mark has been moved. This is used for undoing actions. - */ - private class UndoPosRef - { - /** - * The mark that might need to be reset. - */ - private Mark mark; - - /** - * The original offset to reset the mark to. - */ - private int undoOffset; - - /** - * Creates a new UndoPosRef. - * - * @param m the mark - */ - UndoPosRef(Mark m) - { - mark = m; - undoOffset = mark.mark; - } - - /** - * Resets the position of the mark to the value that it had when - * creating this UndoPosRef. - */ - void reset() - { - mark.mark = undoOffset; - } - } - - /** - * Holds a mark into the buffer that is used by StickyPosition to find - * the actual offset of the position. This is pulled out of the - * GapContentPosition object so that the mark and position can be handled - * independently, and most important, so that the StickyPosition can - * be garbage collected while we still hold a reference to the Mark object. - */ - private class Mark - { - /** - * The actual mark into the buffer. - */ - int mark; - - - /** - * The number of GapContentPosition object that reference this mark. If - * it reaches zero, it get's deleted by - * {@link StringContent#garbageCollect()}. - */ - int refCount; - - /** - * Creates a new Mark object for the specified offset. - * - * @param offset the offset - */ - Mark(int offset) - { - mark = offset; - } - } - - /** The serialization UID (compatible with JDK1.5). */ - private static final long serialVersionUID = 4755994433709540381L; - - // This is package-private to avoid an accessor method. - char[] content; - - private int count; - - /** - * Holds the marks for the positions. - * - * This is package private to avoid accessor methods. - */ - Vector marks; - - private class InsertUndo extends AbstractUndoableEdit - { - private int start; - - private int length; - - private String redoContent; - - private Vector positions; - - public InsertUndo(int start, int length) - { - super(); - this.start = start; - this.length = length; - } - - public void undo() - { - super.undo(); - try - { - if (marks != null) - positions = getPositionsInRange(null, start, length); - redoContent = getString(start, length); - remove(start, length); - } - catch (BadLocationException b) - { - throw new CannotUndoException(); - } - } - - public void redo() - { - super.redo(); - try - { - insertString(start, redoContent); - redoContent = null; - if (positions != null) - { - updateUndoPositions(positions); - positions = null; - } - } - catch (BadLocationException b) - { - throw new CannotRedoException(); - } - } - } - - private class RemoveUndo extends AbstractUndoableEdit - { - private int start; - private int len; - private String undoString; - - Vector positions; - - public RemoveUndo(int start, String str) - { - super(); - this.start = start; - len = str.length(); - this.undoString = str; - if (marks != null) - positions = getPositionsInRange(null, start, str.length()); - } - - public void undo() - { - super.undo(); - try - { - StringContent.this.insertString(this.start, this.undoString); - if (positions != null) - { - updateUndoPositions(positions); - positions = null; - } - undoString = null; - } - catch (BadLocationException bad) - { - throw new CannotUndoException(); - } - } - - public void redo() - { - super.redo(); - try - { - undoString = getString(start, len); - if (marks != null) - positions = getPositionsInRange(null, start, len); - remove(this.start, len); - } - catch (BadLocationException bad) - { - throw new CannotRedoException(); - } - } - } - - private class StickyPosition implements Position - { - Mark mark; - - public StickyPosition(int offset) - { - // Try to make space. - garbageCollect(); - - mark = new Mark(offset); - mark.refCount++; - marks.add(mark); - - new WeakReference(this, queueOfDeath); - } - - /** - * Should be >=0. - */ - public int getOffset() - { - return mark.mark; - } - } - - /** - * Used in {@link #remove(int,int)}. - */ - private static final char[] EMPTY = new char[0]; - - /** - * Queues all references to GapContentPositions that are about to be - * GC'ed. This is used to remove the corresponding marks from the - * positionMarks array if the number of references to that mark reaches zero. - * - * This is package private to avoid accessor synthetic methods. - */ - ReferenceQueue queueOfDeath; - - /** - * Creates a new instance containing the string "\n". This is equivalent - * to calling {@link #StringContent(int)} with an <code>initialLength</code> - * of 10. - */ - public StringContent() - { - this(10); - } - - /** - * Creates a new instance containing the string "\n". - * - * @param initialLength the initial length of the underlying character - * array used to store the content. - */ - public StringContent(int initialLength) - { - super(); - queueOfDeath = new ReferenceQueue(); - if (initialLength < 1) - initialLength = 1; - this.content = new char[initialLength]; - this.content[0] = '\n'; - this.count = 1; - } - - protected Vector getPositionsInRange(Vector v, - int offset, - int length) - { - Vector refPos = v == null ? new Vector() : v; - Iterator iter = marks.iterator(); - while(iter.hasNext()) - { - Mark m = (Mark) iter.next(); - if (offset <= m.mark && m.mark <= offset + length) - refPos.add(new UndoPosRef(m)); - } - return refPos; - } - - /** - * Creates a position reference for the character at the given offset. The - * position offset will be automatically updated when new characters are - * inserted into or removed from the content. - * - * @param offset the character offset. - * - * @throws BadLocationException if offset is outside the bounds of the - * content. - */ - public Position createPosition(int offset) throws BadLocationException - { - // Lazily create marks vector. - if (marks == null) - marks = new Vector(); - StickyPosition sp = new StickyPosition(offset); - return sp; - } - - /** - * Returns the length of the string content, including the '\n' character at - * the end. - * - * @return The length of the string content. - */ - public int length() - { - return count; - } - - /** - * Inserts <code>str</code> at the given position and returns an - * {@link UndoableEdit} that enables undo/redo support. - * - * @param where the insertion point (must be less than - * <code>length()</code>). - * @param str the string to insert (<code>null</code> not permitted). - * - * @return An object that can undo the insertion. - */ - public UndoableEdit insertString(int where, String str) - throws BadLocationException - { - checkLocation(where, 0); - if (where == this.count) - throw new BadLocationException("Invalid location", 1); - if (str == null) - throw new NullPointerException(); - char[] insert = str.toCharArray(); - replace(where, 0, insert); - - // Move all the positions. - if (marks != null) - { - Iterator iter = marks.iterator(); - int start = where; - if (start == 0) - start = 1; - while (iter.hasNext()) - { - Mark m = (Mark) iter.next(); - if (m.mark >= start) - m.mark += str.length(); - } - } - - InsertUndo iundo = new InsertUndo(where, insert.length); - return iundo; - } - - /** - * Removes the specified range of characters and returns an - * {@link UndoableEdit} that enables undo/redo support. - * - * @param where the starting index. - * @param nitems the number of characters. - * - * @return An object that can undo the removal. - * - * @throws BadLocationException if the character range extends outside the - * bounds of the content OR includes the last character. - */ - public UndoableEdit remove(int where, int nitems) throws BadLocationException - { - checkLocation(where, nitems + 1); - RemoveUndo rundo = new RemoveUndo(where, new String(this.content, where, - nitems)); - - replace(where, nitems, EMPTY); - // Move all the positions. - if (marks != null) - { - Iterator iter = marks.iterator(); - while (iter.hasNext()) - { - Mark m = (Mark) iter.next(); - if (m.mark >= where + nitems) - m.mark -= nitems; - else if (m.mark >= where) - m.mark = where; - } - } - return rundo; - } - - private void replace(int offs, int numRemove, char[] insert) - { - int insertLength = insert.length; - int delta = insertLength - numRemove; - int src = offs + numRemove; - int numMove = count - src; - int dest = src + delta; - if (count + delta >= content.length) - { - // Grow data array. - int newLength = Math.max(2 * content.length, count + delta); - char[] newContent = new char[newLength]; - System.arraycopy(content, 0, newContent, 0, offs); - System.arraycopy(insert, 0, newContent, offs, insertLength); - System.arraycopy(content, src, newContent, dest, numMove); - content = newContent; - } - else - { - System.arraycopy(content, src, content, dest, numMove); - System.arraycopy(insert, 0, content, offs, insertLength); - } - count += delta; - } - - /** - * Returns a new <code>String</code> containing the characters in the - * specified range. - * - * @param where the start index. - * @param len the number of characters. - * - * @return A string. - * - * @throws BadLocationException if the requested range of characters extends - * outside the bounds of the content. - */ - public String getString(int where, int len) throws BadLocationException - { - // The RI throws a StringIndexOutOfBoundsException here, which - // smells like a bug. We throw a BadLocationException instead. - checkLocation(where, len); - return new String(this.content, where, len); - } - - /** - * Updates <code>txt</code> to contain a direct reference to the underlying - * character array. - * - * @param where the index of the first character. - * @param len the number of characters. - * @param txt a carrier for the return result (<code>null</code> not - * permitted). - * - * @throws BadLocationException if the requested character range is not - * within the bounds of the content. - * @throws NullPointerException if <code>txt</code> is <code>null</code>. - */ - public void getChars(int where, int len, Segment txt) - throws BadLocationException - { - if (where + len > count) - throw new BadLocationException("Invalid location", where + len); - txt.array = content; - txt.offset = where; - txt.count = len; - } - - - /** - * Resets the positions in the specified vector to their original offset - * after a undo operation is performed. For example, after removing some - * content, the positions in the removed range will all be set to one - * offset. This method restores the positions to their original offsets - * after an undo. - */ - protected void updateUndoPositions(Vector positions) - { - for (Iterator i = positions.iterator(); i.hasNext();) - { - UndoPosRef pos = (UndoPosRef) i.next(); - pos.reset(); - } - } - - /** - * A utility method that checks the validity of the specified character - * range. - * - * @param where the first character in the range. - * @param len the number of characters in the range. - * - * @throws BadLocationException if the specified range is not within the - * bounds of the content. - */ - void checkLocation(int where, int len) throws BadLocationException - { - if (where < 0) - throw new BadLocationException("Invalid location", 1); - else if (where > this.count) - throw new BadLocationException("Invalid location", this.count); - else if ((where + len) > this.count) - throw new BadLocationException("Invalid range", this.count); - } - - /** - * Polls the queue of death for GapContentPositions, updates the - * corresponding reference count and removes the corresponding mark - * if the refcount reaches zero. - * - * This is package private to avoid accessor synthetic methods. - */ - void garbageCollect() - { - Reference ref = queueOfDeath.poll(); - while (ref != null) - { - if (ref != null) - { - StickyPosition pos = (StickyPosition) ref.get(); - Mark m = pos.mark; - m.refCount--; - if (m.refCount == 0) - marks.remove(m); - } - ref = queueOfDeath.poll(); - } - } -} |