changeset: 272145:021e67631e0e tag: tip user: Vladimir Voskresensky date: Mon Feb 17 18:55:59 2014 +0400 summary: fixed #241991 - handle CloneableOpenSupportRedirector based redirections 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 @@ -180,7 +180,7 @@ private UndoRedo.Manager undoRedo; /** lines set for this object */ - private Line.Set lineSet; + private Line.Set[] lineSet = new Line.Set[] { null }; /** Helper variable to prevent multiple cocurrent printing of this * instance. */ @@ -196,7 +196,7 @@ private Set listeners; /** last selected editor pane. */ - private transient Reference lastSelected; + private transient Reference lastSelected[] = new Reference[] { null }; /** The time of the last save to determine the real external modifications */ private long lastSaveTime; @@ -905,17 +905,29 @@ return null; } + + @Override + protected void redirectedOpen(CloneableOpenSupport redirectedTo) { + super.redirectedOpen(redirectedTo); + // synchronize last selected field for correct getRecentPane query + if (redirectedTo instanceof CloneableEditorSupport) { + CloneableEditorSupport other = ((CloneableEditorSupport)redirectedTo); + this.lastSelected = other.lastSelected; + this.openClose = other.openClose; + this.lineSet = other.lineSet; + } + } /** Returns the lastly selected Pane or null */ final Pane getLastSelected() { - Reference r = lastSelected; + Reference r = lastSelected[0]; return (r == null) ? null : r.get(); } final void setLastSelected(Pane lastSelected) { - this.lastSelected = new WeakReference(lastSelected); + this.lastSelected[0] = new WeakReference(lastSelected); } // @@ -1639,19 +1651,19 @@ */ Line.Set updateLineSet(boolean clear) { synchronized (getLock()) { - if ((lineSet != null) && !clear) { - return lineSet; + if ((lineSet[0] != null) && !clear) { + return lineSet[0]; } if ((getDoc() == null) || (openClose.getDocumentStatusLA() == DocumentStatus.RELOADING)) { - lineSet = new EditorSupportLineSet.Closed(CloneableEditorSupport.this); + lineSet[0] = new EditorSupportLineSet.Closed(CloneableEditorSupport.this); } else { - lineSet = new EditorSupportLineSet(CloneableEditorSupport.this,getDoc()); + lineSet[0] = new EditorSupportLineSet(CloneableEditorSupport.this,getDoc()); } - return lineSet; + return lineSet[0]; } } diff --git a/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportRedirectorTest.java b/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportCOSRedirectorTest.java copy from openide.text/test/unit/src/org/openide/text/CloneableEditorSupportRedirectorTest.java copy to openide.text/test/unit/src/org/openide/text/CloneableEditorSupportCOSRedirectorTest.java --- a/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportRedirectorTest.java +++ b/openide.text/test/unit/src/org/openide/text/CloneableEditorSupportCOSRedirectorTest.java @@ -39,7 +39,6 @@ import java.lang.ref.WeakReference; import java.util.Arrays; import javax.swing.SwingUtilities; -import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.EditorKit; import junit.framework.Test; @@ -50,16 +49,18 @@ import org.openide.util.Lookup; import org.openide.util.lookup.AbstractLookup; import org.openide.util.lookup.InstanceContent; +import org.openide.windows.CloneableOpenSupport; +import org.openide.windows.CloneableOpenSupportRedirector; /** - * + * @author Vladimir Voskresensky * @author Jaroslav Tulach */ -public class CloneableEditorSupportRedirectorTest extends NbTestCase +public class CloneableEditorSupportCOSRedirectorTest extends NbTestCase implements CloneableEditorSupport.Env { public static Test suite() { - return GraphicsEnvironment.isHeadless() ? new TestSuite() : new TestSuite(CloneableEditorSupportRedirectorTest.class); + return GraphicsEnvironment.isHeadless() ? new TestSuite() : new TestSuite(CloneableEditorSupportCOSRedirectorTest.class); } static { @@ -71,18 +72,16 @@ // Env variables - private String content = ""; + private StringBuilder content = new StringBuilder(""); private boolean valid = true; private boolean modified = false; - /** if not null contains message why this document cannot be modified */ - private String cannotBeModified; private java.util.Date date = new java.util.Date (); private java.util.List propL = new java.util.ArrayList(); private java.beans.VetoableChangeListener vetoL; - public CloneableEditorSupportRedirectorTest(String testName) { + public CloneableEditorSupportCOSRedirectorTest(String testName) { super(testName); } @@ -94,28 +93,39 @@ red = Lookup.getDefault().lookup(Redirector.class); assertNotNull(red); - CloneableEditorSupportRedirectorTest t = new CloneableEditorSupportRedirectorTest(""); + CloneableEditorSupportCOSRedirectorTest t = new CloneableEditorSupportCOSRedirectorTest(""); + t.content = content; red.master = support; InstanceContent slave = new InstanceContent(); red.slave = new CES(t, new AbstractLookup (slave)); slave.add(red.master); + red.master.open(); + red.slave.open(); } - - public void testSameDocument() throws Exception { + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + red.master.close(); + red.slave.close(); + content.delete(0, content.length()); + } + + public void testSameDocument() throws Exception { javax.swing.text.Document doc = red.slave.openDocument (); assertNotNull (doc); assertSame(doc, red.master.getDocument()); String s = doc.getText (0, doc.getLength ()); - assertEquals ("Same text as in the stream", content, s); + assertEquals ("Same text as in the stream", content.toString(), s); assertFalse ("No redo", red.slave.getUndoRedo ().canRedo ()); assertFalse ("No undo", red.slave.getUndoRedo ().canUndo ()); } public void testLineLookupIsPropagated () throws Exception { - content = "Line1\nLine2\n"; + content.append("Line1\nLine2\n"); Integer template = new Integer (1); ic.add (template); // put anything into the lookup @@ -137,7 +147,7 @@ public void testGetInputStream () throws Exception { - content = "goes\nto\nInputStream"; + content.append("goes\nto\nInputStream"); String added = "added before\n"; javax.swing.text.Document doc = red.master.openDocument (); assertNotNull (doc); @@ -149,38 +159,15 @@ } public void testGetInputStreamWhenClosed () throws Exception { - content = "basic\ncontent"; + content.append("basic\ncontent"); compareStreamWithString(red.master.getInputStream(), content); compareStreamWithString(red.slave.getInputStream(), content); // we should be doing this with the document still closed assertNull("The document is supposed to be still closed", red.master.getDocument ()); } - public void testDocumentCannotBeModified () throws Exception { - content = "Ahoj\nMyDoc"; - cannotBeModified = "No, you cannot modify this document in this test"; - - javax.swing.text.Document doc = red.master.openDocument (); - assertNotNull (doc); - - assertFalse ("Nothing to undo", red.master.getUndoRedo ().canUndo ()); - - // this should not be allowed - try { - doc.insertString (0, "Kuk", null); - fail("Modification should not proceed"); - } catch (BadLocationException ex) { - // Expected - } - - String s = doc.getText (0, doc.getLength ()); - assertEquals ("The document is now the same as at the begining", content, s); - - assertEquals ("Message has been shown to user in status bar", cannotBeModified, org.openide.awt.StatusDisplayer.getDefault ().getStatusText ()); - } - public void testDocumentCanBeGarbageCollectedWhenClosed () throws Exception { - content = "Ahoj\nMyDoc"; + content.append("Ahoj\nMyDoc"); javax.swing.text.Document doc = red.master.openDocument (); assertNotNull (doc); @@ -226,14 +213,14 @@ assertEquals("Wrong default EditorKit", "org.openide.text.CloneableEditorSupport$PlainEditorKit", kit.getClass().getName()); } - private void compareStreamWithString(InputStream is, String s) throws Exception{ + private void compareStreamWithString(InputStream is, CharSequence s) throws Exception{ int i; ByteArrayOutputStream baos = new ByteArrayOutputStream(); while ((i = is.read()) != -1) { baos.write(i); } byte b1[] = baos.toByteArray(); - byte b2[] = s.getBytes(); + byte b2[] = s.toString().getBytes(); assertTrue("Same bytes as would result from the string: " + s, Arrays.equals(b1, b2)); } @@ -270,13 +257,13 @@ } public java.io.InputStream inputStream() throws java.io.IOException { - return new java.io.ByteArrayInputStream (content.getBytes ()); + return new java.io.ByteArrayInputStream (content.toString().getBytes ()); } public java.io.OutputStream outputStream() throws java.io.IOException { class ContentStream extends java.io.ByteArrayOutputStream { public void close () throws java.io.IOException { super.close (); - content = new String (toByteArray ()); + content.append(new String (toByteArray ())); } } @@ -292,16 +279,16 @@ } public void markModified() throws java.io.IOException { - if (cannotBeModified != null) { - final String notify = cannotBeModified; - IOException e = new IOException () { - public String getLocalizedMessage () { - return notify; - } - }; - Exceptions.attachLocalizedMessage(e, cannotBeModified); - throw e; - } +// if (cannotBeModified != null) { +// final String notify = cannotBeModified; +// IOException e = new IOException () { +// public String getLocalizedMessage () { +// return notify; +// } +// }; +// Exceptions.attachLocalizedMessage(e, cannotBeModified); +// throw e; +// } modified = true; } @@ -315,6 +302,11 @@ public CES (Env env, Lookup l) { super (env, l); } + + @Override + protected boolean asynchronousOpen() { + return true; + } protected String messageName() { return "Name"; @@ -339,12 +331,24 @@ } - public static final class Redirector extends CloneableEditorSupportRedirector { + public static final class Redirector extends CloneableOpenSupportRedirector { CES master; CES slave; - - protected CloneableEditorSupport redirect(Lookup ces) { - return ces.lookup(CloneableEditorSupport.class); + + @Override + protected CloneableOpenSupport redirect(CloneableOpenSupport.Env env) { + if (env == slave.cesEnv()) { + return master; + } + return null; } + + @Override + protected void opened(CloneableOpenSupport.Env env) { + } + + @Override + protected void closed(CloneableOpenSupport.Env env) { + } + } } -} diff --git a/openide.windows/src/org/openide/windows/CloneableOpenSupport.java b/openide.windows/src/org/openide/windows/CloneableOpenSupport.java --- a/openide.windows/src/org/openide/windows/CloneableOpenSupport.java +++ b/openide.windows/src/org/openide/windows/CloneableOpenSupport.java @@ -97,6 +97,7 @@ CloneableOpenSupport redirect = CloneableOpenSupportRedirector.findRedirect(this); if (redirect != null) { redirect.open(); + this.redirectedOpenImpl(redirect); return; } //Bugfix #10688 open() is now run in AWT thread @@ -246,6 +247,29 @@ */ protected abstract String messageOpened(); + private void redirectedOpenImpl(CloneableOpenSupport redirectedTo) { + // there is a common patern in user code: + // CloneableEditorSupport ces = ...; + // ces.edit(); + // JEditorPane[] panes = ces.getOpenedPanes(); + // if (panes != null) panes[0].setPosition(offset); + // in case when redirection has happened during edit() call + // 'ces' instance returns null for getOpenedPanes + // but we want panes to be available for 'ces' instance after redirection; + // remember editors from redirected instance to have correct opened panes + // for this instance as well + this.allEditors = redirectedTo.allEditors; +// this.env = redirect.env; + redirectedOpen(redirectedTo); + } + + /** + * notify that other redirected cos was opened instead of this one. + * @param redirectedTo redirected instance which was opened instead of this one + */ + protected void redirectedOpen(CloneableOpenSupport redirectedTo) { + } + /** Abstract interface that is used by CloneableOpenSupport to * talk to outside world. */