001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.languages.features;
043:
044: import java.awt.Color;
045: import java.io.IOException;
046: import java.util.ArrayList;
047: import java.util.Collection;
048: import java.util.HashMap;
049: import java.util.Iterator;
050: import java.util.List;
051: import java.util.List;
052: import java.util.Map;
053: import java.util.Map;
054: import java.util.MissingResourceException;
055: import java.util.ResourceBundle;
056: import javax.swing.text.AttributeSet;
057: import javax.swing.text.Document;
058: import javax.swing.text.SimpleAttributeSet;
059: import javax.swing.text.StyleConstants;
060: import org.netbeans.api.editor.settings.EditorStyleConstants;
061: import org.netbeans.api.languages.ASTItem;
062: import org.netbeans.api.languages.ASTNode;
063: import org.netbeans.api.languages.ASTPath;
064: import org.netbeans.api.languages.Context;
065: import org.netbeans.api.languages.SyntaxContext;
066: import org.netbeans.api.languages.database.DatabaseContext;
067: import org.netbeans.api.languages.database.DatabaseUsage;
068: import org.netbeans.api.languages.database.DatabaseDefinition;
069: import org.netbeans.api.languages.database.DatabaseItem;
070: import org.netbeans.modules.editor.settings.storage.api.EditorSettings;
071: import org.netbeans.modules.editor.settings.storage.api.FontColorSettingsFactory;
072: import org.netbeans.modules.languages.Feature;
073: import org.netbeans.modules.languages.Language;
074: import org.netbeans.modules.languages.TokenType;
075: import org.openide.filesystems.FileObject;
076: import org.openide.filesystems.FileSystem;
077: import org.openide.filesystems.Repository;
078: import org.openide.util.NbBundle;
079:
080: /**
081: *
082: * @author Jan Jancura
083: */
084: public class ColorsManager {
085:
086: public static final String COLOR = "COLOR";
087:
088: static List<AttributeSet> getColors(Language l, ASTPath path,
089: Document doc) {
090: List<AttributeSet> result = new ArrayList<AttributeSet>();
091: Context context = SyntaxContext.create(doc, path);
092: List<Feature> fs = l.getFeatureList().getFeatures(COLOR, path);
093: Iterator<Feature> it = fs.iterator();
094: while (it.hasNext()) {
095: Feature f = it.next();
096: if (!f.getBoolean("condition", context, true))
097: continue;
098: result.add(createColoring(f, null));
099: }
100: ASTNode node = (ASTNode) path.getRoot();
101: DatabaseContext root = DatabaseManager.getRoot(node);
102: if (root == null)
103: return result;
104: ASTItem item = path.getLeaf();
105: DatabaseItem i = root.getDatabaseItem(item.getOffset());
106: if (i == null || i.getEndOffset() != item.getEndOffset())
107: return result;
108: AttributeSet as = getAttributes(i);
109: if (as != null)
110: result.add(as);
111: return result;
112: }
113:
114: private static AttributeSet getAttributes(DatabaseItem item) {
115: if (item instanceof DatabaseDefinition) {
116: DatabaseDefinition definition = (DatabaseDefinition) item;
117: if (definition.getUsages().isEmpty()) {
118: if ("parameter".equals(definition.getType()))
119: return getUnusedParameterAttributes();
120: if ("variable".equals(definition.getType()))
121: return getUnusedLocalVariableAttributes();
122: if ("field".equals(definition.getType()))
123: return getUnusedFieldAttributes();
124: } else {
125: if ("parameter".equals(definition.getType()))
126: return getParameterAttributes();
127: if ("variable".equals(definition.getType()))
128: return getLocalVariableAttributes();
129: if ("field".equals(definition.getType()))
130: return getFieldAttributes();
131: }
132: }
133: if (item instanceof DatabaseUsage) {
134: DatabaseUsage usage = (DatabaseUsage) item;
135: DatabaseDefinition definition = usage.getDefinition();
136: if ("parameter".equals(definition.getType()))
137: return getParameterAttributes();
138: if ("local".equals(definition.getType()))
139: return getLocalVariableAttributes();
140: if ("field".equals(definition.getType()))
141: return getFieldAttributes();
142: }
143: return null;
144: }
145:
146: private static AttributeSet unusedParameterAttributeSet;
147:
148: private static AttributeSet getUnusedParameterAttributes() {
149: if (unusedParameterAttributeSet == null) {
150: SimpleAttributeSet sas = new SimpleAttributeSet();
151: StyleConstants.setForeground(sas, new Color(115, 115, 115));
152: unusedParameterAttributeSet = sas;
153: }
154: return unusedParameterAttributeSet;
155: }
156:
157: private static AttributeSet parameterAttributeSet;
158:
159: private static AttributeSet getParameterAttributes() {
160: if (parameterAttributeSet == null) {
161: SimpleAttributeSet sas = new SimpleAttributeSet();
162: StyleConstants.setForeground(sas, new Color(160, 96, 1));
163: parameterAttributeSet = sas;
164: }
165: return parameterAttributeSet;
166: }
167:
168: private static AttributeSet unusedLocalVariableAttributeSet;
169:
170: private static AttributeSet getUnusedLocalVariableAttributes() {
171: if (unusedLocalVariableAttributeSet == null) {
172: SimpleAttributeSet sas = new SimpleAttributeSet();
173: StyleConstants.setForeground(sas, new Color(115, 115, 115));
174: unusedLocalVariableAttributeSet = sas;
175: }
176: return unusedLocalVariableAttributeSet;
177: }
178:
179: private static AttributeSet localVariableAttributeSet;
180:
181: private static AttributeSet getLocalVariableAttributes() {
182: if (localVariableAttributeSet == null) {
183: SimpleAttributeSet sas = new SimpleAttributeSet();
184: localVariableAttributeSet = sas;
185: }
186: return localVariableAttributeSet;
187: }
188:
189: private static AttributeSet unusedFieldAttributeSet;
190:
191: private static AttributeSet getUnusedFieldAttributes() {
192: if (unusedFieldAttributeSet == null) {
193: SimpleAttributeSet sas = new SimpleAttributeSet();
194: StyleConstants.setForeground(sas, new Color(115, 115, 115));
195: StyleConstants.setBold(sas, true);
196: unusedFieldAttributeSet = sas;
197: }
198: return unusedFieldAttributeSet;
199: }
200:
201: private static AttributeSet fieldAttributeSet;
202:
203: private static AttributeSet getFieldAttributes() {
204: if (fieldAttributeSet == null) {
205: SimpleAttributeSet sas = new SimpleAttributeSet();
206: StyleConstants.setForeground(sas, new Color(9, 134, 24));
207: StyleConstants.setBold(sas, true);
208: fieldAttributeSet = sas;
209: }
210: return fieldAttributeSet;
211: }
212:
213: public static void initColorings(Language l) {
214: FontColorSettingsFactory fcsf = EditorSettings.getDefault()
215: .getFontColorSettings(new String[] { l.getMimeType() });
216: if (!fcsf.getAllFontColors("NetBeans").isEmpty())
217: return;
218:
219: String bundleName = getBundleName(l);
220: ResourceBundle bundle = bundleName != null ? NbBundle
221: .getBundle(bundleName) : null;
222:
223: Map<String, AttributeSet> colorsMap = new HashMap<String, AttributeSet>();
224: Iterator<Language> it = l.getImportedLanguages().iterator();
225: while (it.hasNext())
226: addColors(colorsMap, it.next(), bundle);
227: addColors(colorsMap, l, bundle);
228: fcsf.setAllFontColorsDefaults("NetBeans", colorsMap.values());
229: fcsf.setAllFontColors("NetBeans", colorsMap.values());
230:
231: if (bundleName != null) {
232: FileSystem fs = Repository.getDefault()
233: .getDefaultFileSystem();
234: FileObject fo = fs
235: .findResource("Editors/"
236: + l.getMimeType()
237: + "/FontsColors/NetBeans/org-netbeans-modules-editor-settings-CustomFontsColors.xml"); // NOI18N
238: try {
239: if (fo != null) {
240: fo.setAttribute(
241: "SystemFileSystem.localizingBundle",
242: bundleName);
243: }
244: } catch (IOException e) {
245: }
246: fo = fs
247: .findResource("Editors/"
248: + l.getMimeType()
249: + "/FontsColors/NetBeans/Defaults/org-netbeans-modules-editor-settings-CustomFontsColors.xml"); // NOI18N
250: try {
251: if (fo != null) {
252: fo.setAttribute(
253: "SystemFileSystem.localizingBundle",
254: bundleName);
255: }
256: } catch (IOException e) {
257: }
258: }
259: }
260:
261: private static void addColors(Map<String, AttributeSet> colorsMap,
262: Language l, ResourceBundle bundle) {
263: if (l.getParser() == null)
264: return;
265: Map<String, AttributeSet> defaultsMap = getDefaultColors();
266: List<Feature> list = l.getFeatureList().getFeatures(COLOR);
267: Iterator<Feature> it = list.iterator();
268: while (it.hasNext()) {
269: Feature f = it.next();
270: AttributeSet as = createColoring(f, bundle);
271: colorsMap.put((String) as
272: .getAttribute(StyleConstants.NameAttribute), as);
273: }
274:
275: Iterator<TokenType> it2 = l.getParser().getTokenTypes()
276: .iterator();
277: while (it2.hasNext()) {
278: TokenType token = it2.next();
279: String type = token.getType();
280: if (colorsMap.containsKey(type))
281: continue;
282: SimpleAttributeSet sas = new SimpleAttributeSet();
283: sas.addAttribute(StyleConstants.NameAttribute, type);
284: String displayName = type;
285: if (bundle != null) {
286: try {
287: displayName = bundle.getString(type);
288: } catch (MissingResourceException e) {
289: }
290: }
291: sas.addAttribute(EditorStyleConstants.DisplayName,
292: displayName);
293: String def = type;
294: int i = def.lastIndexOf('_');
295: if (i > 0)
296: def = def.substring(i + 1);
297: if (defaultsMap.containsKey(def))
298: sas.addAttribute(EditorStyleConstants.Default, def);
299: colorsMap.put(type, sas);
300: }
301: }
302:
303: private static List<AttributeSet> getColors(Language l,
304: ResourceBundle bundle) {
305: List<Feature> list = l.getFeatureList().getFeatures("COLORS");
306: List<AttributeSet> result = new ArrayList<AttributeSet>();
307: Iterator<Feature> it = list.iterator();
308: while (it.hasNext()) {
309: Feature f = it.next();
310: result.add(createColoring(f, bundle));
311: }
312: return result;
313: }
314:
315: static SimpleAttributeSet createColoring(Feature f,
316: ResourceBundle bundle) {
317: String colorName = (String) f.getValue("color_name");
318: String displayName = null;
319: if (colorName == null)
320: colorName = f.getSelector().getAsString();
321: if (bundle != null) {
322: try {
323: displayName = bundle.getString(colorName);
324: } catch (MissingResourceException e) {
325: }
326: }
327: if (displayName == null) {
328: displayName = colorName;
329: }
330: return createColoring(colorName, displayName, (String) f
331: .getValue("default_coloring"), (String) f
332: .getValue("foreground_color"), (String) f
333: .getValue("background_color"), (String) f
334: .getValue("underline_color"), (String) f
335: .getValue("wave_underline_color"), (String) f
336: .getValue("strike_through_color"), (String) f
337: .getValue("font_name"), (String) f
338: .getValue("font_type"));
339: }
340:
341: private static SimpleAttributeSet createColoring(String colorName,
342: String displayName, String defaultColor, String foreground,
343: String background, String underline, String waveunderline,
344: String strikethrough, String fontName, String fontType) {
345: SimpleAttributeSet coloring = new SimpleAttributeSet();
346: coloring.addAttribute(StyleConstants.NameAttribute, colorName);
347: coloring.addAttribute(EditorStyleConstants.DisplayName,
348: displayName);
349: if (defaultColor != null)
350: coloring.addAttribute(EditorStyleConstants.Default,
351: defaultColor);
352: if (foreground != null)
353: coloring.addAttribute(StyleConstants.Foreground,
354: readColor(foreground));
355: if (background != null)
356: coloring.addAttribute(StyleConstants.Background,
357: readColor(background));
358: if (strikethrough != null)
359: coloring.addAttribute(StyleConstants.StrikeThrough,
360: readColor(strikethrough));
361: if (underline != null)
362: coloring.addAttribute(StyleConstants.Underline,
363: readColor(underline));
364: if (waveunderline != null)
365: coloring.addAttribute(
366: EditorStyleConstants.WaveUnderlineColor,
367: readColor(waveunderline));
368: if (fontName != null)
369: coloring.addAttribute(StyleConstants.FontFamily, fontName);
370: if (fontType != null) {
371: if (fontType.toLowerCase().indexOf("bold") >= 0)
372: coloring
373: .addAttribute(StyleConstants.Bold, Boolean.TRUE);
374: if (fontType.toLowerCase().indexOf("italic") >= 0)
375: coloring.addAttribute(StyleConstants.Italic,
376: Boolean.TRUE);
377: }
378: return coloring;
379: }
380:
381: private static Map<String, Color> colors = new HashMap<String, Color>();
382: static {
383: colors.put("black", Color.black);
384: colors.put("blue", Color.blue);
385: colors.put("cyan", Color.cyan);
386: colors.put("darkGray", Color.darkGray);
387: colors.put("gray", Color.gray);
388: colors.put("green", Color.green);
389: colors.put("lightGray", Color.lightGray);
390: colors.put("magenta", Color.magenta);
391: colors.put("orange", Color.orange);
392: colors.put("pink", Color.pink);
393: colors.put("red", Color.red);
394: colors.put("white", Color.white);
395: colors.put("yellow", Color.yellow);
396: }
397:
398: static Color readColor(String color) {
399: if (color == null)
400: return null;
401: Color result = (Color) colors.get(color);
402: if (result == null)
403: result = Color.decode(color);
404: return result;
405: }
406:
407: // public static Map<String,AttributeSet> getColorMap (Language l) {
408: // Map defaultsMap = getDefaultColors ();
409: // Map<String,AttributeSet> colorsMap = getCurrentColors (l);
410: // Iterator<TokenType> it = l.getTokenTypes ().iterator ();
411: // while (it.hasNext ()) {
412: // TokenType token = it.next ();
413: // List<SimpleAttributeSet> colors = (List<SimpleAttributeSet>) getFeature
414: // (Language.COLOR, token.getType ());
415: // if (colors != null)
416: // for (Iterator<SimpleAttributeSet> it2 = colors.iterator (); it2.hasNext ();) {
417: // SimpleAttributeSet as = it2.next();
418: // String id = (String) as.getAttribute ("color_name"); // NOI18N
419: // if (id == null)
420: // id = token.getType ();
421: // addColor (id, as, colorsMap, defaultsMap);
422: // }
423: // else
424: // addColor (token.getType (), null, colorsMap, defaultsMap);
425: // }
426: //
427: // //List<AttributeSet> colors = getColors (l);
428: // Map m = (Map) features.get (Language.COLOR);
429: // if (m == null)
430: // return Collections.<String,AttributeSet>emptyMap ();
431: // Iterator<String> it2 = m.keySet ().iterator ();
432: // while (it2.hasNext ()) {
433: // String type = it2.next ();
434: // if (colorsMap.containsKey (type))
435: // continue;
436: // Object obj = m.get (type);
437: // if (obj != null) {
438: // for (Iterator iter = ((List)obj).iterator(); iter.hasNext(); ) {
439: // SimpleAttributeSet as = (SimpleAttributeSet) iter.next();
440: // addColor (type, as, colorsMap, defaultsMap);
441: // }
442: // }
443: // }
444: // addColor ("error", null, colorsMap, defaultsMap);
445: // return colorsMap;
446: // }
447:
448: private static void addColor(String tokenType,
449: SimpleAttributeSet sas,
450: Map<String, AttributeSet> colorsMap,
451: Map<String, AttributeSet> defaultsMap) {
452: if (sas == null)
453: sas = new SimpleAttributeSet();
454: else
455: sas = new SimpleAttributeSet(sas);
456: String colorName = (String) sas
457: .getAttribute(StyleConstants.NameAttribute);
458: if (colorName == null)
459: colorName = tokenType;
460: sas.addAttribute(StyleConstants.NameAttribute, colorName);
461: sas.addAttribute(EditorStyleConstants.DisplayName, colorName);
462: if (!sas.isDefined(EditorStyleConstants.Default)) {
463: String def = colorName;
464: int i = def.lastIndexOf('_');
465: if (i > 0)
466: def = def.substring(i + 1);
467: if (defaultsMap.containsKey(def))
468: sas.addAttribute(EditorStyleConstants.Default, def);
469: }
470: colorsMap.put(colorName, sas);
471: }
472:
473: private static Map<String, AttributeSet> getDefaultColors() {
474: Collection<AttributeSet> defaults = EditorSettings.getDefault()
475: .getDefaultFontColorDefaults("NetBeans");
476: Map<String, AttributeSet> defaultsMap = new HashMap<String, AttributeSet>();
477: Iterator<AttributeSet> it = defaults.iterator(); // check if IDE Defaults module is installed
478: while (it.hasNext()) {
479: AttributeSet as = it.next();
480: defaultsMap.put((String) as
481: .getAttribute(StyleConstants.NameAttribute), as);
482: }
483: return defaultsMap;
484: }
485:
486: private static Map getCurrentColors(Language l) {
487: // current colors
488: FontColorSettingsFactory fcsf = EditorSettings.getDefault()
489: .getFontColorSettings(new String[] { l.getMimeType() });
490: Collection<AttributeSet> colors = fcsf
491: .getAllFontColors("NetBeans");
492: Map<String, AttributeSet> colorsMap = new HashMap<String, AttributeSet>();
493: Iterator<AttributeSet> it = colors.iterator();
494: while (it.hasNext()) {
495: AttributeSet as = it.next();
496: colorsMap.put((String) as
497: .getAttribute(StyleConstants.NameAttribute), as);
498: }
499: return colorsMap;
500: }
501:
502: private static String getBundleName(Language l) {
503: FileSystem fs = Repository.getDefault().getDefaultFileSystem();
504: FileObject root = fs.findResource("Editors/" + l.getMimeType()); // NOI18N
505: Object attrValue = root
506: .getAttribute("SystemFileSystem.localizingBundle"); //NOI18N
507: // [PENDING] if (bundleName == null) ... check for bundle name in nbs file
508: return (String) attrValue;
509: }
510:
511: }
|