public abstract class AbstractTextBuffer extends java.lang.Object implements TextBuffer
AbstractTextBuffer
class is a starting point for
classes implementing the TextBuffer
interface. It
takes care of providing a basic implementation for some of the
functionality (such as locking or line map) of the
TextBuffer
interface. This is declared package-private intentionally as it is part of the implementation, and not part of the published API.
Implementation Notes on Change Id
The Change ID is tagged to a "version" of a buffer's contents. It is guaranteed to be different for two versions of buffer contents that are different (but not vice versa.) It is used for two purposes:
Since change id's are taken from the set of int's
,
they will invariably repeat over time. This implementation
should not be used for a buffer that is heavily modified over a
very long period of time without clearing the modified state.
For such purposes, this implementation should be changed to
use a long
field instead.
TextBuffer
Modifier and Type | Class and Description |
---|---|
static class |
AbstractTextBuffer.UndoState
The UndoState is a layer of indirection between the TextBuffer and
UndoableTextEdit's to allow undo's to be detached from the TextBuffer
and reattach to a TextBuffer with the same buffer contents.
|
Modifier and Type | Field and Description |
---|---|
protected ReadWriteLock |
bufferLock
The lock used for read/write locking.
|
protected static char[] |
EMPTY_CHARS
Private constant for an empty array if trying to call getChars()
with length 0.
|
protected static char |
EOF_MARKER
Constant for marking the end of the buffer - primarily for
debugging purposes.
|
protected static java.lang.String |
platformEOLType
Stores the platform EOL type - default is Windows if we can't
obtain one from the system.
|
EOL_CR, EOL_CRLF, EOL_LF, EOL_MACINTOSH, EOL_UNIX, EOL_WINDOWS, READ_ONLY, WRITABLE
LOCK_STATUS_NONE, LOCK_STATUS_READ, LOCK_STATUS_UNSUPPORTED, LOCK_STATUS_WRITE
Modifier | Constructor and Description |
---|---|
protected |
AbstractTextBuffer(ReadWriteLock lockToUse)
Initialize this abstract class using the given lock instance to use.
|
Modifier and Type | Method and Description |
---|---|
OffsetMark |
addOffsetMark(int offset)
Create a new
OffsetMark at the given location. |
OffsetMark |
addOffsetMark(int offset,
boolean bias)
Create a new
OffsetMark at the given location. |
void |
addTextBufferListener(TextBufferListener listener)
Registers the given observer to begin receiving notifications
when changes are made to the text buffer either by an insert or
remove.
|
boolean |
addWriteLockRequestListener(WriteLockRequestListener listener)
Add a write lock request listener on this text buffer.
|
javax.swing.undo.UndoableEdit |
append(char[] data)
Appends the indicated data into the text buffer at the end of the
buffer.
|
protected void |
applyInsert(int offset,
char[] data,
int oldChangeId)
Re-inserts the data based on stored undo information.
|
protected void |
applyRemove(int offset,
char[] data,
int oldChangeId)
Re-removes the data based on stored undo information.
|
protected boolean |
attachUndoState(AbstractTextBuffer.UndoState state)
Reattach the UndoState to this TextBuffer.
|
void |
beginEdit()
Used to instruct to the text buffer to start a compound edit
such that all the changes made between this point and when the
endEdit() is called should be combined into a single
UndoableEdit record. |
void |
clearModified()
Clears the modification status of the buffer so that it indicates
that it has not been modified.
|
protected AbstractTextBuffer.UndoState |
copyUndoState()
Copy the UndoState from this TextBuffer.
|
protected AbstractTextBuffer.UndoState |
detachUndoState()
Detach the UndoState from this TextBuffer.
|
javax.swing.undo.UndoableEdit |
endEdit()
Used to indicate to the text buffer to end an in progress
compound edit.
|
int |
getChangeId()
Fetches a change, or incarnation, number that represents the
current version of the buffer contents.
|
abstract char |
getChar(int offset)
Fetches the character from the given offset.
|
char[] |
getChars(int offset,
int length)
Fetches a number of characters from the indicated offset in the
buffer.
|
protected abstract char[] |
getCharsImpl(int offset,
int length)
Internal version of getChars() for subclasses to override.
|
java.lang.String |
getEOLType()
Fetches the EOL terminator type found in the document when its
data was read with
read( Reader ) . |
abstract int |
getLength()
Fetches the number of characters in this buffer.
|
LineMap |
getLineMap()
Fetches a line map for the text buffer.
|
int |
getLockStatus()
Fetch the lock status for the current thread only.
|
java.lang.String |
getPlatformEOLType()
Fetches the default EOL terminator type associated with this
platform as defined by the 'line.separator' property in the
system properties.
|
java.lang.String |
getString(int offset,
int length)
Fetches a number of characters from the indicated offset in the
buffer and returns it as a String.
|
protected abstract java.lang.String |
getStringImpl(int offset,
int length)
Internal version of getString() for subclasses to override.
|
void |
getText(int offset,
int length,
javax.swing.text.Segment segment)
Fetches the text contained within the given section of the
TextBuffer The Segment object is
provided by the caller. |
protected abstract void |
getTextImpl(int offset,
int length,
javax.swing.text.Segment segment)
Internal version of getText() for subclasses to override.
|
javax.swing.undo.UndoableEdit |
insert(int offset,
char[] data)
Inserts the indicated data into the text buffer at the given offset.
|
javax.swing.undo.UndoableEdit |
insert(int offset,
java.io.Reader reader)
Inserts the data from a Reader instance into the text buffer at
the given offset.
|
protected void |
insertImpl(int offset,
char[] data)
Internal version of insert() for subclasses to override.
|
protected abstract void |
insertImpl(int offset,
char[] data,
int dataOffset,
int dataLength)
Internal version of insert() for subclasses to override.
|
boolean |
isModified()
Fetches whether the buffer has been modified since its
modification flag was last reset.
|
boolean |
isReadOnly()
Fetches whether this
TextBuffer is in read-only
mode or not. |
protected javax.swing.undo.UndoableEdit |
normalizedInsert(int offset,
char[] data)
Inserts the indicated data into the text buffer at the given offset,
without performing EOL normalization.
|
protected void |
read(oracle.javatools.buffer.EOLNormalizer normalizer)
Read implementation that takes care of locking, notification, undo,
and so on, and delegates the read to a normalizer instance.
|
void |
read(java.nio.channels.FileChannel channel,
java.nio.charset.CharsetDecoder decoder)
Replaces the current contents of the text buffer with the data
from a file channel instance and given character set decorder.
|
void |
read(java.io.Reader reader)
Replaces the current contents of the text buffer with the data
from a reader instance.
|
void |
readLock()
Attempts to acquire a read lock on this text buffer for the purposes
of reading the text buffer - this is a blocking call.
|
void |
readLockInterruptibly()
Attempts to acquire a read lock on this text buffer for the purposes
of reading the text buffer - this is a blocking call.
|
void |
readUnlock()
Releases a held read lock on this text buffer.
|
javax.swing.undo.UndoableEdit |
remove(int offset,
int count)
Removes a range of data from the text buffer.
|
protected abstract void |
removeImpl(int offset,
int count)
Internal version of remove() for subclasses to override.
|
void |
removeOffsetMark(OffsetMark offsetMark)
Remove an existing
OffsetMark from the text buffer. |
void |
removeTextBufferListener(TextBufferListener listener)
Unregisters the given observer from the notification list so
that it will no longer receive change updates.
|
javax.swing.undo.UndoableEdit |
removeToEnd(int offset)
Removes data from the text buffer starting at the given offset to
the end of the buffer.
|
void |
removeWriteLockRequestListener(WriteLockRequestListener listener)
Remove a write lock request listener from this text buffer.
|
void |
setEOLType(java.lang.String eolType)
Changes the EOL terminator type associated with this document to
the type specified.
|
void |
setReadOnly(boolean readOnly)
Sets the read-only mode of this
TextBuffer to
the requested mode. |
boolean |
tryReadLock()
Attempts to acquire a read lock on this buffer in a non-blocking
manner.
|
boolean |
tryWriteLock()
Attempts to acquire a write lock on this text buffer in a
non-blocking manner.
|
void |
write(java.io.Writer writer)
Writes the current contents of the text buffer to a writer, and closes
the writer.
|
void |
write(java.io.Writer writer,
boolean clearModified)
Writes the current contents of the text buffer to a writer, and closes
the writer.
|
void |
writeLock()
Attempts to acquire a write lock on this text buffer for the purposes
of writing to the text buffer - this is a blocking call.
|
void |
writeLock(boolean checkIfReadOnly)
Attempts to acquire a write lock on this text buffer for the
purposes of writing to the text buffer - this is a blocking call.
|
void |
writeLockInterruptibly()
Attempts to acquire a write lock on this text buffer for the purposes
of writing to the text buffer - this is a blocking call.
|
void |
writeUnlock()
Releases a held write lock on this text buffer.
|
protected static final char EOF_MARKER
protected static final char[] EMPTY_CHARS
protected static java.lang.String platformEOLType
protected final ReadWriteLock bufferLock
protected AbstractTextBuffer(ReadWriteLock lockToUse)
lockToUse
- the ReadWriteLock instance to use for this buffer
instancepublic void setReadOnly(boolean readOnly)
TextBuffer
to
the requested mode.setReadOnly
in interface TextBuffer
readOnly
- the new mode to set, READ_ONLY to mark as read-only,
WRITABLE to allow modificationspublic boolean isReadOnly()
TextBuffer
is in read-only
mode or not.isReadOnly
in interface TextBuffer
public abstract int getLength()
getLength
in interface ReadTextBuffer
public abstract char getChar(int offset) throws java.lang.IndexOutOfBoundsException
getChar
in interface ReadTextBuffer
offset
- the offset in the buffer to get the character fromjava.lang.IndexOutOfBoundsException
- if offset is invalidpublic char[] getChars(int offset, int length) throws java.lang.IndexOutOfBoundsException
getChars
in interface ReadTextBuffer
offset
- the offset in the buffer to start fromlength
- number of characters to fetchjava.lang.IndexOutOfBoundsException
- if offset or length are invalidprotected abstract char[] getCharsImpl(int offset, int length) throws java.lang.IndexOutOfBoundsException
offset
- the offset in the buffer to start fromlength
- number of characters to fetchjava.lang.IndexOutOfBoundsException
- if offset or length are invalidpublic java.lang.String getString(int offset, int length) throws java.lang.IndexOutOfBoundsException
getString
in interface ReadTextBuffer
offset
- the offset in the buffer to start fromlength
- number of characters to fetchjava.lang.IndexOutOfBoundsException
- if offset or length are invalidprotected abstract java.lang.String getStringImpl(int offset, int length) throws java.lang.IndexOutOfBoundsException
offset
- the offset in the buffer to start fromlength
- number of characters to fetchjava.lang.IndexOutOfBoundsException
- if offset or length are invalidpublic void getText(int offset, int length, javax.swing.text.Segment segment) throws java.lang.IndexOutOfBoundsException
TextBuffer
The Segment
object is
provided by the caller.getText
in interface ReadTextBuffer
offset
- the offset into the buffer representing the desired
start of the data >= 0length
- the length of the desired data >= 0segment
- the caller's Segment object to return the data injava.lang.IndexOutOfBoundsException
Document.getText(int, int)
protected abstract void getTextImpl(int offset, int length, javax.swing.text.Segment segment) throws java.lang.IndexOutOfBoundsException
TextBuffer
The Segment
object is
provided by the caller.offset
- the offset into the buffer representing the desired
start of the data >= 0length
- the length of the desired data >= 0segment
- the caller's Segment object to return the data injava.lang.IndexOutOfBoundsException
Document.getText(int, int)
public javax.swing.undo.UndoableEdit insert(int offset, char[] data) throws ReadOnlyException
insert
in interface TextBuffer
offset
- the offset at which to insert the new datadata
- the text to insertReadOnlyException
- if the buffer is in read only modeTextBuffer.beginEdit()
,
TextBuffer.endEdit()
,
TextBuffer.addTextBufferListener(oracle.javatools.buffer.TextBufferListener)
,
TextBuffer.removeTextBufferListener(oracle.javatools.buffer.TextBufferListener)
protected javax.swing.undo.UndoableEdit normalizedInsert(int offset, char[] data) throws ReadOnlyException
offset
- the offset at which to insert the new datadata
- the text to insertReadOnlyException
- if the buffer is in read only modeprotected void applyInsert(int offset, char[] data, int oldChangeId) throws ReadOnlyException
offset
- the offset at which to insert the old datadata
- the text to insertoldChangeId
- what to restore the old change id toReadOnlyException
public javax.swing.undo.UndoableEdit append(char[] data) throws ReadOnlyException
append
in interface TextBuffer
data
- the text to insertReadOnlyException
- if the buffer is in read only modeTextBuffer.insert(int, char[])
,
TextBuffer.beginEdit()
,
TextBuffer.endEdit()
,
TextBuffer.addTextBufferListener(oracle.javatools.buffer.TextBufferListener)
,
TextBuffer.removeTextBufferListener(oracle.javatools.buffer.TextBufferListener)
protected void insertImpl(int offset, char[] data)
offset
- the offset at which to insert the new datadata
- the text to insertprotected abstract void insertImpl(int offset, char[] data, int dataOffset, int dataLength)
offset
- the offset at which to insert the new datadata
- the text to insertdataOffset
- the offset in the array where the data startsdataLength
- the length of the data to insertpublic javax.swing.undo.UndoableEdit remove(int offset, int count) throws ReadOnlyException
remove
in interface TextBuffer
offset
- the offset at which to remove datacount
- number of characters to removeReadOnlyException
- if the buffer is in read only modeTextBuffer.beginEdit()
,
TextBuffer.endEdit()
protected void applyRemove(int offset, char[] data, int oldChangeId) throws ReadOnlyException
offset
- the offset at which to remove the old datadata
- the data that was removedoldChangeId
- what to restore the old change id toReadOnlyException
public javax.swing.undo.UndoableEdit removeToEnd(int offset) throws ReadOnlyException
removeToEnd
in interface TextBuffer
offset
- the offset at which to remove dataReadOnlyException
- if the buffer is in read only modeTextBuffer.remove(int, int)
,
TextBuffer.beginEdit()
,
TextBuffer.endEdit()
protected abstract void removeImpl(int offset, int count)
offset
- the offset at which to remove datacount
- number of characters to removepublic LineMap getLineMap()
getLineMap
in interface TextBuffer
public void addTextBufferListener(TextBufferListener listener)
addTextBufferListener
in interface TextBuffer
listener
- the observer to registerReadTextBuffer.readLock()
public void removeTextBufferListener(TextBufferListener listener)
removeTextBufferListener
in interface TextBuffer
listener
- the observer to unregisterpublic void readLock()
readLock
in interface ReadTextBuffer
TextBuffer.getLineMap()
,
TextBuffer.writeLock()
public void readLockInterruptibly() throws java.lang.InterruptedException
readLockInterruptibly
in interface ReadTextBuffer
java.lang.InterruptedException
- if the current thread is in or gets put in
the interrupted state. The interrupted state
is cleared when this exception is thrown.TextBuffer.getLineMap()
,
TextBuffer.writeLock()
public boolean tryReadLock()
tryReadLock()
(i.e.,
where it returns true) must be matched by a call to
readUnlock()
.tryReadLock
in interface ReadTextBuffer
ReadTextBuffer.readLock()
public void readUnlock()
readUnlock
in interface ReadTextBuffer
public int getLockStatus()
getLockStatus
in interface ReadTextBuffer
public void writeLock() throws ReadOnlyException
Clients may acquire a writeLock explicitly if they have multiple changes to make in the text buffer, to ensure that the changes will not be interleaved with another client's changes.
writeLock
in interface TextBuffer
ReadOnlyException
- if the buffer is in read only modeReadTextBuffer.readLock()
public void writeLockInterruptibly() throws java.lang.InterruptedException, ReadOnlyException
Clients may acquire a writeLock explicitly if they have multiple changes to make in the text buffer, to ensure that the changes will not be interleaved with another client's changes.
writeLockInterruptibly
in interface TextBuffer
ReadOnlyException
- if the buffer is in read only modejava.lang.InterruptedException
- if the current thread is in or gets put in
the interrupted state. The interrupted state
is cleared when this exception is thrown.ReadTextBuffer.readLock()
public void writeLock(boolean checkIfReadOnly) throws ReadOnlyException
Clients may acquire a writeLock explicitly if they have multiple changes to make in the text buffer, to ensure that the changes will not be interleaved with another client's changes.
This version of the writeLock() method takes a boolean parameter that controls whether or not an exception is thrown if you attempt to acquire a write lock on a read only text buffer. Note that in most cases, clients should pass true (or use the writeLock() method that takes no arguments) so that they are immediately notified that write operations will fail.
writeLock
in interface TextBuffer
ReadOnlyException
- if the buffer is in read only mode and
checkIfReadOnly is trueReadTextBuffer.readLock()
public boolean tryWriteLock() throws ReadOnlyException
tryWriteLock()
(i.e., where it returns true) must be matched by a call to
writeUnlock()
.tryWriteLock
in interface TextBuffer
ReadOnlyException
- if the buffer is in read only modeTextBuffer.writeLock()
,
ReadTextBuffer.tryReadLock()
public void writeUnlock()
writeUnlock
in interface TextBuffer
public boolean addWriteLockRequestListener(WriteLockRequestListener listener)
TextBuffer
addWriteLockRequestListener
in interface TextBuffer
listener
- the listener to be adddedtrue
if there are already other threads waiting for the
write lock, false
otherwisepublic void removeWriteLockRequestListener(WriteLockRequestListener listener)
TextBuffer
removeWriteLockRequestListener
in interface TextBuffer
listener
- the listener to be removedpublic void beginEdit() throws ReadOnlyException
endEdit()
is called should be combined into a single
UndoableEdit record. This guarantees to the client that the
buffer will be locked for the duration between
beginEdit()
and endEdit()
for data
consistency. This also takes care of locking the buffer, and
collecting the individual UndoableEdit
objects into
a larger compound one.
Note that compound edits may not be nested - it is illegal
to call beginEdit()
twice in a row without calling
endEdit()
in between.
beginEdit
in interface TextBuffer
ReadOnlyException
- if the buffer is in read only modeTextBuffer.endEdit()
public javax.swing.undo.UndoableEdit endEdit()
UndoableEdit
representing all of the
changes made between the calls to beginEdit()
and
endEdit()
.endEdit
in interface TextBuffer
TextBuffer.beginEdit()
public boolean isModified()
isModified
in interface TextBuffer
public void clearModified()
clearModified
in interface TextBuffer
public int getChangeId()
int's
is exhausted (at which point they may repeat.) getChangeId
in interface TextBuffer
public void read(java.io.Reader reader) throws java.io.IOException
read
in interface TextBuffer
reader
- a Reader instance from which to read text datajava.io.IOException
- as thrown by the stream if an error occurs
while reading datapublic void read(java.nio.channels.FileChannel channel, java.nio.charset.CharsetDecoder decoder) throws java.io.IOException
channel
- a FileChannel instance to use for reading text datajava.io.IOException
- as thrown by the channel if an error occurs
while reading dataprotected void read(oracle.javatools.buffer.EOLNormalizer normalizer) throws java.io.IOException
normalizer
- the read normalizer to usejava.io.IOException
public javax.swing.undo.UndoableEdit insert(int offset, java.io.Reader reader) throws java.io.IOException, ReadOnlyException
insertUpdate()
.insert
in interface TextBuffer
offset
- the offset at which to insert the new datareader
- a Reader instance from which to read text datajava.io.IOException
- as thrown by the stream if an error occurs
while reading dataReadOnlyException
- if the buffer is in read only modeTextBuffer.beginEdit()
,
TextBuffer.endEdit()
,
TextBuffer.addTextBufferListener(oracle.javatools.buffer.TextBufferListener)
,
TextBuffer.removeTextBufferListener(oracle.javatools.buffer.TextBufferListener)
public void write(java.io.Writer writer) throws java.io.IOException
The modified state of the buffer is cleared. Clearing the modified state, if not already cleared, will safely take a write lock, which means that if the caller of this method holds a read lock, that read lock will be released and reacquired during the execution of this method.
write
in interface TextBuffer
writer
- a Writer
to which to write buffer contents.java.io.IOException
- if the write throws IOException.public void write(java.io.Writer writer, boolean clearModified) throws java.io.IOException
If the buffer state needs to be cleared, this method will safely take a write lock, which means that if the caller of this method holds a read lock, that read lock will be released and reacquired during the execution of this method.
write
in interface TextBuffer
writer
- a Writer
to which to write buffer contents.clearModified
- whether to clear the modified state of the buffer.java.io.IOException
- if the write throws IOException.public java.lang.String getPlatformEOLType()
getPlatformEOLType
in interface TextBuffer
public java.lang.String getEOLType()
read( Reader )
. The default EOL
terminator is defined as the predominant (majority) terminator
used in the document.getEOLType
in interface TextBuffer
public void setEOLType(java.lang.String eolType) throws ReadOnlyException
setEOLType
in interface TextBuffer
eolType
- the EOL terminator type to useReadOnlyException
- if the buffer is in read only modepublic OffsetMark addOffsetMark(int offset)
OffsetMark
at the given location.addOffsetMark
in interface TextBuffer
offset
- the offset to stick toOffsetMark
for tracking the offsetOffsetMark
,
TextBuffer.removeOffsetMark(oracle.javatools.buffer.OffsetMark)
public OffsetMark addOffsetMark(int offset, boolean bias)
OffsetMark
at the given location. The
bias can be either OffsetMark.BIAS_RIGHT
or
OffsetMark.BIAS_LEFT
.addOffsetMark
in interface TextBuffer
offset
- the offset to stick tobias
- the side of the offset to bias or stick toOffsetMark
for tracking the offsetOffsetMark
,
TextBuffer.removeOffsetMark(oracle.javatools.buffer.OffsetMark)
public void removeOffsetMark(OffsetMark offsetMark)
OffsetMark
from the text buffer.
Since OffsetMarks
persist until they are removed
explicitly, clients must remove OffsetMarks
they
created to ensure proper resource release.removeOffsetMark
in interface TextBuffer
offsetMark
- the mark to removeOffsetMark
,
addOffsetMark(int)
protected AbstractTextBuffer.UndoState detachUndoState()
protected AbstractTextBuffer.UndoState copyUndoState()
protected boolean attachUndoState(AbstractTextBuffer.UndoState state)
state
-