diff -r 0f6733730c8f editor.guards/apichanges.xml --- a/editor.guards/apichanges.xml Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/apichanges.xml Fri Nov 16 19:14:50 2012 +0100 @@ -108,6 +108,23 @@ + + + Ability run guarded readers/writers when the content of the guarded section's content is set + + + + + +

When this option is set, setting the content of a GuardedSection will pass the data through the given + guarded writer and back through the given guarded reader, to ensure the result is the same + as if it would be read from the disk.

+

Note that this new mode is not fully compatible with the original mode, e.g. all the set methods + of all the GuardedSection classes will throw IllegalStateException if invoked inside the write&read part.

+
+ +
+ GuardedSectionsProvider supports Charset diff -r 0f6733730c8f editor.guards/manifest.mf --- a/editor.guards/manifest.mf Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/manifest.mf Fri Nov 16 19:14:50 2012 +0100 @@ -1,5 +1,5 @@ Manifest-Version: 1.0 OpenIDE-Module: org.netbeans.modules.editor.guards/1 OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/guards/Bundle.properties -OpenIDE-Module-Specification-Version: 1.19 +OpenIDE-Module-Specification-Version: 1.20 diff -r 0f6733730c8f editor.guards/src/org/netbeans/api/editor/guards/GuardedSection.java --- a/editor.guards/src/org/netbeans/api/editor/guards/GuardedSection.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/api/editor/guards/GuardedSection.java Fri Nov 16 19:14:50 2012 +0100 @@ -50,9 +50,11 @@ /** * Represents one guarded section. */ -public class GuardedSection { +public abstract class GuardedSection { private final GuardedSectionImpl impl; + private final GuardedSection delegate; + final int offset; /** * Creates new section. @@ -62,6 +64,14 @@ assert impl != null; this.impl = impl; impl.attach(this); + this.delegate = null; + this.offset = 0; + } + + GuardedSection(GuardedSection delegate, int offset) { + this.impl = null; + this.delegate = delegate; + this.offset = offset; } /** @@ -69,7 +79,7 @@ * @return the name */ public String getName() { - return impl.getName(); + return impl != null ? impl.getName() : delegate.getName(); } /** @@ -78,6 +88,7 @@ * @exception PropertyVetoException if the new name is already in use */ public void setName(String name) throws PropertyVetoException { + if (impl == null) throw new IllegalStateException(); impl.setName(name); } @@ -87,6 +98,7 @@ * and it will be impossible to use its methods. */ public void deleteSection() { + if (impl == null) throw new IllegalStateException(); impl.deleteSection(); } @@ -95,7 +107,7 @@ * source. */ public boolean isValid() { - return impl.isValid(); + return impl != null ? impl.isValid() : delegate.isValid(); } /** @@ -104,6 +116,7 @@ * instead of calling NbDocument. */ public void removeSection() { + if (impl == null) throw new IllegalStateException(); impl.removeSection(); } @@ -113,7 +126,7 @@ * @return the position to place the caret. */ public Position getCaretPosition() { - return impl.getCaretPosition(); + return impl != null ? impl.getCaretPosition() : new OffsetPosition(delegate.getCaretPosition(), offset); } /** @@ -121,7 +134,7 @@ * @return The text contained in the section. */ public String getText() { - return impl.getText(); + return impl != null ? impl.getText() : delegate.getText(); } /** @@ -134,7 +147,7 @@ * @return true if the position is inside section. */ public boolean contains(Position pos, boolean permitHoles) { - return impl.contains(pos, permitHoles); + return impl != null ? impl.contains(pos, permitHoles) : delegate.contains(new OffsetPosition(pos, -offset), permitHoles); } /** @@ -142,7 +155,7 @@ * @return the end position of the guarded section. */ public Position getEndPosition() { - return impl.getEndPosition(); + return impl != null ? impl.getEndPosition() : new OffsetPosition(delegate.getEndPosition(), offset); } /** @@ -150,11 +163,29 @@ * @return the start position of the guarded section. */ public Position getStartPosition() { - return impl.getStartPosition(); + return impl != null ? impl.getStartPosition() : new OffsetPosition(delegate.getStartPosition(), offset); } GuardedSectionImpl getImpl() { return impl; } + GuardedSection getDelegate() { + return delegate; + } + + abstract GuardedSection clone(int offset); + + static class OffsetPosition implements Position { + private final Position delegate; + private final int offset; + public OffsetPosition(Position delegate, int offset) { + this.delegate = delegate; + this.offset = offset; + } + @Override public int getOffset() { + return delegate.getOffset() - offset; + } + + } } diff -r 0f6733730c8f editor.guards/src/org/netbeans/api/editor/guards/GuardedSectionManager.java --- a/editor.guards/src/org/netbeans/api/editor/guards/GuardedSectionManager.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/api/editor/guards/GuardedSectionManager.java Fri Nov 16 19:14:50 2012 +0100 @@ -156,6 +156,11 @@ public GuardedSectionImpl getImpl(GuardedSection gs) { return gs.getImpl(); } + + @Override + public GuardedSection clone(GuardedSection gs, int offset) { + return gs.clone(offset); + } }; } diff -r 0f6733730c8f editor.guards/src/org/netbeans/api/editor/guards/InteriorSection.java --- a/editor.guards/src/org/netbeans/api/editor/guards/InteriorSection.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/api/editor/guards/InteriorSection.java Fri Nov 16 19:14:50 2012 +0100 @@ -60,11 +60,16 @@ super(impl); } + InteriorSection(GuardedSection delegate, int offset) { + super(delegate, offset); + } + /** * Sets the text of the body. * @param text the new text */ public void setBody(String text) { + if (getImpl() == null) throw new IllegalStateException(); getImpl().setBody(text); } @@ -74,6 +79,7 @@ * @return contents of the body or null, if the section is not valid. */ public String getBody() { + if (getImpl() == null) return getDelegate().getBody(); return getImpl().getBody(); } @@ -82,6 +88,7 @@ * @param text the new text */ public void setHeader(String text) { + if (getImpl() == null) throw new IllegalStateException(); getImpl().setHeader(text); } @@ -91,6 +98,7 @@ * @return contents of the header or null, if the section is not valid. */ public String getHeader() { + if (getImpl() == null) return getDelegate().getHeader(); return getImpl().getHeader(); } @@ -102,6 +110,7 @@ * @param text the new text */ public void setFooter(String text) { + if (getImpl() == null) throw new IllegalStateException(); getImpl().setFooter(text); } @@ -111,6 +120,7 @@ * @return contents of the footer part, or null if the section is not valid. */ public String getFooter() { + if (getImpl() == null) return getDelegate().getFooter(); return getImpl().getFooter(); } @@ -119,6 +129,7 @@ * @return the start position of the body part */ public Position getBodyStartPosition() { + if (getImpl() == null) return new OffsetPosition(getDelegate().getBodyStartPosition(), offset); return getImpl().getBodyStartPosition(); } @@ -127,6 +138,7 @@ * @return the end position of the body part */ public Position getBodyEndPosition() { + if (getImpl() == null) return new OffsetPosition(getDelegate().getBodyEndPosition(), offset); return getImpl().getBodyEndPosition(); } @@ -154,4 +166,14 @@ } return buf.toString(); }*/ + + @Override + InteriorSection getDelegate() { + return (InteriorSection) super.getDelegate(); + } + + @Override + GuardedSection clone(int offset) { + return new InteriorSection(this, offset); + } } diff -r 0f6733730c8f editor.guards/src/org/netbeans/api/editor/guards/SimpleSection.java --- a/editor.guards/src/org/netbeans/api/editor/guards/SimpleSection.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/api/editor/guards/SimpleSection.java Fri Nov 16 19:14:50 2012 +0100 @@ -61,11 +61,16 @@ super(impl); } + SimpleSection(GuardedSection delegate, int offset) { + super(delegate, offset); + } + /** * Sets the text of the section. * @param text the new text */ public void setText(String text) { + if (getImpl() == null) throw new IllegalStateException(); getImpl().setText(text); } @@ -87,4 +92,9 @@ SimpleSectionImpl getImpl() { return (SimpleSectionImpl) super.getImpl(); } + + @Override + GuardedSection clone(int offset) { + return new SimpleSection(this, offset); + } } diff -r 0f6733730c8f editor.guards/src/org/netbeans/modules/editor/guards/GuardedReader.java --- a/editor.guards/src/org/netbeans/modules/editor/guards/GuardedReader.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/modules/editor/guards/GuardedReader.java Fri Nov 16 19:14:50 2012 +0100 @@ -189,7 +189,7 @@ isClosed = true; reader.close(); if (this.result != null) { - callback.fillSections(this.result.getGuardedSections(), newLineStream.getNewLineType()); + callback.fillSections(gr, this.result.getGuardedSections(), newLineStream.getNewLineType()); } } } diff -r 0f6733730c8f editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionImpl.java --- a/editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionImpl.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionImpl.java Fri Nov 16 19:14:50 2012 +0100 @@ -46,6 +46,9 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyVetoException; +import java.io.ByteArrayOutputStream; +import java.nio.charset.Charset; +import java.util.Collections; import javax.swing.text.BadLocationException; import javax.swing.text.Position; import javax.swing.text.StyledDocument; @@ -179,6 +182,11 @@ try { bounds.setText(text); + if (guards.gr != null) { + char[] data = guards.gr.writeSections(Collections.singletonList(GuardsAccessor.DEFAULT.clone(guard, bounds.getBegin().getOffset())), (bounds.getText() + "\n").toCharArray()); + data = guards.gr.readSections(data).getContent(); + bounds.setText(new String(data, 0, data.length - 1)); + } return true; } catch (BadLocationException e) { } diff -r 0f6733730c8f editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionsImpl.java --- a/editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionsImpl.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/modules/editor/guards/GuardedSectionsImpl.java Fri Nov 16 19:14:50 2012 +0100 @@ -254,13 +254,16 @@ // package + AbstractGuardedSectionsProvider gr; + /** Takes the section descriptors from the GuardedReader and * fills the table 'sections', also marks as guarded all sections * in the given document. * @param is Where to take the guarded section descriptions. * @param doc Where to mark guarded. */ - void fillSections(List l, NewLine newLineType) { + void fillSections(AbstractGuardedSectionsProvider gr, List l, NewLine newLineType) { + this.gr = gr; this.newLineType = newLineType; // XXX this should invalidate removed GS instances // XXX maybe would be useful to map new list to old list to keep track of valid instances as much as possible diff -r 0f6733730c8f editor.guards/src/org/netbeans/modules/editor/guards/GuardsAccessor.java --- a/editor.guards/src/org/netbeans/modules/editor/guards/GuardsAccessor.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/modules/editor/guards/GuardsAccessor.java Fri Nov 16 19:14:50 2012 +0100 @@ -74,4 +74,6 @@ public abstract GuardedSectionImpl getImpl(GuardedSection gs); + public abstract GuardedSection clone(GuardedSection gs, int offset); + } diff -r 0f6733730c8f editor.guards/src/org/netbeans/spi/editor/guards/support/AbstractGuardedSectionsProvider.java --- a/editor.guards/src/org/netbeans/spi/editor/guards/support/AbstractGuardedSectionsProvider.java Fri Nov 16 09:54:37 2012 +0100 +++ b/editor.guards/src/org/netbeans/spi/editor/guards/support/AbstractGuardedSectionsProvider.java Fri Nov 16 19:14:50 2012 +0100 @@ -69,13 +69,25 @@ public abstract class AbstractGuardedSectionsProvider implements GuardedSectionsProvider { private final GuardedSectionsImpl impl; + private final boolean useReadersWritersOnSet; /** * Creates an AbstractGuardedSectionsProvider. * @param editor an editor abstraction */ protected AbstractGuardedSectionsProvider(GuardedEditorSupport editor) { + this(editor, false); + } + + /** + * Creates an AbstractGuardedSectionsProvider. + * @param editor an editor abstraction + * @param useReadersWritersOnSet if readers and writers should be used when the content of the guarded section's text is set + * @since 1.20 + */ + protected AbstractGuardedSectionsProvider(GuardedEditorSupport editor, boolean useReadersWritersOnSet) { this.impl = new GuardedSectionsImpl(editor); + this.useReadersWritersOnSet = useReadersWritersOnSet; } public final Reader createGuardedReader(InputStream stream, Charset charset) { diff -r 0f6733730c8f java.guards/nbproject/project.xml --- a/java.guards/nbproject/project.xml Fri Nov 16 09:54:37 2012 +0100 +++ b/java.guards/nbproject/project.xml Fri Nov 16 19:14:50 2012 +0100 @@ -55,7 +55,7 @@ 1 - 1.0 + 1.20 diff -r 0f6733730c8f java.guards/src/org/netbeans/modules/java/guards/JavaGuardedReader.java --- a/java.guards/src/org/netbeans/modules/java/guards/JavaGuardedReader.java Fri Nov 16 09:54:37 2012 +0100 +++ b/java.guards/src/org/netbeans/modules/java/guards/JavaGuardedReader.java Fri Nov 16 19:14:50 2012 +0100 @@ -78,17 +78,15 @@ * 2. Replace the comments with spaces to hide them from user but to preserve * overall length and positions. * 3. Remove the comments completely. - * Default is #3, can be changed via branding. For a long time #2 used to be - * the default, but neither 1 nor 2 is reliable since artificial chars are - * made part of the sections' content which the clients do not know about. - * Once a client changes the section content, the artificial comments or spaces - * are gone from the document, but they get written to the file on saving and - * so the file is then inconsistent with the document just like in case of #3. + * + * Option #3 causes that offsets inside the editor differ from the offsets on disk, + * which then breaks many clients that create PositionRefs for a closed file and then + * use it for an opened file, and vice versa. + * + * Default is #2. */ private static boolean KEEP_GUARD_COMMENTS // not final only for tests = getPresetValue("KEEP_GUARD_COMMENTS", false); // NOI18N - private static boolean REPLACE_GUARD_COMMENTS_WITH_SPACES // not final only for tests - = getPresetValue("REPLACE_GUARD_COMMENTS_WITH_SPACES", false); // NOI18N /** The list of the SectionsDesc. */ private final LinkedList list; @@ -219,13 +217,10 @@ if (KEEP_GUARD_COMMENTS) { // keep guard comment (content unchanged) i -= match.length(); charBuffPtr += MAGICLEN; - } else if (REPLACE_GUARD_COMMENTS_WITH_SPACES) { + } else { i += toNl; Arrays.fill(charBuff,charBuffPtr,charBuffPtr+sectionSize,' '); charBuffPtr+=sectionSize; - } else { // remove the guard comment - i += toNl; - desc.setEnd(charBuffPtr); } } } @@ -400,15 +395,7 @@ return defaultValue; } - static void setGuardCommentProcessingForTest(int type) { - if (type == 1) { - KEEP_GUARD_COMMENTS = true; - } else if (type == 2) { - KEEP_GUARD_COMMENTS = false; - REPLACE_GUARD_COMMENTS_WITH_SPACES = true; - } else if (type == 3) { - KEEP_GUARD_COMMENTS = false; - REPLACE_GUARD_COMMENTS_WITH_SPACES = false; - } + static void setKeepGuardCommentsForTest(boolean keep) { + KEEP_GUARD_COMMENTS = keep; } } diff -r 0f6733730c8f java.guards/src/org/netbeans/modules/java/guards/JavaGuardedSectionsProvider.java --- a/java.guards/src/org/netbeans/modules/java/guards/JavaGuardedSectionsProvider.java Fri Nov 16 09:54:37 2012 +0100 +++ b/java.guards/src/org/netbeans/modules/java/guards/JavaGuardedSectionsProvider.java Fri Nov 16 19:14:50 2012 +0100 @@ -56,7 +56,7 @@ public final class JavaGuardedSectionsProvider extends AbstractGuardedSectionsProvider { public JavaGuardedSectionsProvider(GuardedEditorSupport editor) { - super(editor); + super(editor, true); } public char[] writeSections(List sections, char[] buff) { diff -r 0f6733730c8f java.guards/test/unit/src/org/netbeans/modules/java/guards/JavaGuardedReaderTest.java --- a/java.guards/test/unit/src/org/netbeans/modules/java/guards/JavaGuardedReaderTest.java Fri Nov 16 09:54:37 2012 +0100 +++ b/java.guards/test/unit/src/org/netbeans/modules/java/guards/JavaGuardedReaderTest.java Fri Nov 16 19:14:50 2012 +0100 @@ -71,7 +71,6 @@ provider = new JavaGuardedSectionsProvider(editor); instance = new JavaGuardedReader(provider); - JavaGuardedReader.setGuardCommentProcessingForTest(2); } protected void tearDown() throws Exception { @@ -124,7 +123,7 @@ String expStr = "\nclass A {//" + "GEN-BEGIN:hu\n\n}//" + "GEN-END:hu\n"; char[] readBuff = readStr.toCharArray(); - JavaGuardedReader.setGuardCommentProcessingForTest(1); + JavaGuardedReader.setKeepGuardCommentsForTest(true); char[] result = instance.translateToCharBuff(readBuff); List sections = instance.getGuardedSections(); @@ -147,30 +146,7 @@ String expStr = "\nclass A { " + " \n\n} " + " \n"; char[] readBuff = readStr.toCharArray(); - JavaGuardedReader.setGuardCommentProcessingForTest(2); - char[] result = instance.translateToCharBuff(readBuff); - List sections = instance.getGuardedSections(); - - assertEquals(expStr, String.valueOf(result)); - assertEquals("sections", 1, sections.size()); - - GuardedSection expSection = sections.get(0); - assertEquals(SimpleSection.class, expSection.getClass()); - assertEquals("section valid", true, expSection.isValid()); - assertEquals("section name", "hu", expSection.getName()); - assertEquals("begin", 1, expSection.getStartPosition().getOffset()); - assertEquals("end", expStr.length() - 1, expSection.getEndPosition().getOffset()); - } - - public void testTranslateBEGIN_END3() { - System.out.println("read //" + "GEN-BEGIN_END3:"); - - String readStr = "\nclass A {//" + "GEN-BEGIN:hu\n\n}//" + "GEN-END:hu\n"; - editor.setStringContent(readStr); - String expStr = "\nclass A {" + "\n\n}" + "\n"; - char[] readBuff = readStr.toCharArray(); - - JavaGuardedReader.setGuardCommentProcessingForTest(3); + JavaGuardedReader.setKeepGuardCommentsForTest(false); char[] result = instance.translateToCharBuff(readBuff); List sections = instance.getGuardedSections();