KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > internal > ui > text > AbstractJavaScanner


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdt.internal.ui.text;
12
13
14 import java.util.HashMap JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Map JavaDoc;
17
18 import org.eclipse.swt.SWT;
19 import org.eclipse.swt.graphics.Color;
20 import org.eclipse.swt.graphics.RGB;
21 import org.eclipse.swt.widgets.Display;
22
23 import org.eclipse.jface.preference.IPreferenceStore;
24 import org.eclipse.jface.preference.PreferenceConverter;
25 import org.eclipse.jface.resource.StringConverter;
26 import org.eclipse.jface.text.TextAttribute;
27 import org.eclipse.jface.text.rules.BufferedRuleBasedScanner;
28 import org.eclipse.jface.text.rules.IRule;
29 import org.eclipse.jface.text.rules.IToken;
30 import org.eclipse.jface.text.rules.Token;
31 import org.eclipse.jface.util.PropertyChangeEvent;
32
33 import org.eclipse.jdt.ui.PreferenceConstants;
34 import org.eclipse.jdt.ui.text.IColorManager;
35 import org.eclipse.jdt.ui.text.IColorManagerExtension;
36
37
38 /**
39  * Initialized with a color manager and a preference store, its subclasses are
40  * only responsible for providing a list of preference keys for based on which tokens
41  * are generated and to use this tokens to define the rules controlling this scanner.
42  * <p>
43  * This scanner stores the color defined by the color preference key into
44  * the color manager under the same key.
45  * </p>
46  * <p>
47  * Preference color key + {@link PreferenceConstants#EDITOR_BOLD_SUFFIX} are used
48  * to retrieve whether the token is rendered in bold.
49  * </p>
50  * <p>
51  * Preference color key + {@link PreferenceConstants#EDITOR_ITALIC_SUFFIX} are used
52  * to retrieve whether the token is rendered in italic.
53  * </p>
54  * <p>
55  * Preference color key + {@link PreferenceConstants#EDITOR_STRIKETHROUGH_SUFFIX} are used
56  * to retrieve whether the token is rendered in strikethrough.
57  * </p>
58  * <p>
59  * Preference color key + {@link PreferenceConstants#EDITOR_UNDERLINE_SUFFIX} are used
60  * to retrieve whether the token is rendered in underline.
61  * </p>
62  */

