Index: src/org/openide/text/CloneableEditorSupport.java
===================================================================
RCS file: /cvs/openide/src/org/openide/text/CloneableEditorSupport.java,v
retrieving revision 1.95
diff -c -r1.95 CloneableEditorSupport.java
*** src/org/openide/text/CloneableEditorSupport.java 27 Aug 2003 20:40:32 -0000 1.95
--- src/org/openide/text/CloneableEditorSupport.java 5 Sep 2003 14:38:40 -0000
***************
*** 80,85 ****
--- 80,90 ----
/** Common name for editor mode. */
public static final String EDITOR_MODE = "editor"; // NOI18N
+ private static final int DOCUMENT_NO = 0;
+ private static final int DOCUMENT_LOADING = 1;
+ private static final int DOCUMENT_READY = 2;
+ private static final int DOCUMENT_RELOADING = 3;
+
/** Flag saying if the CloneableEditorSupport handles already the UserQuestionException*/
private boolean inUserQuestionExceptionHandler;
***************
*** 135,141 ****
/** position manager */
private PositionRef.Manager positionManager;
!
/** The string which will be appended to the name of top component
* when top component becomes modified */
// protected String modifiedAppendix = " *"; // NOI18N
--- 140,146 ----
/** position manager */
private PositionRef.Manager positionManager;
!
/** The string which will be appended to the name of top component
* when top component becomes modified */
// protected String modifiedAppendix = " *"; // NOI18N
***************
*** 165,171 ****
/** Flag whether the document is already modified or not.*/
// #34728 performance optimization
private boolean alreadyModified = false;
!
/** Creates new CloneableEditorSupport attached to given environment.
*
* @param env environment that is source of all actions around the
--- 170,178 ----
/** Flag whether the document is already modified or not.*/
// #34728 performance optimization
private boolean alreadyModified = false;
!
! private int documentStatus = DOCUMENT_NO;
!
/** Creates new CloneableEditorSupport attached to given environment.
*
* @param env environment that is source of all actions around the
***************
*** 270,282 ****
return positionManager;
}
!
!
/** Overrides superclass method, first processes document preparation.
* @see #prepareDocument */
public void open() {
! prepareDocument().waitFinished();
! super.open();
}
//
--- 277,293 ----
return positionManager;
}
!
/** Overrides superclass method, first processes document preparation.
* @see #prepareDocument */
public void open() {
! try {
! openDocument();
! super.open();
! } catch (IOException e) {
! ErrorManager.getDefault().notify(
! ErrorManager.INFORMATIONAL, e);
! }
}
//
***************
*** 302,308 ****
}
/** Report a bound property update to any registered listeners.
! * @param propertyName the programmatic name of the property that was changed.
* @param oldValue rhe old value of the property.
* @param newValue the new value of the property.
* @since 3.40
--- 313,319 ----
}
/** Report a bound property update to any registered listeners.
! * @param propertyName the programmatic name of the property that was changed.
* @param oldValue rhe old value of the property.
* @param newValue the new value of the property.
* @since 3.40
***************
*** 334,399 ****
* @return task for control over loading
*/
public Task prepareDocument() {
! return prepareDocument(false);
}
/** @param clearDocument indicates whether the document is needed
* to clear before (used for reloading) */
private Task prepareDocument(final boolean clearDocument) {
! // first test is done outside of getLock block because the getLock
! // can be held for a long time
! Task t = prepareTask;
! if (t != null) {
! return t;
! }
!
! synchronized (getLock ()) {
! if (prepareTask != null)
! return prepareTask;
! // listen to modifications on env, but remove
! // previous instance first
! env.removePropertyChangeListener(getListener());
! env.addPropertyChangeListener(getListener());
! // after call to this method the originalDoc and kit are initialized
! // in spite of that the document is not yet fully read in
! kit = createEditorKit ();
! if (doc == null) {
! doc = createStyledDocument (kit);
! }
!
! // The thread nume should be: "Loading document " + env; // NOI18N
! prepareTask = RequestProcessor.getDefault().post(new Runnable () {
! public void run () {
! try {
! synchronized (getLock ()) {
! if(clearDocument) {
! // #24676. Reloading: Put positions into memory
! // and fire document is closing (little trick
! // to detach annotations).
! getPositionManager().documentClosed();
! fireDocumentChange(doc, true);
! clearDocument();
! }
! // uses the listener's run method to initialize whole document
! loadTask = new Task(getListener());
! loadTask.run ();
}
! fireDocumentChange(doc, false);
! } catch (RuntimeException t) {
! t.printStackTrace();
! throw t;
}
}
! });
! return prepareTask;
! }
}
/** Clears the doc
document. Helper method. */
--- 345,436 ----
* @return task for control over loading
*/
public Task prepareDocument() {
! synchronized (getLock()) {
! switch (documentStatus) {
! case DOCUMENT_NO:
! documentStatus = DOCUMENT_LOADING;
! return prepareDocument(false);
!
! default:
! if (prepareTask == null) { // should never happen
! throw new IllegalStateException();
! }
! return prepareTask;
! }
! }
}
/** @param clearDocument indicates whether the document is needed
* to clear before (used for reloading) */
private Task prepareDocument(final boolean clearDocument) {
! if (prepareTask != null)
! return prepareTask;
! // listen to modifications on env, but remove
! // previous instance first
! env.removePropertyChangeListener(getListener());
! env.addPropertyChangeListener(getListener());
! // after call to this method the originalDoc and kit are initialized
! // in spite of that the document is not yet fully read in
! kit = createEditorKit ();
! if (doc == null) {
! doc = createStyledDocument (kit);
! }
! // The thread nume should be: "Loading document " + env; // NOI18N
! prepareTask = RequestProcessor.getDefault().post(new Runnable () {
! public void run () {
! int targetStatus = DOCUMENT_NO; // be pesimistic initially
! try {
! // synchronized (getLock ()) {
! if(clearDocument) {
! // document no longer valid here
! documentStatus = DOCUMENT_RELOADING;
!
! // #24676. Reloading: Put positions into memory
! // and fire document is closing (little trick
! // to detach annotations).
! getPositionManager().documentClosed();
! updateLineSet(true);
!
! fireDocumentChange(doc, true);
!
! clearDocument();
}
! // uses the listener's run method to initialize whole document
! loadTask = new Task(getListener());
! loadTask.run ();
! // }
!
! // assign before fireDocumentChange() as listener should be able to access getDocument()
! documentStatus = DOCUMENT_READY;
!
! fireDocumentChange(doc, false);
!
! // Confirm that whole loading succeeded
! targetStatus = DOCUMENT_READY;
!
! } catch (RuntimeException t) {
! t.printStackTrace();
! throw t;
!
! } finally {
!
! synchronized (getLock()) {
! documentStatus = targetStatus;
!
! getLock().notifyAll();
}
}
!
! }
! });
! return prepareTask;
}
/** Clears the doc
document. Helper method. */
***************
*** 425,441 ****
* @exception IOException if the document could not be loaded
*/
public StyledDocument openDocument () throws IOException {
! for (;;) {
! // load the document
! prepareDocument ().waitFinished ();
! IOException loadExc = getListener().checkLoadException();
! if (loadExc != null) {
! throw loadExc;
! }
!
! StyledDocument d = doc;
! if (d != null)
! return d;
}
}
--- 462,506 ----
* @exception IOException if the document could not be loaded
*/
public StyledDocument openDocument () throws IOException {
! synchronized (getLock()) {
! return openDocumentCheckIOE();
! }
! }
!
! private StyledDocument openDocumentCheckIOE() throws IOException {
! StyledDocument doc = openDocumentImpl();
!
! IOException ioe = getListener().checkLoadException();
! if (ioe != null) {
! throw ioe;
! }
!
! return doc;
! }
!
! /**
! * Must be called under getLock().
! */
! private StyledDocument openDocumentImpl() {
! switch (documentStatus) {
! case DOCUMENT_NO:
! documentStatus = DOCUMENT_LOADING;
! prepareDocument(false);
! return openDocumentImpl();
!
! case DOCUMENT_RELOADING: // proceed to DOCUMENT_READY
! case DOCUMENT_READY:
! return doc;
!
! default: // loading
! try {
! getLock().wait();
! } catch (InterruptedException e) {
! ErrorManager.getDefault().notify(
! ErrorManager.INFORMATIONAL, e);
! }
!
! return openDocumentImpl();
}
}
***************
*** 445,468 ****
* @return document or null
if it is not yet loaded
*/
public StyledDocument getDocument () {
! // XXX #16048. In case there is called this method from loadTask
! // (possible only via LineListener->DocumentLine..).
! // PENDING Needs to be tried to redesign DocumentLine to avoid this.
! if(LOCAL_LOAD_TASK.get() != null) {
! return doc;
! }
! Task t = loadTask;
! if (t != null) {
! // if an task exists
! t.waitFinished ();
! return doc;
! } else {
! return null;
}
}
!
!
/** Test whether the document is modified.
* @return true
if the document is in memory and is modified;
* otherwise false
--- 510,539 ----
* @return document or null
if it is not yet loaded
*/
public StyledDocument getDocument () {
! synchronized (getLock()) {
! while (true) {
! switch (documentStatus) {
! case DOCUMENT_NO:
! return null;
!
! default: // ready, loading or reloading
! // XXX #16048. In case there is called this method from loadTask
! // (possible only via LineListener->DocumentLine..).
! // PENDING Needs to be tried to redesign DocumentLine to avoid this.
! if (LOCAL_LOAD_TASK.get() != null) {
! return doc;
! }
! try {
! return openDocumentCheckIOE();
! } catch (IOException e) {
! return null;
! }
! }
! }
}
}
!
/** Test whether the document is modified.
* @return true
if the document is in memory and is modified;
* otherwise false
***************
*** 911,974 ****
* by calling prepareDocument().
*/
protected Task reloadDocument() {
! synchronized (getLock ()) {
! if (doc != null) {
! // UndoManager must be detached from document here because it will be attached in loadDocument()
! doc.removeUndoableEditListener (getUndoRedo ());
! // Remember caret positions in all opened panes
! final JEditorPane[] panes = getOpenedPanes();
! final int[] carets;
! if (panes != null) {
! carets = new int[panes.length];
! for(int i = 0; i < panes.length; i++) {
! carets[i] = panes[i].getCaretPosition();
! }
! } else {
! carets = new int[0];
}
! prepareTask = null; // make sure new loading will occur
! final Task docLoadTask = prepareDocument(true);
! docLoadTask.addTaskListener(
! new TaskListener() {
! public void taskFinished (Task task) {
! //Bugfix #12338: This Swing code replanned to AWT thread
! SwingUtilities.invokeLater(new Runnable() {
! public void run () {
! if (panes != null) {
! for (int i = 0; i < panes.length; i++) {
! // #26407 Adjusts caret position,
! // (reloaded doc could be shorter).
! int textLength = panes[i].getText().length();
! if(carets[i] >= textLength) {
! carets[i] = textLength-1;
! }
!
! panes[i].setCaretPosition(carets[i]);
}
}
- getUndoRedo().discardAllEdits(); // reset undo manager
- // Insert before-save undo event to enable unmodifying undo
- getUndoRedo().undoableEditHappened(
- new UndoableEditEvent(
- CloneableEditorSupport.this,
- new BeforeSaveEdit(lastSaveTime)
- )
- );
-
- notifyUnmodified ();
- updateLineSet(true);
}
! });
! docLoadTask.removeTaskListener(this);
! }
! }
! );
! return docLoadTask;
! }
}
return prepareDocument();
--- 982,1045 ----
* by calling prepareDocument().
*/
protected Task reloadDocument() {
! if (doc != null) {
! // UndoManager must be detached from document here because it will be attached in loadDocument()
! doc.removeUndoableEditListener (getUndoRedo ());
! // Remember caret positions in all opened panes
! final JEditorPane[] panes = getOpenedPanes();
! final int[] carets;
! if (panes != null) {
! carets = new int[panes.length];
! for(int i = 0; i < panes.length; i++) {
! carets[i] = panes[i].getCaretPosition();
}
+ } else {
+ carets = new int[0];
+ }
! documentStatus = DOCUMENT_RELOADING;
!
! prepareTask = null; // make sure new loading will occur
! final Task docLoadTask = prepareDocument(true);
! docLoadTask.addTaskListener(
! new TaskListener() {
! public void taskFinished (Task task) {
! //Bugfix #12338: This Swing code replanned to AWT thread
! SwingUtilities.invokeLater(new Runnable() {
! public void run () {
! if (panes != null) {
! for (int i = 0; i < panes.length; i++) {
! // #26407 Adjusts caret position,
! // (reloaded doc could be shorter).
! int textLength = panes[i].getText().length();
! if(carets[i] >= textLength) {
! carets[i] = textLength-1;
}
+
+ panes[i].setCaretPosition(carets[i]);
}
}
! getUndoRedo().discardAllEdits(); // reset undo manager
! // Insert before-save undo event to enable unmodifying undo
! getUndoRedo().undoableEditHappened(
! new UndoableEditEvent(
! CloneableEditorSupport.this,
! new BeforeSaveEdit(lastSaveTime)
! )
! );
+ notifyUnmodified ();
+ updateLineSet(true);
+ }
+ });
+ docLoadTask.removeTaskListener(this);
+ }
+ }
+ );
!
! return docLoadTask;
}
return prepareDocument();
***************
*** 1165,1178 ****
* @return the set
*/
Line.Set updateLineSet (boolean clear) {
! synchronized(LOCK_LINE_SET) {
if(lineSet != null && !clear) {
return lineSet;
}
Line.Set oldSet = lineSet;
! if (doc == null) {
lineSet = new EditorSupportLineSet.Closed(CloneableEditorSupport.this);
} else {
lineSet = new EditorSupportLineSet(CloneableEditorSupport.this, doc);
--- 1236,1249 ----
* @return the set
*/
Line.Set updateLineSet (boolean clear) {
! synchronized(getLock()) {
if(lineSet != null && !clear) {
return lineSet;
}
Line.Set oldSet = lineSet;
! if (doc == null || documentStatus == DOCUMENT_RELOADING) {
lineSet = new EditorSupportLineSet.Closed(CloneableEditorSupport.this);
} else {
lineSet = new EditorSupportLineSet(CloneableEditorSupport.this, doc);
***************
*** 1275,1308 ****
/** Clears all data from memory.
*/
private void closeDocument () {
! for (;;) {
! Task prep;
!
! synchronized (getLock()) {
! if (doc == null) {
! return;
! }
!
! if (loadTask == null) {
! return;
! }
!
! prep = prepareTask;
! if (prep == null) {
! return;
! }
!
! if (prep.isFinished ()) {
! doCloseDocument ();
! return;
}
}
-
- /* Wait for loading task to be finished
- * so that the document etc. stays valid
- * during the load operation.
- */
- prep.waitFinished();
}
}
--- 1346,1367 ----
/** Clears all data from memory.
*/
private void closeDocument () {
! synchronized (getLock()) {
! while (true) {
! switch (documentStatus) {
! case DOCUMENT_NO:
! return;
!
! case DOCUMENT_LOADING:
! case DOCUMENT_RELOADING:
! openDocumentImpl();
! break; // try to close again
!
! default:
! doCloseDocument();
! return;
}
}
}
}
***************
*** 1324,1336 ****
--- 1383,1400 ----
if (positionManager != null) {
positionManager.documentClosed ();
+
+ documentStatus = DOCUMENT_NO;
fireDocumentChange(doc, true);
}
+
+ documentStatus = DOCUMENT_NO;
doc = null;
kit = null;
updateLineSet (true);
+
}
/** Handles the actual reload of document.
***************
*** 1367,1379 ****
//RequestProcessor
RequestProcessor.getDefault().post(new Runnable() {
public void run () {
! reloadDocument();
}
});
}
}
!
/** Creates netbeans document for a given document.
* @param d document to use as underlaying one
--- 1431,1460 ----
//RequestProcessor
RequestProcessor.getDefault().post(new Runnable() {
public void run () {
! synchronized (getLock()) {
! checkDocumentReload();
! }
}
});
}
}
! private void checkDocumentReload() {
! switch (documentStatus) {
! case DOCUMENT_NO:
! break;
!
! case DOCUMENT_LOADING:
! case DOCUMENT_RELOADING:
! openDocumentImpl();
! checkDocumentReload();
! break;
!
! default:
! reloadDocument();
! break;
! }
! }
/** Creates netbeans document for a given document.
* @param d document to use as underlaying one
***************
*** 1535,1541 ****
/** Access to lock on operations on the support
*/
! Object getLock () {
return allEditors;
}
--- 1616,1622 ----
/** Access to lock on operations on the support
*/
! final Object getLock () {
return allEditors;
}
***************
*** 1683,1689 ****
/** Initialization of the document.
*/
public void run () {
! synchronized (getLock ()) {
/* Remove existing listener before running the loading task
* This should prevent firing of insertUpdate() during load (or reload)
* which can prevent dedloks that sometimes occured during file reload.
--- 1764,1770 ----
/** Initialization of the document.
*/
public void run () {
! // synchronized (getLock ()) {
/* Remove existing listener before running the loading task
* This should prevent firing of insertUpdate() during load (or reload)
* which can prevent dedloks that sometimes occured during file reload.
***************
*** 1714,1720 ****
// Start listening on changes in document
doc.addDocumentListener(getListener());
}
! }
}
--- 1795,1801 ----
// Start listening on changes in document
doc.addDocumentListener(getListener());
}
! // }
}
Index: src/org/openide/text/DocumentLine.java
===================================================================
RCS file: /cvs/openide/src/org/openide/text/DocumentLine.java,v
retrieving revision 1.50
diff -c -r1.50 DocumentLine.java
*** src/org/openide/text/DocumentLine.java 12 Aug 2003 09:38:11 -0000 1.50
--- src/org/openide/text/DocumentLine.java 5 Sep 2003 14:38:40 -0000
***************
*** 18,24 ****
import java.util.*;
import javax.swing.text.*;
import javax.swing.event.*;
- import javax.swing.SwingUtilities;
import org.openide.ErrorManager;
import org.openide.text.EnhancedChangeEvent;
--- 18,23 ----
***************
*** 358,369 ****
}
public String getText() {
! StyledDocument doc = pos.getCloneableEditorSupport ().getDocument ();
// document is not opened
if (doc == null)
return null;
int lineNumber = getLineNumber();
int lineStart = NbDocument.findLineOffset(doc, lineNumber);
// #24434: Check whether the next line exists
--- 357,371 ----
}
public String getText() {
! final StyledDocument doc = pos.getCloneableEditorSupport ().getDocument ();
// document is not opened
if (doc == null)
return null;
+ final String[] retStringArray = new String[1];
+ doc.render(new Runnable() { public void run() {
+ // Part of #33165 - the following code is wrapped by doc.render()
int lineNumber = getLineNumber();
int lineStart = NbDocument.findLineOffset(doc, lineNumber);
// #24434: Check whether the next line exists
***************
*** 377,387 ****
}
try {
! return doc.getText(lineStart, lineEnd - lineStart);
} catch (BadLocationException ex) {
ErrorManager.getDefault ().notify ( ErrorManager.EXCEPTION, ex);
! return null;
}
}
/** Attach created Line.Part to the parent Line */
--- 379,392 ----
}
try {
! retStringArray[0] = doc.getText(lineStart, lineEnd - lineStart);
} catch (BadLocationException ex) {
ErrorManager.getDefault ().notify ( ErrorManager.EXCEPTION, ex);
! retStringArray[0] = null;
}
+ // End of the code wrapped by doc.render()
+ }});
+ return retStringArray[0];
}
/** Attach created Line.Part to the parent Line */
***************
*** 552,569 ****
}
public String getText() {
! StyledDocument doc = position.getCloneableEditorSupport ().getDocument ();
// document is not opened
if (doc == null)
return null;
try {
! return doc.getText(position.getOffset(), getLength());
} catch (BadLocationException ex) {
ErrorManager.getDefault ().notify ( ErrorManager.EXCEPTION, ex);
! return null;
}
}
/** When document is opened or closed the annotations must be added or
--- 557,581 ----
}
public String getText() {
! final StyledDocument doc = position.getCloneableEditorSupport ().getDocument ();
// document is not opened
if (doc == null)
return null;
+ final String[] retStringArray = new String[1];
+ doc.render(new Runnable() { public void run() {
+ // Part of #33165 - the following code is wrapped by doc.render()
try {
! retStringArray[0] = doc.getText(position.getOffset(), getLength());
} catch (BadLocationException ex) {
ErrorManager.getDefault ().notify ( ErrorManager.EXCEPTION, ex);
! retStringArray[0] = null;
}
+ // End of the code wrapped by doc.render()
+ }});
+ return retStringArray[0];
+
}
/** When document is opened or closed the annotations must be added or
***************
*** 645,655 ****
}
private void invoke(int op) {
! SwingUtilities.invokeLater(new LR(op));
}
private void invoke(EnhancedChangeEvent ev) {
! SwingUtilities.invokeLater(new LR(ev));
}
public void stateChanged (ChangeEvent ev) {
--- 657,671 ----
}
private void invoke(int op) {
! // part of #33165 - done synchronously not invoking into EQ
! //SwingUtilities.invokeLater(new LR(op));
! new LR(op).run();
}
private void invoke(EnhancedChangeEvent ev) {
! // part of #33165 - done synchronously not invoking into EQ
! //SwingUtilities.invokeLater(new LR(ev));
! new LR(ev).run();
}
public void stateChanged (ChangeEvent ev) {
Index: src/org/openide/text/NbDocument.java
===================================================================
RCS file: /cvs/openide/src/org/openide/text/NbDocument.java,v
retrieving revision 1.51
diff -c -r1.51 NbDocument.java
*** src/org/openide/text/NbDocument.java 27 Feb 2003 23:41:05 -0000 1.51
--- src/org/openide/text/NbDocument.java 5 Sep 2003 14:38:40 -0000
***************
*** 93,100 ****
--- 93,104 ----
* is null
.
*/
public static int findLineNumber (StyledDocument doc, int offset) {
+ /* pre-33165
Element paragraphsParent = findLineRootElement (doc);
return paragraphsParent.getElementIndex (offset);
+ */
+
+ return new DocumentRenderer(DocumentRenderer.FIND_LINE_NUMBER, doc, offset).renderToInt();
}
/** Finds column number given an offset.
***************
*** 105,113 ****
--- 109,120 ----
* is null
.
*/
public static int findLineColumn (StyledDocument doc, int offset) {
+ /*
Element paragraphsParent = findLineRootElement (doc);
int indx = paragraphsParent.getElementIndex (offset);
return offset - paragraphsParent.getElement (indx).getStartOffset ();
+ */
+ return new DocumentRenderer(DocumentRenderer.FIND_LINE_COLUMN, doc, offset).renderToInt();
}
/** Finds offset of the beginning of a line.
***************
*** 120,125 ****
--- 127,133 ----
* lineNumber
value is inserted
*/
public static int findLineOffset (StyledDocument doc, int lineNumber) {
+ /*
Element paragraphsParent = findLineRootElement (doc);
Element line = paragraphsParent.getElement (lineNumber);
***************
*** 129,134 ****
--- 137,145 ----
}
return line.getStartOffset ();
+ */
+
+ return new DocumentRenderer(DocumentRenderer.FIND_LINE_OFFSET, doc, lineNumber).renderToInt();
}
/** Creates position with a bias. If the bias is {@link javax.swing.text.Position.Bias#Backward}
***************
*** 573,577 ****
* @param annotation annotation which is going to be removed */
public void removeAnnotation(Annotation annotation);
}
!
}
--- 584,648 ----
* @param annotation annotation which is going to be removed */
public void removeAnnotation(Annotation annotation);
}
!
! private static final class DocumentRenderer implements Runnable {
!
! private static final int FIND_LINE_NUMBER = 0;
! private static final int FIND_LINE_COLUMN = 1;
! private static final int FIND_LINE_OFFSET = 2;
!
! private StyledDocument doc;
!
! private int opCode;
!
! private int argInt;
!
! private int retInt;
!
! DocumentRenderer(int opCode, StyledDocument doc, int argInt) {
! this.opCode = opCode;
! this.doc = doc;
! this.argInt = argInt;
! }
!
! int renderToInt() {
! doc.render(this);
! return retInt;
! }
!
!
! public void run() {
! switch (opCode) {
! case FIND_LINE_NUMBER: {
! Element paragraphsParent = findLineRootElement (doc);
! retInt = paragraphsParent.getElementIndex (argInt); // argInt is offset
! break; }
!
!
! case FIND_LINE_COLUMN: {
! Element paragraphsParent = findLineRootElement (doc);
! int indx = paragraphsParent.getElementIndex (argInt); // argInt is offset
! retInt = argInt - paragraphsParent.getElement (indx).getStartOffset ();
! break; }
!
!
! case FIND_LINE_OFFSET: {
! Element paragraphsParent = findLineRootElement (doc);
! Element line = paragraphsParent.getElement (argInt); // argInt is lineNumber
!
! if(line == null) {
! throw new IndexOutOfBoundsException(
! "Index=" + argInt + " is out of bounds."); // NOI18N
! }
!
! retInt = line.getStartOffset ();
! break; }
!
! default:
! throw new IllegalStateException();
!
! }
! }
! }
!
}
Index: src/org/openide/text/PositionRef.java
===================================================================
RCS file: /cvs/openide/src/org/openide/text/PositionRef.java,v
retrieving revision 1.49
diff -c -r1.49 PositionRef.java
*** src/org/openide/text/PositionRef.java 2 Apr 2003 09:46:48 -0000 1.49
--- src/org/openide/text/PositionRef.java 5 Sep 2003 14:38:41 -0000
***************
*** 41,47 ****
/** insert after? */
private boolean insertAfter;
!
/** Creates new PositionRef
using the given manager at the specified
* position offset.
* @param manager manager for the position
--- 41,47 ----
/** insert after? */
private boolean insertAfter;
!
/** Creates new PositionRef
using the given manager at the specified
* position offset.
* @param manager manager for the position
***************
*** 165,171 ****
}
public String toString() {
! return "Pos[" + getOffset () + "]"; // NOI18N
}
/** This class is responsible for the holding the Document object
--- 165,171 ----
}
public String toString() {
! return "Pos[" + getOffset () + "]" + ", kind=" + kind; // NOI18N
}
/** This class is responsible for the holding the Document object
***************
*** 271,281 ****
* pass sweep of the data structure (inlined in the code).
* @param toMemory puts positions to memory if true
,
* from memory if false
*/
! private void processPositions(boolean toMemory) {
// clear the queue, we'll do the sweep inline anyway
while(queue.poll() != null);
counter = 0;
!
synchronized(this) {
ChainItem previous = head;
ChainItem ref = previous.next;
--- 271,282 ----
* pass sweep of the data structure (inlined in the code).
* @param toMemory puts positions to memory if true
,
* from memory if false
*/
! private void processPositions(final boolean toMemory) {
// clear the queue, we'll do the sweep inline anyway
while(queue.poll() != null);
counter = 0;
!
! /* pre-33165
synchronized(this) {
ChainItem previous = head;
ChainItem ref = previous.next;
***************
*** 298,304 ****
ref = ref.next;
}
! }
}
/** Polls queue and increases the counter
accordingly.
--- 299,308 ----
ref = ref.next;
}
! }
! */
!
! new DocumentRenderer(DocumentRenderer.PROCESS_POSITIONS, toMemory).render();
}
/** Polls queue and increases the counter
accordingly.
***************
*** 339,346 ****
}
/** Adds the position to this manager. */
! Kind addPosition(PositionRef pos) {
Kind kind;
synchronized(this) {
head.next = new ChainItem(pos, queue, head.next);
--- 343,352 ----
}
/** Adds the position to this manager. */
! Kind addPosition(final PositionRef pos) {
Kind kind;
+
+ /* pre-33165
synchronized(this) {
head.next = new ChainItem(pos, queue, head.next);
***************
*** 348,353 ****
--- 354,362 ----
pos.kind :
pos.kind.toMemory(pos.insertAfter));
}
+ */
+
+ kind = (Kind)new DocumentRenderer(DocumentRenderer.ADD_POSITION, pos).renderToObject();
checkQueue();
***************
*** 418,423 ****
--- 427,434 ----
/** Converts the kind to representation in memory */
public PositionKind toMemory (boolean insertAfter) {
+
+ /* pre-33165
// try to find the right position
Position p;
try {
***************
*** 426,431 ****
--- 437,446 ----
p = doc.getEndPosition ();
}
return new PositionKind (p);
+ */
+
+ return (PositionKind)new DocumentRenderer(
+ DocumentRenderer.KIND_TO_MEMORY, this, insertAfter).renderToObject();
}
/** Converts the kind to representation out from memory */
***************
*** 453,472 ****
/** Get the line number */
public int getLine() {
! return NbDocument.findLineNumber(doc, getOffset());
}
/** Get the column number */
public int getColumn() {
! return NbDocument.findLineColumn(doc, getOffset());
}
/** Writes the kind to stream */
public void write (DataOutput os) throws IOException {
int offset = getOffset();
int line = getLine();
int column = getColumn();
if(offset < 0 || line < 0 || column < 0) {
throw new IOException(
"Illegal PositionKind: " + pos + "[offset=" // NOI18N
--- 468,501 ----
/** Get the line number */
public int getLine() {
! // pre-33165 return NbDocument.findLineNumber(doc, getOffset());
! return new DocumentRenderer(
! DocumentRenderer.POSITION_KIND_GET_LINE, this).renderToInt();
}
/** Get the column number */
public int getColumn() {
! // pre-33165 return NbDocument.findLineColumn(doc, getOffset());
! return new DocumentRenderer(
! DocumentRenderer.POSITION_KIND_GET_COLUMN, this).renderToInt();
}
/** Writes the kind to stream */
public void write (DataOutput os) throws IOException {
+
+ /* pre-33165
int offset = getOffset();
int line = getLine();
int column = getColumn();
+ */
+
+ DocumentRenderer renderer = new DocumentRenderer(
+ DocumentRenderer.POSITION_KIND_WRITE, this);
+ int offset = renderer.renderToIntIOE();
+ int line = renderer.getLine();
+ int column = renderer.getColumn();
+
if(offset < 0 || line < 0 || column < 0) {
throw new IOException(
"Illegal PositionKind: " + pos + "[offset=" // NOI18N
***************
*** 505,513 ****
--- 534,553 ----
/** Constructs the out kind from the position kind.
*/
public OutKind (PositionKind kind) {
+
+ /* pre-33165
int offset = kind.getOffset();
int line = kind.getLine();
int column = kind.getColumn();
+ */
+
+
+ DocumentRenderer renderer = new DocumentRenderer(
+ DocumentRenderer.OUT_KIND_CONSTRUCTOR, kind);
+
+ int offset = renderer.renderToInt();
+ int line = renderer.getLine();
+ int column = renderer.getColumn();
if(offset < 0 || line < 0 || column < 0) {
throw new IndexOutOfBoundsException(
***************
*** 590,601 ****
/** Get the line number */
public int getLine() throws IOException {
! return NbDocument.findLineNumber(getCloneableEditorSupport().openDocument(), offset);
}
/** Get the column number */
public int getColumn() throws IOException {
! return NbDocument.findLineColumn (getCloneableEditorSupport().openDocument(), offset);
}
/** Writes the kind to stream */
--- 630,647 ----
/** Get the line number */
public int getLine() throws IOException {
! // pre-33165 return NbDocument.findLineNumber(getCloneableEditorSupport().openDocument(), offset);
! getCloneableEditorSupport().openDocument(); // make sure document is fully read
! return new DocumentRenderer(DocumentRenderer.OFFSET_KIND_GET_LINE,
! this, offset).renderToIntIOE();
}
/** Get the column number */
public int getColumn() throws IOException {
! // pre-33165 return NbDocument.findLineColumn (getCloneableEditorSupport().openDocument(), offset);
! getCloneableEditorSupport().openDocument(); // make sure document fully read
! return new DocumentRenderer(DocumentRenderer.OFFSET_KIND_GET_COLUMN,
! this, offset).renderToIntIOE();
}
/** Writes the kind to stream */
***************
*** 638,643 ****
--- 684,691 ----
/** Offset */
public int getOffset () {
+
+ /* pre-33165
try {
StyledDocument doc = getCloneableEditorSupport().getDocument();
if (doc == null) {
***************
*** 648,653 ****
--- 696,717 ----
// what to do? hopefully unlikelly
return 0;
}
+ */
+
+
+ try {
+ StyledDocument doc = getCloneableEditorSupport().getDocument();
+ if (doc == null) {
+ doc = getCloneableEditorSupport().openDocument();
+ }
+ int retOffset = new DocumentRenderer(DocumentRenderer.LINE_KIND_GET_OFFSET,
+ this, line, column, doc).renderToInt();
+ return retOffset;
+
+ } catch (IOException e) {
+ // what to do? hopefully unlikelly
+ return 0;
+ }
}
/** Get the line number */
***************
*** 677,682 ****
--- 741,748 ----
/** Converts the kind to representation in memory */
public PositionKind toMemory (boolean insertAfter) {
+
+ /* pre-33165
// try to find the right position
Position p;
try {
***************
*** 684,695 ****
} catch (BadLocationException e) {
p = doc.getEndPosition ();
}
return new PositionKind (p);
}
}
! }
}
--- 750,1004 ----
} catch (BadLocationException e) {
p = doc.getEndPosition ();
}
+ */
+
+ Position p = (Position)new DocumentRenderer(
+ DocumentRenderer.LINE_KIND_TO_MEMORY, this,
+ line, column, insertAfter).renderToObject();
+
return new PositionKind (p);
}
}
+
+ /**
+ * Helper class ensuring that critical parts will run under document's read lock
+ * by using {@link javax.swing.text.Document#render(Runnable)}.
+ */
+ private final class DocumentRenderer implements Runnable {
+
+ private static final int KIND_TO_MEMORY = 0;
+
+ private static final int POSITION_KIND_GET_LINE = KIND_TO_MEMORY + 1;
+
+ private static final int POSITION_KIND_GET_COLUMN = POSITION_KIND_GET_LINE + 1;
+
+ private static final int POSITION_KIND_WRITE = POSITION_KIND_GET_COLUMN + 1;
! private static final int OUT_KIND_CONSTRUCTOR = POSITION_KIND_WRITE + 1;
!
! private static final int OFFSET_KIND_GET_LINE = OUT_KIND_CONSTRUCTOR + 1;
!
! private static final int OFFSET_KIND_GET_COLUMN = OFFSET_KIND_GET_LINE + 1;
!
! private static final int LINE_KIND_GET_OFFSET = OFFSET_KIND_GET_COLUMN + 1;
!
! private static final int LINE_KIND_TO_MEMORY = LINE_KIND_GET_OFFSET + 1;
!
! private static final int PROCESS_POSITIONS = LINE_KIND_TO_MEMORY + 1;
!
! private static final int ADD_POSITION = PROCESS_POSITIONS + 1;
!
! private final int opCode;
!
! private Kind argKind;
!
! private boolean argInsertAfter;
!
! private boolean argToMemory;
!
! private int argInt;
!
! private Object retObject;
!
! private int retInt;
!
! private int argLine;
!
! private int argColumn;
!
! private PositionRef argPos;
!
! private StyledDocument argDoc;
!
! private IOException ioException;
!
! DocumentRenderer(int opCode, Kind argKind) {
! this.opCode = opCode;
! this.argKind = argKind;
! }
!
! DocumentRenderer(int opCode, Kind argKind, boolean argInsertAfter) {
! this(opCode, argKind);
! this.argInsertAfter = argInsertAfter;
! }
!
! DocumentRenderer(int opCode, Kind argKind, int argInt) {
! this(opCode, argKind);
! this.argInt = argInt;
! }
!
! DocumentRenderer(int opCode, Kind argKind, int argLine, int argColumn) {
! this(opCode, argKind);
! this.argLine = argLine;
! this.argColumn = argColumn;
! }
!
! DocumentRenderer(int opCode, Kind argKind, int argLine, int argColumn, StyledDocument argDoc) {
! this(opCode, argKind, argLine, argColumn);
! this.argDoc = argDoc;
! }
!
! DocumentRenderer(int opCode, Kind argKind, int argLine, int argColumn, boolean argInsertAfter) {
! this(opCode, argKind, argLine, argColumn);
! this.argInsertAfter = argInsertAfter;
! }
!
! DocumentRenderer(int opCode, boolean toMemory) {
! this.opCode = opCode;
! this.argToMemory = toMemory;
! }
!
! DocumentRenderer(int opCode, PositionRef argPos) {
! this.opCode = opCode;
! this.argPos = argPos;
! }
!
! void render() {
! if (doc != null) {
! doc.render(this);
! } else {
! this.run();
! }
! }
!
! Object renderToObjectIOE() throws IOException {
! Object o = renderToObject();
!
! if (ioException != null) {
! throw ioException;
! }
!
! return o;
! }
!
! Object renderToObject() {
! render();
! return retObject;
! }
!
! int renderToIntIOE() throws IOException {
! int i = renderToInt();
!
! if (ioException != null) {
! throw ioException;
! }
!
! return i;
! }
!
! int renderToInt() {
! render();
! return retInt;
! }
!
! int getLine() {
! return argLine;
! }
!
! int getColumn() {
! return argColumn;
! }
!
! public void run() {
! try {
! switch (opCode) {
! case KIND_TO_MEMORY: {
! // try to find the right position
! Position p;
! try {
! p = NbDocument.createPosition (doc, argKind.getOffset (),
! argInsertAfter ? Position.Bias.Forward : Position.Bias.Backward);
! } catch (BadLocationException e) {
! p = doc.getEndPosition ();
! }
! retObject = (PositionKind)new PositionKind (p);
! break; }
!
! case POSITION_KIND_GET_LINE: {
! retInt = NbDocument.findLineNumber(doc, argKind.getOffset());
! break; }
!
! case POSITION_KIND_GET_COLUMN: {
! retInt = NbDocument.findLineColumn(doc, argKind.getOffset());
! break; }
!
! case POSITION_KIND_WRITE:
! case OUT_KIND_CONSTRUCTOR: {
! retInt = argKind.getOffset();
! argLine = argKind.getLine();
! argColumn = argKind.getColumn();
! break; }
!
! case OFFSET_KIND_GET_LINE: {
! retInt = NbDocument.findLineNumber(getCloneableEditorSupport().openDocument(), argInt);
! break; }
!
! case OFFSET_KIND_GET_COLUMN: {
! retInt = NbDocument.findLineColumn (getCloneableEditorSupport().openDocument(), argInt);
! break; }
!
! case LINE_KIND_GET_OFFSET: {
! retInt = NbDocument.findLineOffset (argDoc, argLine) + argColumn;
! break; }
!
! case LINE_KIND_TO_MEMORY: {
! // try to find the right position
! try {
! retObject = NbDocument.createPosition (doc,
! NbDocument.findLineOffset (doc, argLine) + argColumn,
! argInsertAfter ? Position.Bias.Forward : Position.Bias.Backward);
! } catch (BadLocationException e) {
! retObject = doc.getEndPosition ();
! }
! break; }
!
! case PROCESS_POSITIONS: {
! synchronized(Manager.this) {
! ChainItem previous = head;
! ChainItem ref = previous.next;
!
! while(ref != null) {
! PositionRef pos = (PositionRef)ref.get();
! if(pos == null) {
! // Remove the item from data structure.
! previous.next = ref.next;
! } else {
! // Process the PostionRef.
! if(argToMemory) {
! pos.kind = pos.kind.toMemory(pos.insertAfter);
! } else {
! pos.kind = pos.kind.fromMemory();
! }
!
! previous = ref;
! }
!
! ref = ref.next;
! }
! }
! break; }
!
! case ADD_POSITION: {
! synchronized(Manager.this) {
! head.next = new ChainItem(argPos, queue, head.next);
!
! retObject = (doc == null ?
! argPos.kind :
! argPos.kind.toMemory(argPos.insertAfter));
! }
! break; }
+ default:
+ throw new IllegalStateException(); // Unknown opcode
+ }
+ } catch (IOException e) {
+ ioException = e;
+ }
+ }
+
+ }
+
+ }
}