# HG changeset patch # Parent d19e3da7cc8ae369c4816b11a1dde71a0b6ed7a7 # User Jesse Glick #162526: FileObject.revert. diff --git a/core.startup/nbproject/project.xml b/core.startup/nbproject/project.xml --- a/core.startup/nbproject/project.xml +++ b/core.startup/nbproject/project.xml @@ -63,7 +63,7 @@ - 7.35 + 7.55 diff --git a/core.startup/src/org/netbeans/core/startup/layers/LocalFileSystemEx.java b/core.startup/src/org/netbeans/core/startup/layers/LocalFileSystemEx.java --- a/core.startup/src/org/netbeans/core/startup/layers/LocalFileSystemEx.java +++ b/core.startup/src/org/netbeans/core/startup/layers/LocalFileSystemEx.java @@ -222,13 +222,13 @@ } } - private class WritableRemover implements Callable { + private class WritableRemover implements Callable { private String name; public WritableRemover( String name ) { this.name = name; } - public Object call() throws Exception { + @Override public Void call() throws IOException { FileObject fo = findResource( name ); if( null != fo ) { fo.delete(); diff --git a/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesModifiedTest.java b/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesModifiedTest.java --- a/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesModifiedTest.java +++ b/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesModifiedTest.java @@ -50,14 +50,12 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.concurrent.Callable; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; import org.netbeans.Module; import org.netbeans.core.startup.Main; import org.netbeans.junit.NbTestCase; -import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -116,7 +114,7 @@ existingFile.setAttribute( "myAttribute", "myAttributeValue" ); - assertNull( "removeWritables does not work for file attributes", FileUtil.getConfigFile( "foo" ).getAttribute( "removeWritables" ) ); + assertFalse("removeWritables does not work for file attributes", FileUtil.getConfigFile("foo").canRevert()); } diff --git a/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesTest.java b/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesTest.java --- a/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesTest.java +++ b/core.startup/test/unit/src/org/netbeans/core/startup/layers/RemoveWritablesTest.java @@ -50,7 +50,6 @@ import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; -import java.util.concurrent.Callable; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; import java.util.jar.Manifest; @@ -114,13 +113,9 @@ File writableFile = new File( new File( configDir, "foo"), "newFile.ext" ); assertTrue( writableFile.exists() ); - - Object writablesRemover = newFile.getAttribute( "removeWritables" ); - - assertNotNull( writablesRemover ); - assertTrue( writablesRemover instanceof Callable ); - - ((Callable)writablesRemover).call(); + + assertTrue(newFile.canRevert()); + newFile.revert(); assertFalse( "local file removed", writableFile.exists() ); assertNull( "FileObject does not exist", FileUtil.getConfigFile( "foo/newFile.ext" ) ); @@ -135,13 +130,10 @@ File maskFile = new File( new File( configDir, "foo"), "test1_hidden" ); assertTrue( maskFile.exists() ); - - Object writablesRemover = FileUtil.getConfigFile( "foo" ).getAttribute( "removeWritables" ); - - assertNotNull( writablesRemover ); - assertTrue( writablesRemover instanceof Callable ); - - ((Callable)writablesRemover).call(); + + FileObject newFile = FileUtil.getConfigFile("foo"); + assertTrue(newFile.canRevert()); + newFile.revert(); assertFalse( "local file removed", maskFile.exists() ); assertNotNull( "FileObject exists again", FileUtil.getConfigFile( "foo/test1" ) ); @@ -161,12 +153,9 @@ File maskFile = new File( new File( configDir, "foo"), "test1_hidden" ); assertTrue( maskFile.exists() ); - Object writablesRemover = FileUtil.getConfigFile( "foo" ).getAttribute( "removeWritables" ); - - assertNotNull( writablesRemover ); - assertTrue( writablesRemover instanceof Callable ); - - ((Callable)writablesRemover).call(); + FileObject newFile = FileUtil.getConfigFile("foo"); + assertTrue(newFile.canRevert()); + newFile.revert(); assertFalse( "local file removed", maskFile.exists() ); assertNotNull( "FileObject exists again", FileUtil.getConfigFile( "foo/test1" ) ); diff --git a/core.windows/nbproject/project.xml b/core.windows/nbproject/project.xml --- a/core.windows/nbproject/project.xml +++ b/core.windows/nbproject/project.xml @@ -125,7 +125,7 @@ - 7.19 + 7.55 diff --git a/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ResetToolbarsAction.java b/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ResetToolbarsAction.java --- a/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ResetToolbarsAction.java +++ b/core.windows/src/org/netbeans/core/windows/view/ui/toolbars/ResetToolbarsAction.java @@ -45,7 +45,7 @@ package org.netbeans.core.windows.view.ui.toolbars; import java.awt.event.ActionEvent; -import java.util.concurrent.Callable; +import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.AbstractAction; @@ -68,13 +68,10 @@ public void actionPerformed(ActionEvent e) { String name = ToolbarPool.getDefault().getConfiguration(); FileObject fo = FileUtil.getConfigFile( "Toolbars" ); //NOI18N - Object attr = fo.getAttribute( "removeWritables" ); //NOI18N - if( null != attr && attr instanceof Callable ) { - try { - ((Callable)attr).call(); - } catch (Exception ex) { - Logger.getLogger(ResetToolbarsAction.class.getName()).log( Level.FINE, null, ex ); - } + try { + fo.revert(); + } catch (IOException ex) { + Logger.getLogger(ResetToolbarsAction.class.getName()).log( Level.FINE, null, ex ); } ToolbarPool.getDefault().waitFinished(); ToolbarPool.getDefault().setConfiguration(name); diff --git a/editor/nbproject/project.xml b/editor/nbproject/project.xml --- a/editor/nbproject/project.xml +++ b/editor/nbproject/project.xml @@ -167,7 +167,7 @@ - 7.19 + 7.55 diff --git a/editor/src/org/netbeans/modules/editor/EditorModule.java b/editor/src/org/netbeans/modules/editor/EditorModule.java --- a/editor/src/org/netbeans/modules/editor/EditorModule.java +++ b/editor/src/org/netbeans/modules/editor/EditorModule.java @@ -78,7 +78,6 @@ import org.netbeans.editor.LocaleSupport; import org.netbeans.modules.editor.indent.api.Reformat; import org.netbeans.modules.editor.lib.EditorPackageAccessor; -import org.netbeans.modules.editor.lib2.EditorApiPackageAccessor; import org.netbeans.modules.editor.lib2.document.ReadWriteUtils; import org.netbeans.modules.editor.options.AnnotationTypesFolder; import org.openide.cookies.EditorCookie; @@ -324,8 +323,7 @@ @Override public void operationRename(Rename ev) {} @Override public void operationCreateShadow(Copy ev) {} @Override public void operationCreateFromTemplate(Copy ev) { - Object removeWritables = ev.getOriginalDataObject().getPrimaryFile().getAttribute("removeWritables"); - if (removeWritables == null) { + if (!ev.getOriginalDataObject().getPrimaryFile().canRevert()) { // Reformat only files created from original templates. reformat(ev.getObject()); } diff --git a/favorites/nbproject/project.xml b/favorites/nbproject/project.xml --- a/favorites/nbproject/project.xml +++ b/favorites/nbproject/project.xml @@ -95,7 +95,7 @@ - 7.19 + 7.55 diff --git a/favorites/src/org/netbeans/modules/favorites/templates/TemplatesPanel.java b/favorites/src/org/netbeans/modules/favorites/templates/TemplatesPanel.java --- a/favorites/src/org/netbeans/modules/favorites/templates/TemplatesPanel.java +++ b/favorites/src/org/netbeans/modules/favorites/templates/TemplatesPanel.java @@ -81,11 +81,7 @@ import org.openide.explorer.ExplorerUtils; import org.openide.explorer.view.BeanTreeView; import org.openide.filesystems.FileObject; -import org.openide.filesystems.FileStateInvalidException; -import org.openide.filesystems.FileSystem; import org.openide.filesystems.FileUtil; -import org.openide.filesystems.LocalFileSystem; -import org.openide.filesystems.MultiFileSystem; import org.openide.loaders.DataFilter; import org.openide.loaders.DataFolder; import org.openide.loaders.DataObject; @@ -99,7 +95,6 @@ import org.openide.nodes.NodeReorderEvent; import org.openide.nodes.PropertySupport; import org.openide.nodes.Sheet; -import org.openide.util.Exceptions; import org.openide.util.HelpCtx; import org.openide.util.Lookup; import org.openide.util.NbBundle; @@ -107,7 +102,6 @@ import org.openide.util.actions.NodeAction; import org.openide.util.actions.SystemAction; import org.openide.util.lookup.AbstractLookup; -import org.openide.util.lookup.InstanceContent; import org.openide.util.lookup.ProxyLookup; import org.openide.windows.TopComponent; @@ -1188,7 +1182,7 @@ String name = n.getFileName(); String displayName = n.getDisplayName(); FileObject fo = n.getLookup().lookup(FileObject.class); - RenameTemplatePanel editPanel = new RenameTemplatePanel(isUserFile(fo)); + RenameTemplatePanel editPanel = new RenameTemplatePanel(fo.canRevert()); editPanel.setFileName(name); editPanel.setFileDisplayName(displayName); String title = org.openide.util.NbBundle.getMessage(TemplatesPanel.class, "RenameTemplatePanel.title.text"); @@ -1208,53 +1202,6 @@ } } - /** Test if the file physically exists on disk and thus was created by user and can be renamed. */ - private static boolean isUserFile(FileObject fo) { - String path = fo.getPath(); - // Find if this path is on non-local filesystems - FileSystem fs; - try { - fs = fo.getFileSystem(); - } catch (FileStateInvalidException ex) { - return false; - } - return !isOnNonLocalFS(fs, path); - } - - private static boolean isOnNonLocalFS(FileSystem fs, String path) { - if (fs instanceof MultiFileSystem) { - MultiFileSystem mfs = (MultiFileSystem) fs; - try { - java.lang.reflect.Method getDelegatesMethod; - getDelegatesMethod = MultiFileSystem.class.getDeclaredMethod("getDelegates"); // NOI18N - getDelegatesMethod.setAccessible(true); - FileSystem[] delegates = (FileSystem[]) getDelegatesMethod.invoke(mfs); - for (FileSystem fsd : delegates) { - if (isOnNonLocalFS(fsd, path)) { - return true; - } - } - } catch (NoSuchMethodException ex) { - Exceptions.printStackTrace(ex); - } catch (SecurityException ex) { - Exceptions.printStackTrace(ex); - } catch (IllegalAccessException ex) { - Exceptions.printStackTrace(ex); - } catch (IllegalArgumentException ex) { - Exceptions.printStackTrace(ex); - } catch (InvocationTargetException ex) { - Exceptions.printStackTrace(ex); - } - return false; - } else { - if (fs instanceof LocalFileSystem) { - return false; // is local FS - } else { - return fs.findResource(path) != null; - } - } - } - // action private static class AddAction extends NodeAction { protected void performAction (Node[] activatedNodes) { diff --git a/ide.ergonomics/nbproject/project.xml b/ide.ergonomics/nbproject/project.xml --- a/ide.ergonomics/nbproject/project.xml +++ b/ide.ergonomics/nbproject/project.xml @@ -115,7 +115,7 @@ - 7.19 + 7.55 diff --git a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FeatureManager.java b/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FeatureManager.java --- a/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FeatureManager.java +++ b/ide.ergonomics/src/org/netbeans/modules/ide/ergonomics/fod/FeatureManager.java @@ -56,7 +56,6 @@ import java.util.Map; import java.util.Set; import java.util.TreeSet; -import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.logging.LogRecord; import java.util.logging.Logger; @@ -466,10 +465,7 @@ first = false; } LOG.info(cnb); - Object clean = module.getAttribute("removeWritables"); // NOI18N - if (clean instanceof Callable) { - ((Callable)clean).call(); - } + module.revert(); } } diff --git a/java.j2seplatform/nbproject/project.xml b/java.j2seplatform/nbproject/project.xml --- a/java.j2seplatform/nbproject/project.xml +++ b/java.j2seplatform/nbproject/project.xml @@ -182,7 +182,7 @@ - 7.19 + 7.55 diff --git a/java.j2seplatform/src/org/netbeans/modules/java/j2seplatform/J2SEPlatformModule.java b/java.j2seplatform/src/org/netbeans/modules/java/j2seplatform/J2SEPlatformModule.java --- a/java.j2seplatform/src/org/netbeans/modules/java/j2seplatform/J2SEPlatformModule.java +++ b/java.j2seplatform/src/org/netbeans/modules/java/j2seplatform/J2SEPlatformModule.java @@ -43,7 +43,7 @@ */ package org.netbeans.modules.java.j2seplatform; -import java.util.concurrent.Callable; +import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import org.openide.cookies.InstanceCookie; @@ -92,12 +92,9 @@ } if (!valid) { Logger.getLogger("global").log(Level.WARNING,"default_platform.xml is broken, regenerating."); - Object attr = defaultPlatform.getAttribute("removeWritables"); //NOI18N - if (attr instanceof Callable) { - ((Callable)attr).call (); - } + defaultPlatform.revert(); } - } catch (Exception e) { + } catch (IOException e) { Exceptions.printStackTrace(e); } } diff --git a/o.apache.tools.ant.module/nbproject/project.xml b/o.apache.tools.ant.module/nbproject/project.xml --- a/o.apache.tools.ant.module/nbproject/project.xml +++ b/o.apache.tools.ant.module/nbproject/project.xml @@ -157,7 +157,7 @@ - 7.19 + 7.55 diff --git a/o.apache.tools.ant.module/src/org/apache/tools/ant/module/wizards/shortcut/ShortcutWizard.java b/o.apache.tools.ant.module/src/org/apache/tools/ant/module/wizards/shortcut/ShortcutWizard.java --- a/o.apache.tools.ant.module/src/org/apache/tools/ant/module/wizards/shortcut/ShortcutWizard.java +++ b/o.apache.tools.ant.module/src/org/apache/tools/ant/module/wizards/shortcut/ShortcutWizard.java @@ -52,7 +52,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; -import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.KeyStroke; @@ -172,13 +171,8 @@ delete(shortcut); } private static void delete(FileObject file) throws IOException { // cf. #162526 - Object delete = file.getAttribute("removeWritables"); // NOI18N - if (delete instanceof Callable) { - try { - ((Callable) delete).call(); - } catch (java.lang.Exception x) { - throw (IOException) new IOException("Could not delete " + file + ": " + x.toString()).initCause(x); - } + if (file.canRevert()) { + file.revert(); } else { throw new IOException("Could not delete " + file); } diff --git a/openide.filesystems/apichanges.xml b/openide.filesystems/apichanges.xml --- a/openide.filesystems/apichanges.xml +++ b/openide.filesystems/apichanges.xml @@ -49,6 +49,26 @@ Filesystems API + + + Introduced FileObject.revert + + + + +