63 public abstract class AbstractJavaScanner extends BufferedRuleBasedScanner {
64
65
66     private IColorManager fColorManager;
67     private IPreferenceStore fPreferenceStore;
68
69     private Map JavaDoc fTokenMap= new HashMap JavaDoc();
70     private String JavaDoc[] fPropertyNamesColor;
71     /**
72      * Preference keys for boolean preferences which are <code>true</code>,
73      * iff the corresponding token should be rendered bold.
74      */

75     private String JavaDoc[] fPropertyNamesBold;
76     /**
77      * Preference keys for boolean preferences which are <code>true</code>,
78      * iff the corresponding token should be rendered italic.
79      *
80      * @since 3.0
81      */

82     private String JavaDoc[] fPropertyNamesItalic;
83     /**
84      * Preference keys for boolean preferences which are <code>true</code>,
85      * iff the corresponding token should be rendered strikethrough.
86      *
87      * @since 3.1
88      */

89     private String JavaDoc[] fPropertyNamesStrikethrough;
90     /**
91      * Preference keys for boolean preferences which are <code>true</code>,
92      * iff the corresponding token should be rendered underline.
93      *
94      * @since 3.1
95      */

96     private String JavaDoc[] fPropertyNamesUnderline;
97
98
99     private boolean fNeedsLazyColorLoading;
100
101     /**
102      * Returns an array of preference keys which define the tokens
103      * used in the rules of this scanner.
104      * <p>
105      * The preference key is used access the color in the preference
106      * store and in the color manager.
107      * </p>
108      * <p>
109      * Preference key + {@link PreferenceConstants#EDITOR_BOLD_SUFFIX} is used
110      * to retrieve whether the token is rendered in bold.
111      * </p>
112      * <p>
113      * Preference key + {@link PreferenceConstants#EDITOR_ITALIC_SUFFIX} is used
114      * to retrieve whether the token is rendered in italic.
115      * </p>
116      * <p>
117      * Preference key + {@link PreferenceConstants#EDITOR_UNDERLINE_SUFFIX} is used
118      * to retrieve whether the token is rendered underlined.
119      * </p>
120      * <p>
121      * Preference key + {@link PreferenceConstants#EDITOR_STRIKETHROUGH_SUFFIX} is used
122      * to retrieve whether the token is rendered stricken out.
123      * </p>
124      */

125     abstract protected String JavaDoc[] getTokenProperties();
126
127     /**
128      * Creates the list of rules controlling this scanner.
129      */

130     abstract protected List JavaDoc createRules();
131
132
133     /**
134      * Creates an abstract Java scanner.
135      */

136     public AbstractJavaScanner(IColorManager manager, IPreferenceStore store) {
137         super();
138         fColorManager= manager;
139         fPreferenceStore= store;
140     }
141
142     /**
143      * Must be called after the constructor has been called.
144      */

145     public final void initialize() {
146
147         fPropertyNamesColor= getTokenProperties();
148         int length= fPropertyNamesColor.length;
149         fPropertyNamesBold= new String JavaDoc[length];
150         fPropertyNamesItalic= new String JavaDoc[length];
151         fPropertyNamesStrikethrough= new String JavaDoc[length];
152         fPropertyNamesUnderline= new String JavaDoc[length];
153
154         for (int i= 0; i < length; i++) {
155             fPropertyNamesBold[i]= getBoldKey(fPropertyNamesColor[i]);
156             fPropertyNamesItalic[i]= getItalicKey(fPropertyNamesColor[i]);
157             fPropertyNamesStrikethrough[i]= getStrikethroughKey(fPropertyNamesColor[i]);
158             fPropertyNamesUnderline[i]= getUnderlineKey(fPropertyNamesColor[i]);
159         }
160         
161         fNeedsLazyColorLoading= Display.getCurrent() == null;
162         for (int i= 0; i < length; i++) {
163             if (fNeedsLazyColorLoading)
164                 addTokenWithProxyAttribute(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
165             else
166                 addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
167         }
168
169         initializeRules();
170     }
171     
172     protected String JavaDoc getBoldKey(String JavaDoc colorKey) {
173         return colorKey + PreferenceConstants.EDITOR_BOLD_SUFFIX;
174     }
175
176     protected String JavaDoc getItalicKey(String JavaDoc colorKey) {
177         return colorKey + PreferenceConstants.EDITOR_ITALIC_SUFFIX;
178     }
179     
180     protected String JavaDoc getStrikethroughKey(String JavaDoc colorKey) {
181         return colorKey + PreferenceConstants.EDITOR_STRIKETHROUGH_SUFFIX;
182     }
183     
184     protected String JavaDoc getUnderlineKey(String JavaDoc colorKey) {
185         return colorKey + PreferenceConstants.EDITOR_UNDERLINE_SUFFIX;
186     }
187     
188     public IToken nextToken() {
189         if (fNeedsLazyColorLoading)
190             resolveProxyAttributes();
191         return super.nextToken();
192     }
193
194     private void resolveProxyAttributes() {
195         if (fNeedsLazyColorLoading && Display.getCurrent() != null) {
196             for (int i= 0; i < fPropertyNamesColor.length; i++) {
197                 addToken(fPropertyNamesColor[i], fPropertyNamesBold[i], fPropertyNamesItalic[i], fPropertyNamesStrikethrough[i], fPropertyNamesUnderline[i]);
198             }
199             fNeedsLazyColorLoading= false;
200         }
201     }
202
203     private void addTokenWithProxyAttribute(String JavaDoc colorKey, String JavaDoc boldKey, String JavaDoc italicKey, String JavaDoc strikethroughKey, String JavaDoc underlineKey) {
204         fTokenMap.put(colorKey, new Token(createTextAttribute(null, boldKey, italicKey, strikethroughKey, underlineKey)));
205     }
206
207     private void addToken(String JavaDoc colorKey, String JavaDoc boldKey, String JavaDoc italicKey, String JavaDoc strikethroughKey, String JavaDoc underlineKey) {
208         if (fColorManager != null && colorKey != null && fColorManager.getColor(colorKey) == null) {
209             RGB rgb= PreferenceConverter.getColor(fPreferenceStore, colorKey);
210             if (fColorManager instanceof IColorManagerExtension) {
211                 IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
212                 ext.unbindColor(colorKey);
213                 ext.bindColor(colorKey, rgb);
214             }
215         }
216
217         if (!fNeedsLazyColorLoading)
218             fTokenMap.put(colorKey, new Token(createTextAttribute(colorKey, boldKey, italicKey, strikethroughKey, underlineKey)));
219         else {
220             Token token= ((Token)fTokenMap.get(colorKey));
221             if (token != null)
222                 token.setData(createTextAttribute(colorKey, boldKey, italicKey, strikethroughKey, underlineKey));
223         }
224     }
225
226     /**
227      * Create a text attribute based on the given color, bold, italic, strikethrough and underline preference keys.
228      *
229      * @param colorKey the color preference key
230      * @param boldKey the bold preference key
231      * @param italicKey the italic preference key
232      * @param strikethroughKey the strikethrough preference key
233      * @param underlineKey the italic preference key
234      * @return the created text attribute
235      * @since 3.0
236      */

237     private TextAttribute createTextAttribute(String JavaDoc colorKey, String JavaDoc boldKey, String JavaDoc italicKey, String JavaDoc strikethroughKey, String JavaDoc underlineKey) {
238         Color color= null;
239         if (colorKey != null)
240             color= fColorManager.getColor(colorKey);
241
242         int style= fPreferenceStore.getBoolean(boldKey) ? SWT.BOLD : SWT.NORMAL;
243         if (fPreferenceStore.getBoolean(italicKey))
244             style |= SWT.ITALIC;
245
246         if (fPreferenceStore.getBoolean(strikethroughKey))
247             style |= TextAttribute.STRIKETHROUGH;
248
249         if (fPreferenceStore.getBoolean(underlineKey))
250             style |= TextAttribute.UNDERLINE;
251
252         return new TextAttribute(color, null, style);
253     }
254
255     protected Token getToken(String JavaDoc key) {
256         if (fNeedsLazyColorLoading)
257             resolveProxyAttributes();
258         return (Token) fTokenMap.get(key);
259     }
260
261     private void initializeRules() {
262         List JavaDoc rules= createRules();
263         if (rules != null) {
264             IRule[] result= new IRule[rules.size()];
265             rules.toArray(result);
266             setRules(result);
267         }
268     }
269
270     private int indexOf(String JavaDoc property) {
271         if (property != null) {
272             int length= fPropertyNamesColor.length;
273             for (int i= 0; i < length; i++) {
274                 if (property.equals(fPropertyNamesColor[i]) || property.equals(fPropertyNamesBold[i]) || property.equals(fPropertyNamesItalic[i]) || property.equals(fPropertyNamesStrikethrough[i]) || property.equals(fPropertyNamesUnderline[i]))
275                     return i;
276             }
277         }
278         return -1;
279     }
280
281     public boolean affectsBehavior(PropertyChangeEvent event) {
282         return indexOf(event.getProperty()) >= 0;
283     }
284
285     public void adaptToPreferenceChange(PropertyChangeEvent event) {
286         String JavaDoc p= event.getProperty();
287         int index= indexOf(p);
288         Token token= getToken(fPropertyNamesColor[index]);
289         if (fPropertyNamesColor[index].equals(p))
290             adaptToColorChange(token, event);
291         else if (fPropertyNamesBold[index].equals(p))
292             adaptToStyleChange(token, event, SWT.BOLD);
293         else if (fPropertyNamesItalic[index].equals(p))
294             adaptToStyleChange(token, event, SWT.ITALIC);
295         else if (fPropertyNamesStrikethrough[index].equals(p))
296             adaptToStyleChange(token, event, TextAttribute.STRIKETHROUGH);
297         else if (fPropertyNamesUnderline[index].equals(p))
298             adaptToStyleChange(token, event, TextAttribute.UNDERLINE);
299     }
300
301     private void adaptToColorChange(Token token, PropertyChangeEvent event) {
302         RGB rgb= null;
303
304         Object JavaDoc value= event.getNewValue();
305         if (value instanceof RGB)
306             rgb= (RGB) value;
307         else if (value instanceof String JavaDoc)
308             rgb= StringConverter.asRGB((String JavaDoc) value);
309
310         if (rgb != null) {
311
312             String JavaDoc property= event.getProperty();
313             Color color= fColorManager.getColor(property);
314
315             if ((color == null || !rgb.equals(color.getRGB())) && fColorManager instanceof IColorManagerExtension) {
316                 IColorManagerExtension ext= (IColorManagerExtension) fColorManager;
317
318                 ext.unbindColor(property);
319                 ext.bindColor(property, rgb);
320
321                 color= fColorManager.getColor(property);
322             }
323
324             Object JavaDoc data= token.getData();
325             if (data instanceof TextAttribute) {
326                 TextAttribute oldAttr= (TextAttribute) data;
327                 token.setData(new TextAttribute(color, oldAttr.getBackground(), oldAttr.getStyle()));
328             }
329         }
330     }
331
332     private void adaptToStyleChange(Token token, PropertyChangeEvent event, int styleAttribute) {
333         boolean eventValue= false;
334         Object JavaDoc value= event.getNewValue();
335         if (value instanceof Boolean JavaDoc)
336             eventValue= ((Boolean JavaDoc) value).booleanValue();
337         else if (IPreferenceStore.TRUE.equals(value))
338             eventValue= true;
339
340         Object JavaDoc data= token.getData();
341         if (data instanceof TextAttribute) {
342             TextAttribute oldAttr= (TextAttribute) data;
343             boolean activeValue= (oldAttr.getStyle() & styleAttribute) == styleAttribute;
344             if (activeValue != eventValue)
345                 token.setData(new TextAttribute(oldAttr.getForeground(), oldAttr.getBackground(), eventValue ? oldAttr.getStyle() | styleAttribute : oldAttr.getStyle() & ~styleAttribute));
346         }
347     }
348     /**
349      * Returns the preference store.
350      *
351      * @return the preference store.
352      *
353      * @since 3.0
354      */

355     protected IPreferenceStore getPreferenceStore() {
356         return fPreferenceStore;
357     }
358 }
359
Popular Tags