Index: editor/settings/storage/manifest.mf
===================================================================
RCS file: /cvs/editor/settings/storage/manifest.mf,v
retrieving revision 1.10
retrieving revision 1.8.4.2
diff -u -r1.10 -r1.8.4.2
--- editor/settings/storage/manifest.mf 5 Feb 2007 09:43:30 -0000 1.10
+++ editor/settings/storage/manifest.mf 19 Mar 2007 02:44:45 -0000 1.8.4.2
@@ -2,5 +2,5 @@
OpenIDE-Module: org.netbeans.modules.editor.settings.storage/1
OpenIDE-Module-Localizing-Bundle: org/netbeans/modules/editor/settings/storage/Bundle.properties
OpenIDE-Module-Provides: org.netbeans.api.editor.settings.implementation
-OpenIDE-Module-Specification-Version: 1.9
+OpenIDE-Module-Specification-Version: 1.10
OpenIDE-Module-Layer: org/netbeans/modules/editor/settings/storage/layer.xml
Index: editor/settings/storage/arch/apichanges.xml
===================================================================
RCS file: /cvs/editor/settings/storage/arch/apichanges.xml,v
retrieving revision 1.3
retrieving revision 1.1.6.2
diff -u -r1.3 -r1.1.6.2
--- editor/settings/storage/arch/apichanges.xml 5 Feb 2007 09:43:32 -0000 1.3
+++ editor/settings/storage/arch/apichanges.xml 19 Mar 2007 02:44:45 -0000 1.1.6.2
@@ -82,6 +82,28 @@
+ #90403 - phase 1
+
+
+
+
+
+
+ The phase 1 of the editor settings enhancements, please see
+ issue 90403
+ for details. Briefly, the changes involve introducing a special
+ folder for each setting type, profiles are always stored in their
+ own folder, modules are allowed to register multiple settings files,
+ platform specific settings, the use of 'text/base' for all-editors
+ settings has been deprecated in favor of the hierarchy root (ie. 'Editors' folder), etc.
+
+
+ The changes are documented in the Architecture Description document
+ and marked with the module version.
+
+
+
+
Adding EditorSettings.getAllMimeTypes()
Index: editor/settings/storage/arch/arch-editor-settings-storage.xml
===================================================================
RCS file: /cvs/editor/settings/storage/arch/arch-editor-settings-storage.xml,v
retrieving revision 1.9
retrieving revision 1.9.4.1
diff -u -r1.9 -r1.9.4.1
--- editor/settings/storage/arch/arch-editor-settings-storage.xml 23 Nov 2006 03:07:26 -0000 1.9
+++ editor/settings/storage/arch/arch-editor-settings-storage.xml 19 Mar 2007 02:44:46 -0000 1.9.4.1
@@ -134,10 +134,53 @@
Font & color files
+
+Since version 1.10 the storage module does not require coloring files to be
+called any special name. The coloring profiles and files are expected to be
+registered by modules under a special folder called FontsColors
. The
+structure below shows an example of registering several different coloring files
+for all editors and the text/x-java mime type.
+
+
+
+ Editors
+ |- FontsColors
+ | |- NetBeans
+ | |- Defaults
+ | |- foo.xml
+ | |- bar.xml
+ |- text
+ |- x-java
+ |- FontsColors
+ |- NetBeans
+ |- Defaults
+ |- xyz.xml
+ |- abc.xml
+
+
-There are three different types of files containing information about fonts and colors
-that should be used in editor. All of them have the same structure, but different
-purpose.
+In order to distinguish files containing token-related colorings from those
+with highlight-related colorings the storage module recognizes a special file
+attribute called nbeditor-settings-ColoringType
, which value can
+either be token
or highlight
. If a coloring file does
+not specify this attribute it is automatically expected to contain token-related
+colorings.
+
+
+
+Generally, the files with default values are stored in Defaults
+subfolders while the files with user changes are stored directly in the
+profile's folder.
+
+
+
+The default profile for font & colors is called 'NetBeans'.
+
+
+Prior to version 1.10 the storage module expected colorings in the
+three different types of files. They are still recognized to support
+backwards compatibility, but modules are suggusted to use the new registration
+scheme. All of those three files had the same structure, but different purpose.
+
+Key bindings files
-Generally, files for both the default values and user changes have the same name.
-The files with default values are stored in Defaults
subfolders while
-the files with user changes are stored directly in the profile's folder.
+Since version 1.10 modules can provide their keybindings in multiple files
+placed under the special folder called Keybindings
and its profiles'
+subfolders. Similarily as for colorings the files with default key bindings are stored in Defaults
+subfolder and user changes are stored in files directly in the profile's folder.
+The example below shows registration of several keybinding files for all editors
+and the text/x-java mime type.
+
+ Editors
+ |- Keybindings
+ | |- NetBeans
+ | |- Defaults
+ | |- foo.xml
+ | |- bar.xml
+ |- text
+ |- x-java
+ |- Keybindings
+ |- NetBeans
+ |- Defaults
+ |- xyz.xml
+ |- abc.xml
+
+
-The default profile for font & colors is called 'NetBeans'.
+Prior to version 1.10 the default profile for key bindings, called NetBeans,
+had not been stored in its own folder. Therefore the default key bindings for
+the NetBeans profile used to be stored directly in
+Editors/<mime-type>/Defaults/keybindings.xml
and similarily
+user changes used to be stored in Editors/<mime-type>/keybindings.xml
.
+This has been deprecated, but is still supported for backwards compatibility reasons.
+
+Also the special mime type called text/base
, has been deprecated
+and should not be used anymore. It is however still supported to preserve
+backwards compatibility.
+
+
+Platform specific settings
-Key bindings files
-The key bindings information is stored in keybindings.xml
files. The
-files with default key bindings are stored in Defaults
subfolder and
-user changes are stored in files directly in the profile's folder.
+Since 1.10 it is possible to mark setting files as applicable only on a certain
+platform (a.k.a. operating system). This was mainly introduced for keybindings,
+which are generally platform sensitive settings, but can be used for any other
+setting type supported by the storage module.
+
+
+
+Some platforms (eg. Mac) define their own special rules for the use of some
+combinations of keystrokes (eg. ctrl+Q closes the app) that applications on that
+platform have to obey. NetBeans mitigates this problem by introducing a special
+module ide/applemenu, which is only loaded on Mac and which overrides
+keybindings.xml
files provided by some Netbeans modules (eg. editor and java).
+This approach works albeit some severe limitations. However with introducing
+multiple setting files this would no longer be practical, which is why platform
+specific settings have been introduced.
-Althought the default profile for key bindings is called NetBeans, but there is no
-special folder used for this profile. It means that the default key bindings for
-the NetBeans profile should be stored in Editors/<mime-type>/Defaults/keybindings.xml
.
-Similarily user changes will be stored in Editors/<mime-type>/keybindings.xml
.
+The storage module recognizes a special file attribute for marking
+platform specific setting files called nbeditor-settings-targetOS
.
+The rules for its use follow.
+
+
+ Any file that does not define nbeditor-settings-targetOS
is loaded
+ on all platforms. All such files will be loaded exactly in the same order as
+ they appear on the system filesystem.
+
+
+ If a file defines nbeditor-settings-targetOS
attribute, but its
+ value does not correspond to the current Operating System, the file is ignored.
+
+
+ If a file defines nbeditor-settings-targetOS
attribute and its
+ value designates the current Operating System, the file will be loaded.
+ Furthermore, any such a file will be loaded after other files in the
+ same folder that do not define this attribute and therefore its settings will
+ override settings from those other files.
+
+
+ If there is more files that define nbeditor-settings-targetOS
+ attribute and are eligible for loading on the current Operating System,
+ they will be loaded in the same order as they appear on the system filesystem.
+
+
+
-Additionally to normal mime types there is a special mime type called
-text/base
, which can be used for providing default key bindings that
-will be added to all mime type specific key bindings.
+The available values that can be used for the nbeditor-settings-targetOS
+attribute are the string names of the OS_*
constants in org.openide.util.Utilities
+class. So, for example the following file will only be loaded on MacOS and its settings
+will override settings from all other files that do not specify the target OS attribute.
+
+<folder name="Editors">
+ <folder name="Keybindings">
+ <folder name="NetBeans">
+ <folder name="Defaults">
+ <file name="keybindings-for-mac.xml" url="...">
+ <attr name="nbeditor-settings-targetOS" stringvalue="OS_MAC"/>
+ </file>
+ </folder>
+ </folder>
+ </folder>
+</folder>
+
+
@@ -730,7 +855,7 @@
-->
-Yes. module creates a new MimeLookupInitializer and plug it into the MimeLookup. Also EditorSettings
+Yes. module creates a new MimeDataProvider and plug it into the MimeLookup. Also EditorSettings
implementation is registered into default lookup.
@@ -746,7 +871,7 @@
-->
-Yes. The implementation of MimeLookupInitializer
is
+Yes. The implementation of MimeDataProvider
is
registered via META-INF/services
.
@@ -939,7 +1064,8 @@
-->
-Yes. The layer is used for registering DTDs in the Netbeans catalog.
+Yes. The layer is used for registering DTDs in the Netbeans catalog and MIME type
+resolvers for editor settings files.
Index: editor/settings/storage/nbproject/project.xml
===================================================================
RCS file: /cvs/editor/settings/storage/nbproject/project.xml,v
retrieving revision 1.10
retrieving revision 1.9.2.2
diff -u -r1.10 -r1.9.2.2
--- editor/settings/storage/nbproject/project.xml 26 Jan 2007 04:58:50 -0000 1.10
+++ editor/settings/storage/nbproject/project.xml 10 Mar 2007 00:54:59 -0000 1.9.2.2
@@ -87,6 +87,9 @@
org.netbeans.core.startup
+
+ org.openide.modules
+
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Bundle.properties
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Bundle.properties,v
retrieving revision 1.3
retrieving revision 1.3.12.1
diff -u -r1.3 -r1.3.12.1
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Bundle.properties 30 Jun 2006 19:18:23 -0000 1.3
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Bundle.properties 10 Mar 2007 00:55:03 -0000 1.3.12.1
@@ -20,3 +20,5 @@
OpenIDE-Module-Short-Description=Contains support for editor settings storage
OpenIDE-Module-Long-Description=Editor Settings Storage module.
+# MIMEResolver
+Services/MIMEResolver/org-netbeans-modules-editor-settings-storage-mime-resolver.xml=Netbeans Editor Settings Files
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ColoringStorage.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ColoringStorage.java,v
retrieving revision 1.25
retrieving revision 1.19.2.4
diff -u -r1.25 -r1.19.2.4
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ColoringStorage.java 26 Jan 2007 04:58:51 -0000 1.25
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ColoringStorage.java 15 Mar 2007 21:46:29 -0000 1.19.2.4
@@ -20,10 +20,12 @@
package org.netbeans.modules.editor.settings.storage;
import java.awt.Color;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
import java.util.HashMap;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
@@ -32,10 +34,10 @@
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import org.netbeans.api.editor.mimelookup.MimePath;
-import org.netbeans.api.editor.settings.AttributesUtilities;
import org.netbeans.api.editor.settings.EditorStyleConstants;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.FileUtil;
import org.openide.filesystems.Repository;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Document;
@@ -52,19 +54,11 @@
*
* @author Jan Jancura
*/
-final class ColoringStorage {
+public final class ColoringStorage {
private static final Logger LOG = Logger.getLogger(ColoringStorage.class.getName());
- // XXX: These constants are package private only for EditorSettingsImpl.init*() method.
- // Once we get rid of filenames these will be removed.
-
- /* package */ static final String ALL_LANGUAGES_FILE_NAME = "defaultColoring.xml"; // NOI18N
- /* package */ static final String COLORING_FILE_NAME = "coloring.xml"; // NOI18N
- /* package */ static final String HIGHLIGHTING_FILE_NAME = "editorColoring.xml"; // NOI18N
-
- /** The name of the folder within a profile's folder containing module installed defaults. */
- /* package */ static final String DEFAULTS_FOLDER = "Defaults"; //NOI18N
+ private static final String HIGHLIGHTING_FILE_NAME = "editorColoring.xml"; // NOI18N
private static final String E_ROOT = "fontscolors"; //NOI18N
private static final String E_FONTCOLOR = "fontcolor"; //NOI18N
@@ -85,6 +79,10 @@
private static final String PUBLIC_ID = "-//NetBeans//DTD Editor Fonts and Colors settings 1.1//EN"; //NOI18N
private static final String SYSTEM_ID = "http://www.netbeans.org/dtds/EditorFontsColors-1_1.dtd"; //NOI18N
+
+ private static final String FA_TYPE = "nbeditor-settings-ColoringType"; //NOI18N
+ private static final String FAV_TOKEN = "token"; //NOI18N
+ private static final String FAV_HIGHLIGHT = "highlight"; //NOI18N
private ColoringStorage() {
}
@@ -97,49 +95,102 @@
boolean colorings, // true for colorings, false for highlightings
boolean defaults // read default values only
) {
- String fileName = determineFileName(mimePath, colorings);
+ assert mimePath != null : "The parameter mimePath must not be null"; //NOI18N
+ assert profile != null : "The parameter profile must not be null"; //NOI18N
- // 1) load colorings
- FileSystem fs = Repository.getDefault().getDefaultFileSystem();
- FileObject fo = null;
-
- if (!defaults) {
- fo = fs.findResource(Utils.getFileName(mimePath, profile, fileName));
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors"); //NOI18N
+ Map> files = new HashMap>();
+ SettingsType.FONTSCOLORS.getLocator().scan(baseFolder, mimePath.getPath(), profile, true, true, !defaults, files);
+
+ assert files.size() <= 1 : "Too many results in the scan"; //NOI18N
+
+ List profileInfos = files.get(profile);
+ if (profileInfos == null) {
+ return Collections.emptyMap();
}
- if (fo == null) {
- fo = fs.findResource(Utils.getFileName(
- mimePath, profile, DEFAULTS_FOLDER + "/" + fileName)); //NOI18N
+ List filesForLocalization;
+ if (!profile.equals(EditorSettingsImpl.DEFAULT_PROFILE)) {
+ // If non-default profile load the default profile supplied by modules
+ // to find the localizing bundles.
+ Map> defaultProfileModulesFiles = new HashMap>();
+ SettingsType.FONTSCOLORS.getLocator().scan(baseFolder, mimePath.getPath(), EditorSettingsImpl.DEFAULT_PROFILE, true, true, false, defaultProfileModulesFiles);
+ filesForLocalization = defaultProfileModulesFiles.get(EditorSettingsImpl.DEFAULT_PROFILE);
+
+ // if there is no default profile (eg. in tests)
+ if (filesForLocalization == null) {
+ filesForLocalization = Collections.emptyList();
+ }
+ } else {
+ filesForLocalization = profileInfos;
}
- if (fo == null) {
- return null;
- } else {
- List l = (List) XMLStorage.load(fo, new ColoringsReader());
+ Map fontsColorsMap = new HashMap();
+ for(Object [] info : profileInfos) {
+ FileObject profileHome = (FileObject) info[0];
+ FileObject settingFile = (FileObject) info[1];
+ boolean modulesFile = ((Boolean) info[2]).booleanValue();
+
+ // Skip files with wrong type of colorings
+ boolean isTokenColoringFile = isTokenColoringFile(settingFile);
+ if (isTokenColoringFile != colorings) {
+ continue;
+ }
- // 2) translate names of categories
- FileObject basicName = fs.findResource(
- Utils.getFileName(mimePath, EditorSettingsImpl.DEFAULT_PROFILE, DEFAULTS_FOLDER + "/" + fileName) //NOI18N
- );
+ // Load colorings from the settingFile
+ @SuppressWarnings("unchecked")
+ List sets = (List) XMLStorage.load(settingFile, new ColoringsReader());
- Map m = new HashMap();
- Iterator it = l.iterator();
- while (it.hasNext()) {
- SimpleAttributeSet as = (SimpleAttributeSet) it.next();
+ // Process loaded colorings
+ for(SimpleAttributeSet as : sets) {
String name = (String) as.getAttribute(StyleConstants.NameAttribute);
- String displayName = Utils.getLocalizedName(basicName, name, name);
+ SimpleAttributeSet previous = fontsColorsMap.get(name);
+ if (previous == null) {
+ // Find display name
+ // Try the settingFile first
+ String displayName = Utils.getLocalizedName(settingFile, name, null, true);
+ // Then try all module files from the default profile
+ if (displayName == null) {
+ for(Object [] locFileInfo : filesForLocalization) {
+ FileObject locFile = (FileObject) locFileInfo[1];
+ displayName = Utils.getLocalizedName(settingFile, name, null, true);
+ if (displayName != null) {
+ break;
+ }
+ }
+ }
+
+ if (displayName == null) {
+ displayName = name;
+ }
+
as.addAttribute(EditorStyleConstants.DisplayName, displayName);
- m.put(name, AttributesUtilities.createImmutable(as));
+ fontsColorsMap.put(name, as);
+ } else {
+ mergeAttributeSets(previous, as);
+ }
}
+ }
- return m;
+ return Utils.immutize(fontsColorsMap);
+ }
+
+ private static void mergeAttributeSets(SimpleAttributeSet original, AttributeSet toMerge) {
+ for(Enumeration names = toMerge.getAttributeNames(); names.hasMoreElements(); ) {
+ Object key = names.nextElement();
+ Object value = toMerge.getAttribute(key);
+ original.addAttribute(key, value);
}
- }
+ }
private static class ColoringsReader extends XMLStorage.Handler {
+
private List colorings = new ArrayList();
+ public ColoringsReader() {
+ }
+
public Object getResult () {
return colorings;
}
@@ -157,9 +208,9 @@
} else if (name.equals(E_FONTCOLOR)) {
SimpleAttributeSet a = new SimpleAttributeSet();
String value;
-
+
a.addAttribute(StyleConstants.NameAttribute, attributes.getValue(A_NAME));
-
+
value = attributes.getValue(A_BACKGROUND);
if (value != null) {
a.addAttribute(StyleConstants.Background, Utils.stringToColor(value));
@@ -239,15 +290,45 @@
public static void deleteColorings(
MimePath mimePath,
String profile,
- boolean colorings, // true for colorings, false for highlightings
+ final boolean colorings, // true for colorings, false for highlightings
boolean defaults // delete default values
) {
- String fileName = determineFileName(mimePath, colorings);
- if (defaults) {
- fileName = DEFAULTS_FOLDER + "/" + fileName;
- }
+ assert mimePath != null : "The parameter mimePath must not be null"; //NOI18N
+ assert profile != null : "The parameter profile must not be null"; //NOI18N
+
+ FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
+ FileObject baseFolder = sfs.findResource("Editors"); //NOI18N
+ Map> files = new HashMap>();
+ SettingsType.FONTSCOLORS.getLocator().scan(baseFolder, mimePath.getPath(), profile, true, defaults, !defaults, files);
+
+ assert files.size() <= 1 : "Too many results in the scan"; //NOI18N
- Utils.deleteFileObject(mimePath, profile, fileName);
+ final List profileInfos = files.get(profile);
+ if (profileInfos != null) {
+ try {
+ sfs.runAtomicAction(new FileSystem.AtomicAction() {
+ public void run() {
+ for(Object [] info : profileInfos) {
+ FileObject settingFile = (FileObject) info[1];
+
+ // Skip files with wrong type of colorings
+ boolean isTokenColoringFile = isTokenColoringFile(settingFile);
+ if (isTokenColoringFile != colorings) {
+ continue;
+ }
+
+ try {
+ settingFile.delete();
+ } catch (IOException ioe) {
+ LOG.log(Level.WARNING, "Can't delete editor settings file " + settingFile.getPath(), ioe); //NOI18N
+ }
+ }
+ }
+ });
+ } catch (IOException ioe) {
+ LOG.log(Level.WARNING, "Can't delete editor colorings for " + mimePath.getPath() + ", " + profile, ioe); //NOI18N
+ }
+ }
}
// save ..........................................................
@@ -255,17 +336,28 @@
public static void saveColorings(
MimePath mimePath,
String profile,
- boolean colorings, // true for colorings, false for highlightings
+ final boolean colorings, // true for colorings, false for highlightings
boolean defaults, // save default values
- Collection fontColors
+ final Collection fontColors
) {
- String fileName = determineFileName(mimePath, colorings);
- if (defaults) {
- fileName = DEFAULTS_FOLDER + "/" + fileName;
- }
+ assert mimePath != null : "The parameter mimePath must not be null"; //NOI18N
+ assert profile != null : "The parameter profile must not be null"; //NOI18N
- FileObject fo = Utils.createFileObject(mimePath, profile, fileName);
- saveColorings(fo, fontColors);
+ final FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
+ final String settingFileName = SettingsType.FONTSCOLORS.getLocator().getWritableFileName(mimePath.getPath(), profile, defaults);
+
+ try {
+ sfs.runAtomicAction(new FileSystem.AtomicAction() {
+ public void run() throws IOException {
+ FileObject baseFolder = sfs.findResource("Editors"); //NOI18N
+ FileObject f = FileUtil.createData(baseFolder, settingFileName);
+ f.setAttribute(FA_TYPE, colorings ? FAV_TOKEN : FAV_HIGHLIGHT);
+ saveColorings(f, fontColors);
+ }
+ });
+ } catch (IOException ioe) {
+ LOG.log(Level.WARNING, "Can't save editor colorings for " + mimePath.getPath() + ", " + profile, ioe); //NOI18N
+ }
}
private static void saveColorings(FileObject fo, Collection colorings) {
@@ -357,19 +449,12 @@
XMLStorage.save(fo, doc);
}
- private static String determineFileName(MimePath mimePath, boolean colorings) {
- String fileName;
-
- if (colorings) {
- if (mimePath.size() == 0) {
- fileName = ALL_LANGUAGES_FILE_NAME;
- } else {
- fileName = COLORING_FILE_NAME;
- }
+ private static boolean isTokenColoringFile(FileObject f) {
+ Object typeValue = f.getAttribute(FA_TYPE);
+ if (typeValue instanceof String) {
+ return typeValue.equals(FAV_TOKEN);
} else {
- fileName = HIGHLIGHTING_FILE_NAME;
+ return !f.getNameExt().equals(HIGHLIGHTING_FILE_NAME);
}
-
- return fileName;
}
}
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/CompositeFCS.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/CompositeFCS.java,v
retrieving revision 1.3
retrieving revision 1.3.4.1
diff -u -r1.3 -r1.3.4.1
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorKeyBindings-1_1.dtd
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorKeyBindings-1_1.dtd,v
retrieving revision 1.2
retrieving revision 1.2.6.1
diff -u -r1.2 -r1.2.6.1
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorKeyBindings-1_1.dtd 9 Nov 2006 02:03:40 -0000 1.2
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorKeyBindings-1_1.dtd 16 Mar 2007 02:54:24 -0000 1.2.6.1
@@ -31,10 +31,12 @@
-
+
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorSettingsImpl.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorSettingsImpl.java,v
retrieving revision 1.36
retrieving revision 1.29.2.4
diff -u -r1.36 -r1.29.2.4
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorSettingsImpl.java 5 Feb 2007 09:26:18 -0000 1.36
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/EditorSettingsImpl.java 15 Mar 2007 08:54:05 -0000 1.29.2.4
@@ -24,15 +24,15 @@
import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
-import java.util.Enumeration;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.text.AttributeSet;
import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.editor.settings.FontColorSettings;
+import org.netbeans.api.editor.settings.KeyBindingSettings;
import org.netbeans.modules.editor.settings.storage.api.EditorSettings;
import org.netbeans.modules.editor.settings.storage.api.FontColorSettingsFactory;
import org.netbeans.modules.editor.settings.storage.api.KeyBindingSettingsFactory;
@@ -71,6 +71,9 @@
/** Storage folder for the current keybindings profile attribute. */
private static final String KEYMAPS_FOLDER = "Keymaps"; // NOI18N
+ public static final String TEXT_BASE_MIME_TYPE = "text/base"; //NOI18N
+ private static final String [] EMPTY = new String[0];
+
private static EditorSettingsImpl instance = null;
public static synchronized EditorSettingsImpl getInstance() {
@@ -80,29 +83,29 @@
return instance;
}
- public Set getAllMimeTypes () {
- FileObject editorsFo = Repository.getDefault().getDefaultFileSystem().findResource(EDITORS_FOLDER);
- HashSet mimeTypes = new HashSet();
-
- if (editorsFo != null) {
- for(FileObject f : editorsFo.getChildren()) {
- if (!f.isFolder()) {
- continue;
- }
+ // ------------------------------------------------------
+ // Mime types
+ // ------------------------------------------------------
- String firstPart = f.getNameExt();
- for(FileObject ff : f.getChildren()) {
- if (!ff.isFolder()) {
- continue;
- }
+ private final MimeTypesTracker topLevelMimeTypes = new MimeTypesTracker(EDITORS_FOLDER, null);
+ private final HashMap settingMimeTypes = new HashMap();
+
+ public Set getAllMimeTypes () {
+ return topLevelMimeTypes.getMimeTypes();
+ }
- String mimeType = firstPart + "/" + ff.getNameExt(); //NOI18N
- mimeTypes.add(mimeType);
- }
+ private MimeTypesTracker getMimeTypesTracker(Class settingApiClass) {
+ SettingsType type = SettingsType.get(settingApiClass);
+ assert type != null : "Invalid editor settings API class: " + settingApiClass; //NOI18N
+
+ synchronized (settingMimeTypes) {
+ MimeTypesTracker tracker = settingMimeTypes.get(type);
+ if (tracker == null) {
+ tracker = new MimeTypesTracker(EDITORS_FOLDER, type);
+ settingMimeTypes.put(type, tracker);
}
+ return tracker;
}
-
- return mimeTypes;
}
/**
@@ -110,11 +113,9 @@
*
* @return set of mimetypes
*/
- public Set getMimeTypes () {
- if (mimeTypesWithColoring == null) {
- init ();
- }
- return mimeTypesWithColoring;
+ // XXX: the API should actually use Collection
+ public Set getMimeTypes() {
+ return getMimeTypesTracker(FontColorSettings.class).getMimeTypes();
}
/**
@@ -123,12 +124,48 @@
* @return name of language for given mime type
*/
public String getLanguageName (String mimeType) {
- FileObject fo = Repository.getDefault().getDefaultFileSystem().findResource("Editors/" + mimeType); //NOI18N
- return fo == null ? mimeType : Utils.getLocalizedName(fo, mimeType, mimeType);
+ return topLevelMimeTypes.getMimeTypeDisplayName(mimeType);
}
+ // ------------------------------------------------------
+ // Profiles
+ // ------------------------------------------------------
+
+ private final HashMap settingProfiles = new HashMap();
+ private ProfilesTracker getProfilesTracker(Class settingApiClass) {
+ SettingsType type = SettingsType.get(settingApiClass);
+ assert type != null : "Invalid editor settings API class: " + settingApiClass; //NOI18N
+
+ synchronized (settingProfiles) {
+ ProfilesTracker tracker = settingProfiles.get(type);
+ if (tracker == null) {
+ tracker = new ProfilesTracker(type, topLevelMimeTypes);
+ settingProfiles.put(type, tracker);
+ }
+ return tracker;
+ }
+ }
- // FontColors ..............................................................
+ /**
+ * Translates profile's display name to its Id. If the profile's display name
+ * can't be translated this method will simply return the profile's display name
+ * without translation.
+ */
+ String getInternalFontColorProfile(String profile) {
+ ProfilesTracker tracker = getProfilesTracker(FontColorSettings.class);
+ ProfilesTracker.ProfileDescription pd = tracker.getProfileByDisplayName(profile);
+ return pd == null ? profile : pd.getId();
+ }
+
+ String getInternalKeymapProfile (String profile) {
+ ProfilesTracker tracker = getProfilesTracker(KeyBindingSettings.class);
+ ProfilesTracker.ProfileDescription pd = tracker.getProfileByDisplayName(profile);
+ return pd == null ? profile : pd.getId();
+ }
+
+ // ------------------------------------------------------
+ // Font Colors
+ // ------------------------------------------------------
/* package */ void notifyTokenFontColorChange(MimePath mimePath, String profile) {
// XXX: this is hack, we should not abuse the event values like that
@@ -141,22 +178,9 @@
* @return set of font & colors profiles
*/
public Set getFontColorProfiles () {
- if (fontColorProfiles == null) {
- init ();
- }
-
- Set result = new HashSet();
- for(String profile : fontColorProfiles.keySet()) {
- if (!profile.startsWith ("test")) {
- result.add(profile);
- }
- }
-
- return result;
+ return getProfilesTracker(FontColorSettings.class).getProfilesDisplayNames();
}
- private Set systemFontColorProfiles;
-
/**
* Returns true for user defined profile.
*
@@ -164,13 +188,12 @@
* @return true for user defined profile
*/
public boolean isCustomFontColorProfile(String profile) {
- if (systemFontColorProfiles == null) {
- init ();
- }
-
- return !systemFontColorProfiles.contains(profile);
+ ProfilesTracker tracker = getProfilesTracker(FontColorSettings.class);
+ ProfilesTracker.ProfileDescription pd = tracker.getProfileByDisplayName(profile);
+ return pd != null && !pd.isRollbackAllowed();
}
-
+
+ // XXX: Rewrite this using NbPreferences
private String currentFontColorProfile;
/**
@@ -347,7 +370,6 @@
ColoringStorage.deleteColorings
(MimePath.EMPTY, internalProfile, false, false);
highlightings.remove (internalProfile);
- init ();
} else {
if (fontColors.equals (highlightings.get (internalProfile))) return;
@@ -365,8 +387,6 @@
false,
fontColors.values ()
);
- if (fontColorProfiles.get (profile) == null)
- fontColorProfiles.put (profile, profile);
}
}
@@ -374,20 +394,20 @@
}
- // KeyMaps .................................................................
+ // ------------------------------------------------------
+ // Keybindings
+ // ------------------------------------------------------
/**
* Returns set of keymap profiles.
*
* @return set of font & colors profiles
*/
+ // XXX: the API should actually use Collection
public Set getKeyMapProfiles () {
- if (keyMapProfiles == null) init ();
- return Collections.unmodifiableSet (keyMapProfiles.keySet ());
+ return getProfilesTracker(KeyBindingSettings.class).getProfilesDisplayNames();
}
- private Set systemKeymapProfiles;
-
/**
* Returns true for user defined profile.
*
@@ -395,11 +415,9 @@
* @return true for user defined profile
*/
public boolean isCustomKeymapProfile (String profile) {
- if (systemKeymapProfiles == null) {
- init();
- }
-
- return !systemKeymapProfiles.contains (profile);
+ ProfilesTracker tracker = getProfilesTracker(KeyBindingSettings.class);
+ ProfilesTracker.ProfileDescription pd = tracker.getProfileByDisplayName(profile);
+ return pd == null || !pd.isRollbackAllowed();
}
private String currentKeyMapProfile;
@@ -497,135 +515,11 @@
// support methods .........................................................
-
- private Map fontColorProfiles;
- private Map keyMapProfiles;
- private Set mimeTypesWithColoring;
private EditorSettingsImpl() {
}
- private void init () {
- fontColorProfiles = new HashMap();
- keyMapProfiles = new HashMap();
- keyMapProfiles.put (DEFAULT_PROFILE, DEFAULT_PROFILE);
- mimeTypesWithColoring = new HashSet();
- systemFontColorProfiles = new HashSet();
- systemKeymapProfiles = new HashSet();
- FileSystem fs = Repository.getDefault ().getDefaultFileSystem ();
- FileObject fo = fs.findResource (EDITORS_FOLDER);
- if (fo != null) {
- Enumeration e = fo.getFolders (false);
- while (e.hasMoreElements()) {
- init1 ((FileObject) e.nextElement ());
- }
- }
-
- mimeTypesWithColoring = Collections.unmodifiableSet(mimeTypesWithColoring);
- }
-
- private void init1 (FileObject fo) {
- Enumeration e = fo.getChildren (false);
- while (e.hasMoreElements ())
- init2 ((FileObject) e.nextElement ());
- }
-
- private void init2 (FileObject fo) {
- if (fo.getNameExt ().equals (ColoringStorage.DEFAULTS_FOLDER) && fo.isFolder () &&
- fo.getFileObject (ColoringStorage.HIGHLIGHTING_FILE_NAME) != null
- )
- addFontColorsProfile (fo, true); // Editors/ProfileName/Defaults/editorColoring.xml
- else
- if (fo.getNameExt ().equals (ColoringStorage.HIGHLIGHTING_FILE_NAME))
- addFontColorsProfile (fo, false); // Editors/ProfileName/editorColoring.xml
- else
- if (fo.getFileObject (DEFAULT_PROFILE + "/" + ColoringStorage.DEFAULTS_FOLDER + "/" + ColoringStorage.COLORING_FILE_NAME) != null) //NOI18N
- addMimeType (fo); // Editors/XXX/YYY/NetBeans/Defaults/coloring.xml
- else
- if (fo.getPath ().endsWith ("text/base") && fo.isFolder ()) { //NOI18N
- if (fo.getFileObject (KeyMapsStorage.DEFAULTS_FOLDER + "/" + KeyMapsStorage.KEYBINDING_FILE_NAME) != null) //NOI18N
- addKeyMapProfile (fo, true); // Editors/text/base/Defaults/keybindings.xml
- else
- if (fo.getFileObject (KeyMapsStorage.KEYBINDING_FILE_NAME) != null)
- addKeyMapProfile (fo, false); // Editors/text/base/keybindings.xml
- Enumeration e = fo.getChildren (false);
- while (e.hasMoreElements ()) {
- FileObject ff = (FileObject) e.nextElement ();
- if (!ff.getNameExt().equals(KeyMapsStorage.DEFAULTS_FOLDER)) {
- init3 (ff);
- }
- }
- }
- }
-
- private void init3 (FileObject fo) {
- if (fo.getFileObject (KeyMapsStorage.DEFAULTS_FOLDER + "/" + KeyMapsStorage.KEYBINDING_FILE_NAME) != null) //NOI18N
- addKeyMapProfile (fo, true); // Editors/text/base/ProfileName/Defaults/keybindings.xml
- else
- if (fo.getFileObject (KeyMapsStorage.KEYBINDING_FILE_NAME) != null)
- addKeyMapProfile (fo, false); // Editors/text/base/ProfileName/keybindings.xml
- }
-
- private void addMimeType(FileObject fo) {
- String mimeType = fo.getPath().substring(8);
- mimeTypesWithColoring.add(mimeType);
- }
-
- private void addFontColorsProfile(FileObject fo, boolean systemProfile) {
- String profile = fo.getParent().getNameExt();
- String displayName = Utils.getLocalizedName(fo.getParent(), profile, profile);
-
- if (systemProfile) {
- systemFontColorProfiles.add(displayName);
- }
-
- fontColorProfiles.put(displayName, profile);
- }
-
- private void addKeyMapProfile(FileObject fo, boolean systemProfile) {
- String profile = fo.getNameExt();
- if (profile.equals("base")) { //NOI18N
- profile = DEFAULT_PROFILE;
- }
-
- String displayName = Utils.getLocalizedName(fo, profile, profile);
-
- if (systemProfile) {
- systemKeymapProfiles.add(displayName);
- }
-
- keyMapProfiles.put(displayName, profile);
- }
-
- /**
- * Translates profile's display name to its Id. If the profile's display name
- * can't be translated this method will simply return the profile's display name
- * without translation.
- */
- String getInternalFontColorProfile(String profile) {
- if (fontColorProfiles == null) {
- init ();
- }
-
- String result = fontColorProfiles.get(profile);
- return result != null ? result : profile;
- }
-
- String getInternalKeymapProfile (String profile) {
- if (keyMapProfiles == null) {
- init();
- }
-
- String result = keyMapProfiles.get (profile);
- if (result != null) {
- return result;
- } else {
- keyMapProfiles.put(profile, profile);
- return profile;
- }
- }
-
public KeyBindingSettingsFactory getKeyBindingSettings (String[] mimeTypes) {
mimeTypes = filter(mimeTypes);
return KeyBindingSettingsImpl.get(Utils.mimeTypes2mimePath(mimeTypes));
@@ -637,12 +531,28 @@
}
private String [] filter(String [] mimeTypes) {
- if (mimeTypes.length > 0 && mimeTypes[0].startsWith("test")) { //NOI18N
- String [] filtered = new String [mimeTypes.length];
- System.arraycopy(mimeTypes, 0, filtered, 0, mimeTypes.length);
- filtered[0] = mimeTypes[0].substring(mimeTypes[0].indexOf('_') + 1); //NOI18N
+ if (mimeTypes.length > 0) {
+ String [] filtered = mimeTypes;
- LOG.log(Level.INFO, "Don't use 'test' mime type to access settings through the editor/settings/storage API!", new Throwable("Stacktrace"));
+ if (mimeTypes[0].contains(TEXT_BASE_MIME_TYPE)) {
+ if (mimeTypes.length == 1) {
+ filtered = EMPTY;
+ } else {
+ filtered = new String [mimeTypes.length - 1];
+ System.arraycopy(mimeTypes, 1, filtered, 0, mimeTypes.length - 1);
+ }
+
+ if (LOG.isLoggable(Level.INFO)) {
+ LOG.log(Level.INFO, TEXT_BASE_MIME_TYPE + "has been deprecated, use MimePath.EMPTY instead."); //, new Throwable("Stacktrace") //NOI18N
+ }
+
+ } else if (mimeTypes[0].startsWith("test")) {
+ filtered = new String [mimeTypes.length];
+ System.arraycopy(mimeTypes, 0, filtered, 0, mimeTypes.length);
+ filtered[0] = mimeTypes[0].substring(mimeTypes[0].indexOf('_') + 1); //NOI18N
+
+ LOG.log(Level.INFO, "Don't use 'test' mime type to access settings through the editor/settings/storage API!", new Throwable("Stacktrace"));
+ }
return filtered;
} else {
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImpl.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImpl.java,v
retrieving revision 1.41
retrieving revision 1.37.2.2
diff -u -r1.41 -r1.37.2.2
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImpl.java 4 Jan 2007 01:07:33 -0000 1.41
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImpl.java 15 Mar 2007 08:54:02 -0000 1.37.2.2
@@ -27,7 +27,6 @@
import java.util.WeakHashMap;
import java.util.logging.Logger;
import javax.swing.text.AttributeSet;
-import javax.swing.text.StyleConstants;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.modules.editor.settings.storage.api.FontColorSettingsFactory;
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyBindingSettingsImpl.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyBindingSettingsImpl.java,v
retrieving revision 1.34
retrieving revision 1.29.2.3
diff -u -r1.34 -r1.29.2.3
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyBindingSettingsImpl.java 11 Jan 2007 03:01:27 -0000 1.34
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyBindingSettingsImpl.java 19 Mar 2007 04:28:56 -0000 1.29.2.3
@@ -41,11 +41,6 @@
import org.netbeans.api.editor.settings.MultiKeyBinding;
import org.netbeans.modules.editor.settings.storage.api.EditorSettings;
import org.netbeans.modules.editor.settings.storage.api.KeyBindingSettingsFactory;
-import org.openide.filesystems.FileAttributeEvent;
-import org.openide.filesystems.FileChangeListener;
-import org.openide.filesystems.FileEvent;
-import org.openide.filesystems.FileObject;
-import org.openide.filesystems.FileRenameEvent;
import org.openide.util.Utilities;
/**
@@ -109,8 +104,8 @@
private void init () {
if (init) return;
init = true;
- if (mimePath.size() != 1 || !mimePath.getMimeType(0).equals("text/base")) { //NOI18N
- baseKBS = EditorSettingsImpl.getInstance().getKeyBindingSettings(new String[] {"text/base"}); //NOI18N
+ if (mimePath.size() > 0) {
+ baseKBS = get(MimePath.EMPTY);
}
listener = new Listener(this, baseKBS);
}
@@ -138,26 +133,8 @@
List result = new ArrayList();
if (!keyMaps.containsKey (profile)) {
synchronized (this) {
-
- // 2) load original profile for this mimeType
- // Map (List (KeyStroke) > MultiKeyBinding)
- Map, MultiKeyBinding> defaults =
- new HashMap, MultiKeyBinding>(getDefaults(profile));
-
- // 3) load & apply modifications to defaults
- Object[] ret = KeyMapsStorage.loadKeyMaps(mimePath, profile, false);
-
- @SuppressWarnings("unchecked")
- Map, MultiKeyBinding> shortcuts = (Map, MultiKeyBinding>) ret[0];
- @SuppressWarnings("unchecked")
- Set> removedShortcuts = (Set>) ret[1];
-
- for(Collection s : removedShortcuts) {
- defaults.remove(s);
- }
- defaults.putAll(shortcuts);
-
- List localShortcuts = new ArrayList(defaults.values());
+ Map, MultiKeyBinding> shortcuts = KeyMapsStorage.loadKeyMaps(mimePath, profile, false);
+ List localShortcuts = new ArrayList(shortcuts.values());
keyMaps.put(profile, localShortcuts);
result.addAll(localShortcuts);
}
@@ -279,11 +256,7 @@
*/
private Map, MultiKeyBinding> getDefaults(String profile) {
if (!defaults.containsKey (profile)) {
- Object [] ret = KeyMapsStorage.loadKeyMaps(mimePath, profile, true);
- @SuppressWarnings("unchecked")
- Map, MultiKeyBinding> keyMap =
- (Map, MultiKeyBinding>) ret[0];
-
+ Map, MultiKeyBinding> keyMap = KeyMapsStorage.loadKeyMaps(mimePath, profile, true);
defaults.put(profile, keyMap);
}
@@ -334,10 +307,7 @@
private static class Listener extends WeakReference
- implements FileChangeListener, PropertyChangeListener, Runnable {
-
- /** /Editor/mimetype/currentProfile/ folder*/
- private FileObject fo;
+ implements PropertyChangeListener, Runnable {
private KeyBindingSettingsFactory baseKBS;
Listener (
@@ -363,11 +333,9 @@
);
if (baseKBS != null)
baseKBS.addPropertyChangeListener (this);
- setFolderListener ();
}
private void removeListeners () {
- fo.removeFileChangeListener (this);
if (baseKBS != null)
baseKBS.removePropertyChangeListener (this);
EditorSettingsImpl.getInstance().removePropertyChangeListener(
@@ -379,56 +347,12 @@
public void propertyChange (PropertyChangeEvent evt) {
KeyBindingSettingsImpl r = getSettings ();
if (r == null) return;
- if (EditorSettings.PROP_CURRENT_KEY_MAP_PROFILE.equals (
- evt.getPropertyName ()
- ))
- setFolderListener ();
r.log ("refresh2", Collections.EMPTY_SET);
r.pcs.firePropertyChange (null, null, null);
}
public void run() {
removeListeners();
- }
-
- public void fileDataCreated (FileEvent fe) {
- }
-
- public void fileChanged (FileEvent fe) {
- KeyBindingSettingsImpl r = getSettings ();
- if (r == null) return;
- if (fe.getFile().getNameExt().equals(KeyMapsStorage.KEYBINDING_FILE_NAME)) {
- r.refresh();
- }
- }
-
- public void fileDeleted (FileEvent fe) {
- KeyBindingSettingsImpl r = getSettings ();
- if (r == null) return;
- if (fe.getFile().getNameExt().equals(KeyMapsStorage.KEYBINDING_FILE_NAME)) {
- r.refresh();
- }
- }
-
- public void fileFolderCreated(FileEvent fe) {
- }
-
- public void fileRenamed(FileRenameEvent fe) {
- }
-
- public void fileAttributeChanged(FileAttributeEvent fe) {
- }
-
- private void setFolderListener() {
- if (fo != null) fo.removeFileChangeListener (this);
- String profile = EditorSettingsImpl.getInstance().getCurrentKeyMapProfile();
- if (profile.equals(EditorSettingsImpl.DEFAULT_PROFILE)) profile = null;
-
- KeyBindingSettingsImpl kbsi = getSettings();
- if (kbsi != null) {
- fo = Utils.createFileObject(kbsi.mimePath, profile, null);
- fo.addFileChangeListener (this);
- }
}
}
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyMapsStorage.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyMapsStorage.java,v
retrieving revision 1.19
retrieving revision 1.14.2.3
diff -u -r1.19 -r1.14.2.3
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyMapsStorage.java 11 Jan 2007 14:48:09 -0000 1.19
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/KeyMapsStorage.java 16 Mar 2007 02:54:24 -0000 1.14.2.3
@@ -19,11 +19,13 @@
package org.netbeans.modules.editor.settings.storage;
+import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
@@ -31,8 +33,10 @@
import javax.swing.KeyStroke;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.api.editor.settings.MultiKeyBinding;
-
import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.FileUtil;
+import org.openide.filesystems.Repository;
import org.openide.util.Utilities;
import org.openide.xml.XMLUtil;
import org.w3c.dom.Document;
@@ -53,13 +57,6 @@
private static final Logger LOG = Logger.getLogger(KeyMapsStorage.class.getName());
- // XXX: These constants are package private only for EditorSettingsImpl.init*() method.
- // Once we get rid of filenames these will be removed.
- /* package */ static final String KEYBINDING_FILE_NAME = "keybindings.xml"; // NOI18N
-
- /** The name of the folder within a profile's folder containing module installed defaults. */
- /* package */ static final String DEFAULTS_FOLDER = "Defaults"; //NOI18N
-
private static final String ROOT = "bindings"; //NOI18N
private static final String E_BIND = "bind"; //NOI18N
private static final String A_ACTION_NAME = "actionName"; //NOI18N
@@ -75,34 +72,58 @@
// load ....................................................................
- /**
- * Object [Map (List (KeyStroke) > MultiKeyBinding),
- * Set (List (KeyStroke))]
- * [modified, removed]
- */
- public static Object[] loadKeyMaps (
+ public static Map, MultiKeyBinding> loadKeyMaps (
MimePath mimePath,
String profile,
boolean defaults
) {
- // 1) load colorings
- if (profile.equals(EditorSettingsImpl.DEFAULT_PROFILE)) profile = null;
+ assert mimePath != null : "The parameter mimePath must not be null"; //NOI18N
+ assert profile != null : "The parameter profile must not be null"; //NOI18N
+
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors"); //NOI18N
+ Map> files = new HashMap>();
+ SettingsType.KEYBINDINGS.getLocator().scan(baseFolder, mimePath.getPath(), profile, true, true, !defaults, files);
+
+ assert files.size() <= 1 : "Too many results in the scan"; //NOI18N
- String fileName = defaults ? DEFAULTS_FOLDER + "/" + KEYBINDING_FILE_NAME : KEYBINDING_FILE_NAME;
- FileObject fo = Utils.getFileObject(mimePath, profile, fileName);
- if (fo == null) {
- return new Object[] {
- Collections., MultiKeyBinding>emptyMap(),
- Collections.>emptySet()
- };
- } else {
- return (Object[]) XMLStorage.load(fo, new KeyMapsReader());
+ List profileInfos = files.get(profile);
+ if (profileInfos == null) {
+ return Collections., MultiKeyBinding>emptyMap();
}
+
+ Map, MultiKeyBinding> keybindingsMap = new HashMap, MultiKeyBinding>();
+ for(Object [] info : profileInfos) {
+ FileObject profileHome = (FileObject) info[0];
+ FileObject settingFile = (FileObject) info[1];
+ boolean modulesFile = ((Boolean) info[2]).booleanValue();
+
+ // Load colorings from the settingFile
+ @SuppressWarnings("unchecked")
+ Object [] loadedData = (Object []) XMLStorage.load(settingFile, new KeyMapsReader());
+ @SuppressWarnings("unchecked")
+ Map, MultiKeyBinding> addedBindings = (Map, MultiKeyBinding>) loadedData[0];
+ @SuppressWarnings("unchecked")
+ Collection> removedBindings = (Collection>) loadedData[1];
+
+// System.out.println("settingsFile : " + settingFile.getPath());
+// System.out.println("addedBindings : " + addedBindings);
+// System.out.println("removedBindings : " + removedBindings);
+
+ // First add all new bindings
+ keybindingsMap.putAll(addedBindings);
+
+ // Remove all keybindings marked as removed
+ for(Collection binding : removedBindings) {
+ keybindingsMap.remove(binding);
+ }
+ }
+
+ return Collections.unmodifiableMap(keybindingsMap);
}
private static class KeyMapsReader extends XMLStorage.Handler {
private Map, MultiKeyBinding> keyMap = new HashMap, MultiKeyBinding>();
- private Set> removedShortcuts = new HashSet>();
+ private Collection> removedShortcuts = new HashSet>();
public Object getResult() {
return new Object[] {keyMap, removedShortcuts};
@@ -119,7 +140,6 @@
// We don't read anything from the root element
} else if (name.equals(E_BIND)) {
- String actionName = attributes.getValue(A_ACTION_NAME);
String key = attributes.getValue(A_KEY);
if (!Utilities.isMac() &&
@@ -129,8 +149,8 @@
// these characters do not work on MAC, Alt should be coded as 'O'
// and Ctrl as 'D'
int idx = key.indexOf('-');
- if (idx != -1 && (key.charAt(0) == 'A' || key.charAt(0) == 'C')) {
- LOG.warning("The keybinding '" + key + "' for action '" + actionName + //NOI18N
+ if (idx != -1 && (key.charAt(0) == 'A' || key.charAt(0) == 'C')) { //NOI18N
+ LOG.warning("The keybinding '" + key + //NOI18N
"' in " + getProcessedFile().getPath() + " may not work correctly on Mac. " + //NOI18N
"Keybindings starting with Alt or Ctrl should " + //NOI18N
"be coded with latin capital letters 'O' " + //NOI18N
@@ -144,8 +164,14 @@
if (Boolean.valueOf(remove)) {
removedShortcuts.add(Arrays.asList(shortcut));
} else {
- MultiKeyBinding mkb = new MultiKeyBinding(shortcut, actionName);
- keyMap.put(Arrays.asList(shortcut), mkb);
+ String actionName = attributes.getValue(A_ACTION_NAME);
+ if (actionName != null) {
+ MultiKeyBinding mkb = new MultiKeyBinding(shortcut, actionName);
+ keyMap.put(Arrays.asList(shortcut), mkb);
+// System.out.println("!!! adding: '" + key + "' -> '" + actionName + "'");
+ } else {
+ LOG.warning("Ignoring keybinding '" + key + "' with no action name."); //NOI18N
+ }
}
}
} catch (Exception ex) {
@@ -168,12 +194,35 @@
String profile,
boolean defaults
) {
- if (profile.equals(EditorSettingsImpl.DEFAULT_PROFILE)) {
- profile = null;
- }
+ assert mimePath != null : "The parameter mimePath must not be null"; //NOI18N
+ assert profile != null : "The parameter profile must not be null"; //NOI18N
+
+ FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
+ FileObject baseFolder = sfs.findResource("Editors"); //NOI18N
+ Map> files = new HashMap>();
+ SettingsType.KEYBINDINGS.getLocator().scan(baseFolder, mimePath.getPath(), profile, true, defaults, !defaults, files);
+
+ assert files.size() <= 1 : "Too many results in the scan"; //NOI18N
- String fileName = defaults ? DEFAULTS_FOLDER + "/" + KEYBINDING_FILE_NAME : KEYBINDING_FILE_NAME;
- Utils.deleteFileObject(mimePath, profile, fileName);
+ final List profileInfos = files.get(profile);
+ if (profileInfos != null) {
+ try {
+ sfs.runAtomicAction(new FileSystem.AtomicAction() {
+ public void run() {
+ for(Object [] info : profileInfos) {
+ FileObject settingFile = (FileObject) info[1];
+ try {
+ settingFile.delete();
+ } catch (IOException ioe) {
+ LOG.log(Level.WARNING, "Can't delete editor settings file " + settingFile.getPath(), ioe); //NOI18N
+ }
+ }
+ }
+ });
+ } catch (IOException ioe) {
+ LOG.log(Level.WARNING, "Can't delete editor keybindings for " + mimePath.getPath() + ", " + profile, ioe); //NOI18N
+ }
+ }
}
// save ..........................................................
@@ -182,19 +231,29 @@
MimePath mimePath,
String profile,
boolean defaults,
- Collection keyMap, // modified shortcuts
- Set> removed // shortcuts
+ final Collection keybindings, // modified shortcuts
+ final Set> removedKeybindings // shortcuts
) {
- if (profile.equals(EditorSettingsImpl.DEFAULT_PROFILE)) {
- profile = null;
- }
+ assert mimePath != null : "The parameter mimePath must not be null"; //NOI18N
+ assert profile != null : "The parameter profile must not be null"; //NOI18N
- String fileName = defaults ? DEFAULTS_FOLDER + "/" + KEYBINDING_FILE_NAME : KEYBINDING_FILE_NAME;
- FileObject fo = Utils.createFileObject(mimePath, profile, fileName);
- saveKeyMaps (fo, keyMap, removed);
+ final FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
+ final String settingFileName = SettingsType.KEYBINDINGS.getLocator().getWritableFileName(mimePath.getPath(), profile, defaults);
+
+ try {
+ sfs.runAtomicAction(new FileSystem.AtomicAction() {
+ public void run() throws IOException {
+ FileObject baseFolder = sfs.findResource("Editors"); //NOI18N
+ FileObject f = FileUtil.createData(baseFolder, settingFileName);
+ saveKeybindings(f, keybindings, removedKeybindings);
+ }
+ });
+ } catch (IOException ioe) {
+ LOG.log(Level.WARNING, "Can't save editor keybindings for " + mimePath.getPath() + ", " + profile, ioe); //NOI18N
+ }
}
- private static void saveKeyMaps(
+ private static void saveKeybindings(
FileObject fo,
Collection keyMap,
Set> removed
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/MimeTypesTracker.java
===================================================================
RCS file: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/MimeTypesTracker.java
diff -N editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/MimeTypesTracker.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/MimeTypesTracker.java 12 Mar 2007 10:24:12 -0000 1.1.2.2
@@ -0,0 +1,328 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.openide.filesystems.FileChangeAdapter;
+import org.openide.filesystems.FileChangeListener;
+import org.openide.filesystems.FileEvent;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileRenameEvent;
+import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.Repository;
+import org.openide.util.WeakListeners;
+
+/**
+ * The tracker of mime types registered as folders under a common root. This class
+ * will listen on a hierarchical structure of folders under a baseFolder
+ * and will interpret its subfolders as mime type definitions. For example the
+ * following structure of folders will be interpreted as two mime types 'text/x-java'
+ * and 'application/pdf'.
+ *
+ *
+ * <baseFolder>/text/x-java
+ * <baseFolder>/application/pdf
+ *
+ *
+ * @author Vita Stejskal
+ */
+public final class MimeTypesTracker {
+
+ private static final Logger LOG = Logger.getLogger(MimeTypesTracker.class.getName());
+
+ private static final Pattern REG_NAME_PATTERN = Pattern.compile("^[[\\p{Alnum}][!#$&.+\\-^_]]{1,127}$"); //NOI18N
+
+ private static final Set WELL_KNOWN_TYPES = new HashSet(Arrays.asList(
+ "application", //NOI18N
+ "audio", //NOI18N
+ "image", //NOI18N
+ "message", //NOI18N
+ "model", //NOI18N
+ "multipart", //NOI18N
+ "text", //NOI18N
+ "video" //NOI18N
+ ));
+
+ private static final String ATTR_MIME_TYPE_FOLDER_MARKER = "org-netbeans-editor-MimeTypeDefinition"; //NOI18N
+
+ /** The property for notifying changes in mime types tracked by this tracker. */
+ public static final String PROP_MIME_TYPES = "mime-types"; //NOI18N
+
+ /**
+ * Create a new tracker for tracking mime types under the basePath
+ * folder.
+ *
+ * @param basePath The path on the system FileSystem
where the
+ * mime types should be tracked.
+ * @param settingsType The type of settings to track mime types for. If not
+ * null
the tracker will only list mime types that declare
+ * settings of this type.
+ */
+ public MimeTypesTracker(String basePath, SettingsType settingsType) {
+ this.basePath = basePath;
+ this.basePathElements = basePath.split("/"); //NOI18N
+ this.locator = settingsType == null ? null : settingsType.getLocator();
+
+ rebuild();
+
+ // Start listening
+ this.listener = new Listener();
+ FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
+ sfs.addFileChangeListener(WeakListeners.create(FileChangeListener.class,listener, sfs));
+ }
+
+ /**
+ * Gets the root of the mime types hierarchy watched by this tracker.
+ *
+ * @return The basePath
passed to the constructor.
+ */
+ public String getBasePath() {
+ return basePath;
+ }
+
+ /**
+ * Gets the list of mime types (String
s) located under this
+ * tracker's basePath
.
+ *
+ * @return The list of mime types.
+ */
+ public Set getMimeTypes() {
+ synchronized (LOCK) {
+ return mimeTypes.keySet();
+ }
+ }
+
+ /**
+ * Gets a display name for a mime type. The display name is read from the
+ * localizing bundle associated to the mime type's folder (FileObject
).
+ * The value of the mimeType
parameter will be used as bundle
+ * key to read the display name.
+ *
+ * @param mimeType The mime type to get the display name for.
+ * @return The display (localized) name of the mime type or the mimeType
+ * if the display name can't be found.
+ */
+ public String getMimeTypeDisplayName(String mimeType) {
+ String displayName = mimeTypes.get(mimeType);
+ return displayName == null ? mimeType : displayName;
+ }
+
+ /**
+ * Adds a listener that will be receiving PROP_MIME_TYPES
notifcations.
+ *
+ * @param l The listener to add.
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ pcs.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Removes a previously added listener.
+ *
+ * @param l The listener to remove.
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ pcs.removePropertyChangeListener(l);
+ }
+
+ // ------------------------------------------------------------------
+ // private implementation
+ // ------------------------------------------------------------------
+
+ private final String LOCK = new String("MimeTypesTracker.LOCK"); //NOI18N
+
+ private final String basePath;
+ private final String [] basePathElements;
+ private final SettingsType.Locator locator;
+
+ private FileObject folder;
+ private boolean isBaseFolder;
+
+ private Map mimeTypes = Collections.emptyMap();
+
+ private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+ private final FileChangeListener listener;
+
+ private void rebuild() {
+ PropertyChangeEvent event = null;
+
+ synchronized (LOCK) {
+ Object [] ret = findTarget(basePathElements);
+ FileObject f = (FileObject) ret[0];
+ boolean isBase = ((Boolean) ret[1]).booleanValue();
+
+ // The base folder or some folder up in the hierarchy has been created/deleted
+ if (f != folder) {
+ // Set the current folder and its is-target-flag
+ folder = f;
+ isBaseFolder = isBase;
+
+ LOG.finest("folder = '" + folder.getPath() + "'"); //NOI18N
+ LOG.finest("isBaseFolder = '" + isBaseFolder + "'"); //NOI18N
+ }
+
+ if (isBaseFolder) {
+ // Clear the cache
+ Map newMimeTypes = new HashMap();
+
+ // Go through mime type types
+ FileObject [] types = folder.getChildren();
+ for(int i = 0; i < types.length; i++) {
+ if (!isValidType(types[i])) {
+ continue;
+ }
+
+ // Go through mime type subtypes
+ FileObject [] subTypes = types[i].getChildren();
+ for(int j = 0; j < subTypes.length; j++) {
+ if (!isValidSubtype(subTypes[j])) {
+ continue;
+ }
+
+ String mimeType = types[i].getNameExt() + "/" + subTypes[j].getNameExt(); //NOI18N
+
+ boolean add;
+ if (locator != null) {
+ Map> scan = new HashMap>();
+ locator.scan(folder, mimeType, null, false, true, true, scan);
+ add = !scan.isEmpty();
+ } else {
+ add = true;
+ }
+
+ if (add) {
+ // First try the standard way for filesystem annotations
+ String displayName = Utils.getLocalizedName(subTypes[j], null);
+
+ // Then try the crap way introduced with Tools-Options
+ if (displayName == null) {
+ displayName = Utils.getLocalizedName(subTypes[j], mimeType, mimeType);
+ }
+ newMimeTypes.put(mimeType, displayName);
+ }
+ }
+ }
+
+ newMimeTypes = Collections.unmodifiableMap(newMimeTypes);
+ if (!mimeTypes.equals(newMimeTypes)) {
+ event = new PropertyChangeEvent(this, PROP_MIME_TYPES, mimeTypes, newMimeTypes);
+ mimeTypes = newMimeTypes;
+ }
+ }
+ }
+
+ if (event != null) {
+ pcs.firePropertyChange(event);
+ }
+ }
+
+ private static boolean isValidType(FileObject typeFile) {
+ if (!typeFile.isFolder()) {
+ return false;
+ }
+
+ String typeName = typeFile.getNameExt();
+
+ if (!isValidRegName(typeName)) {
+ return false;
+ }
+
+ if (WELL_KNOWN_TYPES.contains(typeName)) {
+ return true;
+ }
+
+ // XXX: undocumented backdoor
+ Object marker = typeFile.getAttribute(ATTR_MIME_TYPE_FOLDER_MARKER);
+ if ((marker instanceof Boolean) && ((Boolean) marker).booleanValue()) {
+ return true;
+ }
+
+ return false;
+ }
+
+ private static boolean isValidSubtype(FileObject subtypeFile) {
+ if (!subtypeFile.isFolder()) {
+ return false;
+ }
+
+ String typeName = subtypeFile.getNameExt();
+ return isValidRegName(typeName) && !typeName.equals("base"); //NOI18N
+ }
+
+ private static boolean isValidRegName(String name) {
+ Matcher m = REG_NAME_PATTERN.matcher(name);
+ return m.matches();
+ }
+
+ private static Object [] findTarget(String [] path) {
+ FileObject target = Repository.getDefault().getDefaultFileSystem().getRoot();
+ boolean isTarget = 0 == path.length;
+
+ for (int i = 0; i < path.length; i++) {
+ FileObject f = target.getFileObject(path[i]);
+
+ if (f == null || !f.isFolder() || !f.isValid() || f.isVirtual()) {
+ break;
+ } else {
+ target = f;
+ isTarget = i + 1 == path.length;
+ }
+ }
+
+ return new Object [] { target, Boolean.valueOf(isTarget) };
+ }
+
+ private final class Listener extends FileChangeAdapter {
+
+ public Listener() {
+ }
+
+ public void fileFolderCreated(FileEvent fe) {
+ notifyRebuild(fe.getFile());
+ }
+
+ public void fileDeleted(FileEvent fe) {
+ notifyRebuild(fe.getFile());
+ }
+
+ public void fileRenamed(FileRenameEvent fe) {
+ notifyRebuild(fe.getFile());
+ }
+
+ private void notifyRebuild(FileObject f) {
+ String path = f.getPath();
+ if (path.startsWith(basePath)) {
+ rebuild();
+ }
+ }
+ } // End of Listener class
+}
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ProfilesTracker.java
===================================================================
RCS file: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ProfilesTracker.java
diff -N editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ProfilesTracker.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/ProfilesTracker.java 12 Mar 2007 10:24:12 -0000 1.1.2.4
@@ -0,0 +1,284 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Logger;
+import org.openide.filesystems.FileChangeAdapter;
+import org.openide.filesystems.FileChangeListener;
+import org.openide.filesystems.FileEvent;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileRenameEvent;
+import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.Repository;
+import org.openide.util.WeakListeners;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public final class ProfilesTracker {
+
+ /**
+ * The property name for notifying changes in the tracked profiles.
+ */
+ public static final String PROP_PROFILES = "profiles"; //NOI18N
+
+ /**
+ * Creates a new instance of ProfilesTracker.
+ *
+ * @param type
+ * @param mimeTypes
+ * @param strict
+ */
+ public ProfilesTracker(SettingsType type, MimeTypesTracker mimeTypes) {
+ assert type != null : "The parameter type must not be null"; //NOI18N
+ assert type.isUsingProfiles() : "No need to track profiles for settings that do not use profiles."; //NOI18N
+
+ this.locator = type == null ? null : type.getLocator();
+ this.mimeTypes = mimeTypes;
+
+ rebuild();
+
+ // Start listening
+ this.listener = new Listener();
+ this.sfs = Repository.getDefault().getDefaultFileSystem();
+ this.sfs.addFileChangeListener(WeakListeners.create(FileChangeListener.class, listener, this.sfs));
+ this.mimeTypes.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Gets the list of profiles for the tracked setting type.
+ *
+ * @return Profiles as a map of profile name -> profile display name.
+ */
+ public Set getProfilesDisplayNames() {
+ synchronized (LOCK) {
+ return profilesByDisplayName.keySet();
+ }
+ }
+
+ /**
+ * Gets description for a profile by its name.
+ *
+ * @param displayName The display name of the profile to get the description for.
+ * @retutn The profile's description or null
if there is no
+ * profile with the display name.
+ */
+ public ProfileDescription getProfileByDisplayName(String displayName) {
+ synchronized (LOCK) {
+ return profilesByDisplayName.get(displayName);
+ }
+ }
+
+ /**
+ * Adds a listener that will be receiving PROP_PROFILES
notifcations.
+ *
+ * @param l The listener to add.
+ */
+ public void addPropertyChangeListener(PropertyChangeListener l) {
+ pcs.addPropertyChangeListener(l);
+ }
+
+ /**
+ * Removes a previously added listener.
+ *
+ * @param l The listener to remove.
+ */
+ public void removePropertyChangeListener(PropertyChangeListener l) {
+ pcs.removePropertyChangeListener(l);
+ }
+
+ public static final class ProfileDescription {
+ private final String id;
+ private final String displayName;
+ private final boolean isRollbackAllowed;
+
+ private ProfileDescription(String id, String displayName, boolean isRollbackAllowed) {
+ this.id = id;
+ this.displayName = displayName;
+ this.isRollbackAllowed = isRollbackAllowed;
+ }
+
+ public boolean isRollbackAllowed() {
+ return isRollbackAllowed;
+ }
+
+ public String getDisplayName() {
+ return displayName;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ } // End of ProfileDescription class
+
+ // ------------------------------------------------------------------
+ // private implementation
+ // ------------------------------------------------------------------
+
+ private static final Logger LOG = Logger.getLogger(ProfilesTracker.class.getName());
+
+ private final SettingsType.Locator locator;
+ private final MimeTypesTracker mimeTypes;
+
+ private final FileSystem sfs;
+ private final Listener listener;
+ private final PropertyChangeSupport pcs = new PropertyChangeSupport(this);
+
+ private final String LOCK = new String("ProfilesTracker.LOCK"); //NOI18N
+ private Map profiles = Collections.emptyMap();
+ private Map profilesByDisplayName = Collections.emptyMap();
+
+ private void rebuild() {
+ PropertyChangeEvent event = null;
+
+ synchronized (LOCK) {
+ FileSystem sfs = Repository.getDefault().getDefaultFileSystem();
+ Map> scan = new HashMap>();
+
+ FileObject baseFolder = sfs.findResource(mimeTypes.getBasePath());
+ if (baseFolder != null && baseFolder.isFolder()) {
+ // Scan base folder
+ locator.scan(baseFolder, null, null, false, true, true, scan);
+
+ // Scan mime type folders
+ Collection mimes = mimeTypes.getMimeTypes();
+ for(String mime : mimes) {
+ locator.scan(baseFolder, mime, null, false, true, true, scan);
+ }
+ }
+
+ HashMap newProfiles = new HashMap();
+ HashMap newProfilesByDisplayName = new HashMap();
+ for(String id : scan.keySet()) {
+ List profileInfos = scan.get(id);
+
+ // Determine profile's display name and if it can roll back user changes
+ String displayName = null;
+ boolean canRollback = false;
+ for(Object [] info : profileInfos) {
+ FileObject profileHome = (FileObject) info[0];
+ FileObject settingFile = (FileObject) info[1];
+ boolean modulesFile = ((Boolean) info[2]);
+
+ if (displayName == null && profileHome != null) {
+ // First try the standard way for filesystem annotations
+ displayName = Utils.getLocalizedName(profileHome, null);
+
+ // Then try the crap way introduced with Tools-Options
+ if (displayName == null) {
+ displayName = Utils.getLocalizedName(profileHome, id, null);
+ }
+ }
+
+ if (!canRollback) {
+ canRollback = modulesFile;
+ }
+
+ if (displayName != null && canRollback) {
+ break;
+ }
+ }
+ displayName = displayName == null ? id : displayName;
+
+ // Check for duplicate display names
+ ProfileDescription maybeDupl = newProfilesByDisplayName.get(displayName);
+ if (maybeDupl != null) {
+ LOG.warning("Ignoring profile '" + id + "', it's got the same display name as '" + maybeDupl.getId()); //NOI18N
+ continue;
+ }
+
+ ProfileDescription desc = reuseOrCreate(id, displayName, canRollback);
+ newProfiles.put(id, desc);
+ newProfilesByDisplayName.put(displayName, desc);
+ }
+
+ // Just a sanity check
+ assert newProfilesByDisplayName.size() == newProfiles.size() : "Inconsistent profile maps"; //NOI18N
+
+ if (!profiles.equals(newProfiles)) {
+ event = new PropertyChangeEvent(this, PROP_PROFILES, profiles, newProfiles);
+ profiles = newProfiles;
+ profilesByDisplayName = newProfilesByDisplayName;
+ }
+ }
+
+ if (event != null) {
+ pcs.firePropertyChange(event);
+ }
+ }
+
+ private ProfileDescription reuseOrCreate(String id, String displayName, boolean rollback) {
+ ProfileDescription desc = profiles.get(id);
+ if (desc != null) {
+ if (desc.getDisplayName().equals(displayName) && desc.isRollbackAllowed() == rollback) {
+ return desc;
+ }
+ }
+ return new ProfileDescription(id, displayName, rollback);
+ }
+
+ private final class Listener extends FileChangeAdapter implements PropertyChangeListener {
+
+ public Listener() {
+ }
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ rebuild();
+ }
+
+ @Override
+ public void fileDataCreated(FileEvent fe) {
+ notifyRebuild(fe.getFile());
+ }
+
+ @Override
+ public void fileFolderCreated(FileEvent fe) {
+ notifyRebuild(fe.getFile());
+ }
+
+ @Override
+ public void fileDeleted(FileEvent fe) {
+ notifyRebuild(fe.getFile());
+ }
+
+ @Override
+ public void fileRenamed(FileRenameEvent fe) {
+ notifyRebuild(fe.getFile());
+ }
+
+ private void notifyRebuild(FileObject file) {
+ String path = file.getPath();
+ if (path.startsWith(mimeTypes.getBasePath())) {
+ rebuild();
+ }
+ }
+ } // End of Listener class
+}
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsProvider.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsProvider.java,v
retrieving revision 1.6
retrieving revision 1.3.4.2
diff -u -r1.6 -r1.3.4.2
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsProvider.java 4 Jan 2007 01:07:31 -0000 1.6
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsProvider.java 15 Mar 2007 08:54:05 -0000 1.3.4.2
@@ -63,6 +63,14 @@
* @return Lookup or null, if there are no lookup-able objects for mime or global level.
*/
public Lookup getLookup(MimePath mimePath) {
+ if (mimePath.size() > 0 && mimePath.getMimeType(0).contains(EditorSettingsImpl.TEXT_BASE_MIME_TYPE)) {
+ if (LOG.isLoggable(Level.INFO)) {
+ LOG.log(Level.INFO, "Won't provide any settings for " + EditorSettingsImpl.TEXT_BASE_MIME_TYPE + //NOI18N
+ "It's been deprecated, use MimePath.EMPTY instead."); //, new Throwable("Stacktrace") //NOI18N
+ }
+ return null;
+ }
+
synchronized (cache) {
WeakReference ref = cache.get(mimePath);
Lookup lookup = ref == null ? null : ref.get();
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsType.java
===================================================================
RCS file: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsType.java
diff -N editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsType.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/SettingsType.java 16 Mar 2007 01:18:53 -0000 1.1.2.5
@@ -0,0 +1,559 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+import org.netbeans.api.editor.settings.FontColorSettings;
+import org.netbeans.api.editor.settings.KeyBindingSettings;
+import org.openide.filesystems.FileObject;
+import org.openide.util.TopologicalSortException;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public enum SettingsType {
+
+ FONTSCOLORS(
+ "FontsColors", //NOI18N
+ true,
+ FontColorSettings.class,
+ "text/x-nbeditor-fontcolorsettings" //NOI18N
+ ),
+ KEYBINDINGS(
+ "Keybindings", //NOI18N
+ true,
+ KeyBindingSettings.class,
+ "text/x-nbeditor-keybindingsettings" //NOI18N
+ );
+
+ public static SettingsType get(Class apiClass) {
+ assert apiClass != null : "The parameter apiClass can't be null"; //NOI18N
+
+ for (SettingsType type : SettingsType.values()) {
+ if (type.apiClass.equals(apiClass)) {
+ return type;
+ }
+ }
+ return null;
+ }
+
+ public static interface Locator {
+ public void scan(FileObject baseFolder, String mimeType, String profileId, boolean fullScan, boolean scanModules, boolean scanUsers, Map> results);
+ public String getWritableFileName(String mimeType, String profileId, boolean modulesFile);
+ }
+
+ // ------------------------------------------------------------------
+ // private implementation
+ // ------------------------------------------------------------------
+
+ private static final Logger LOG = Logger.getLogger(SettingsType.class.getName());
+
+ private final String settingsTypeId;
+ private final boolean usesProfiles;
+ private final Class apiClass;
+ private final String mimeType;
+ private Locator locator;
+
+ private SettingsType(String settingsTypeId, boolean usesProfiles, Class apiClass, String mimeType) {
+ this.settingsTypeId = settingsTypeId;
+ this.usesProfiles = usesProfiles;
+ this.apiClass = apiClass;
+ this.mimeType = mimeType;
+ }
+
+ public String getId() {
+ return settingsTypeId;
+ }
+
+ public boolean isUsingProfiles() {
+ return usesProfiles;
+ }
+
+ public String getMimeType() {
+ return mimeType;
+ }
+
+ public Locator getLocator() {
+ if (locator == null) {
+ switch (this) {
+ case FONTSCOLORS: locator = new FontsColorsLocator(); break;
+ case KEYBINDINGS: locator = new KeybindingsLocator(); break;
+ default: locator = new DefaultLocator(this);
+ }
+ }
+ return locator;
+ }
+
+ private static class DefaultLocator implements Locator {
+
+ protected static final String MODULE_FILES_FOLDER = "Defaults"; //NOI18N
+ protected static final String DEFAULT_PROFILE_NAME = EditorSettingsImpl.DEFAULT_PROFILE;
+
+ private static final String WRITABLE_FILE_PREFIX = "org-netbeans-modules-editor-settings-Custom"; //NOI18N
+ private static final String WRITABLE_FILE_SUFFIX = ".xml"; //NOI18N
+ private static final String FA_TARGET_OS = "nbeditor-settings-targetOS"; //NOI18N
+
+ private final SettingsType settingType;
+ private final String settingTypeFolderName;
+ private final String writableFileName;
+ private final String modulesWritableFileName;
+ private final String usersWritableFileName;
+
+ public DefaultLocator(SettingsType settingType) {
+ assert settingType != null : "The parameter settingType can't be null"; //NOI18N
+ this.settingType = settingType;
+ this.settingTypeFolderName = "/" + settingType.getId() + "/"; //NOI18N
+ this.writableFileName = WRITABLE_FILE_PREFIX + settingType.getId() + WRITABLE_FILE_SUFFIX;
+ this.modulesWritableFileName = "/" + MODULE_FILES_FOLDER + "/" + WRITABLE_FILE_PREFIX + settingType.getId() + WRITABLE_FILE_SUFFIX; //NOI18N
+ this.usersWritableFileName = "/" + writableFileName; //NOI18N
+ }
+
+ public final void scan(
+ FileObject baseFolder,
+ String mimeType,
+ String profileId,
+ boolean fullScan,
+ boolean scanModules,
+ boolean scanUsers,
+ Map> results
+ ) {
+ assert baseFolder != null : "The parameter baseFolder can't be null"; //NOI18N
+ assert results != null : "The parameter results can't be null"; //NOI18N
+
+ FileObject mimeFolder = getMimeFolder(baseFolder, mimeType);
+ FileObject legacyMimeFolder = getLegacyMimeFolder(baseFolder, mimeType);
+
+ if (scanModules) {
+ if (legacyMimeFolder != null && legacyMimeFolder.isFolder()) {
+ addModulesLegacyFiles(legacyMimeFolder, profileId, fullScan, results);
+ }
+ if (mimeFolder != null && mimeFolder.isFolder()) {
+ addModulesFiles(mimeFolder, profileId, fullScan, results);
+ }
+ }
+
+ if (scanUsers) {
+ if (legacyMimeFolder != null && legacyMimeFolder.isFolder()) {
+ addUsersLegacyFiles(legacyMimeFolder, profileId, fullScan, results);
+ }
+ if (mimeFolder != null && mimeFolder.isFolder()) {
+ addUsersFiles(mimeFolder, profileId, fullScan, results);
+ }
+ }
+ }
+
+ public final String getWritableFileName(String mimeType, String profileId, boolean modulesFile) {
+ assert mimeType != null : "The mimeType parameter must not be null"; //NOI18N
+ assert profileId != null : "The profileId parameter must not be null"; //NOI18N
+
+ String part;
+
+ if (mimeType.length() == 0) {
+ part = settingType.getId() + "/"; //NOI18N
+ } else {
+ part = mimeType + settingTypeFolderName;
+ }
+
+ if (modulesFile) {
+ return part + profileId + modulesWritableFileName;
+ } else {
+ return part + profileId + usersWritableFileName;
+ }
+ }
+
+ protected FileObject getLegacyMimeFolder(FileObject baseFolder, String mimeType) {
+ return mimeType == null ? baseFolder : baseFolder.getFileObject(mimeType);
+ }
+
+ protected void addModulesLegacyFiles(FileObject mimeFolder, String profileId, boolean fullScan, Map> files) {
+ // Do nothing by default
+ }
+
+ protected void addUsersLegacyFiles(FileObject mimeFolder, String profileId, boolean fullScan, Map> files) {
+ // Do nothing by default
+ }
+
+ private FileObject getMimeFolder(FileObject baseFolder, String mimeType) {
+ return mimeType == null ? baseFolder : baseFolder.getFileObject(mimeType);
+ }
+
+ private void addModulesFiles(FileObject mimeFolder, String profileId, boolean fullScan, Map> files) {
+ if (profileId == null) {
+ FileObject settingHome = mimeFolder.getFileObject(settingType.getId());
+ if (settingHome != null && settingHome.isFolder()) {
+ FileObject [] profileHomes = settingHome.getChildren();
+ for(FileObject f : profileHomes) {
+ if (!f.isFolder()) {
+ continue;
+ }
+
+ String id = f.getNameExt();
+ FileObject folder = f.getFileObject(MODULE_FILES_FOLDER);
+ if (folder != null && folder.isFolder()) {
+ addFiles(folder, fullScan, files, id, f, true);
+ }
+ }
+ }
+ } else {
+ FileObject folder = mimeFolder.getFileObject(settingType.getId() + "/" + profileId + "/" + MODULE_FILES_FOLDER); //NOI18N
+ if (folder != null && folder.isFolder()) {
+ addFiles(folder, fullScan, files, profileId, folder.getParent(), true);
+ }
+ }
+ }
+
+ private void addUsersFiles(FileObject mimeFolder, String profileId, boolean fullScan, Map> files) {
+ if (profileId == null) {
+ FileObject settingHome = mimeFolder.getFileObject(settingType.getId());
+ if (settingHome != null && settingHome.isFolder()) {
+ FileObject [] profileHomes = settingHome.getChildren();
+ for(FileObject f : profileHomes) {
+ if (f.isFolder()) {
+ String id = f.getNameExt();
+ addFiles(f, fullScan, files, id, f, false);
+ }
+ }
+ }
+ } else {
+ FileObject folder = mimeFolder.getFileObject(settingType.getId() + "/" + profileId); //NOI18N
+ if (folder != null && folder.isFolder()) {
+ addFiles(folder, fullScan, files, profileId, folder, false);
+ }
+ }
+ }
+
+ private final void addFiles(FileObject folder, boolean fullScan, Map> files, String profileId, FileObject profileHome, boolean moduleFiles) {
+ Object [] writableFile = null;
+ List osSpecificFiles = new ArrayList();
+
+ FileObject [] ff = getOrderedChildren(folder);
+ for(FileObject f : ff) {
+ if (f.isData() && f.getMIMEType().equals(settingType.getMimeType())) {
+ Object targetOs = f.getAttribute(FA_TARGET_OS);
+ if (targetOs != null) {
+ try {
+ if (!isApplicableForThisTargetOs(targetOs)) {
+ continue;
+ }
+ } catch (Exception e) {
+ LOG.log(Level.WARNING, "Ignoring editor settings file with invalid OS type mask '" + targetOs + "' file: " + f.getPath()); //NOI18N
+ continue;
+ }
+ }
+
+ List infos = files.get(profileId);
+ if (infos == null) {
+ infos = new ArrayList();
+ files.put(profileId, infos);
+ }
+ Object [] oo = new Object [] { profileHome, f, moduleFiles };
+
+ // There can be a writable file in the modules folder and it
+ // needs to be added last so that it does not get hidden by
+ // other module files.
+ if (f.getNameExt().equals(writableFileName)) {
+ assert writableFile == null;
+ writableFile = oo;
+ } else if (targetOs != null) {
+ osSpecificFiles.add(oo);
+ } else {
+ infos.add(oo);
+ }
+
+ // Stop scanning if this is not a full scan mode
+ if (!fullScan) {
+ break;
+ }
+ } else {
+ LOG.fine("Ignoring file: " + f.getPath() + " of type " + f.getMIMEType()); //NOI18N
+ }
+ }
+
+ if (!osSpecificFiles.isEmpty()) {
+ List infos = files.get(profileId);
+ infos.addAll(osSpecificFiles);
+ }
+
+ // Add the writable file if there is any
+ if (writableFile != null) {
+ List infos = files.get(profileId);
+ infos.add(writableFile);
+ }
+ }
+
+ private boolean isApplicableForThisTargetOs(Object targetOs) throws NoSuchFieldException, IllegalAccessException {
+ if (targetOs instanceof Boolean) {
+ return ((Boolean) targetOs).booleanValue();
+ } else if (targetOs instanceof String) {
+ Field field = Utilities.class.getDeclaredField((String) targetOs);
+ int targetOsMask = field.getInt(null);
+ int currentOsId = Utilities.getOperatingSystem();
+ return (currentOsId & targetOsMask) != 0;
+ } else {
+ return false;
+ }
+ }
+
+ protected static FileObject [] getOrderedChildren(FileObject folder) {
+ // Collect all children
+ Map children = new HashMap();
+ for (FileObject f : folder.getChildren()) {
+ String name = f.getNameExt();
+ children.put(name, f);
+ }
+
+ // Collect all edges
+ Map> edges = new HashMap>();
+ for (Enumeration attrNames = folder.getAttributes(); attrNames.hasMoreElements(); ) {
+ String attrName = attrNames.nextElement();
+ Object attrValue = folder.getAttribute(attrName);
+
+ // Check whether the attribute affects sorting
+ int slashIdx = attrName.indexOf('/'); //NOI18N
+ if (slashIdx == -1 || !(attrValue instanceof Boolean)) {
+ continue;
+ }
+
+ // Get the file names
+ String name1 = attrName.substring(0, slashIdx);
+ String name2 = attrName.substring(slashIdx + 1);
+ if (!((Boolean) attrValue).booleanValue()) {
+ // Swap the names
+ String s = name1;
+ name1 = name2;
+ name2 = s;
+ }
+
+ // Get the files and add them among the edges
+ FileObject from = children.get(name1);
+ FileObject to = children.get(name2);
+
+ if (from != null && to != null) {
+ Set vertices = edges.get(from);
+ if (vertices == null) {
+ vertices = new HashSet();
+ edges.put(from, vertices);
+ }
+ vertices.add(to);
+ }
+ }
+
+ // Sort the children
+ List sorted;
+
+ try {
+ sorted = Utilities.topologicalSort(children.values(), edges);
+ } catch (TopologicalSortException e) {
+ LOG.log(Level.WARNING, "Can't sort folder children.", e); //NOI18N
+ @SuppressWarnings("unchecked")
+ List whyTheHellDoINeedToDoThis = e.partialSort();
+ sorted = whyTheHellDoINeedToDoThis;
+ }
+
+ return sorted.toArray(new FileObject[sorted.size()]);
+ }
+ } // End of DefaultLocator class
+
+ private static final class FontsColorsLocator extends DefaultLocator {
+
+ private static final String [] M_LEGACY_FILE_NAMES = new String [] {
+ MODULE_FILES_FOLDER + "/defaultColoring.xml", // NOI18N
+ MODULE_FILES_FOLDER + "/coloring.xml", // NOI18N
+ MODULE_FILES_FOLDER + "/editorColoring.xml", // NOI18N
+ };
+
+ private static final String [] U_LEGACY_FILE_NAMES = new String [] {
+ "defaultColoring.xml", // NOI18N
+ "coloring.xml", // NOI18N
+ "editorColoring.xml", // NOI18N
+ };
+
+ public FontsColorsLocator() {
+ super(FONTSCOLORS);
+ }
+
+ @Override
+ protected void addModulesLegacyFiles(
+ FileObject mimeFolder,
+ String profileId,
+ boolean fullScan,
+ Map> files
+ ) {
+ addFiles(mimeFolder, profileId, fullScan, M_LEGACY_FILE_NAMES, files, true);
+ }
+
+ @Override
+ protected void addUsersLegacyFiles(
+ FileObject mimeFolder,
+ String profileId,
+ boolean fullScan,
+ Map> files
+ ) {
+ addFiles(mimeFolder, profileId, fullScan, U_LEGACY_FILE_NAMES, files, false);
+ }
+
+ private void addFiles(
+ FileObject mimeFolder,
+ String profileId,
+ boolean fullScan,
+ String [] filePaths,
+ Map> files,
+ boolean moduleFiles
+ ) {
+ if (profileId == null) {
+ FileObject [] profileHomes = mimeFolder.getChildren();
+ for(FileObject f : profileHomes) {
+ if (!f.isFolder()) {
+ continue;
+ }
+
+ String id = f.getNameExt();
+ addFiles(f, filePaths, fullScan, files, id, f, moduleFiles); //NOI18N
+ }
+ } else {
+ FileObject profileHome = mimeFolder.getFileObject(profileId);
+ if (profileHome != null && profileHome.isFolder()) {
+ addFiles(profileHome, filePaths, fullScan, files, profileId, profileHome, moduleFiles);
+ }
+ }
+ }
+
+ private void addFiles(FileObject folder, String [] filePaths, boolean fullScan, Map> files, String profileId, FileObject profileHome, boolean moduleFiles) {
+ for(String filePath : filePaths) {
+ FileObject f = folder.getFileObject(filePath);
+ if (f != null) {
+ List pair = files.get(profileId);
+ if (pair == null) {
+ pair = new ArrayList();
+ files.put(profileId, pair);
+ }
+ pair.add(new Object [] { profileHome, f, moduleFiles });
+ if (!fullScan) {
+ break;
+ }
+ }
+ }
+ }
+ } // End of FontsColorsLocator class
+
+ private static final class KeybindingsLocator extends DefaultLocator {
+
+ private static final String M_KEYBINDING_FILE_NAME = MODULE_FILES_FOLDER + "/keybindings.xml"; // NOI18N
+ private static final String U_KEYBINDING_FILE_NAME = "keybindings.xml"; // NOI18N
+
+ public KeybindingsLocator() {
+ super(KEYBINDINGS);
+ }
+
+ @Override
+ protected FileObject getLegacyMimeFolder(FileObject baseFolder, String mimeType) {
+ if (mimeType == null || mimeType.length() == 0) {
+ return baseFolder.getFileObject(EditorSettingsImpl.TEXT_BASE_MIME_TYPE);
+ } else {
+ return super.getMimeFolder(baseFolder, mimeType);
+ }
+ }
+
+ @Override
+ protected void addModulesLegacyFiles(
+ FileObject mimeFolder,
+ String profileId,
+ boolean fullScan,
+ Map> files
+ ) {
+ addFiles(mimeFolder, profileId, fullScan, M_KEYBINDING_FILE_NAME, files, true);
+ }
+
+ @Override
+ protected void addUsersLegacyFiles(
+ FileObject mimeFolder,
+ String profileId,
+ boolean fullScan,
+ Map> files
+ ) {
+ addFiles(mimeFolder, profileId, fullScan, U_KEYBINDING_FILE_NAME, files, false);
+ }
+
+ private void addFiles(
+ FileObject mimeFolder,
+ String profileId,
+ boolean fullScan,
+ String filePath,
+ Map> files,
+ boolean moduleFiles
+ ) {
+ if (profileId == null) {
+ FileObject [] profileHomes = mimeFolder.getChildren();
+ for(FileObject f : profileHomes) {
+ if (!f.isFolder() || f.getNameExt().equals(MODULE_FILES_FOLDER)) {
+ continue;
+ }
+
+ String id = f.getNameExt();
+ FileObject file = f.getFileObject(filePath);
+ if (file != null) {
+ addFile(file, files, id, f, moduleFiles);
+ }
+ }
+
+ FileObject file = mimeFolder.getFileObject(filePath);
+ if (file != null) {
+ addFile(file, files, DEFAULT_PROFILE_NAME, null, moduleFiles);
+ }
+ } else {
+ if (profileId.equals(DEFAULT_PROFILE_NAME)) {
+ FileObject file = mimeFolder.getFileObject(filePath); //NOI18N
+ if (file != null) {
+ addFile(file, files, profileId, null, moduleFiles);
+ }
+ } else {
+ FileObject profileHome = mimeFolder.getFileObject(profileId);
+ if (profileHome != null && profileHome.isFolder()) {
+ FileObject file = profileHome.getFileObject(filePath);
+ if (file != null) {
+ addFile(file, files, profileId, profileHome, moduleFiles);
+ }
+ }
+ }
+ }
+ }
+
+ private void addFile(FileObject file, Map> files, String profileId, FileObject profileHome, boolean moduleFiles) {
+ List pair = files.get(profileId);
+ if (pair == null) {
+ pair = new ArrayList();
+ files.put(profileId, pair);
+ }
+ pair.add(new Object [] { profileHome, file, moduleFiles });
+ }
+
+ } // End of KeybindingsLocator class
+}
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Utils.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Utils.java,v
retrieving revision 1.17
retrieving revision 1.12.2.6
diff -u -r1.17 -r1.12.2.6
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Utils.java 26 Jan 2007 04:58:52 -0000 1.17
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/Utils.java 19 Mar 2007 04:28:57 -0000 1.12.2.6
@@ -21,16 +21,17 @@
import java.awt.Color;
import java.awt.Font;
-import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;
+import java.util.Set;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
import java.util.logging.Level;
@@ -40,12 +41,15 @@
import javax.swing.text.StyleConstants;
import org.netbeans.api.editor.mimelookup.MimePath;
import org.netbeans.api.editor.settings.AttributesUtilities;
+import org.openide.filesystems.FileAttributeEvent;
+import org.openide.filesystems.FileChangeAdapter;
+import org.openide.filesystems.FileChangeListener;
+import org.openide.filesystems.FileEvent;
import org.openide.filesystems.FileObject;
-import org.openide.filesystems.FileSystem;
-import org.openide.filesystems.FileUtil;
-import org.openide.filesystems.Repository;
+import org.openide.filesystems.FileStateInvalidException;
import org.openide.util.NbBundle;
import org.openide.util.Utilities;
+import org.openide.util.WeakListeners;
/**
@@ -154,80 +158,32 @@
return result.toArray(new KeyStroke[result.size ()]);
}
- static FileObject getFileObject(MimePath mimePath, String profile, String fileNameExt) {
- String name = getFileName(mimePath, profile, fileNameExt);
- FileSystem fs = Repository.getDefault().getDefaultFileSystem();
- return fs.findResource(name);
- }
-
- /**
- * Crates FileObject for given mimeTypes and profile.
- */
- static FileObject createFileObject(MimePath mimePath, String profile, String fileName) {
- String name = getFileName(mimePath, profile, fileName);
- FileSystem fs = Repository.getDefault().getDefaultFileSystem();
+ static String getLocalizedName(FileObject fo, String defaultValue) {
try {
- if (fileName == null) {
- return FileUtil.createFolder(fs.getRoot(), name);
- } else {
- return FileUtil.createData(fs.getRoot(), name);
- }
- } catch (IOException ex) {
- LOG.log(Level.WARNING, "Can't create editor settings file or folder: " + name, ex); //NOI18N
- return null;
- }
- }
-
- /**
- * Crates FileObject for given mimeTypes and profile.
- */
- static void deleteFileObject(MimePath mimePath, String profile, String fileName) {
- String name = getFileName(mimePath, profile, fileName);
- FileSystem fs = Repository.getDefault().getDefaultFileSystem();
- FileObject fo = fs.findResource(name);
- if (fo != null) {
- try {
- fo.delete();
- } catch (IOException ex) {
- LOG.log(Level.WARNING, "Can't delete editor settings file " + fo.getPath(), ex); //NOI18N
+ return fo.getFileSystem().getStatus().annotateName(defaultValue, Collections.singleton(fo));
+ } catch (FileStateInvalidException ex) {
+ if (LOG.isLoggable(Level.INFO)) {
+ logOnce(Level.INFO, "Can't find localized name of " + fo, ex); //NOI18N
}
+ return defaultValue;
}
}
- static String getFileName(MimePath mimePath, String profile, String fileName) {
- StringBuilder sb = new StringBuilder("Editors");
-
- if (mimePath.size() > 0) {
- sb.append('/').append(mimePath.getPath());
- }
-
- if (profile != null) {
- sb.append('/').append(profile);
- }
-
- if (fileName != null) {
- sb.append('/').append(fileName);
- }
-
- return sb.toString();
- }
-
- private static FileObject createFile (FileObject fo, String next) throws IOException {
- FileObject fo1 = fo.getFileObject (next);
- if (fo1 == null)
- return fo.createFolder (next);
- return fo1;
+ static String getLocalizedName(FileObject fo, String key, String defaultValue) {
+ return getLocalizedName(fo, key, defaultValue, false);
}
- static String getLocalizedName(FileObject fo, String key, String defaultValue) {
+ static String getLocalizedName(FileObject fo, String key, String defaultValue, boolean silent) {
assert key != null : "The key can't be null"; //NOI18N
- Object [] bundleInfo = findResourceBundle(fo);
+ Object [] bundleInfo = findResourceBundle(fo, silent);
if (bundleInfo[1] != null) {
try {
return ((ResourceBundle) bundleInfo[1]).getString(key);
} catch (MissingResourceException ex) {
- LOG.log(Level.WARNING, "The bundle '" + bundleInfo[0] + "' is missing key '" + key + "'.", ex); //NOI18N
+ if (!silent && LOG.isLoggable(Level.INFO)) {
+ logOnce(Level.INFO, "The bundle '" + bundleInfo[0] + "' is missing key '" + key + "'.", ex); //NOI18N
+ }
}
}
@@ -235,7 +191,25 @@
}
private static final WeakHashMap bundleInfos = new WeakHashMap();
- private static Object [] findResourceBundle(FileObject fo) {
+ private static final FileChangeListener listener = new FileChangeAdapter() {
+ @Override
+ public void fileDeleted(FileEvent fe) {
+ synchronized (bundleInfos) {
+ bundleInfos.remove(fe.getFile());
+ }
+ }
+
+ @Override
+ public void fileAttributeChanged(FileAttributeEvent fe) {
+ if (fe.getName() != null && fe.getName().equals("SystemFileSystem.localizingBundle")) { //NOI18N
+ synchronized (bundleInfos) {
+ bundleInfos.remove(fe.getFile());
+ }
+ }
+ }
+ };
+ private static final FileChangeListener weakListener = WeakListeners.create(FileChangeListener.class, listener, null);
+ private static Object [] findResourceBundle(FileObject fo, boolean silent) {
assert fo != null : "FileObject can't be null"; //NOI18N
synchronized (bundleInfos) {
@@ -251,10 +225,14 @@
try {
bundleInfo = new Object [] { bundleName, NbBundle.getBundle(bundleName) };
} catch (MissingResourceException ex) {
- LOG.log(Level.WARNING, "Can't find resource bundle for " + fo.getPath(), ex); //NOI18N
+ if (!silent && LOG.isLoggable(Level.INFO)) {
+ logOnce(Level.INFO, "Can't find resource bundle for " + fo.getPath(), ex); //NOI18N
+ }
}
} else {
- //[PENDING][HACK] LOG.log(Level.WARNING, "The file " + fo.getPath() + " does not specify its resource bundle.", new Throwable("@@@")); //NOI18N
+ if (!silent && LOG.isLoggable(Level.FINE)) {
+ logOnce(Level.FINE, "The file " + fo.getPath() + " does not specify its resource bundle.", null); //NOI18N
+ }
}
if (bundleInfo == null) {
@@ -262,12 +240,30 @@
}
bundleInfos.put(fo, bundleInfo);
+ fo.removeFileChangeListener(weakListener);
+ fo.addFileChangeListener(weakListener);
}
return bundleInfo;
}
}
+ private static final Set ALREADY_LOGGED = Collections.synchronizedSet(new HashSet());
+ private static void logOnce(Level level, String msg, Throwable t) {
+ if (!ALREADY_LOGGED.contains(msg)) {
+ ALREADY_LOGGED.add(msg);
+ if (t != null) {
+ LOG.log(level, msg, t);
+ } else {
+ LOG.log(level, msg);
+ }
+
+ if (ALREADY_LOGGED.size() > 100) {
+ ALREADY_LOGGED.clear();
+ }
+ }
+ }
+
/**
* Converts an array of mime types to a MimePath
instance.
*/
@@ -285,7 +281,7 @@
* Creates unmodifiable copy of the original map converting AttributeSet
s
* to their immutable versions.
*/
- public static Map immutize(Map map) {
+ public static Map immutize(Map map) {
Map immutizedMap = new HashMap();
for(String name : map.keySet()) {
@@ -310,5 +306,4 @@
return Collections.unmodifiableMap(immutizedMap);
}
-
}
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/layer.xml
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/layer.xml,v
retrieving revision 1.2
retrieving revision 1.2.6.1
diff -u -r1.2 -r1.2.6.1
--- editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/layer.xml 9 Nov 2006 01:57:19 -0000 1.2
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/layer.xml 10 Mar 2007 00:55:02 -0000 1.2.6.1
@@ -20,6 +20,17 @@
+
+
+
+
+
+
+
+
+
+
+
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/mime-resolvers.xml
===================================================================
RCS file: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/mime-resolvers.xml
diff -N editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/mime-resolvers.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/mime-resolvers.xml 10 Mar 2007 00:55:02 -0000 1.1.2.1
@@ -0,0 +1,60 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/api/EditorSettings.java
===================================================================
RCS file: /cvs/editor/settings/storage/src/org/netbeans/modules/editor/settings/storage/api/EditorSettings.java,v
retrieving revision 1.13
retrieving revision 1.9.4.1
diff -u -r1.13 -r1.9.4.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/Bundle.properties
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/Bundle.properties
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/Bundle.properties
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/Bundle.properties 12 Mar 2007 01:16:10 -0000 1.1.2.2
@@ -0,0 +1,19 @@
+# The contents of this file are subject to the terms of the Common Development
+# and Distribution License (the License). You may not use this file except in
+# compliance with the License.
+#
+# You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+# or http://www.netbeans.org/cddl.txt.
+#
+# When distributing Covered Code, include this CDDL Header Notice in each file
+# and include the License file at http://www.netbeans.org/cddl.txt.
+# If applicable, add the following below the CDDL Header, with the fields
+# enclosed by brackets [] replaced by your own identifying information:
+# "Portions Copyrighted [year] [name of copyright owner]"
+#
+# The Original Software is NetBeans. The Initial Developer of the Original
+# Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+# Microsystems, Inc. All Rights Reserved.
+
+Xyz/XoX/abc/text/plain/FontsColors/ProfileA=Nice Display Name Of Profile A
+Xyz/XoX/abc/text/plain/Keybindings/ProfileA=Nice Display Name Of Profile A
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorSettingsStorageTest.java
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorSettingsStorageTest.java,v
retrieving revision 1.11
retrieving revision 1.11.2.2
diff -u -r1.11 -r1.11.2.2
--- editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorSettingsStorageTest.java 20 Dec 2006 02:09:15 -0000 1.11
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorSettingsStorageTest.java 14 Mar 2007 08:09:23 -0000 1.11.2.2
@@ -61,9 +61,11 @@
EditorTestLookup.setLookup(
new URL[] {
getClass().getClassLoader().getResource(
- "org/netbeans/modules/editor/settings/storage/test-layer.xml"),
+ "org/netbeans/modules/editor/settings/storage/test-layer.xml"),
getClass().getClassLoader().getResource(
- "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/core/resources/mf-layer.xml"), // for MIMEResolverImpl to work
},
getWorkDir(),
new Object[] {},
@@ -159,7 +161,7 @@
AttributeSet attribs = fcs.getTokenFontColors(coloringName);
assertNotNull("Can't find " + coloringName + " coloring", attribs);
- assertEquals("Wrong bgColor", new Color(rgb), attribs.getAttribute(attributeKey));
+ assertEquals("Wrong " + attributeKey, new Color(rgb), attribs.getAttribute(attributeKey));
}
public void testSetColors() {
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorTestLookup.java
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorTestLookup.java,v
retrieving revision 1.4
retrieving revision 1.4.4.1
diff -u -r1.4 -r1.4.4.1
--- editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorTestLookup.java 8 Nov 2006 03:37:41 -0000 1.4
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/EditorTestLookup.java 12 Mar 2007 03:46:10 -0000 1.4.4.1
@@ -24,6 +24,8 @@
import java.io.File;
import java.io.IOException;
import java.net.URL;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
import junit.framework.Assert;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileSystem;
@@ -35,6 +37,7 @@
import org.openide.loaders.DataFolder;
import org.openide.loaders.FolderLookup;
import org.openide.util.Lookup;
+import org.openide.util.NbBundle;
import org.openide.util.lookup.Lookups;
import org.openide.util.lookup.ProxyLookup;
@@ -146,9 +149,9 @@
createFileOnPath(mountPoint, resources[i]);
}
- LocalFileSystem lfs = new StatusFileSystem();
+ LocalFileSystem lfs = new LocalFileSystem();
try {
- lfs.setRootDirectory(mountPoint);
+ lfs.setRootDirectory(mountPoint);
} catch (Exception ex) {}
return lfs;
@@ -171,24 +174,7 @@
}
}
- private static class StatusFileSystem extends LocalFileSystem {
- Status status = new Status () {
- public String annotateName (String name, java.util.Set files) {
- return name;
- }
-
- public java.awt.Image annotateIcon (java.awt.Image icon, int iconType, java.util.Set files) {
- return icon;
- }
- };
-
- public org.openide.filesystems.FileSystem.Status getStatus() {
- return status;
- }
-
- }
-
- private static class SystemFileSystem extends MultiFileSystem {
+ private static class SystemFileSystem extends MultiFileSystem implements FileSystem.Status {
public SystemFileSystem(FileSystem [] orig) {
super(orig);
}
@@ -196,5 +182,32 @@
public void setOrig(FileSystem [] orig) {
setDelegates(orig);
}
- }
+
+ public FileSystem.Status getStatus() {
+ return this;
+ }
+
+ public String annotateName (String name, java.util.Set files) {
+ for(Object o : files) {
+ FileObject fo = (FileObject) o;
+ String bundleName = (String)fo.getAttribute ("SystemFileSystem.localizingBundle"); // NOI18N
+ if (bundleName != null) {
+ bundleName = org.openide.util.Utilities.translate(bundleName);
+ ResourceBundle b = NbBundle.getBundle(bundleName);
+ try {
+ return b.getString (fo.getPath());
+ } catch (MissingResourceException ex) {
+ // ignore--normal
+ ex.printStackTrace();
+ }
+ }
+ }
+
+ return name;
+ }
+
+ public java.awt.Image annotateIcon (java.awt.Image icon, int iconType, java.util.Set files) {
+ return icon;
+ }
+ } // End of SystemFileSystem class
}
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImplTest.java
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImplTest.java,v
retrieving revision 1.3
retrieving revision 1.3.8.2
diff -u -r1.3 -r1.3.8.2
--- editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImplTest.java 4 Jan 2007 01:07:29 -0000 1.3
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/FontColorSettingsImplTest.java 10 Mar 2007 00:55:00 -0000 1.3.8.2
@@ -49,9 +49,11 @@
EditorTestLookup.setLookup(
new URL[] {
getClass().getClassLoader().getResource(
- "org/netbeans/modules/editor/settings/storage/test-layer.xml"),
+ "org/netbeans/modules/editor/settings/storage/test-layer.xml"),
getClass().getClassLoader().getResource(
- "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/core/resources/mf-layer.xml"), // for MIMEResolverImpl to work
},
getWorkDir(),
new Object[] {},
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/LocatorTest.java
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/LocatorTest.java
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/LocatorTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/LocatorTest.java 16 Mar 2007 02:54:25 -0000 1.1.2.2
@@ -0,0 +1,311 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage;
+
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.netbeans.core.startup.Main;
+import org.netbeans.junit.NbTestCase;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.Repository;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public class LocatorTest extends NbTestCase {
+
+ private static final String FC_CONTENTS =
+ "\n" +
+ "\n" +
+ " ";
+
+ private static final String KB_CONTENTS =
+ "\n" +
+ "\n" +
+ " ";
+
+ /** Creates a new instance of LocatorTest */
+ public LocatorTest(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ EditorTestLookup.setLookup(
+ new URL[] {
+ getClass().getClassLoader().getResource(
+ "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/core/resources/mf-layer.xml"), // for MIMEResolverImpl to work
+ },
+ getWorkDir(),
+ new Object[] {},
+ getClass().getClassLoader()
+ );
+
+ // This is here to initialize Nb URL factory (org.netbeans.core.startup),
+ // which is needed by Nb EntityCatalog (org.netbeans.core).
+ // Also see the test dependencies in project.xml
+ Main.initializeURLFactory();
+ }
+
+ public void testOsSpecificFiles() throws Exception {
+ String currentOs = getCurrentOsId();
+ String [] files = new String [] {
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/f.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/e.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/d.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/a.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/file4.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/file1.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/file99.xml",
+ };
+
+ createOrderedFiles(files, FC_CONTENTS);
+
+ FileObject f = Repository.getDefault().getDefaultFileSystem().findResource("Editors/text/x-whatever/FontsColors/PPP/Defaults/e.xml");
+ f.setAttribute("nbeditor-settings-targetOS", currentOs);
+
+ String [] osOrderedFiles = new String [] {
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/f.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/d.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/a.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/Defaults/e.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/file4.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/file1.xml",
+ "Editors/text/x-whatever/FontsColors/PPP/file99.xml",
+ };
+
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors");
+ Map> results = new HashMap>();
+ SettingsType.FONTSCOLORS.getLocator().scan(baseFolder, "text/x-whatever", null, true, true, true, results);
+
+ assertNotNull("Scan results should not null", results);
+ assertEquals("Wrong number of profiles", 1, results.size());
+
+ List profileFiles = results.get("PPP");
+ checkProfileFiles(osOrderedFiles, null, profileFiles, "PPP");
+ }
+
+ public void testFullLayout() throws Exception {
+ String [] files1 = new String [] {
+ "Editors/text/x-whatever/FontsColors/MyProfileA/Defaults/file1.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfileA/Defaults/file2.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfileA/Defaults/file3.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfileA/Defaults/file4.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfileA/file1.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfileA/file2.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfileA/file3.xml",
+ };
+
+ String [] files2 = new String [] {
+ "Editors/text/x-whatever/FontsColors/MyProfile2/Defaults/xyz.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfile2/Defaults/abc.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfile2/mrkev.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfile2/okurka.xml",
+ "Editors/text/x-whatever/FontsColors/MyProfile2/cibule.xml",
+ };
+
+ createOrderedFiles(files1, FC_CONTENTS);
+ TestUtilities.createFile("Editors/text/x-whatever/FontsColors/MyProfileA/org-netbeans-modules-editor-settings-CustomFontsColors.xml", FC_CONTENTS);
+ createOrderedFiles(files2, FC_CONTENTS);
+ TestUtilities.createFile("Editors/text/x-whatever/FontsColors/MyProfile2/org-netbeans-modules-editor-settings-CustomFontsColors.xml", FC_CONTENTS);
+
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors");
+ Map> results = new HashMap>();
+ SettingsType.FONTSCOLORS.getLocator().scan(baseFolder, "text/x-whatever", null, true, true, true, results);
+
+ assertNotNull("Scan results should not null", results);
+ assertEquals("Wrong number of profiles", 2, results.size());
+
+ List profileAFiles = results.get("MyProfileA");
+ checkProfileFiles(files1, "Editors/text/x-whatever/FontsColors/MyProfileA/org-netbeans-modules-editor-settings-CustomFontsColors.xml", profileAFiles, "ProfileA");
+
+ List profile2Files = results.get("MyProfile2");
+ checkProfileFiles(files2, "Editors/text/x-whatever/FontsColors/MyProfile2/org-netbeans-modules-editor-settings-CustomFontsColors.xml", profile2Files, "ProfileA");
+ }
+
+ public void testFullFontsColorsLegacyLayout() throws Exception {
+ String [] files = new String [] {
+ "Editors/NetBeans/Defaults/defaultColoring.xml",
+ "Editors/NetBeans/Defaults/coloring.xml",
+ "Editors/NetBeans/Defaults/editorColoring.xml",
+ "Editors/NetBeans/coloring.xml",
+ "Editors/NetBeans/editorColoring.xml",
+ };
+
+ createOrderedFiles(files, FC_CONTENTS);
+
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors");
+ Map> results = new HashMap>();
+ SettingsType.FONTSCOLORS.getLocator().scan(baseFolder, null, null, true, true, true, results);
+
+ assertNotNull("Scan results should not null", results);
+ assertEquals("Wrong number of profiles", 1, results.size());
+
+ List profileFiles = results.get("NetBeans");
+ checkProfileFiles(files, null, profileFiles, "NetBeans");
+ }
+
+ public void testFullFontsColorsMixedLayout() throws Exception {
+ String [] files = new String [] {
+ "Editors/text/x-whatever/NetBeans/Defaults/defaultColoring.xml",
+ "Editors/text/x-whatever/NetBeans/Defaults/coloring.xml",
+ "Editors/text/x-whatever/NetBeans/Defaults/editorColoring.xml",
+ "Editors/text/x-whatever/FontsColors/NetBeans/Defaults/file1.xml",
+ "Editors/text/x-whatever/FontsColors/NetBeans/Defaults/file2.xml",
+ "Editors/text/x-whatever/FontsColors/NetBeans/Defaults/file3.xml",
+ "Editors/text/x-whatever/FontsColors/NetBeans/Defaults/file4.xml",
+ "Editors/text/x-whatever/NetBeans/coloring.xml",
+ "Editors/text/x-whatever/NetBeans/editorColoring.xml",
+ "Editors/text/x-whatever/FontsColors/NetBeans/file1.xml",
+ "Editors/text/x-whatever/FontsColors/NetBeans/file2.xml",
+ "Editors/text/x-whatever/FontsColors/NetBeans/file3.xml",
+ };
+
+ createOrderedFiles(files, FC_CONTENTS);
+ TestUtilities.createFile("Editors/text/x-whatever/FontsColors/NetBeans/org-netbeans-modules-editor-settings-CustomFontsColors.xml", FC_CONTENTS);
+
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors");
+ Map> results = new HashMap>();
+ SettingsType.FONTSCOLORS.getLocator().scan(baseFolder, "text/x-whatever", null, true, true, true, results);
+
+ assertNotNull("Scan results should not null", results);
+ assertEquals("Wrong number of profiles", 1, results.size());
+
+ List profileFiles = results.get("NetBeans");
+ checkProfileFiles(files, "Editors/text/x-whatever/FontsColors/NetBeans/org-netbeans-modules-editor-settings-CustomFontsColors.xml", profileFiles, "NetBeans");
+ }
+
+ public void testFullKeybindingsLegacyLayout() throws Exception {
+ String [] files = new String [] {
+ "Editors/text/base/Defaults/keybindings.xml",
+ "Editors/Keybindings/NetBeans/Defaults/zz.xml",
+ "Editors/Keybindings/NetBeans/Defaults/dd.xml",
+ "Editors/Keybindings/NetBeans/Defaults/kk.xml",
+ "Editors/Keybindings/NetBeans/Defaults/aa.xml",
+ "Editors/text/base/keybindings.xml",
+ "Editors/Keybindings/NetBeans/papap.xml",
+ "Editors/Keybindings/NetBeans/kekeke.xml",
+ "Editors/Keybindings/NetBeans/dhdhdddd.xml",
+ };
+
+ createOrderedFiles(files, KB_CONTENTS);
+ TestUtilities.createFile("Editors/Keybindings/NetBeans/org-netbeans-modules-editor-settings-CustomKeybindings.xml", KB_CONTENTS);
+
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors");
+ Map> results = new HashMap>();
+ SettingsType.KEYBINDINGS.getLocator().scan(baseFolder, null, null, true, true, true, results);
+
+ assertNotNull("Scan results should not null", results);
+ assertEquals("Wrong number of profiles", 1, results.size());
+
+ List profileFiles = results.get("NetBeans");
+ checkProfileFiles(files, "Editors/Keybindings/NetBeans/org-netbeans-modules-editor-settings-CustomKeybindings.xml", profileFiles, "NetBeans");
+ }
+
+ public void testFullKeybindingsMixedLayout() throws Exception {
+ String [] files = new String [] {
+ "Editors/text/base/Defaults/keybindings.xml",
+ "Editors/text/base/keybindings.xml",
+ };
+
+ createOrderedFiles(files, KB_CONTENTS);
+
+ FileObject baseFolder = Repository.getDefault().getDefaultFileSystem().findResource("Editors");
+ Map> results = new HashMap>();
+ SettingsType.KEYBINDINGS.getLocator().scan(baseFolder, null, null, true, true, true, results);
+
+ assertNotNull("Scan results should not null", results);
+ assertEquals("Wrong number of profiles", 1, results.size());
+
+ List profileFiles = results.get("NetBeans");
+ checkProfileFiles(files, null, profileFiles, "NetBeans");
+ }
+
+ private void checkProfileFiles(String [] paths, String writablePath, List files, String profileId) {
+ assertNotNull(profileId + ": No files", files);
+ assertEquals(profileId + ": Wrong number of files",
+ writablePath != null ? paths.length + 1 : paths.length, files.size());
+
+ for(int i = 0; i < paths.length; i++) {
+ FileObject profileHome = (FileObject) files.get(i)[0];
+ FileObject settingFile = (FileObject) files.get(i)[1];
+ boolean modulesFile = ((Boolean) files.get(i)[2]).booleanValue();
+
+ assertEquals(profileId + ": wrong file", paths[i], settingFile.getPath());
+ }
+
+ if (writablePath != null) {
+ FileObject profileHome = (FileObject) files.get(paths.length)[0];
+ FileObject settingFile = (FileObject) files.get(paths.length)[1];
+ boolean modulesFile = ((Boolean) files.get(paths.length)[2]).booleanValue();
+
+ assertEquals(profileId + ": wrong writable file", writablePath, settingFile.getPath());
+ }
+ }
+
+ private void createOrderedFiles(String [] files, String contents) throws IOException {
+ for(int i = 0; i < files.length; i++) {
+ FileObject f = TestUtilities.createFile(files[i], contents);
+ if (i + 1 < files.length) {
+ String [] thisFile = getNameParts(files[i]);
+ String [] nextFile = getNameParts(files[i + 1]);
+
+ if (thisFile[0].equals(nextFile[0])) {
+ String ordering = thisFile[1] + "/" + nextFile[1];
+ f.getParent().setAttribute(ordering, Boolean.TRUE);
+ }
+ }
+ }
+ }
+
+ private String [] getNameParts(String path) {
+ int idx = path.lastIndexOf('/');
+ if (idx != -1) {
+ return new String [] { path.substring(0, idx), path.substring(idx + 1) };
+ } else {
+ return new String [] { "", path };
+ }
+ }
+
+ private String getCurrentOsId() {
+ int osId = Utilities.getOperatingSystem();
+ for(Field field : Utilities.class.getDeclaredFields()) {
+ try {
+ int value = field.getInt(null);
+ if (value == osId) {
+ return field.getName();
+ }
+ } catch (Exception e) {
+ // ignore
+ }
+ }
+ fail("Can't detect OS type ");
+ return null; // not reachable
+ }
+}
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/MimeTypesTrackerTest.java
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/MimeTypesTrackerTest.java
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/MimeTypesTrackerTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/MimeTypesTrackerTest.java 16 Mar 2007 03:05:24 -0000 1.1.2.2
@@ -0,0 +1,294 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.io.IOException;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+import java.util.TreeSet;
+import org.netbeans.junit.NbTestCase;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public class MimeTypesTrackerTest extends NbTestCase {
+
+ private static final String BASE = "Some/Folder/SomeWhere";
+
+ /** Creates a new instance of MimeTypesTrackerTest */
+ public MimeTypesTrackerTest(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ EditorTestLookup.setLookup(
+ new URL[] { },
+ getWorkDir(),
+ new Object[] {},
+ getClass().getClassLoader()
+ );
+ }
+
+ public void testBasic() throws Exception {
+ TestUtilities.createFolder(BASE + "/text/plain");
+ MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+ Collection mimeTypes = mtt.getMimeTypes();
+
+ assertNotNull("MimeTypes should not be null", mimeTypes);
+ assertEquals("Wrong # of recognized mime types", 1, mimeTypes.size());
+ assertEquals("Wrong mime type", "text/plain", mimeTypes.iterator().next());
+ }
+
+ public void testGC() throws Exception {
+ TestUtilities.createFolder(BASE + "/text/plain");
+ MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+ Collection mimeTypes = mtt.getMimeTypes();
+
+ assertNotNull("MimeTypes should not be null", mimeTypes);
+ assertEquals("Wrong # of recognized mime types", 1, mimeTypes.size());
+ assertEquals("Wrong mime type", "text/plain", mimeTypes.iterator().next());
+
+ WeakReference ref = new WeakReference(mtt);
+ mtt = null;
+ assertGC("Can't GC the tracker", ref);
+ }
+
+ public void testWellKnownMimeTypes() throws Exception {
+ // See http://www.iana.org/assignments/media-types/ for details
+ String [] mimeTypes = new String [] {
+ "application/pdf", //NOI18N
+ "audio/mpeg", //NOI18N
+ "image/jpeg", //NOI18N
+ "message/news", //NOI18N
+ "model/vrml", //NOI18N
+ "multipart/mixed", //NOI18N
+ "text/plain", //NOI18N
+ "video/mpeg" //NOI18N
+ };
+
+ for(String s : mimeTypes) {
+ TestUtilities.createFolder(BASE + "/" + s);
+ }
+
+ MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+ Collection recognized = mtt.getMimeTypes();
+
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", mimeTypes.length, recognized.size());
+ assertEquals("Wrong mime types", new TreeSet(Arrays.asList(mimeTypes)), new TreeSet(recognized));
+ }
+
+ public void testFoldersNotRecognized() throws IOException {
+ String [] mimeTypes = new String [] {
+ "NetBeans/Default", //NOI18N
+ "Default", //NOI18N
+ "KeyBindings/whatever", //NOI18N
+ "Toolbars/Default", //NOI18N
+ "SideBar/MySideBar", //NOI18N
+ };
+
+ for(String s : mimeTypes) {
+ TestUtilities.createFolder(BASE + "/" + s);
+ }
+
+ MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+ Collection recognized = mtt.getMimeTypes();
+
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+
+ public void testFilesNotRecognized() throws IOException {
+ TestUtilities.createFile(BASE + "/text/hello.xml");
+ TestUtilities.createFile(BASE + "/text");
+ TestUtilities.createFile(BASE + "/application/pdf");
+
+ MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+ Collection recognized = mtt.getMimeTypes();
+
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+
+ public void testRecognition() throws IOException {
+ final MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+
+ {
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+
+ {
+ TestUtilities.createFolder(BASE);
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+
+ {
+ TestUtilities.createFolder(BASE + "/text");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+
+ {
+ TestUtilities.createFolder(BASE + "/text/x-java");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 1, recognized.size());
+ assertEquals("Wrong mime type recognized", "text/x-java", recognized.iterator().next());
+ }
+
+ {
+ TestUtilities.delete(BASE + "/text/x-java");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+ {
+ TestUtilities.delete(BASE + "/text");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+ {
+ TestUtilities.delete(BASE);
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ }
+ }
+
+ public void testEvents() throws IOException {
+ final L listener = new L();
+ final MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+ mtt.addPropertyChangeListener(listener);
+
+ {
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ assertEquals("Wrong # of events fired", 0, listener.events);
+ }
+
+ {
+ TestUtilities.createFolder(BASE + "/text/x-java");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 1, recognized.size());
+ assertEquals("Wrong mime type recognized", "text/x-java", recognized.iterator().next());
+ assertEquals("Wrong # of events fired", 1, listener.events);
+ assertEquals("Wrong change event name", MimeTypesTracker.PROP_MIME_TYPES, listener.lastEventName);
+ assertTrue("Wrong change event old value", listener.lastEventOldValue instanceof Map);
+ assertEquals("Wrong change event old value contents", 0, ((Map) listener.lastEventOldValue).size());
+ assertTrue("Wrong change event new value", listener.lastEventNewValue instanceof Map);
+ assertEquals("Wrong change event new value contents", 1, ((Map) listener.lastEventNewValue).size());
+ assertEquals("Wrong change event new value mime type", "text/x-java", ((Map) listener.lastEventNewValue).keySet().iterator().next());
+ }
+
+ {
+ listener.reset();
+ TestUtilities.delete(BASE);
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ assertEquals("Wrong # of events fired", 1, listener.events);
+ assertEquals("Wrong change event name", MimeTypesTracker.PROP_MIME_TYPES, listener.lastEventName);
+ assertTrue("Wrong change event old value", listener.lastEventOldValue instanceof Map);
+ assertEquals("Wrong change event old value contents", 1, ((Map) listener.lastEventOldValue).size());
+ assertEquals("Wrong change event old value mime type", "text/x-java", ((Map) listener.lastEventOldValue).keySet().iterator().next());
+ assertTrue("Wrong change event new value", listener.lastEventNewValue instanceof Map);
+ assertEquals("Wrong change event new value contents", 0, ((Map) listener.lastEventNewValue).size());
+ }
+ }
+
+ public void testEvents2() throws IOException {
+ final L listener = new L();
+ final MimeTypesTracker mtt = new MimeTypesTracker(BASE, null);
+ mtt.addPropertyChangeListener(listener);
+
+ {
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 0, recognized.size());
+ assertEquals("Wrong # of events fired", 0, listener.events);
+ }
+
+ {
+ TestUtilities.createFolder(BASE + "/text/plain");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 1, recognized.size());
+ assertEquals("Wrong mime type recognized", "text/plain", recognized.iterator().next());
+ assertEquals("Wrong # of events fired", 1, listener.events);
+ }
+
+ {
+ listener.reset();
+ TestUtilities.createFolder(BASE + "/NetBeans");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 1, recognized.size());
+ assertEquals("Wrong mime type recognized", "text/plain", recognized.iterator().next());
+ assertEquals("Wrong # of events fired", 0, listener.events);
+ }
+
+ {
+ listener.reset();
+ TestUtilities.createFolder(BASE + "/text/plain/NetBeans");
+ Collection recognized = mtt.getMimeTypes();
+ assertNotNull("MimeTypes should not be null", recognized);
+ assertEquals("Wrong # of recognized mime types", 1, recognized.size());
+ assertEquals("Wrong mime type recognized", "text/plain", recognized.iterator().next());
+ assertEquals("Wrong # of events fired", 0, listener.events);
+ }
+ }
+
+ private static final class L implements PropertyChangeListener {
+ public int events;
+ public String lastEventName;
+ public Object lastEventOldValue;
+ public Object lastEventNewValue;
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ events++;
+ lastEventName = evt.getPropertyName();
+ lastEventOldValue = evt.getOldValue();
+ lastEventNewValue = evt.getNewValue();
+ }
+
+ public void reset() {
+ events = 0;
+ lastEventName = null;
+ lastEventOldValue = null;
+ lastEventNewValue = null;
+ }
+ }
+}
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/ProfilesTrackerTest.java
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/ProfilesTrackerTest.java
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/ProfilesTrackerTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/ProfilesTrackerTest.java 16 Mar 2007 03:05:25 -0000 1.1.2.5
@@ -0,0 +1,390 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.ref.WeakReference;
+import java.net.URL;
+import java.util.Map;
+import java.util.Set;
+import junit.framework.Test;
+import junit.framework.TestResult;
+import org.netbeans.core.startup.Main;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.junit.NbTestSuite;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.Repository;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public class ProfilesTrackerTest extends NbTestCase {
+
+ // This is also in Bundle.properties
+ private static final String BASE = "Xyz/XoX/abc";
+
+ // XXX: This is here just for junit to match the test names in the results properly
+ private SettingsType type = (SettingsType) Suite.ENV[0][2];
+ private String folder = (String) Suite.ENV[0][1];
+ private String contents = (String) Suite.ENV[0][0];
+
+ public static Test suite() {
+ return new Suite(ProfilesTrackerTest.class);
+ }
+
+ /** Creates a new instance of MimeTypesTrackerTest */
+ public ProfilesTrackerTest(String name) {
+ super(name);
+ }
+
+ private void setEnv(SettingsType type, String folder, String contents) {
+ this.type = type;
+ this.folder = folder;
+ this.contents = contents;
+ }
+
+ public String getName() {
+ return super.getName() + "(" + type + ")";
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ EditorTestLookup.setLookup(
+ new URL[] {
+ getClass().getClassLoader().getResource(
+ "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/core/resources/mf-layer.xml"), // for MIMEResolverImpl to work
+ },
+ getWorkDir(),
+ new Object[] {},
+ getClass().getClassLoader()
+ );
+
+ // This is here to initialize Nb URL factory (org.netbeans.core.startup),
+ // which is needed by Nb EntityCatalog (org.netbeans.core).
+ // Also see the test dependencies in project.xml
+ Main.initializeURLFactory();
+ }
+
+ protected void tearDown() {
+ assertGC("Perform GC", new WeakReference(new Object()));
+ }
+
+ public void testBasic() throws Exception {
+ TestUtilities.createFile(BASE + "/text/plain/" + folder + "/ProfileA/abc.xml", contents);
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+ Set profiles = pt.getProfilesDisplayNames();
+
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "ProfileA", profiles.iterator().next());
+ }
+
+ public void testBasicRoot() throws Exception {
+ TestUtilities.createFile(BASE + "/" + folder + "/ProfileA/abc.xml", contents);
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+ Set profiles = pt.getProfilesDisplayNames();
+
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "ProfileA", profiles.iterator().next());
+ }
+
+ public void testSeveralMimes() throws Exception {
+ TestUtilities.createFile(BASE + "/text/plain/" + folder + "/ProfileA/abc.xml", contents);
+ TestUtilities.createFile(BASE + "/text/x-java/" + folder + "/ProfileA/abc.xml", contents);
+ TestUtilities.createFile(BASE + "/text/xml/" + folder + "/ProfileA/abc.xml", contents);
+ TestUtilities.createFile(BASE + "/text/plain/" + folder + "/ProfileB/abc.xml", contents);
+ TestUtilities.createFile(BASE + "/text/xml/" + folder + "/ProfileB/abc.xml", contents);
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+ Set profiles = pt.getProfilesDisplayNames();
+
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 2, profiles.size());
+ assertTrue("No 'ProfileA'", profiles.contains("ProfileA"));
+ assertTrue("No 'ProfileB'", profiles.contains("ProfileB"));
+ }
+
+ public void testDisplayName() throws Exception {
+ TestUtilities.createFile(BASE + "/text/plain/" + folder + "/ProfileA/abc.xml", contents);
+ FileObject f = Repository.getDefault().getDefaultFileSystem().findResource(BASE + "/text/plain/" + folder + "/ProfileA");
+ f.setAttribute("SystemFileSystem.localizingBundle", "org.netbeans.modules.editor.settings.storage.Bundle");
+
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+ Set profiles = pt.getProfilesDisplayNames();
+
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "Nice Display Name Of Profile A", profiles.iterator().next());
+ }
+
+ public void testRollbackIndicator() throws Exception {
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+
+ {
+ TestUtilities.createFile(BASE + "/text/plain/" + folder + "/ProfileA/abc.xml", contents);
+ ProfilesTracker.ProfileDescription pd = pt.getProfileByDisplayName("ProfileA");
+ assertNotNull("ProfileDescription should not be null", pd);
+ assertFalse("Wrong isRollbackAllowed value", pd.isRollbackAllowed());
+ }
+
+ {
+ TestUtilities.createFile(BASE + "/text/plain/" + folder + "/ProfileA/Defaults/abc.xml", contents);
+ ProfilesTracker.ProfileDescription pd = pt.getProfileByDisplayName("ProfileA");
+ assertNotNull("ProfileDescription should not be null", pd);
+ assertTrue("Wrong isRollbackAllowed value", pd.isRollbackAllowed());
+ }
+ }
+
+ public void testGC() throws Exception {
+ TestUtilities.createFile(BASE + "/text/plain/" + folder + "/ProfileA/abc.xml", contents);
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+ Set profiles = pt.getProfilesDisplayNames();
+
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "ProfileA", profiles.iterator().next());
+
+ WeakReference ref = new WeakReference(pt);
+ pt = null;
+ assertGC("Can't GC the tracker", ref);
+ }
+
+ public void testRecognition() throws Exception {
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+
+ {
+ TestUtilities.createFolder(BASE);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ }
+ {
+ TestUtilities.createFolder(BASE + "/text");
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ }
+ {
+ TestUtilities.createFolder(BASE + "/text/x-jsp");
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ }
+ {
+ TestUtilities.createFolder(BASE + "/text/x-jsp/FontsColors");
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ }
+ {
+ TestUtilities.createFile(BASE + "/text/x-jsp/" + folder + "/MyProfile/abc.xml", contents);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "MyProfile", profiles.iterator().next());
+ }
+ }
+
+ public void testRecognition2() throws Exception {
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+
+ {
+ TestUtilities.createFile(BASE + "/text/x-jsp/" + folder + "/MyProfile/abc.xml", contents);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "MyProfile", profiles.iterator().next());
+ }
+ {
+ TestUtilities.delete(BASE + "/text/x-jsp/" + folder + "/MyProfile/abc.xml");
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ }
+ {
+ TestUtilities.createFile(BASE + "/text/x-jsp/" + folder + "/MyProfile/abc.xml", contents);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "MyProfile", profiles.iterator().next());
+ }
+ {
+ TestUtilities.delete(BASE);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ }
+ }
+
+ public void testEvents() throws Exception {
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+ L listener = new L();
+
+ pt.addPropertyChangeListener(listener);
+ {
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ assertEquals("Wrong # of events", 0, listener.events);
+ }
+
+ {
+ TestUtilities.createFile(BASE + "/text/x-jsp/" + folder + "/MyProfile/abc.xml", contents);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "MyProfile", profiles.iterator().next());
+ assertEquals("Wrong # of events", 1, listener.events);
+ assertEquals("Wrong change event name", ProfilesTracker.PROP_PROFILES, listener.lastEventName);
+ assertTrue("Wrong change event old value", listener.lastEventOldValue instanceof Map);
+ assertEquals("Wrong change event old value contents", 0, ((Map) listener.lastEventOldValue).size());
+ assertTrue("Wrong change event new value", listener.lastEventNewValue instanceof Map);
+ assertEquals("Wrong change event new value contents", 1, ((Map) listener.lastEventNewValue).size());
+ assertEquals("Wrong change event new value profile", "MyProfile", ((Map) listener.lastEventNewValue).keySet().iterator().next());
+ }
+
+ {
+ listener.reset();
+ TestUtilities.delete(BASE);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ assertEquals("Wrong # of events", 1, listener.events);
+ assertEquals("Wrong change event name", ProfilesTracker.PROP_PROFILES, listener.lastEventName);
+ assertTrue("Wrong change event old value", listener.lastEventOldValue instanceof Map);
+ assertEquals("Wrong change event old value contents", 1, ((Map) listener.lastEventOldValue).size());
+ assertEquals("Wrong change event new value profile", "MyProfile", ((Map) listener.lastEventOldValue).keySet().iterator().next());
+ assertTrue("Wrong change event new value", listener.lastEventNewValue instanceof Map);
+ assertEquals("Wrong change event new value contents", 0, ((Map) listener.lastEventNewValue).size());
+ }
+ }
+
+ public void testEventsRoot() throws Exception {
+ ProfilesTracker pt = new ProfilesTracker(type, new MimeTypesTracker(BASE, null));
+ L listener = new L();
+
+ pt.addPropertyChangeListener(listener);
+ {
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ assertEquals("Wrong # of events", 0, listener.events);
+ }
+
+ {
+ TestUtilities.createFile(BASE + "/" + folder + "/MyProfile/abc.xml", contents);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 1, profiles.size());
+ assertEquals("Wrong profile display name", "MyProfile", profiles.iterator().next());
+ assertEquals("Wrong # of events", 1, listener.events);
+ assertEquals("Wrong change event name", ProfilesTracker.PROP_PROFILES, listener.lastEventName);
+ assertTrue("Wrong change event old value", listener.lastEventOldValue instanceof Map);
+ assertEquals("Wrong change event old value contents", 0, ((Map) listener.lastEventOldValue).size());
+ assertTrue("Wrong change event new value", listener.lastEventNewValue instanceof Map);
+ assertEquals("Wrong change event new value contents", 1, ((Map) listener.lastEventNewValue).size());
+ assertEquals("Wrong change event new value profile", "MyProfile", ((Map) listener.lastEventNewValue).keySet().iterator().next());
+ }
+
+ {
+ listener.reset();
+ TestUtilities.delete(BASE);
+ Set profiles = pt.getProfilesDisplayNames();
+ assertNotNull("Profiles should not be null", profiles);
+ assertEquals("Wrong # of recognized profiles", 0, profiles.size());
+ assertEquals("Wrong # of events", 1, listener.events);
+ assertEquals("Wrong change event name", ProfilesTracker.PROP_PROFILES, listener.lastEventName);
+ assertTrue("Wrong change event old value", listener.lastEventOldValue instanceof Map);
+ assertEquals("Wrong change event old value contents", 1, ((Map) listener.lastEventOldValue).size());
+ assertEquals("Wrong change event new value profile", "MyProfile", ((Map) listener.lastEventOldValue).keySet().iterator().next());
+ assertTrue("Wrong change event new value", listener.lastEventNewValue instanceof Map);
+ assertEquals("Wrong change event new value contents", 0, ((Map) listener.lastEventNewValue).size());
+ }
+ }
+
+ private static final class L implements PropertyChangeListener {
+ public int events;
+ public String lastEventName;
+ public Object lastEventOldValue;
+ public Object lastEventNewValue;
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ events++;
+ lastEventName = evt.getPropertyName();
+ lastEventOldValue = evt.getOldValue();
+ lastEventNewValue = evt.getNewValue();
+ }
+
+ public void reset() {
+ events = 0;
+ lastEventName = null;
+ lastEventOldValue = null;
+ lastEventNewValue = null;
+ }
+ }
+
+ private static final class Suite extends NbTestSuite {
+
+ public static final Object [][] ENV = {
+ new Object [] {
+ "\n" +
+ "\n" +
+ " ",
+ "FontsColors",
+ SettingsType.FONTSCOLORS
+ },
+ new Object [] {
+ "\n" +
+ "\n" +
+ " ",
+ "Keybindings",
+ SettingsType.KEYBINDINGS
+ },
+ };
+
+ public Suite(Class klass) {
+ super(klass);
+ }
+
+ @Override
+ public void run(TestResult result) {
+ for(int i = 0; i < ENV.length; i++) {
+ String contents = (String) ENV[i][0];
+ String folder = (String) ENV[i][1];
+ SettingsType type = (SettingsType) ENV[i][2];
+
+ for(int j = 0; j < testCount(); j++) {
+ Test test = testAt(j);
+ if (test instanceof ProfilesTrackerTest) {
+ ((ProfilesTrackerTest) test).setEnv(type, folder, contents);
+ }
+ }
+
+ System.out.println("Running tests for: " + type);
+ super.run(result);
+ }
+ }
+ }
+}
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/SettingsProviderTest.java
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/SettingsProviderTest.java,v
retrieving revision 1.5
retrieving revision 1.3.2.2
diff -u -r1.5 -r1.3.2.2
--- editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/SettingsProviderTest.java 17 Jan 2007 04:09:01 -0000 1.5
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/SettingsProviderTest.java 10 Mar 2007 00:55:01 -0000 1.3.2.2
@@ -51,9 +51,11 @@
EditorTestLookup.setLookup(
new URL[] {
getClass().getClassLoader().getResource(
- "org/netbeans/modules/editor/settings/storage/test-layer.xml"),
+ "org/netbeans/modules/editor/settings/storage/test-layer.xml"),
getClass().getClassLoader().getResource(
- "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/core/resources/mf-layer.xml"), // for MIMEResolverImpl to work
},
getWorkDir(),
new Object[] {},
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/TestUtilities.java
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/TestUtilities.java
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/TestUtilities.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/TestUtilities.java 16 Mar 2007 01:18:55 -0000 1.1.2.2
@@ -0,0 +1,111 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.FileSystem;
+import org.openide.filesystems.Repository;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public final class TestUtilities {
+
+ /** Creates a new instance of TestUtilities */
+ private TestUtilities() {
+ }
+
+ public static FileObject createFile(String path) throws IOException {
+ return createFO(path, false, null);
+ }
+
+ public static FileObject createFile(String path, String contents) throws IOException {
+ return createFO(path, false, contents);
+ }
+
+ public static FileObject createFolder(String path) throws IOException {
+ return createFO(path, true, null);
+ }
+
+ private static FileObject createFO(final String path, final boolean folder, final String contents) throws IOException {
+ Repository rp = Repository.getDefault();
+ final FileSystem sfs = rp == null ? null : rp.getDefaultFileSystem();
+
+ if (sfs == null) {
+ throw new IOException("No system FS.");
+ }
+
+ final FileObject [] createdFo = new FileObject[1];
+ sfs.runAtomicAction(new FileSystem.AtomicAction() {
+ public void run() throws IOException {
+ FileObject fo = sfs.getRoot();
+ String [] pathElements = path.split("/", -1);
+ for (int i = 0; i < pathElements.length; i++ ) {
+ String elementName = pathElements[i];
+
+ if (elementName.length() == 0) {
+ continue;
+ }
+
+ FileObject f = fo.getFileObject(elementName);
+ if (f != null && f.isValid()) {
+ fo = f;
+ } else {
+ if (i + 1 < pathElements.length || folder) {
+ fo = fo.createFolder(elementName);
+ } else {
+ // The last element in the path should be a file
+ fo = fo.createData(elementName);
+ if (contents != null) {
+ OutputStream os = fo.getOutputStream();
+ try {
+ os.write(contents.getBytes());
+ } finally {
+ os.close();
+ }
+ }
+ }
+ }
+ }
+ createdFo[0] = fo;
+ }
+ });
+
+ return createdFo[0];
+ }
+
+ public static void delete(String path) throws IOException {
+ Repository rp = Repository.getDefault();
+ FileSystem sfs = rp == null ? null : rp.getDefaultFileSystem();
+
+ if (sfs == null) {
+ throw new IOException("No system FS.");
+ }
+
+ FileObject fo = sfs.findResource(path);
+ if (fo != null) {
+ fo.delete();
+ }
+ }
+
+}
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-2.xml
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-2.xml,v
retrieving revision 1.2
retrieving revision 1.2.4.1
diff -u -r1.2 -r1.2.4.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-3.xml
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-3.xml,v
retrieving revision 1.1
retrieving revision 1.1.8.1
diff -u -r1.1 -r1.1.8.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-4.xml
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-4.xml,v
retrieving revision 1.1
retrieving revision 1.1.8.1
diff -u -r1.1 -r1.1.8.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-5.xml
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-5.xml,v
retrieving revision 1.1
retrieving revision 1.1.6.1
diff -u -r1.1 -r1.1.6.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-all-languages.xml
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors-all-languages.xml,v
retrieving revision 1.2
retrieving revision 1.2.8.1
diff -u -r1.2 -r1.2.8.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors.xml
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fonts-and-colors.xml,v
retrieving revision 1.2
retrieving revision 1.1.6.1
diff -u -r1.2 -r1.1.6.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/test-layer.xml
===================================================================
RCS file: /cvs/editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/test-layer.xml,v
retrieving revision 1.5
retrieving revision 1.2.4.1
diff -u -r1.5 -r1.2.4.1
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/ColoringStorageTest.java
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/ColoringStorageTest.java
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/ColoringStorageTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/ColoringStorageTest.java 16 Mar 2007 02:54:26 -0000 1.1.2.2
@@ -0,0 +1,178 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage.fontscolors;
+
+import java.awt.Color;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Map;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.AttributeSet;
+import javax.swing.text.StyleConstants;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.editor.settings.AttributesUtilities;
+import org.netbeans.core.startup.Main;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.editor.settings.storage.ColoringStorage;
+import org.netbeans.modules.editor.settings.storage.EditorTestLookup;
+import org.netbeans.modules.editor.settings.storage.SettingsType;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.Repository;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public class ColoringStorageTest extends NbTestCase {
+
+ /** Creates a new instance of ColoringStorageTest */
+ public ColoringStorageTest(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ EditorTestLookup.setLookup(
+ new URL[] {
+ getClass().getClassLoader().getResource(
+ "org/netbeans/modules/editor/settings/storage/fontscolors/test-layer-ColoringStorageTest.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/core/resources/mf-layer.xml"), // for MIMEResolverImpl to work
+ },
+ getWorkDir(),
+ new Object[] {},
+ getClass().getClassLoader()
+ );
+
+ // This is here to initialize Nb URL factory (org.netbeans.core.startup),
+ // which is needed by Nb EntityCatalog (org.netbeans.core).
+ // Also see the test dependencies in project.xml
+ Main.initializeURLFactory();
+ }
+
+ public void testAllLanguages() {
+ Map colorings = ColoringStorage.loadColorings(MimePath.EMPTY, "MyProfileXyz", true, true); //NOI18N
+ assertNotNull("Colorings map should not be null", colorings);
+ assertEquals("Wrong number of colorings", 1, colorings.size());
+
+ AttributeSet c = colorings.get("test-all-languages-super-default");
+ assertNotNull("Should have test-all-languages-super-default coloring", c);
+ assertEquals("Wrong bgColor", new Color(0xABCDEF), c.getAttribute(StyleConstants.Background));
+ }
+
+ public void testAllLanguages2() {
+ Map colorings = ColoringStorage.loadColorings(MimePath.EMPTY, "MyProfileXyz", true, false); //NOI18N
+ assertNotNull("Colorings map should not be null", colorings);
+ assertEquals("Wrong number of colorings", 1, colorings.size());
+
+ AttributeSet c = colorings.get("test-all-languages-super-default");
+ assertNotNull("Should have test-all-languages-super-default coloring", c);
+ assertEquals("Wrong bgColor", new Color(0xABCDEF), c.getAttribute(StyleConstants.Background));
+ }
+
+ public void testAllLanguagesHighlights() {
+ Map colorings = ColoringStorage.loadColorings(MimePath.EMPTY, "MyProfileXyz", false, true); //NOI18N
+ assertNotNull("Colorings map should not be null", colorings);
+ assertEquals("Wrong number of colorings", 1, colorings.size());
+
+ AttributeSet c = colorings.get("test-text-limit-line");
+ assertNotNull("Should have test-text-limit-line coloring", c);
+ assertEquals("Wrong bgColor", new Color(0x010101), c.getAttribute(StyleConstants.Foreground));
+ }
+
+ public void testAllLanguagesHighlights2() {
+ Map colorings = ColoringStorage.loadColorings(MimePath.EMPTY, "MyProfileXyz", false, false); //NOI18N
+ assertNotNull("Colorings map should not be null", colorings);
+ assertEquals("Wrong number of colorings", 1, colorings.size());
+
+ AttributeSet c = colorings.get("test-text-limit-line");
+ assertNotNull("Should have test-text-limit-line coloring", c);
+ assertEquals("Wrong bgColor", new Color(0x010101), c.getAttribute(StyleConstants.Foreground));
+ }
+
+ public void testMultipleFiles() {
+ MimePath mimePath = MimePath.parse("text/x-type-A");
+ Map colorings = ColoringStorage.loadColorings(mimePath, "MyProfileXyz", true, false); //NOI18N
+ assertNotNull("Colorings map should not be null", colorings);
+ assertEquals("Wrong number of colorings", 3, colorings.size());
+
+ // Check coloring in module A only
+ {
+ AttributeSet c = colorings.get("module-A-coloring");
+ assertNotNull("Should have module-A-coloring coloring", c);
+ assertEquals("Wrong bgColor", new Color(0xAA0000), c.getAttribute(StyleConstants.Background));
+ }
+ {
+ // Check coloring in module B only
+ AttributeSet c = colorings.get("module-B-coloring");
+ assertNotNull("Should have module-B-coloring coloring", c);
+ assertEquals("Wrong bgColor", new Color(0xBB0000), c.getAttribute(StyleConstants.Background));
+ }
+ {
+ // Check shared coloring
+ AttributeSet c = colorings.get("both-modules-coloring");
+ assertNotNull("Should have both-modules-coloring coloring", c);
+ assertEquals("Wrong bgColor", new Color(0xAA0000), c.getAttribute(StyleConstants.Background));
+ assertEquals("Wrong foreColor", new Color(0x00BB00), c.getAttribute(StyleConstants.Foreground));
+ assertEquals("Wrong underline", new Color(0x0000BB), c.getAttribute(StyleConstants.Underline));
+ }
+ }
+
+ public void testDeleteFiles() {
+ MimePath mimePath = MimePath.parse("text/x-type-A");
+ ColoringStorage.deleteColorings(mimePath, "MyProfileXyz", true, true);
+
+ FileObject profileHome = Repository.getDefault().getDefaultFileSystem().findResource("Editors/text/x-type-A/FontsColors/MyProfileXyz/Defaults");
+ assertNotNull("Can't find profileHome", profileHome);
+
+ FileObject [] files = profileHome.getChildren();
+ assertEquals("There should be no files", 0, files.length);
+
+ Map colorings = ColoringStorage.loadColorings(mimePath, "MyProfileXyz", true, true); //NOI18N
+ assertNotNull("Colorings map should not be null", colorings);
+ assertEquals("There should be no colorings", 0, colorings.size());
+ }
+
+ public void testWriteColorings() {
+ final String name = "new-coloring";
+ final Color color = new Color(0x1F2F3F);
+ MimePath mimePath = MimePath.parse("text/x-type-A");
+ ArrayList newColorings = new ArrayList();
+ newColorings.add(AttributesUtilities.createImmutable(StyleConstants.Underline, color, StyleConstants.NameAttribute, name));
+
+ ColoringStorage.saveColorings(mimePath, "MyProfileXyz", true, false, newColorings);
+
+ FileObject settingFile = Repository.getDefault().getDefaultFileSystem().findResource("Editors/text/x-type-A/FontsColors/MyProfileXyz/org-netbeans-modules-editor-settings-CustomFontsColors.xml");
+ assertNotNull("Can't find custom settingFile", settingFile);
+ assertEquals("Wrong mime type", SettingsType.FONTSCOLORS.getMimeType(), settingFile.getMIMEType());
+
+ Map colorings = ColoringStorage.loadColorings(mimePath, "MyProfileXyz", true, false); //NOI18N
+ assertNotNull("Colorings map should not be null", colorings);
+ assertEquals("There should be no colorings", 4, colorings.size());
+
+ AttributeSet c = colorings.get(name);
+ assertNotNull("Should have " + name + " coloring", c);
+ assertEquals("Wrong underline", color, c.getAttribute(StyleConstants.Underline));
+ }
+
+}
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/highlight-colorings-all-languages.xml
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/highlight-colorings-all-languages.xml
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/highlight-colorings-all-languages.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/highlight-colorings-all-languages.xml 14 Mar 2007 08:09:21 -0000 1.1.2.1
@@ -0,0 +1,6 @@
+
+
+
+
+
+
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-A.xml
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-A.xml
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-A.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-A.xml 14 Mar 2007 08:09:21 -0000 1.1.2.1
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-B.xml
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-B.xml
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-B.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/module-B.xml 14 Mar 2007 08:09:23 -0000 1.1.2.1
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/test-layer-ColoringStorageTest.xml
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/test-layer-ColoringStorageTest.xml
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/test-layer-ColoringStorageTest.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/test-layer-ColoringStorageTest.xml 15 Mar 2007 21:46:30 -0000 1.1.2.2
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/token-colorings-all-languages.xml
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/token-colorings-all-languages.xml
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/token-colorings-all-languages.xml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/fontscolors/token-colorings-all-languages.xml 14 Mar 2007 08:09:22 -0000 1.1.2.1
@@ -0,0 +1,6 @@
+
+
+
+
+
+
Index: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/keybindings/KeybindingStorageTest.java
===================================================================
RCS file: editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/keybindings/KeybindingStorageTest.java
diff -N editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/keybindings/KeybindingStorageTest.java
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ editor/settings/storage/test/unit/src/org/netbeans/modules/editor/settings/storage/keybindings/KeybindingStorageTest.java 16 Mar 2007 02:54:22 -0000 1.1.2.1
@@ -0,0 +1,139 @@
+/*
+ * The contents of this file are subject to the terms of the Common Development
+ * and Distribution License (the License). You may not use this file except in
+ * compliance with the License.
+ *
+ * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
+ * or http://www.netbeans.org/cddl.txt.
+ *
+ * When distributing Covered Code, include this CDDL Header Notice in each file
+ * and include the License file at http://www.netbeans.org/cddl.txt.
+ * If applicable, add the following below the CDDL Header, with the fields
+ * enclosed by brackets [] replaced by your own identifying information:
+ * "Portions Copyrighted [year] [name of copyright owner]"
+ *
+ * The Original Software is NetBeans. The Initial Developer of the Original
+ * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
+ * Microsystems, Inc. All Rights Reserved.
+ */
+
+package org.netbeans.modules.editor.settings.storage.keybindings;
+
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import javax.swing.KeyStroke;
+import org.netbeans.api.editor.mimelookup.MimePath;
+import org.netbeans.api.editor.settings.MultiKeyBinding;
+import org.netbeans.core.startup.Main;
+import org.netbeans.junit.NbTestCase;
+import org.netbeans.modules.editor.settings.storage.EditorTestLookup;
+import org.netbeans.modules.editor.settings.storage.KeyMapsStorage;
+import org.netbeans.modules.editor.settings.storage.SettingsType;
+import org.openide.filesystems.FileObject;
+import org.openide.filesystems.Repository;
+import org.openide.util.Utilities;
+
+/**
+ *
+ * @author Vita Stejskal
+ */
+public class KeybindingStorageTest extends NbTestCase {
+
+ /** Creates a new instance of KeybindingsStorageTest */
+ public KeybindingStorageTest(String name) {
+ super(name);
+ }
+
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ EditorTestLookup.setLookup(
+ new URL[] {
+ getClass().getClassLoader().getResource(
+ "org/netbeans/modules/editor/settings/storage/keybindings/test-layer-KeybindingStorageTest.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/modules/editor/settings/storage/layer.xml"),
+ getClass().getClassLoader().getResource(
+ "org/netbeans/core/resources/mf-layer.xml"), // for MIMEResolverImpl to work
+ },
+ getWorkDir(),
+ new Object[] {},
+ getClass().getClassLoader()
+ );
+
+ // This is here to initialize Nb URL factory (org.netbeans.core.startup),
+ // which is needed by Nb EntityCatalog (org.netbeans.core).
+ // Also see the test dependencies in project.xml
+ Main.initializeURLFactory();
+ }
+
+ public void testAllLanguages() {
+ Map, MultiKeyBinding> keybindings = KeyMapsStorage.loadKeyMaps(MimePath.EMPTY, "MyProfileXyz", true); //NOI18N
+ assertNotNull("Keybindings map should not be null", keybindings);
+ assertEquals("Wrong number of keybindings", 1, keybindings.size());
+
+ checkMapConsistency(keybindings);
+
+ MultiKeyBinding mkb = keybindings.values().iterator().next();
+ assertNotNull("MultiKeyBinding should not be null", mkb);
+ assertEquals("Wrong action name", "test-action-all-languages-A", mkb.getActionName());
+ assertEquals("Wrong number of key strokes", 1, mkb.getKeyStrokeCount());
+ assertEquals("Wrong key stroke", Utilities.stringToKey("O-A"), mkb.getKeyStroke(0));
+ }
+
+ public void testMultipleFiles() {
+ MimePath mimePath = MimePath.parse("text/x-type-A");
+ Map, MultiKeyBinding> keybindings = KeyMapsStorage.loadKeyMaps(mimePath, "MyProfileXyz", true); //NOI18N
+ assertNotNull("Keybindings map should not be null", keybindings);
+ assertEquals("Wrong number of keybindings", 5, keybindings.size());
+
+ checkMapConsistency(keybindings);
+
+ checkKeybinding(keybindings, "test-action-1", "D-1 A");
+ checkKeybinding(keybindings, "test-action-2", "D-2 A");
+ checkKeybinding(keybindings, "test-action-2", "D-2 B");
+ checkKeybinding(keybindings, "test-action-4", "D-4 B");
+ checkKeybinding(keybindings, "test-action-5", "D-5 B");
+ }
+
+ public void testWriteKeybindings() {
+ // Create new keybindings
+ Collection newKeybindings = new ArrayList();
+ newKeybindings.add(new MultiKeyBinding(Utilities.stringToKeys("D-D D"), "the-super-action"));
+
+ // Create new removed keybindings
+ Set> newRemovedKeybindings = new HashSet>();
+ newRemovedKeybindings.add(Arrays.asList(Utilities.stringToKeys("O-A")));
+
+ KeyMapsStorage.saveKeyMaps(MimePath.EMPTY, "MyProfileXyz", false, newKeybindings, newRemovedKeybindings);
+
+ FileObject settingFile = Repository.getDefault().getDefaultFileSystem().findResource("Editors/Keybindings/MyProfileXyz/org-netbeans-modules-editor-settings-CustomKeybindings.xml");
+ assertNotNull("Can't find custom settingFile", settingFile);
+ assertEquals("Wrong mime type", SettingsType.KEYBINDINGS.getMimeType(), settingFile.getMIMEType());
+
+ Map, MultiKeyBinding> keybindings = KeyMapsStorage.loadKeyMaps(MimePath.EMPTY, "MyProfileXyz", false); //NOI18N
+ assertNotNull("Keybindings map should not be null", keybindings);
+ assertEquals("Wrong number of keybindings", 1, keybindings.size());
+ checkKeybinding(keybindings, "the-super-action", "D-D D");
+ }
+
+ private void checkMapConsistency(Map, MultiKeyBinding> keybindings) {
+ for(Collection keyStrokes : keybindings.keySet()) {
+ MultiKeyBinding mkb = keybindings.get(keyStrokes);
+ assertEquals("Inconsistent keystrokes", keyStrokes, mkb.getKeyStrokeList());
+ }
+ }
+
+ private void checkKeybinding(Map, MultiKeyBinding> keybindings, String actionName, String keyStroke) {
+ Collection