+ The previous SPI has been kept. Only a more convenient API has been introduced, + so it is no longer necessary for callers to look for a removeWritables attribute. +

+
+ +

+ Added revert and canRevert to FileObject. +

+
+ + +
FileObject.getMIMEType(String... withinMIMETypes) diff --git a/openide.filesystems/manifest.mf b/openide.filesystems/manifest.mf --- a/openide.filesystems/manifest.mf +++ b/openide.filesystems/manifest.mf @@ -2,5 +2,5 @@ OpenIDE-Module: org.openide.filesystems OpenIDE-Module-Localizing-Bundle: org/openide/filesystems/Bundle.properties OpenIDE-Module-Layer: org/openide/filesystems/resources/layer.xml -OpenIDE-Module-Specification-Version: 7.54 +OpenIDE-Module-Specification-Version: 7.55 diff --git a/openide.filesystems/src/org/openide/filesystems/FileObject.java b/openide.filesystems/src/org/openide/filesystems/FileObject.java --- a/openide.filesystems/src/org/openide/filesystems/FileObject.java +++ b/openide.filesystems/src/org/openide/filesystems/FileObject.java @@ -60,6 +60,7 @@ import java.util.LinkedList; import java.util.List; import java.util.StringTokenizer; +import java.util.concurrent.Callable; import java.util.logging.Level; import org.openide.util.Enumerations; import org.openide.util.UserQuestionException; @@ -1058,6 +1059,42 @@ return true; } + static final String REMOVE_WRITABLES_ATTR = "removeWritables"; + + /** + * Checks whether this file can be reverted to a pristine state. + * @return whether {@link #revert} might do something + * @since 7.55 + */ + public final boolean canRevert() { + return getAttribute(REMOVE_WRITABLES_ATTR) instanceof Callable; + } + + /** + * Revert this file to a pristine state. + * Generally only meaningful for files on the system filesystem (layers + user directory): + * if the file is defined in a layer but modified in the user directory, it is reset; + * if it is defined only in the user directory, it is deleted. + * If {@link #canRevert} is false, does nothing. + * Note that while content can be reset, it may not be possible to reset attributes. + *

Implementors: for historical reasons this method checks {@link #getAttribute} + * for a special attribute named {@code removeWritables} which must be of type + * {@link Callable Callable}. If present, the file is considered modified. + * @since 7.55 + */ + public final void revert() throws IOException { + Object v = getAttribute(REMOVE_WRITABLES_ATTR); + if (v instanceof Callable) { + try { + ((Callable) v).call(); + } catch (IOException x) { + throw x; + } catch (Exception x) { + throw new IOException(x); + } + } + } + /** Should check for external modifications. For folders it should reread * the content of disk, for data file it should check for the last * time the file has been modified. diff --git a/openide.filesystems/src/org/openide/filesystems/MultiFileObject.java b/openide.filesystems/src/org/openide/filesystems/MultiFileObject.java --- a/openide.filesystems/src/org/openide/filesystems/MultiFileObject.java +++ b/openide.filesystems/src/org/openide/filesystems/MultiFileObject.java @@ -792,7 +792,7 @@ } /** Special attributes which should not be checked for weight. See RemoveWritablesTest. */ - private static final Set SPECIAL_ATTR_NAMES = new HashSet(Arrays.asList("removeWritables", WEIGHT_ATTRIBUTE, "java.io.File")); // NOI18N + private static final Set SPECIAL_ATTR_NAMES = new HashSet(Arrays.asList(FileObject.REMOVE_WRITABLES_ATTR, WEIGHT_ATTRIBUTE, "java.io.File")); // NOI18N private final Object getAttribute(String attrName, String path) { // Look for attribute in any file system starting at the front. // Additionally, look for attribute in root folder, where diff --git a/openide.loaders/nbproject/project.xml b/openide.loaders/nbproject/project.xml --- a/openide.loaders/nbproject/project.xml +++ b/openide.loaders/nbproject/project.xml @@ -122,7 +122,7 @@ - 7.52 + 7.55 diff --git a/openide.loaders/src/org/openide/loaders/FolderInstance.java b/openide.loaders/src/org/openide/loaders/FolderInstance.java --- a/openide.loaders/src/org/openide/loaders/FolderInstance.java +++ b/openide.loaders/src/org/openide/loaders/FolderInstance.java @@ -49,7 +49,6 @@ import java.beans.PropertyChangeEvent; import java.io.IOException; import java.util.*; -import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.logging.Logger; @@ -462,13 +461,10 @@ return cookie; } private void revertProblematicFile(DataObject dob) { - Object rw = dob.getPrimaryFile().getAttribute("removeWritables"); // NOI18N - if (rw instanceof Callable) { - try { - ((Callable) rw).call(); - } catch (Exception x) { - err.log(Level.INFO, null, x); - } + try { + dob.getPrimaryFile().revert(); + } catch (IOException x) { + err.log(Level.INFO, null, x); } } diff --git a/openide.modules/arch.xml b/openide.modules/arch.xml --- a/openide.modules/arch.xml +++ b/openide.modules/arch.xml @@ -326,14 +326,7 @@ --> - - FileObjects created on XML layer now support a new - attribute removeWritables returning an instance of - Callable which removes the local writable version of the - given FileObject thus reverting the folder or file to - its initial state as defined in XML layers. Please note that is not - possible to reset FileObject's attributes. - + No. diff --git a/spi.palette/nbproject/project.xml b/spi.palette/nbproject/project.xml --- a/spi.palette/nbproject/project.xml +++ b/spi.palette/nbproject/project.xml @@ -87,7 +87,7 @@ - 7.19 + 7.55 diff --git a/spi.palette/src/org/netbeans/modules/palette/Utils.java b/spi.palette/src/org/netbeans/modules/palette/Utils.java --- a/spi.palette/src/org/netbeans/modules/palette/Utils.java +++ b/spi.palette/src/org/netbeans/modules/palette/Utils.java @@ -54,7 +54,6 @@ import java.io.IOException; import java.util.Arrays; import java.util.Comparator; -import java.util.concurrent.Callable; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.*; @@ -204,13 +203,10 @@ if( null != dob ) { FileObject primaryFile = dob.getPrimaryFile(); if( null != primaryFile && primaryFile.isFolder() ) { - final Object cleaner = primaryFile.getAttribute( "removeWritables" ); //NOI18N - if( null != cleaner && (cleaner instanceof Callable) ) { - try { - ((Callable)cleaner).call(); - } catch (Exception ex) { - ERR.log( Level.INFO, ex.getLocalizedMessage(), ex ); - } + try { + primaryFile.revert(); + } catch (IOException ex) { + ERR.log(Level.INFO, null, ex); } } }