diff --git a/openide.text/src/org/openide/text/CloneableEditorSupport.java b/openide.text/src/org/openide/text/CloneableEditorSupport.java --- a/openide.text/src/org/openide/text/CloneableEditorSupport.java +++ b/openide.text/src/org/openide/text/CloneableEditorSupport.java @@ -456,7 +456,6 @@ if (getListener().loadExc instanceof UserQuestionException) { getListener().loadExc = null; - prepareTask = null; documentStatus = DOCUMENT_NO; } @@ -476,7 +475,6 @@ public Void call() throws IOException { getListener().loadExc = null; - prepareTask = null; documentStatus = DOCUMENT_NO; //Assign reference to local variable to avoid gc before return StyledDocument doc = openDocument(); @@ -562,7 +560,7 @@ return redirect.prepareDocument(); } synchronized (getLock()) { - StyledDocument doc = getDoc(); + final StyledDocument doc = getDoc(); if ((doc == null) && (documentStatus != DOCUMENT_NO)) { //Sync document status closeDocument(); @@ -585,9 +583,14 @@ }); return t; - + + case DOCUMENT_READY: + assert doc != null; + Task tt = new Task(new Runnable() { private final StyledDocument d = doc; public void run() {}}); + tt.run(); + return tt; + default: - if (prepareTask == null) { // should never happen throw new IllegalStateException(); } @@ -655,7 +658,6 @@ NbDocument.runAtomic(docToLoad[0], this); if (fireEvent) { fireDocumentChange(d, false); - d = null; } return; } @@ -688,15 +690,12 @@ d = getDoc(); } catch (DelegateIOExc t) { prepareDocumentRuntimeException = t; - prepareTask = null; } catch (RuntimeException t) { prepareDocumentRuntimeException = t; - prepareTask = null; Exceptions.printStackTrace(t); throw t; } catch (Error t) { prepareDocumentRuntimeException = t; - prepareTask = null; Exceptions.printStackTrace(t); throw t; } finally { @@ -709,9 +708,9 @@ } }); prepareTaskReturn = prepareTask; - ((RequestProcessor.Task)prepareTask).schedule(0); + ((RequestProcessor.Task)prepareTaskReturn).schedule(0); if (RP.isRequestProcessorThread()) { - prepareTask.waitFinished(); + prepareTaskReturn.waitFinished(); } failed = false; } catch (RuntimeException ex) { @@ -721,6 +720,7 @@ prepareDocumentRuntimeException = err; throw err; } finally { + prepareTask = null; if (failed) { documentStatus = DOCUMENT_NO; getLock().notifyAll(); @@ -1679,11 +1679,7 @@ ERR.fine("clearDocument"); clearDocument(); // uses the listener's run method to initialize whole document - prepareTask = new Task(getListener()); - ERR.fine("new prepare task: " + - prepareTask); - prepareTask.run(); - ERR.fine("prepareTask finished"); + getListener().run(); documentStatus = DOCUMENT_READY; reloadDocumentFireDocumentChangeOpen = true; //fireDocumentChange(getDoc(), false); @@ -1703,12 +1699,10 @@ return; } prepareDocumentRuntimeException = t; - prepareTask = null; throw t; } catch (Error t) { prepareDocumentRuntimeException = t; - prepareTask = null; throw t; } finally { @@ -1774,8 +1768,6 @@ } } }); - - return prepareTask; } return prepareDocument(); @@ -2207,7 +2199,6 @@ */ private boolean doCloseDocument() { boolean fireEvent = false; - prepareTask = null; // notifies the support that cesEnv().removePropertyChangeListener(getListener()); @@ -2226,7 +2217,7 @@ documentStatus = DOCUMENT_NO; fireEvent = true; setDoc(null, false); -// kit = null; + kit = null; getUndoRedo().discardAllEdits(); updateLineSet(true); @@ -2622,7 +2613,7 @@ setStrong(alreadyModified, false); } - private StyledDocument getDoc() { + /* test */ StyledDocument getDoc() { synchronized (LOCK_STRONG_REF) { StrongRef _doc = doc; return _doc != null ? _doc.get() : null; diff --git a/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportTest.java b/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportTest.java --- a/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportTest.java +++ b/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportTest.java @@ -45,6 +45,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; @@ -52,6 +53,7 @@ import java.util.Date; import javax.swing.JEditorPane; import javax.swing.SwingUtilities; +import javax.swing.text.Document; import javax.swing.text.EditorKit; import junit.framework.AssertionFailedError; import junit.framework.Test; @@ -60,6 +62,7 @@ import org.netbeans.junit.NbTestSuite; import org.openide.util.Exceptions; import org.openide.util.Lookup; +import org.openide.util.Task; import org.openide.util.UserQuestionException; import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.InstanceContent; @@ -383,6 +386,34 @@ processed[0]); } + public void testPrepareDocument() throws Exception { + content = "Ahoj\nMyDoc"; + Task task = support.prepareDocument(); + task.waitFinished(); + + try { + Object o = new Object(); + assertGC("", new WeakReference(o)); + } catch (AssertionFailedError e) { + // ignore, intentional + } + + Document doc = support.getDoc(); + assertNotNull("Document should not be GCed while its loading task exists", doc); + + Task task2 = support.prepareDocument(); + assertTrue("Loading task should be finished", task2.isFinished()); + assertNotSame("Expecting different task instance", task, task2); + task2 = null; + + Reference taskRef = new WeakReference(task); + Reference docRef = new WeakReference(doc); + task = null; + doc = null; + assertGC("Can't GC document loading task", taskRef); + assertGC("Can't GC document", docRef); + } + // // Implementation of the CloneableEditorSupport.Env //