Source Code Cross Referenced for Settings.java in  » IDE-Netbeans » editor » org » netbeans » editor » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » editor » org.netbeans.editor 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:
0042:        package org.netbeans.editor;
0043:
0044:        import java.awt.Color;
0045:        import java.awt.Dimension;
0046:        import java.awt.Insets;
0047:        import java.lang.reflect.Method;
0048:        import java.util.Map;
0049:        import java.util.List;
0050:        import java.util.Iterator;
0051:        import java.util.HashMap;
0052:        import java.util.ArrayList;
0053:        import java.util.Arrays;
0054:        import java.util.Collection;
0055:        import java.util.Collections;
0056:        import java.util.HashSet;
0057:        import java.util.Set;
0058:        import java.util.StringTokenizer;
0059:        import java.util.WeakHashMap;
0060:        import java.util.logging.Level;
0061:        import java.util.logging.Logger;
0062:        import java.util.prefs.PreferenceChangeEvent;
0063:        import java.util.prefs.PreferenceChangeListener;
0064:        import java.util.prefs.Preferences;
0065:        import javax.swing.KeyStroke;
0066:        import javax.swing.text.AttributeSet;
0067:        import javax.swing.text.StyleConstants;
0068:        import org.netbeans.api.editor.mimelookup.MimeLookup;
0069:        import org.netbeans.api.editor.mimelookup.MimePath;
0070:        import org.netbeans.api.editor.settings.CodeTemplateDescription;
0071:        import org.netbeans.api.editor.settings.CodeTemplateSettings;
0072:        import org.netbeans.api.editor.settings.FontColorSettings;
0073:        import org.netbeans.api.editor.settings.KeyBindingSettings;
0074:        import org.openide.util.Lookup;
0075:        import org.openide.util.LookupEvent;
0076:        import org.openide.util.LookupListener;
0077:        import org.openide.util.RequestProcessor;
0078:        import org.openide.util.WeakListeners;
0079:
0080:        /**
0081:         * Configurable settings that editor uses. All the methods are static
0082:         * The editor is configurable mainly by using the following static
0083:         * method in Settings class:
0084:         *
0085:         *   org.netbeans.editor.Settings.setValue(Class kitClass, String settingName, Object newValue);
0086:         *
0087:         * kitClass - this is the class of the editor kit for which the setting is changed.
0088:         *   The current hierarchy of editor kits starts
0089:         *   with the <tt>org.netbeans.editor.BaseKit</tt> kit, the begining of the whole
0090:         *   kit hierarchy. There should be a different editor kit for each mime-type.
0091:         *
0092:         *   When the particular setting is not set foar a given kit, then the superclass of
0093:         *   the given kit class is retrieved and the search for the setting value is performed.
0094:         *   Example: If the java document calls Settings.getValue() to retrieve the value
0095:         *   for TAB_SIZE setting and it passes JavaKit.class as the kitClass
0096:         *   parameter and the setting has no value on this level, then the super class
0097:         *   of the JavaKit is retrieved (by using Class.getSuperclass() call) which is BaseKit
0098:         *   in this case and the search for the value of TAB_SIZE setting
0099:         *   is performed again. It is finished by reaching the null value for the kitClass.
0100:         *   The null value can be also used as the kitClass parameter value.
0101:         *   In a more general look not only the kit-class hierarchy could be used
0102:         *   in <tt>Settings</tt>. Any class inheritance hierarchy could be used here
0103:         *   having the null as the common root.
0104:         *
0105:         *   This way the inheritance of the setting values is guaranteed. By changing
0106:         *   the setting value on the BaseKit level (or even on the null level),
0107:         *   all the kit classes that don't
0108:         *   override the particular setting are affected.
0109:         *
0110:         * settingName - name of the setting to change. The base setting names
0111:         *   are defined as public String constants in <tt>SettingsNames</tt> class.
0112:         *   The additional packages that extend the basic editor functionality
0113:         *   can define additional setting names.
0114:         *
0115:         * newValue - new value for the setting. It must be always an object even
0116:         *   if the setting is logicaly the basic datatype such as int (java.lang.Integer
0117:         *   would be used in this case). A particular class types that can be used for
0118:         *   the value of the settings are documented for each setting.
0119:         *
0120:         * WARNING! Please read carefully the description for each option you're
0121:         *   going to change as you can make the editor stop working if you'll
0122:         *   change the setting in a wrong way.
0123:         *
0124:         * @author Miloslav Metelka
0125:         * @version 1.00
0126:         */
0127:
0128:        public class Settings {
0129:
0130:            private static final Logger LOG = Logger.getLogger(Settings.class
0131:                    .getName());
0132:            private static final boolean LOG_STACTRACES = Boolean
0133:                    .getBoolean(Settings.class.getName() + ".stacktraces"); //NOI18N
0134:
0135:            /** Core level used by the settings initializers. This is the level used
0136:             * for the base and ext editor packages initializers only.
0137:             */
0138:            public static final int CORE_LEVEL = 0;
0139:
0140:            /** System level used by the settings initializers. This is the (default)
0141:             * first level.
0142:             * It should be used by all the modules that install the new kits
0143:             * into the editor.
0144:             */
0145:            public static final int SYSTEM_LEVEL = 1;
0146:
0147:            /** Extension level used by the settings initializers. This is the second
0148:             * level. It should be used by all the modules that want to extend
0149:             * or modify the settings but they don't install their own kits.
0150:             * The example can be a module extending the popup menu of an existing
0151:             * kit.
0152:             */
0153:            public static final int EXTENSION_LEVEL = 2;
0154:
0155:            /** Option level used by the settings initializers. This is the third
0156:             * level. It should be used by the visual options created by the IDE.
0157:             */
0158:            public static final int OPTION_LEVEL = 3;
0159:
0160:            /** User level used by the settings initializers. This is the fourth level.
0161:             * All the initializers with this level will be called AFTER
0162:             * all the initializers at the system level. All the user custom
0163:             * initializers should be added at this level to guarantee
0164:             * they will overwrite the settings added by the system.
0165:             */
0166:            public static final int USER_LEVEL = 4;
0167:
0168:            /** List of Initializers */
0169:            private static final ArrayList initializerLists = new ArrayList();
0170:            private static long initializerListsVersion = 0;
0171:            private static List[] listsOfInitializers = null;
0172:            private static long listsOfInitializersVersion = -1;
0173:
0174:            /** Current initializer sorter. */
0175:            private static InitializerSorter currentInitializerSorter;
0176:
0177:            /** List of Filters */
0178:            private static final Filter[] NULL_FILTERS = new Filter[0];
0179:            private static final String FILTERS_LOCK = new String(
0180:                    "Settings.FILTERS_LOCK"); //NOI18N
0181:            private static volatile Filter[] filters = NULL_FILTERS;
0182:
0183:            /** [kit-class, map-of-settings] pairs */
0184:            private static final Map kit2Maps = new HashMap();
0185:
0186:            /** Support for firing change events */
0187:            private static final WeakEventListenerList listenerList = new WeakEventListenerList();
0188:
0189:            private static volatile int firingEnabled = 0;
0190:
0191:            /** Save repetitive creation of the empty maps using this variable.
0192:             * [kit-class, map-of-settings] pairs
0193:             */
0194:            private static final HashMap emptyMaps = new HashMap();
0195:
0196:            private static final RequestProcessor PROCESSOR = new RequestProcessor(
0197:                    "org.netbeans.editor.Settings.PROCESSOR"); //NOI18N
0198:            private static final RequestProcessor.Task RESET_TASK = PROCESSOR
0199:                    .create(new Runnable() {
0200:                        public void run() {
0201:                            synchronized (Settings.class) {
0202:                                kit2Maps.clear();
0203:                            }
0204:                            fireSettingsChange(null, null, null, null);
0205:                        }
0206:                    });
0207:
0208:            private Settings() {
0209:                // no instances allowed
0210:            }
0211:
0212:            /** Add the initializer at the system level and perform reset. */
0213:            public static void addInitializer(Initializer i) {
0214:                addInitializer(i, SYSTEM_LEVEL);
0215:                reset();
0216:            }
0217:
0218:            /** Add initializer instance to the list of current initializers.
0219:             * You can call reset() after adding the initializer to make sure
0220:             * it will update the current settings with its values.
0221:             * However all the changes
0222:             * that were made explicitly by calling setValue() will be lost
0223:             * in this case.
0224:             *
0225:             * @param i initializer to add to the current list of initializers
0226:             * @param level initializer level. It defines in which order
0227:             *  the initializers will be called. There are currently three levels
0228:             *  <tt>CORE_LEVEL</tt>, <tt>SYSTEM_LEVEL</tt> and <tt>USER_LEVEL</tt>.
0229:             *  It's guaranteed that initializers with the particular level
0230:             *  will be called in the order shown above.
0231:             *  The order of the initializers at the same
0232:             *  level is given by the order of their addition.
0233:             */
0234:            public static void addInitializer(Initializer i, int level) {
0235:                synchronized (initializerLists) {
0236:                    int size = initializerLists.size();
0237:                    for (int j = size; j <= level; j++) {
0238:                        initializerLists.add(new ArrayList());
0239:                    }
0240:                    ((List) initializerLists.get(level)).add(i);
0241:
0242:                    // Sort the initializers if there's a valid sorter
0243:                    if (currentInitializerSorter != null) {
0244:                        currentInitializerSorter.sort(initializerLists);
0245:                    }
0246:
0247:                    initializerListsVersion++;
0248:                }
0249:            }
0250:
0251:            /** Remove the initializer of the given name from all the levels
0252:             * where it occurs.
0253:             * @param name name of the initializer sorter to remove.
0254:             */
0255:            public static void removeInitializer(String name) {
0256:                synchronized (initializerLists) {
0257:                    Iterator itit = initializerLists.iterator();
0258:                    while (itit.hasNext()) {
0259:                        Iterator it = ((List) itit.next()).iterator();
0260:                        while (it.hasNext()) {
0261:                            if (name
0262:                                    .equals(((Initializer) it.next()).getName())) {
0263:                                it.remove();
0264:                            }
0265:                        }
0266:                    }
0267:
0268:                    // Sort the initializers if there's a valid sorter
0269:                    if (currentInitializerSorter != null) {
0270:                        currentInitializerSorter.sort(initializerLists);
0271:                    }
0272:
0273:                    initializerListsVersion++;
0274:                }
0275:            }
0276:
0277:            /** Get the current initializer sorter. */
0278:            public static InitializerSorter getInitializerSorter() {
0279:                synchronized (initializerLists) {
0280:                    return currentInitializerSorter;
0281:                }
0282:            }
0283:
0284:            /** Set the current initializer sorter. */
0285:            public static void setInitializerSorter(
0286:                    InitializerSorter initializerSorter) {
0287:                synchronized (initializerLists) {
0288:                    currentInitializerSorter = initializerSorter;
0289:                }
0290:            }
0291:
0292:            private static List[] getListsOfInitializers() {
0293:                synchronized (initializerLists) {
0294:                    if (listsOfInitializersVersion != initializerListsVersion) {
0295:                        List[] lists = (List[]) initializerLists
0296:                                .toArray(new List[initializerLists.size()]);
0297:
0298:                        // copy & immutize
0299:                        for (int i = 0; i < lists.length; i++) {
0300:                            lists[i] = Collections
0301:                                    .unmodifiableList(new ArrayList(lists[i]));
0302:                        }
0303:
0304:                        listsOfInitializers = lists;
0305:                        listsOfInitializersVersion = initializerListsVersion;
0306:                    }
0307:
0308:                    return listsOfInitializers;
0309:                }
0310:            }
0311:
0312:            /** Add filter instance to the list of current filters.
0313:             * If there are already existing editor components,
0314:             * and you want to apply the changes that this filter makes
0315:             * to these existing
0316:             * components, you can call reset(). However all the changes
0317:             * that were made explicitly by calling setValue() will be lost
0318:             * in this case.
0319:             *
0320:             * @param f filter to add to the list of the filters
0321:             */
0322:            public static void addFilter(Filter f) {
0323:                synchronized (FILTERS_LOCK) {
0324:                    if (filters.length == 0) {
0325:                        filters = new Filter[] { f };
0326:                    } else {
0327:                        Filter[] tmp = new Filter[filters.length + 1];
0328:                        System.arraycopy(filters, 0, tmp, 0, filters.length);
0329:                        tmp[filters.length] = f;
0330:
0331:                        filters = tmp;
0332:                    }
0333:                }
0334:            }
0335:
0336:            public static void removeFilter(Filter f) {
0337:                synchronized (FILTERS_LOCK) {
0338:                    if (filters.length == 0) {
0339:                        return;
0340:                    } else if (filters.length == 1 && filters[0] == f) {
0341:                        filters = NULL_FILTERS;
0342:                    } else {
0343:                        int idx = -1;
0344:                        for (int i = 0; i < filters.length; i++) {
0345:                            if (filters[i] == f) {
0346:                                idx = i;
0347:                                break;
0348:                            }
0349:                        }
0350:
0351:                        if (idx != -1) {
0352:                            Filter[] tmp = new Filter[filters.length - 1];
0353:                            System.arraycopy(filters, 0, tmp, 0, idx);
0354:                            if (idx < tmp.length) {
0355:                                System.arraycopy(filters, idx + 1, tmp, idx,
0356:                                        tmp.length - idx);
0357:                            }
0358:
0359:                            filters = tmp;
0360:                        }
0361:                    }
0362:                }
0363:            }
0364:
0365:            /** Get the value and evaluate the evaluators. */
0366:            public static Object getValue(Class kitClass, String settingName) {
0367:                return getValue(kitClass, settingName, true);
0368:            }
0369:
0370:            /** Get the property by searching the given kit class settings and if not
0371:             * found then the settings for super class and so on.
0372:             * @param kitClass editor kit class for which the value of setting should
0373:             *   be retrieved. The null can be used as the root of the whole hierarchy.
0374:             * @param settingName name of the setting for which the value should
0375:             *   be retrieved
0376:             * @return the value of the setting
0377:             */
0378:            public static Object getValue(Class kitClass, String settingName,
0379:                    boolean evaluateEvaluators) {
0380:                String mimeType = BaseKit.kitsTracker_FindMimeType(kitClass);
0381:                MimePath mimePath = mimeType == null ? MimePath.EMPTY
0382:                        : MimePath.parse(mimeType);
0383:
0384:                // Get the value
0385:                Object value = getValueEx(mimePath, kitClass, settingName,
0386:                        evaluateEvaluators);
0387:
0388:                // filter the value if necessary
0389:                Filter[] currentFilters = filters;
0390:                for (int i = 0; i < currentFilters.length; i++) {
0391:                    value = currentFilters[i].filterValue(kitClass,
0392:                            settingName, value);
0393:                }
0394:
0395:                return value;
0396:            }
0397:
0398:            private static Object getValueEx(MimePath mimePath, Class kitClass,
0399:                    String settingName, boolean evaluateEvaluators) {
0400:                Object value = null;
0401:                boolean hasValue = false;
0402:
0403:                // read the value according to the guessed type of the setting
0404:                if (settingName != null
0405:                        && SettingsNames.ABBREV_MAP.equals(settingName)) {
0406:                    Object abbrevsFromInitializers = getValueOld(kitClass,
0407:                            SettingsNames.ABBREV_MAP, true);
0408:                    Map<String, String> abbrevs = findCodeTemplates(mimePath);
0409:
0410:                    if (abbrevsFromInitializers instanceof  Map) {
0411:                        value = new HashMap((Map) abbrevsFromInitializers);
0412:                        ((Map) value).putAll(abbrevs);
0413:                    } else {
0414:                        value = abbrevs;
0415:                    }
0416:
0417:                    hasValue = true;
0418:                } else if (settingName != null
0419:                        && SettingsNames.KEY_BINDING_LIST.equals(settingName)) {
0420:                    Object keybindingsFromInitializers = getValueOld(kitClass,
0421:                            SettingsNames.KEY_BINDING_LIST, true);
0422:                    List<MultiKeyBinding> keybindings = findKeyBindings(mimePath);
0423:
0424:                    if (keybindingsFromInitializers instanceof  List) {
0425:                        value = new ArrayList(
0426:                                (List) keybindingsFromInitializers);
0427:                        ((List) value).addAll(keybindings);
0428:                    } else {
0429:                        value = keybindings;
0430:                    }
0431:
0432:                    hasValue = true;
0433:                } else if (settingName != null
0434:                        && SettingsNames.MACRO_MAP.equals(settingName)) {
0435:                    Object macrosFromInitializers = getValueOld(kitClass,
0436:                            SettingsNames.MACRO_MAP, true);
0437:                    Map<String, String> macros = findMacros(mimePath);
0438:
0439:                    if (macrosFromInitializers instanceof  Map) {
0440:                        value = new HashMap((Map) macrosFromInitializers);
0441:                        ((Map) value).putAll(macros);
0442:                    } else {
0443:                        value = macros;
0444:                    }
0445:
0446:                    hasValue = true;
0447:                } else {
0448:                    // Check if the requested setting is a coloring
0449:                    if (settingName != null
0450:                            && HIGHLIGHT_COLOR_NAMES.contains(settingName)) {
0451:                        value = findColor(settingName, mimePath);
0452:                        hasValue = true;
0453:                    } else if (settingName != null
0454:                            && HIGHLIGHT_COLORING_NAMES.contains(settingName)) {
0455:                        value = findColoring(settingName, mimePath, false, true);
0456:                        hasValue = true;
0457:                    } else {
0458:                        String coloringName = translateOldTokenColoringName(settingName);
0459:                        if (coloringName != null) {
0460:                            value = findColoring(coloringName, mimePath, true,
0461:                                    true);
0462:                            hasValue = true;
0463:                        }
0464:                    }
0465:
0466:                    // Try getting it from editor Preferences
0467:                    if (!hasValue) {
0468:                        Preferences prefs = findPreferences(mimePath);
0469:
0470:                        // check if there is actually some value
0471:                        if (prefs != null
0472:                                && null != prefs.get(settingName, null)) {
0473:                            // try guessing the type
0474:                            Class type = null;
0475:                            String javaType = prefs.get(JAVATYPE_KEY_PREFIX
0476:                                    + settingName, null);
0477:                            if (javaType != null) {
0478:                                type = typeFromString(javaType);
0479:                            }
0480:
0481:                            if (type != null) {
0482:                                if (type.equals(Boolean.class)) {
0483:                                    value = prefs
0484:                                            .getBoolean(settingName, false);
0485:                                    hasValue = true;
0486:                                } else if (type.equals(Integer.class)) {
0487:                                    value = prefs.getInt(settingName, 0);
0488:                                    hasValue = true;
0489:                                } else if (type.equals(Long.class)) {
0490:                                    value = prefs.getLong(settingName, 0L);
0491:                                    hasValue = true;
0492:                                } else if (type.equals(Float.class)) {
0493:                                    value = prefs.getFloat(settingName, 0.0F);
0494:                                    hasValue = true;
0495:                                } else if (type.equals(Double.class)) {
0496:                                    value = prefs.getDouble(settingName, 0.0D);
0497:                                    hasValue = true;
0498:                                } else if (type.equals(Insets.class)) {
0499:                                    value = parseInsets(prefs.get(settingName,
0500:                                            null));
0501:                                    hasValue = true;
0502:                                } else if (type.equals(Dimension.class)) {
0503:                                    value = parseDimension(prefs.get(
0504:                                            settingName, null));
0505:                                    hasValue = true;
0506:                                } else if (type.equals(Color.class)) {
0507:                                    value = parseColor(prefs.get(settingName,
0508:                                            null));
0509:                                    hasValue = true;
0510:                                } else if (type.equals(String.class)) {
0511:                                    value = prefs.get(settingName, null);
0512:                                    hasValue = true;
0513:                                } else {
0514:                                    LOG
0515:                                            .log(
0516:                                                    Level.WARNING,
0517:                                                    "Can't load setting '"
0518:                                                            + settingName
0519:                                                            + "' with value '"
0520:                                                            + prefs
0521:                                                                    .get(
0522:                                                                            settingName,
0523:                                                                            null) //NOI18N
0524:                                                            + "' through org.netbeans.editor.Settings! Unsupported value conversion to "
0525:                                                            + type,
0526:                                                    new Throwable("Stacktrace")); //NOI18N
0527:                                }
0528:                            } else {
0529:                                // unknown setting type, treat it as String
0530:                                LOG
0531:                                        .warning("Can't determine type of '"
0532:                                                + settingName
0533:                                                + "' editor setting. If you supplied this setting" //NOI18N
0534:                                                + " through the editor implementation of java.util.prefs.Preferences you should use the 'javaType'" //NOI18N
0535:                                                + " attribute and specify the class representing values of this setting. There seem to be legacy" //NOI18N
0536:                                                + " clients accessing your setting through the old org.netbeans.editor.Settings."); //NOI18N
0537:                            }
0538:                        }
0539:                    }
0540:                }
0541:
0542:                // Fallback on to the kitmaps
0543:                if (!hasValue) {
0544:                    value = getValueOld(kitClass, settingName,
0545:                            evaluateEvaluators);
0546:                }
0547:
0548:                return value;
0549:            }
0550:
0551:            private static Object getValueOld(Class kitClass,
0552:                    String settingName, boolean evaluateEvaluators) {
0553:                Object value = null;
0554:                List allKitMaps = getAllKitMaps(kitClass);
0555:                assert allKitMaps.size() % 2 == 0 : "allKitMaps should contain pairs of [kitClass, settingsMap]."; //NOI18N
0556:
0557:                for (int i = 0; i < allKitMaps.size() / 2; i++) {
0558:                    Class kc = (Class) allKitMaps.get(2 * i);
0559:                    Map map = (Map) allKitMaps.get(2 * i + 1);
0560:                    value = map.get(settingName);
0561:                    if (evaluateEvaluators && value instanceof  Evaluator) {
0562:                        value = ((Evaluator) value).getValue(kc, settingName);
0563:                    }
0564:                    if (value != null) {
0565:                        break;
0566:                    }
0567:                }
0568:
0569:                return value;
0570:            }
0571:
0572:            /** Get the value hierarchy and evaluate the evaluators */
0573:            public static KitAndValue[] getValueHierarchy(Class kitClass,
0574:                    String settingName) {
0575:                return getValueHierarchy(kitClass, settingName, true);
0576:            }
0577:
0578:            /** Get array of KitAndValue objects sorted from the given kit class to its
0579:             * deepest superclass and the last member can be filled whether there
0580:             * is global setting (kit class of that member would be null).
0581:             * This method is useful for objects like keymaps that
0582:             * need to create all the parent keymaps to work properly.
0583:             * The method can either evaluate evaluators or leave them untouched
0584:             * which can become handy in some cases.
0585:             * @param kitClass editor kit class for which the value of setting should
0586:             *   be retrieved. The null can be used as the root of the whole hierarchy.
0587:             * @param settingName name of the setting for which the value should
0588:             *   be retrieved
0589:             * @param evaluateEvaluators whether the evaluators should be evaluated or not
0590:             * @return the array containing KitAndValue instances describing the particular
0591:             *   setting's value on the specific kit level.
0592:             */
0593:            public static KitAndValue[] getValueHierarchy(Class kitClass,
0594:                    String settingName, boolean evaluateEvaluators) {
0595:                ArrayList<KitAndValue> kavList = new ArrayList<KitAndValue>();
0596:
0597:                for (Class kc = kitClass; kc != null; kc = kc.getSuperclass()) {
0598:                    String mimeType = BaseKit.kitsTracker_FindMimeType(kc);
0599:                    MimePath mimePath = mimeType == null ? MimePath.EMPTY
0600:                            : MimePath.parse(mimeType);
0601:
0602:                    Object value = getValueEx(mimePath, kc, settingName,
0603:                            evaluateEvaluators);
0604:                    if (value != null) {
0605:                        kavList.add(new KitAndValue(kc, value));
0606:                    }
0607:
0608:                    if (mimePath == MimePath.EMPTY) {
0609:                        break;
0610:                    }
0611:                }
0612:
0613:                KitAndValue[] kavArray = kavList
0614:                        .toArray(new KitAndValue[kavList.size()]);
0615:
0616:                // filter the value if necessary
0617:                Filter[] currentFilters = filters;
0618:                for (int i = 0; i < currentFilters.length; i++) {
0619:                    kavArray = currentFilters[i].filterValueHierarchy(kitClass,
0620:                            settingName, kavArray);
0621:                }
0622:
0623:                return kavArray;
0624:            }
0625:
0626:            /** Set the new value for property on kit level. The old and new values
0627:             * are compared and if they are equal the setting is not changed and
0628:             * nothing is fired.
0629:             *
0630:             * @param kitClass editor kit class for which the value of setting should
0631:             *   be set. The null can be used as the root of the whole hierarchy.
0632:             * @param settingName the string used for searching the value
0633:             * @param newValue new value to set for the property; the value can
0634:             *   be null to clear the value for the specified kit
0635:             */
0636:            public static void setValue(Class kitClass, String settingName,
0637:                    Object newValue) {
0638:                if (settingName != null
0639:                        && SettingsNames.ABBREV_MAP.equals(settingName)) {
0640:                    LOG
0641:                            .log(
0642:                                    Level.WARNING,
0643:                                    "Can't save 'SettingsNames.ABBREV_MAP' setting through org.netbeans.editor.Settings!",
0644:                                    new Throwable("Stacktrace")); //NOI18N
0645:                } else if (settingName != null
0646:                        && SettingsNames.KEY_BINDING_LIST.equals(settingName)) {
0647:                    LOG
0648:                            .log(
0649:                                    Level.WARNING,
0650:                                    "Can't save 'SettingsNames.KEY_BINDING_LIST' setting through org.netbeans.editor.Settings!",
0651:                                    new Throwable("Stacktrace")); //NOI18N
0652:                } else if (settingName != null
0653:                        && SettingsNames.MACRO_MAP.equals(settingName)) {
0654:                    LOG
0655:                            .log(
0656:                                    Level.WARNING,
0657:                                    "Can't save 'SettingsNames.MACRO_MAP' setting through org.netbeans.editor.Settings!",
0658:                                    new Throwable("Stacktrace")); //NOI18N
0659:                } else {
0660:                    boolean coloring = false;
0661:
0662:                    // Check if the requested setting is a coloring
0663:                    if (settingName != null
0664:                            && HIGHLIGHT_COLOR_NAMES.contains(settingName)) {
0665:                        coloring = true;
0666:                    } else if (settingName != null
0667:                            && HIGHLIGHT_COLORING_NAMES.contains(settingName)) {
0668:                        coloring = true;
0669:                    } else {
0670:                        String coloringName = translateOldTokenColoringName(settingName);
0671:                        if (coloringName != null) {
0672:                            coloring = true;
0673:                        }
0674:                    }
0675:
0676:                    if (coloring) {
0677:                        LOG.log(Level.WARNING, "Can't save coloring '"
0678:                                + settingName
0679:                                + "' through org.netbeans.editor.Settings!",
0680:                                new Throwable("Stacktrace")); //NOI18N
0681:                    } else {
0682:                        boolean useKitMaps = false;
0683:                        String mimeType = BaseKit
0684:                                .kitsTracker_FindMimeType(kitClass);
0685:                        MimePath mimePath = mimeType == null ? MimePath.EMPTY
0686:                                : MimePath.parse(mimeType);
0687:                        Preferences prefs = findPreferences(mimePath);
0688:
0689:                        if (prefs != null) {
0690:                            if (newValue != null) {
0691:                                if (newValue instanceof  Boolean) {
0692:                                    prefs.putBoolean(settingName,
0693:                                            (Boolean) newValue);
0694:                                } else if (newValue instanceof  Integer) {
0695:                                    prefs.putInt(settingName,
0696:                                            (Integer) newValue);
0697:                                } else if (newValue instanceof  Long) {
0698:                                    prefs.putLong(settingName, (Long) newValue);
0699:                                } else if (newValue instanceof  Float) {
0700:                                    prefs.putFloat(settingName,
0701:                                            (Float) newValue);
0702:                                } else if (newValue instanceof  Double) {
0703:                                    prefs.putDouble(settingName,
0704:                                            (Double) newValue);
0705:                                } else if (newValue instanceof  Insets) {
0706:                                    prefs.put(settingName,
0707:                                            insetsToString((Insets) newValue));
0708:                                    prefs.put(
0709:                                            JAVATYPE_KEY_PREFIX + settingName,
0710:                                            Insets.class.getName());
0711:                                } else if (newValue instanceof  Dimension) {
0712:                                    prefs
0713:                                            .put(
0714:                                                    settingName,
0715:                                                    dimensionToString((Dimension) newValue));
0716:                                    prefs.put(
0717:                                            JAVATYPE_KEY_PREFIX + settingName,
0718:                                            Dimension.class.getName());
0719:                                } else if (newValue instanceof  Color) {
0720:                                    prefs.put(settingName,
0721:                                            color2String((Color) newValue));
0722:                                    prefs.put(
0723:                                            JAVATYPE_KEY_PREFIX + settingName,
0724:                                            Color.class.getName());
0725:                                } else if (newValue instanceof  String) {
0726:                                    prefs.put(settingName, (String) newValue);
0727:                                } else {
0728:                                    LOG
0729:                                            .log(
0730:                                                    Level.FINE,
0731:                                                    "Can't save setting '"
0732:                                                            + settingName
0733:                                                            + "' with value '"
0734:                                                            + newValue //NOI18N
0735:                                                            + "' through org.netbeans.editor.Settings; unsupported value conversion!",
0736:                                                    new Throwable("Stacktrace")); //NOI18N
0737:                                    useKitMaps = true;
0738:                                }
0739:                            } else {
0740:                                prefs.remove(settingName);
0741:                            }
0742:                        } else {
0743:                            useKitMaps = true;
0744:                        }
0745:
0746:                        if (useKitMaps) {
0747:                            // no prefs implementation, fall back on to the kit maps
0748:                            synchronized (Settings.class) {
0749:                                Map map = getKitMap(kitClass, true);
0750:                                Object oldValue = map.get(settingName);
0751:                                if (oldValue == null
0752:                                        && newValue == null
0753:                                        || (oldValue != null && oldValue
0754:                                                .equals(newValue))) {
0755:                                    return; // no change                    
0756:                                }
0757:                                if (newValue != null) {
0758:                                    map.put(settingName, newValue);
0759:                                } else {
0760:                                    map.remove(settingName);
0761:                                }
0762:                            }
0763:                        }
0764:                    }
0765:                }
0766:
0767:                fireSettingsChange(kitClass, settingName, null, newValue);
0768:            }
0769:
0770:            /** Don't change the value of the setting, but fire change
0771:             * event. This is useful when there's internal change in the value object
0772:             * of some setting.
0773:             */
0774:            public static void touchValue(Class kitClass, String settingName) {
0775:                fireSettingsChange(kitClass, settingName, null, null); // kit class currently not used
0776:            }
0777:
0778:            /** Set the value for the current kit and propagate it to all
0779:             * the children of the given kit by removing
0780:             * the possible values for the setting from the children kit setting maps.
0781:             * Note: This call only affects the settings for the kit classes for which
0782:             * the kit setting map with the setting values currently exists, i.e. when
0783:             * there was at least one getValue() or setValue() call performed for any
0784:             * setting on that particular kit class level. Other kit classes maps
0785:             * will be initialized by the particular initializer(s) as soon as
0786:             * the first getValue() or setValue() will be performed for them.
0787:             * However that future process will not be affected by the current
0788:             * propagateValue() call.
0789:             * This method is useful for the visual options that always set
0790:             * the value on all the kit levels without regard whether it's necessary or not.
0791:             * If the value is then changed for the base kit, it's not propagated
0792:             * naturally as there's a special setting
0793:             * This method enables
0794:             *
0795:             * The current implementation always fires the change regardless whether
0796:             * there was real change in setting value or not.
0797:             * @param kitClass editor kit class for which the value of setting should
0798:             *   be set.  The null can be used as the root of the whole hierarchy.
0799:             * @param settingName the string used for searching the value
0800:             * @param newValue new value to set for the property; the value can
0801:             *   be null to clear the value for the specified kit
0802:             */
0803:            public static void propagateValue(Class kitClass,
0804:                    String settingName, Object newValue) {
0805:                synchronized (Settings.class) {
0806:                    Map map = getKitMap(kitClass, true);
0807:                    if (newValue != null) {
0808:                        map.put(settingName, newValue);
0809:                    } else {
0810:                        map.remove(settingName);
0811:                    }
0812:                    // resolve kits
0813:                    Iterator it = kit2Maps.entrySet().iterator();
0814:                    while (it.hasNext()) {
0815:                        Map.Entry me = (Map.Entry) it.next();
0816:                        Class kc = (Class) me.getKey();
0817:                        if (kitClass != kc
0818:                                && (kitClass == null || kitClass
0819:                                        .isAssignableFrom(kc))) {
0820:                            ((Map) me.getValue()).remove(settingName);
0821:                        }
0822:                    }
0823:                }
0824:
0825:                fireSettingsChange(null, settingName, null, null);
0826:            }
0827:
0828:            /** Run the given runnable. All the changes in the settings are not fired until
0829:             * the whole runnable completes. Nesting of <tt>update()</tt> call is allowed.
0830:             * Only one firing is performed after the whole runnable completes
0831:             * using the 'null triple'.
0832:             */
0833:            public static void update(final Runnable r) {
0834:                // Just a backdoor for BaseOptions and OptionSupport to be able
0835:                // to serialize settings related tasks.
0836:                if (isAsyncTask(r)) {
0837:                    PROCESSOR.post(r, getTaskDelay(r));
0838:                } else {
0839:                    boolean fire = false;
0840:
0841:                    synchronized (Settings.class) {
0842:                        firingEnabled++;
0843:                        try {
0844:                            r.run();
0845:                        } finally {
0846:                            firingEnabled--;
0847:                            fire = firingEnabled == 0;
0848:                        }
0849:                    }
0850:
0851:                    if (fire) {
0852:                        fireSettingsChange(null, null, null, null);
0853:                    }
0854:                }
0855:            }
0856:
0857:            private static boolean isAsyncTask(Runnable r) {
0858:                try {
0859:                    Method m = r.getClass().getDeclaredMethod("asynchronous"); //NOI18N
0860:                    m.setAccessible(true);
0861:                    return (Boolean) m.invoke(r);
0862:                } catch (Exception e) {
0863:                    return false;
0864:                }
0865:            }
0866:
0867:            private static int getTaskDelay(Runnable r) {
0868:                try {
0869:                    Method m = r.getClass().getDeclaredMethod("delay"); //NOI18N
0870:                    m.setAccessible(true);
0871:                    return (Integer) m.invoke(r);
0872:                } catch (Exception e) {
0873:                    return 0;
0874:                }
0875:            }
0876:
0877:            /** Reset all the settings and fire the change of the settings
0878:             * so that all the listeners will be notified and will reload
0879:             * the settings.
0880:             * The settings that were changed using setValue() and propagateValue()
0881:             * are lost. Initializers will be asked for the settings values when
0882:             * necessary.
0883:             */
0884:            public static void reset() {
0885:                RESET_TASK.schedule(1);
0886:            }
0887:
0888:            /** Debug the current initializers */
0889:            public static String initializersToString() {
0890:                StringBuffer sb = new StringBuffer();
0891:                List[] lists = getListsOfInitializers();
0892:                for (int i = 0; i < lists.length; i++) {
0893:                    // debug the level
0894:                    switch (i) {
0895:                    case CORE_LEVEL:
0896:                        sb.append("CORE_LEVEL"); // NOI18N
0897:                        break;
0898:
0899:                    case SYSTEM_LEVEL:
0900:                        sb.append("SYSTEM_LEVEL"); // NOI18N
0901:                        break;
0902:
0903:                    case EXTENSION_LEVEL:
0904:                        sb.append("EXTENSION_LEVEL"); // NOI18N
0905:                        break;
0906:
0907:                    case OPTION_LEVEL:
0908:                        sb.append("OPTION_LEVEL"); // NOI18N
0909:                        break;
0910:
0911:                    case USER_LEVEL:
0912:                        sb.append("USER_LEVEL"); // NOI18N
0913:                        break;
0914:
0915:                    default:
0916:                        sb.append("level " + i); // NOI18N
0917:                        break;
0918:                    }
0919:                    sb.append(":\n"); // NOI18N
0920:
0921:                    // debug the initializers
0922:                    sb.append(EditorDebug.debugList((List) lists[i]));
0923:                    sb.append('\n'); //NOI18N
0924:                }
0925:
0926:                return sb.toString();
0927:            }
0928:
0929:            /** Add weak listener to listen to change of any property. The caller must
0930:             * hold the listener object in some instance variable to prevent it
0931:             * from being garbage collected.
0932:             */
0933:            public static void addSettingsChangeListener(
0934:                    SettingsChangeListener l) {
0935:                listenerList.add(SettingsChangeListener.class, l);
0936:            }
0937:
0938:            /** Remove listener for changes in properties */
0939:            public static void removeSettingsChangeListener(
0940:                    SettingsChangeListener l) {
0941:                listenerList.remove(SettingsChangeListener.class, l);
0942:            }
0943:
0944:            private static void fireSettingsChange(Class kitClass,
0945:                    String settingName, Object oldValue, Object newValue) {
0946:                if (firingEnabled == 0) {
0947:                    SettingsChangeListener[] listeners = (SettingsChangeListener[]) listenerList
0948:                            .getListeners(SettingsChangeListener.class);
0949:                    SettingsChangeEvent evt = new SettingsChangeEvent(
0950:                            Settings.class, kitClass, settingName, oldValue,
0951:                            newValue);
0952:                    for (int i = 0; i < listeners.length; i++) {
0953:                        listeners[i].settingsChange(evt);
0954:                    }
0955:                }
0956:            }
0957:
0958:            /** 
0959:             * Gets (and possibly creates) kit map for particular kit. This always runs
0960:             * under the Settings.class lock and because it calls initializers that
0961:             * can do whatever ever they like, it is important not to fire any events
0962:             * (eg. when an initializer calls setValue or something similar). See issue #118763.
0963:             */
0964:            private static Map getKitMap(Class kitClass, boolean forceCreation) {
0965:                firingEnabled++;
0966:                try {
0967:                    return getKitMapWithEvent(kitClass, forceCreation);
0968:                } finally {
0969:                    firingEnabled--;
0970:                }
0971:            }
0972:
0973:            private static Map getKitMapWithEvent(Class kitClass,
0974:                    boolean forceCreation) {
0975:                Map kitMap = (Map) kit2Maps.get(kitClass);
0976:                if (kitMap == null) {
0977:                    Map emptyMap = (Map) emptyMaps.get(kitClass);
0978:                    if (emptyMap != null) {
0979:                        // recursive initialization, return what we have collected so far
0980:                        return emptyMap;
0981:                    }
0982:
0983:                    if (emptyMap == null) {
0984:                        if (LOG.isLoggable(Level.FINE)) {
0985:                            emptyMap = new LoggingMap(kitClass, Level.FINE);
0986:                        } else {
0987:                            emptyMap = new HashMap();
0988:                        }
0989:                        emptyMaps.put(kitClass, emptyMap);
0990:                    }
0991:
0992:                    // Go through all the initializers
0993:                    List[] lists = getListsOfInitializers();
0994:                    for (int i = 0; i < lists.length; i++) {
0995:                        Iterator it = ((List) lists[i]).iterator();
0996:                        while (it.hasNext()) {
0997:                            Initializer initializer = (Initializer) it.next();
0998:
0999:                            // A call to initializer shouldn't break the whole updating
1000:                            try {
1001:                                initializer.updateSettingsMap(kitClass,
1002:                                        emptyMap);
1003:                            } catch (Throwable t) {
1004:                                LOG.log(Level.WARNING, null, t);
1005:                            }
1006:                        }
1007:                    }
1008:
1009:                    kitMap = emptyMap;
1010:
1011:                    kit2Maps.put(kitClass, kitMap);
1012:                    emptyMaps.remove(kitClass);
1013:                }
1014:
1015:                return kitMap;
1016:            }
1017:
1018:            private static List getAllKitMaps(Class kitClass) {
1019:                synchronized (Settings.class) {
1020:                    // Collect the kit classes that we need to ask for settings
1021:                    List<Class> classes = new ArrayList<Class>();
1022:                    for (Class kc = kitClass; kc != null; kc = kc
1023:                            .getSuperclass()) {
1024:                        classes.add(kc);
1025:                    }
1026:
1027:                    // Load the kit maps starting with BaseKit.class and going to kitClass.
1028:                    // This allows an initializer for a superclass to add more initializers
1029:                    // for subclasses. See for example NbEditorSettingsInitializer.updateSettingsMap.
1030:                    List list = new ArrayList();
1031:                    for (int i = classes.size() - 1; i >= 0; i--) {
1032:                        Class kc = classes.get(i);
1033:                        Map map = getKitMap(kc, false);
1034:                        if (map != null) {
1035:                            list.add(map);
1036:                            list.add(kc);
1037:                        }
1038:                    }
1039:
1040:                    Collections.reverse(list);
1041:                    return list;
1042:                }
1043:            }
1044:
1045:            /** Kit class and value pair */
1046:            public static class KitAndValue {
1047:
1048:                public Class kitClass;
1049:
1050:                public Object value;
1051:
1052:                public KitAndValue(Class kitClass, Object value) {
1053:                    this .kitClass = kitClass;
1054:                    this .value = value;
1055:                }
1056:
1057:            }
1058:
1059:            /** Initializer of the settings updates the map filled
1060:             * with settings for the particular kit class when asked.
1061:             * If the settings are being initialized all the initializers registered
1062:             * by the <tt>Settings.addInitializer()</tt> are being asked to update
1063:             * the settings-map through calling their <tt>updateSettingsMap()</tt>.
1064:             */
1065:            public static interface Initializer {
1066:
1067:                /** Each initializer must have a name. The name should be unique.
1068:                 * The name is used for identifying the initializer during removal
1069:                 * and sort operations and for debuging purposes.
1070:                 */
1071:                public String getName();
1072:
1073:                /** Update map filled with the settings.
1074:                 * @param kitClass kit class for which the settings are being updated.
1075:                 *    It can be null which means the root of the whole kit class hierarchy.
1076:                 * @param settingsMap map holding [setting-name, setting-value] pairs.
1077:                 *   The map can be empty if this is the first initializer
1078:                 *   that updates it or if no previous initializers updated it.
1079:                 */
1080:                public void updateSettingsMap(Class kitClass, Map settingsMap);
1081:
1082:            }
1083:
1084:            /** Abstract implementation of the initializer dealing with the name. */
1085:            public static abstract class AbstractInitializer implements 
1086:                    Initializer {
1087:
1088:                private String name;
1089:
1090:                public AbstractInitializer(String name) {
1091:                    this .name = name;
1092:                }
1093:
1094:                public String getName() {
1095:                    return name;
1096:                }
1097:
1098:                public @Override
1099:                String toString() {
1100:                    return getName();
1101:                }
1102:
1103:            } // End of AbstractInitializer class
1104:
1105:            /** Sort the settings initializers that were added to the settings.
1106:             * There can be only one sorter for the Settings, but it can delegate
1107:             * to previously registered sorter.
1108:             */
1109:            public static interface InitializerSorter {
1110:
1111:                public void sort(List initializersList);
1112:
1113:            }
1114:
1115:            /** Initializer sorter that delegates to another sorter. */
1116:            public static abstract class FilterInitializerSorter {
1117:
1118:                private InitializerSorter delegate;
1119:
1120:                public FilterInitializerSorter(InitializerSorter delegate) {
1121:                    this .delegate = delegate;
1122:                }
1123:
1124:                public void sort(List initializersList) {
1125:                    if (delegate != null) {
1126:                        delegate.sort(initializersList);
1127:                    }
1128:                }
1129:
1130:            }
1131:
1132:            /** Evaluator can be used in cases when value of some setting
1133:             * depends on the value for other setting and it allows to compute
1134:             * the value dynamically based on the other setting(s) value.
1135:             * The <tt>Evaluator</tt> instance can be used as the value
1136:             * in the <tt>Settings.setValue()</tt> call. In that case the call
1137:             * to the <tt>Settings.getValue()</tt> call will 'evaluate' the Evaluator
1138:             * by calling its <tt>getValue()</tt>.
1139:             */
1140:            public static interface Evaluator {
1141:
1142:                /** Compute the particular setting's value.
1143:                 * @param kitClass kit class for which the setting is being retrieved.
1144:                 * @param settingName name of the setting to retrieve. Although the Evaluator
1145:                 *   are usually constructed only for the concrete setting, this parameter
1146:                 *   allows creation of the Evaluator for multiple settings.
1147:                 * @return the value for the requested setting. The substitution
1148:                 *   is not attempted again, so the return value cannot be another
1149:                 *   Evaluator instance. If the returned value is null, the same
1150:                 *   action is taken as if there would no value set on the particular
1151:                 *   kit level.
1152:                 *
1153:                 */
1154:                public Object getValue(Class kitClass, String settingName);
1155:
1156:            }
1157:
1158:            /** Filter is applied on every value or KitAndValue pairs returned from getValue().
1159:             * The filter can be registered by calling <tt>Settings.addFilter()</tt>.
1160:             * Each call to <tt>Settings.getValue()</tt> will first retrieve the value and
1161:             * then call the <tt>Filter.filterValue()</tt> to get the final value. Each call
1162:             * to <tt>Settings.getValueHierarchy()</tt> will first retrieve the kit-and-value
1163:             * array and then call the <tt>Filter.filterValueHierarchy()</tt>.
1164:             * If more filters are registered they are all used in the order they were added.
1165:             */
1166:            public static interface Filter {
1167:
1168:                /** Filter single value. The value can be substituted here.
1169:                 * @param kitClass class of the kit for which the value is retrieved
1170:                 * @param settingName name of the retrieved setting
1171:                 * @param value value to be optionally filtered
1172:                 */
1173:                public Object filterValue(Class kitClass, String settingName,
1174:                        Object value);
1175:
1176:                /** Filter array of kit-class and value pairs. The pairs can be completely
1177:                 * substituted with an array with different length and different members.
1178:                 * @param kitClass class of the kit for which the value is retrieved
1179:                 * @param settingName name of the retrieved setting
1180:                 * @param kavArray kit-class and value array to be filtered
1181:                 */
1182:                public KitAndValue[] filterValueHierarchy(Class kitClass,
1183:                        String settingName, KitAndValue[] kavArray);
1184:
1185:            }
1186:
1187:            // This is just for debugging and should not normally be used.
1188:            private static final class LoggingMap extends HashMap {
1189:
1190:                private Class kitClass;
1191:                private Level logLevel;
1192:
1193:                private static final Set<String> DEPRECATED_SETTINGS = Collections
1194:                        .synchronizedSet(Collections
1195:                                .unmodifiableSet(new HashSet<String>(
1196:                                        Arrays
1197:                                                .asList(new String[] {
1198:                                                        // Fonts & Colors related settings
1199:                                                        SettingsNames.BLOCK_SEARCH_COLORING,
1200:                                                        SettingsNames.CARET_COLOR_INSERT_MODE,
1201:                                                        SettingsNames.CARET_COLOR_OVERWRITE_MODE,
1202:                                                        SettingsNames.CODE_FOLDING_COLORING,
1203:                                                        SettingsNames.COLORING_NAME_LIST,
1204:                                                        SettingsNames.COLORING_NAME_PRINT_SUFFIX,
1205:                                                        SettingsNames.COLORING_NAME_SUFFIX,
1206:                                                        SettingsNames.DEFAULT_COLORING,
1207:                                                        SettingsNames.GUARDED_COLORING,
1208:                                                        SettingsNames.HIGHLIGHT_SEARCH_COLORING,
1209:                                                        SettingsNames.INC_SEARCH_COLORING,
1210:                                                        SettingsNames.LINE_NUMBER_COLORING,
1211:                                                        SettingsNames.SELECTION_COLORING,
1212:                                                        SettingsNames.STATUS_BAR_BOLD_COLORING,
1213:                                                        SettingsNames.STATUS_BAR_COLORING,
1214:                                                        SettingsNames.TEXT_LIMIT_LINE_COLOR,
1215:
1216:                                                        // Keybindings related settings
1217:                                                        SettingsNames.KEY_BINDING_LIST, }))));
1218:
1219:                public LoggingMap(Class kitClass, Level logLevel) {
1220:                    super ();
1221:                    this .kitClass = kitClass;
1222:                    this .logLevel = logLevel;
1223:                }
1224:
1225:                public @Override
1226:                Object put(Object key, Object value) {
1227:                    if (key != null
1228:                            && (key.equals(SettingsNames.RENDERING_HINTS) || key
1229:                                    .equals("textAntialiasing") //NOI18N
1230:                            )) {
1231:                        String msg = "Settings map: put('" + key + "' to '"
1232:                                + value + "') for kitClass=" + kitClass; //NOI18N
1233:                        if (LOG_STACTRACES) {
1234:                            LOG.log(logLevel, null, new Throwable(msg));
1235:                        } else {
1236:                            LOG.log(logLevel, msg);
1237:                        }
1238:                    }
1239:
1240:                    logDeprecatedKey(key);
1241:                    return super .put(key, value);
1242:                }
1243:
1244:                public @Override
1245:                Object get(Object key) {
1246:                    logDeprecatedKey(key);
1247:                    return super .get(key);
1248:                }
1249:
1250:                public @Override
1251:                boolean containsKey(Object key) {
1252:                    logDeprecatedKey(key);
1253:                    return super .containsKey(key);
1254:                }
1255:
1256:                public @Override
1257:                Object remove(Object key) {
1258:                    logDeprecatedKey(key);
1259:                    return super .remove(key);
1260:                }
1261:
1262:                private void logDeprecatedKey(Object key) {
1263:                    if (LOG.isLoggable(logLevel)) {
1264:                        if (key != null && DEPRECATED_SETTINGS.contains(key)) {
1265:                            String msg = "The editor setting '"
1266:                                    + key
1267:                                    + "' is deprecated. Please use Editor Settings API instead."; //NOI18N
1268:                            if (LOG_STACTRACES) {
1269:                                LOG.log(logLevel, null, new Throwable(msg));
1270:                            } else {
1271:                                LOG.log(logLevel, msg);
1272:                            }
1273:                        }
1274:                    }
1275:                }
1276:            } // End of LoggingMap class
1277:
1278:            // ----------------------------------------------------------
1279:            // Fonts & Colors bridge to Editor Settings API
1280:            // ----------------------------------------------------------
1281:
1282:            private static final Map<MimePath, ChangesTrackingLookupResult<FontColorSettings>> FCS_CACHE = new WeakHashMap<MimePath, Settings.ChangesTrackingLookupResult<FontColorSettings>>();
1283:
1284:            private static final Set<String> HIGHLIGHT_COLOR_NAMES = new HashSet<String>();
1285:            private static final Set<String> HIGHLIGHT_COLORING_NAMES = new HashSet<String>();
1286:            static {
1287:                HIGHLIGHT_COLOR_NAMES
1288:                        .add(SettingsNames.CARET_COLOR_INSERT_MODE);
1289:                HIGHLIGHT_COLOR_NAMES
1290:                        .add(SettingsNames.CARET_COLOR_OVERWRITE_MODE);
1291:                HIGHLIGHT_COLOR_NAMES.add(SettingsNames.TEXT_LIMIT_LINE_COLOR);
1292:
1293:                HIGHLIGHT_COLORING_NAMES
1294:                        .add(SettingsNames.LINE_NUMBER_COLORING);
1295:                HIGHLIGHT_COLORING_NAMES.add(SettingsNames.GUARDED_COLORING);
1296:                HIGHLIGHT_COLORING_NAMES
1297:                        .add(SettingsNames.CODE_FOLDING_COLORING);
1298:                HIGHLIGHT_COLORING_NAMES
1299:                        .add(SettingsNames.CODE_FOLDING_BAR_COLORING);
1300:                HIGHLIGHT_COLORING_NAMES.add(SettingsNames.SELECTION_COLORING);
1301:                HIGHLIGHT_COLORING_NAMES
1302:                        .add(SettingsNames.HIGHLIGHT_SEARCH_COLORING);
1303:                HIGHLIGHT_COLORING_NAMES.add(SettingsNames.INC_SEARCH_COLORING);
1304:                HIGHLIGHT_COLORING_NAMES
1305:                        .add(SettingsNames.BLOCK_SEARCH_COLORING);
1306:                HIGHLIGHT_COLORING_NAMES.add(SettingsNames.STATUS_BAR_COLORING);
1307:                HIGHLIGHT_COLORING_NAMES
1308:                        .add(SettingsNames.STATUS_BAR_BOLD_COLORING);
1309:            }
1310:
1311:            private static Coloring findColoring(String coloringName,
1312:                    MimePath mimePath, boolean token, boolean highlight) {
1313:                AttributeSet attribs = findAttribs(coloringName, mimePath,
1314:                        token, highlight);
1315:                return attribs == null ? null : Coloring
1316:                        .fromAttributeSet(attribs);
1317:            }
1318:
1319:            private static Color findColor(String coloringName,
1320:                    MimePath mimePath) {
1321:                AttributeSet attribs = findAttribs(coloringName, mimePath,
1322:                        false, true);
1323:                return attribs == null ? null : (Color) attribs
1324:                        .getAttribute(StyleConstants.Foreground);
1325:            }
1326:
1327:            private static AttributeSet findAttribs(String coloringName,
1328:                    MimePath mimePath, boolean token, boolean highlight) {
1329:                synchronized (FCS_CACHE) {
1330:                    ChangesTrackingLookupResult<FontColorSettings> ctlr = FCS_CACHE
1331:                            .get(mimePath);
1332:
1333:                    if (ctlr == null) {
1334:                        Lookup.Result<FontColorSettings> lookupResult = MimeLookup
1335:                                .getLookup(mimePath).lookupResult(
1336:                                        FontColorSettings.class);
1337:                        ctlr = new ChangesTrackingLookupResult<FontColorSettings>(
1338:                                lookupResult, null);
1339:                        FCS_CACHE.put(mimePath, ctlr);
1340:                    }
1341:
1342:                    AttributeSet attribs = null;
1343:                    Collection<? extends FontColorSettings> allFcs = ctlr
1344:                            .getLookupResult().allInstances();
1345:                    FontColorSettings fcs = allFcs.isEmpty() ? null : allFcs
1346:                            .iterator().next();
1347:
1348:                    if (fcs != null) {
1349:                        if (token && !highlight) {
1350:                            attribs = fcs.getTokenFontColors(coloringName);
1351:                        } else if (!token && highlight) {
1352:                            attribs = fcs.getFontColors(coloringName);
1353:                        } else {
1354:                            attribs = fcs.getFontColors(coloringName);
1355:                            if (attribs == null) {
1356:                                attribs = fcs.getTokenFontColors(coloringName);
1357:                            }
1358:                        }
1359:                    }
1360:
1361:                    return attribs;
1362:                }
1363:            }
1364:
1365:            private static String translateOldTokenColoringName(String name) {
1366:                String translated = null;
1367:
1368:                if (name != null
1369:                        && name.endsWith(SettingsNames.COLORING_NAME_SUFFIX)) {
1370:                    translated = name.substring(0, name.length()
1371:                            - SettingsNames.COLORING_NAME_SUFFIX.length());
1372:                }
1373:
1374:                if (name != null
1375:                        && name
1376:                                .endsWith(SettingsNames.COLORING_NAME_PRINT_SUFFIX)) {
1377:                    translated = name
1378:                            .substring(0, name.length()
1379:                                    - SettingsNames.COLORING_NAME_PRINT_SUFFIX
1380:                                            .length());
1381:                }
1382:
1383:                return translated;
1384:            }
1385:
1386:            // ----------------------------------------------------------
1387:            // KeyBindings bridge to Editor Settings API
1388:            // ----------------------------------------------------------
1389:
1390:            private static final Map<MimePath, ChangesTrackingLookupResult<KeyBindingSettings>> KBS_CACHE = new WeakHashMap<MimePath, ChangesTrackingLookupResult<KeyBindingSettings>>();
1391:
1392:            private static List<MultiKeyBinding> findKeyBindings(
1393:                    MimePath mimePath) {
1394:                synchronized (KBS_CACHE) {
1395:                    ChangesTrackingLookupResult<KeyBindingSettings> ctlr = KBS_CACHE
1396:                            .get(mimePath);
1397:
1398:                    if (ctlr == null) {
1399:                        Lookup.Result<KeyBindingSettings> lookupResult = MimeLookup
1400:                                .getLookup(mimePath).lookupResult(
1401:                                        KeyBindingSettings.class);
1402:                        ctlr = new ChangesTrackingLookupResult<KeyBindingSettings>(
1403:                                lookupResult, SettingsNames.KEY_BINDING_LIST);
1404:                        KBS_CACHE.put(mimePath, ctlr);
1405:                    }
1406:
1407:                    @SuppressWarnings("unchecked")
1408:                    List<MultiKeyBinding> list = (List<MultiKeyBinding>) ctlr
1409:                            .getCustomData();
1410:                    if (list == null) {
1411:                        Collection<? extends KeyBindingSettings> allKbs = ctlr
1412:                                .getLookupResult().allInstances();
1413:                        KeyBindingSettings kbs = allKbs.isEmpty() ? null
1414:                                : allKbs.iterator().next();
1415:
1416:                        list = new ArrayList<MultiKeyBinding>();
1417:
1418:                        if (kbs != null) {
1419:                            for (org.netbeans.api.editor.settings.MultiKeyBinding mkb : kbs
1420:                                    .getKeyBindings()) {
1421:                                List<KeyStroke> keyStrokes = mkb
1422:                                        .getKeyStrokeList();
1423:                                list
1424:                                        .add(new MultiKeyBinding(
1425:                                                keyStrokes
1426:                                                        .toArray(new KeyStroke[keyStrokes
1427:                                                                .size()]), mkb
1428:                                                        .getActionName()));
1429:                            }
1430:
1431:                            ctlr.setCustomData(list);
1432:                        }
1433:                    }
1434:
1435:                    return list;
1436:                }
1437:            }
1438:
1439:            // ----------------------------------------------------------
1440:            // CodeTemplates bridge to Editor Settings API
1441:            // ----------------------------------------------------------
1442:
1443:            private static final Map<MimePath, ChangesTrackingLookupResult<CodeTemplateSettings>> CTS_CACHE = new WeakHashMap<MimePath, ChangesTrackingLookupResult<CodeTemplateSettings>>();
1444:
1445:            private static Map<String, String> findCodeTemplates(
1446:                    MimePath mimePath) {
1447:                synchronized (CTS_CACHE) {
1448:                    ChangesTrackingLookupResult<CodeTemplateSettings> ctlr = CTS_CACHE
1449:                            .get(mimePath);
1450:
1451:                    if (ctlr == null) {
1452:                        Lookup.Result<CodeTemplateSettings> lookupResult = MimeLookup
1453:                                .getLookup(mimePath).lookupResult(
1454:                                        CodeTemplateSettings.class);
1455:                        ctlr = new ChangesTrackingLookupResult<CodeTemplateSettings>(
1456:                                lookupResult, SettingsNames.ABBREV_MAP);
1457:                        CTS_CACHE.put(mimePath, ctlr);
1458:                    }
1459:
1460:                    @SuppressWarnings("unchecked")
1461:                    Map<String, String> map = (Map<String, String>) ctlr
1462:                            .getCustomData();
1463:                    if (map == null) {
1464:                        Collection<? extends CodeTemplateSettings> allCts = ctlr
1465:                                .getLookupResult().allInstances();
1466:                        CodeTemplateSettings cts = allCts.isEmpty() ? null
1467:                                : allCts.iterator().next();
1468:
1469:                        map = new HashMap<String, String>();
1470:
1471:                        if (cts != null) {
1472:                            for (CodeTemplateDescription ctd : cts
1473:                                    .getCodeTemplateDescriptions()) {
1474:                                map.put(ctd.getAbbreviation(), ctd
1475:                                        .getParametrizedText());
1476:                            }
1477:
1478:                            ctlr.setCustomData(map);
1479:                        }
1480:                    }
1481:
1482:                    return map;
1483:                }
1484:            }
1485:
1486:            private static final class ChangesTrackingLookupResult<T>
1487:                    implements  LookupListener {
1488:
1489:                private final Lookup.Result<T> lookupResult;
1490:                private final String settingName;
1491:                private Object customData = null;
1492:
1493:                public ChangesTrackingLookupResult(
1494:                        Lookup.Result<T> lookupResult, String settingName) {
1495:                    this .lookupResult = lookupResult;
1496:                    this .lookupResult.addLookupListener(WeakListeners.create(
1497:                            LookupListener.class, this , this .lookupResult));
1498:                    this .settingName = settingName;
1499:                }
1500:
1501:                public Lookup.Result<T> getLookupResult() {
1502:                    return lookupResult;
1503:                }
1504:
1505:                public Object getCustomData() {
1506:                    return customData;
1507:                }
1508:
1509:                public void setCustomData(Object data) {
1510:                    this .customData = data;
1511:                }
1512:
1513:                public void resultChanged(LookupEvent ev) {
1514:                    this .customData = null;
1515:                    fireSettingsChange(null, settingName, null, null);
1516:                }
1517:            } // End of TrackingResult class
1518:
1519:            // ----------------------------------------------------------
1520:            // Preferences bridge to Editor Settings API
1521:            // ----------------------------------------------------------
1522:
1523:            private static final Map<MimePath, PreferenceChangesTracker> PREFS_CACHE = new WeakHashMap<MimePath, PreferenceChangesTracker>();
1524:
1525:            private static Preferences findPreferences(MimePath mimePath) {
1526:                synchronized (PREFS_CACHE) {
1527:                    PreferenceChangesTracker tracker = PREFS_CACHE
1528:                            .get(mimePath);
1529:
1530:                    if (tracker == null) {
1531:                        Preferences prefs = MimeLookup.getLookup(mimePath)
1532:                                .lookup(Preferences.class);
1533:
1534:                        // in some tests there is no MimeLookup at all
1535:                        if (prefs != null) {
1536:                            tracker = new PreferenceChangesTracker(prefs);
1537:                            PREFS_CACHE.put(mimePath, tracker);
1538:                        }
1539:                    }
1540:
1541:                    return tracker == null ? null : tracker.getPreferences();
1542:                }
1543:            }
1544:
1545:            private static final class PreferenceChangesTracker implements 
1546:                    PreferenceChangeListener {
1547:                private final Preferences prefs;
1548:
1549:                public PreferenceChangesTracker(Preferences prefs) {
1550:                    this .prefs = prefs;
1551:                    this .prefs.addPreferenceChangeListener(WeakListeners
1552:                            .create(PreferenceChangeListener.class, this ,
1553:                                    this .prefs));
1554:                }
1555:
1556:                public Preferences getPreferences() {
1557:                    return prefs;
1558:                }
1559:
1560:                public void preferenceChange(PreferenceChangeEvent evt) {
1561:                    fireSettingsChange(null, evt.getKey(), null, null);
1562:                }
1563:            } // End of TrackingResult class
1564:
1565:            // ----------------------------------------------------------
1566:            // Macros to Editor Settings API
1567:            // ----------------------------------------------------------
1568:
1569:            // XXX: rewrite this to not use reflection. It will require dependency on editor/macros
1570:            // and editor/settings/storage. It should also listen on changes fired from EditorSettingsStorage
1571:            // and call fireSettingsChange(null, SettingsName.MACRO_MAP, null, null). Should be done
1572:            // after the Settings & co. is factored out to its own deprecated module so that we don't
1573:            // introduce additional dependencies in editor/lib.
1574:            private static Map<String, String> findMacros(MimePath mimePath) {
1575:                Map macros = new HashMap();
1576:
1577:                ClassLoader classLoader = Lookup.getDefault().lookup(
1578:                        ClassLoader.class);
1579:                try {
1580:                    Class essClass = classLoader
1581:                            .loadClass("org.netbeans.modules.editor.settings.storage.api.EditorSettingsStorage"); //NOI18N
1582:                    Method findMethod = essClass.getDeclaredMethod("find",
1583:                            String.class); //NOI18N
1584:                    Object macrosEss = findMethod.invoke(null, "Macros"); //NOI18N
1585:
1586:                    if (macrosEss != null) {
1587:                        Class mdClass = classLoader
1588:                                .loadClass("org.netbeans.modules.editor.macros.storage.MacroDescription"); //NOI18N
1589:                        Method getCodeMethod = mdClass
1590:                                .getDeclaredMethod("getCode"); //NOI18N
1591:
1592:                        Method loadMethod = essClass.getDeclaredMethod("load",
1593:                                MimePath.class, String.class, Boolean.TYPE); //NOI18N
1594:                        Map macroDescriptions = (Map) loadMethod.invoke(
1595:                                macrosEss, mimePath, null, false);
1596:                        for (Object key : macroDescriptions.keySet()) {
1597:                            String macroName = (String) key;
1598:                            Object macroDescription = macroDescriptions
1599:                                    .get(key);
1600:
1601:                            String macroCode = (String) getCodeMethod
1602:                                    .invoke(macroDescription);
1603:                            macros.put(macroName, macroCode);
1604:                        }
1605:                    }
1606:                } catch (Exception e) {
1607:                    // ignore
1608:                }
1609:
1610:                macros.put(null, findKeyBindings(mimePath));
1611:                return macros;
1612:            }
1613:
1614:            /** Coverts Insets to String representation */
1615:            private static String insetsToString(Insets ins) {
1616:                StringBuilder sb = new StringBuilder();
1617:                sb.append(ins.top);
1618:                sb.append(','); //NOI18N
1619:
1620:                sb.append(ins.left);
1621:                sb.append(','); //NOI18N
1622:
1623:                sb.append(ins.bottom);
1624:                sb.append(','); //NOI18N
1625:
1626:                sb.append(ins.right);
1627:
1628:                return sb.toString();
1629:            }
1630:
1631:            /** Converts textual representation of Insets */
1632:            private static Insets parseInsets(String s) {
1633:                StringTokenizer st = new StringTokenizer(s, ","); //NOI18N
1634:
1635:                int arr[] = new int[4];
1636:                int i = 0;
1637:                while (st.hasMoreElements()) {
1638:                    if (i > 3) {
1639:                        return null;
1640:                    }
1641:                    try {
1642:                        arr[i] = Integer.parseInt(st.nextToken());
1643:                    } catch (NumberFormatException nfe) {
1644:                        LOG.log(Level.WARNING, null, nfe);
1645:                        return null;
1646:                    }
1647:                    i++;
1648:                }
1649:                if (i != 4) {
1650:                    return null;
1651:                } else {
1652:                    return new Insets(arr[0], arr[1], arr[2], arr[3]);
1653:                }
1654:            }
1655:
1656:            private static String dimensionToString(Dimension dim) {
1657:                StringBuilder sb = new StringBuilder();
1658:                sb.append(dim.width);
1659:                sb.append(','); //NOI18N
1660:                sb.append(dim.height);
1661:                return sb.toString();
1662:            }
1663:
1664:            private static Dimension parseDimension(String s) {
1665:                StringTokenizer st = new StringTokenizer(s, ","); // NOI18N
1666:
1667:                int arr[] = new int[2];
1668:                int i = 0;
1669:                while (st.hasMoreElements()) {
1670:                    if (i > 1) {
1671:                        return null;
1672:                    }
1673:                    try {
1674:                        arr[i] = Integer.parseInt(st.nextToken());
1675:                    } catch (NumberFormatException nfe) {
1676:                        LOG.log(Level.WARNING, null, nfe);
1677:                        return null;
1678:                    }
1679:                    i++;
1680:                }
1681:                if (i != 2) {
1682:                    return null;
1683:                } else {
1684:                    return new Dimension(arr[0], arr[1]);
1685:                }
1686:            }
1687:
1688:            private static String wrap(String s) {
1689:                return (s.length() == 1) ? "0" + s : s; // NOI18N
1690:            }
1691:
1692:            /** Converts Color to hexadecimal String representation */
1693:            private static String color2String(Color c) {
1694:                StringBuilder sb = new StringBuilder();
1695:                sb.append('#'); // NOI18N
1696:                sb.append(wrap(Integer.toHexString(c.getRed()).toUpperCase()));
1697:                sb
1698:                        .append(wrap(Integer.toHexString(c.getGreen())
1699:                                .toUpperCase()));
1700:                sb.append(wrap(Integer.toHexString(c.getBlue()).toUpperCase()));
1701:                return sb.toString();
1702:            }
1703:
1704:            /** Converts a String to an integer and returns the specified opaque Color. */
1705:            private static Color parseColor(String s) {
1706:                try {
1707:                    return Color.decode(s);
1708:                } catch (NumberFormatException nfe) {
1709:                    LOG.log(Level.WARNING, null, nfe);
1710:                    return null;
1711:                }
1712:            }
1713:
1714:            //    private static final Map<String, Class> typesCache = new HashMap<String, Class>();
1715:            //    private static final class NO_TYPE {};
1716:            //    private static Class typeFromName(String settingName) {
1717:            //        synchronized (typesCache) {
1718:            //            Class settingType = typesCache.get(settingName);
1719:            //            
1720:            //            if (settingType == null) {
1721:            //                EditorSettingClass esc = null;
1722:            //
1723:            //                try {
1724:            //                    for (Field f : SettingsNames.class.getDeclaredFields()) {
1725:            //                        Object value;
1726:            //                        try {
1727:            //                            if ((f.getModifiers() & Modifier.STATIC) == Modifier.STATIC &&
1728:            //                                null != (value = f.get(null)) &&
1729:            //                                value.equals(settingName)
1730:            //                            ) {
1731:            //                                esc = f.getAnnotation(EditorSettingClass.class);
1732:            //                                break;
1733:            //                            }
1734:            //                        } catch (Exception e) {
1735:            //                            LOG.log(Level.FINE, null, e);
1736:            //                        }
1737:            //                    }
1738:            //                } catch (SecurityException se) {
1739:            //                    LOG.log(Level.FINE, null, se);
1740:            //                }
1741:            //                
1742:            //                settingType = esc == null ? NO_TYPE.class : esc.value();
1743:            //                typesCache.put(settingName, settingType);
1744:            //            }
1745:            //            
1746:            //            return settingType == NO_TYPE.class ? null : settingType;
1747:            //        }
1748:            //    }
1749:
1750:            private static final String JAVATYPE_KEY_PREFIX = "nbeditor-javaType-for-legacy-setting_"; //NOI18N
1751:
1752:            private static Class typeFromString(String javaType) {
1753:                try {
1754:                    ClassLoader classLoader = Lookup.getDefault().lookup(
1755:                            ClassLoader.class);
1756:                    return classLoader == null ? null : classLoader
1757:                            .loadClass(javaType);
1758:                } catch (ClassNotFoundException cnfe) {
1759:                    LOG.log(Level.WARNING, null, cnfe);
1760:                    return null;
1761:                }
1762:            }
1763:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.