KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > api > editor > settings > AttributesUtilities


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19
20 package org.netbeans.api.editor.settings;
21
22 import java.util.ArrayList JavaDoc;
23 import java.util.Arrays JavaDoc;
24 import java.util.Collection JavaDoc;
25 import java.util.Collections JavaDoc;
26 import java.util.Enumeration JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.HashSet JavaDoc;
29 import java.util.List JavaDoc;
30 import javax.swing.text.AttributeSet JavaDoc;
31 import javax.swing.text.SimpleAttributeSet JavaDoc;
32
33 /**
34  * A collection of utility menthods for working with <code>AttributeSet</code>s.
35  *
36  * @author Vita Stejskal
37  */

38 public final class AttributesUtilities {
39
40     private static final String JavaDoc ATTR_DISMANTLED_STRUCTURE = "dismantled-structure"; //NOI18N
41

42     /**
43      * Creates an immutable <code>AttributeSet</code>, which will contain the
44      * <code>keyValuePairs</code> attributes. If the pairs
45      * contain attributes with the same name the resulting <code>AttributeSet</code>
46      * will return value of the first attribute it will find going through
47      * the pairs in the order as they were passed in.
48      *
49      * @param keyValuePairs The contents of the <code>AttributeSet</code> created
50      * by this method. This parameter should list pairs
51      * of key-value objects; each pair defining one attribute.
52      *
53      * @return The new immutable <code>AttributeSet</code>.
54      */

55     public static AttributeSet JavaDoc createImmutable(Object JavaDoc... keyValuePairs) {
56         assert keyValuePairs.length % 2 == 0 : "There must be even number of prameters. " +
57             "They are key-value pairs of attributes that will be inserted into the set.";
58
59         HashMap JavaDoc<Object JavaDoc, Object JavaDoc> map = new HashMap JavaDoc<Object JavaDoc, Object JavaDoc>();
60         
61         for(int i = keyValuePairs.length / 2 - 1; i >= 0 ; i--) {
62             Object JavaDoc attrKey = keyValuePairs[2 * i];
63             Object JavaDoc attrValue = keyValuePairs[2 * i + 1];
64
65             map.put(attrKey, attrValue);
66         }
67         
68         return new Immutable(map);
69     }
70
71     /**
72      * Creates an immutable <code>AttributeSet</code> as a copy of <code>AttributeSet</code>s
73      * passed into this method. If the <code>AttributeSet</code>s
74      * contain attributes with the same name the resulting <code>AttributeSet</code>
75      * will return value of the first attribute it will find going through
76      * the sets in the order as they were passed in.
77      *
78      * @param sets The <code>AttributeSet</code>s which attributes will become
79      * a contents of the newly created <code>AttributeSet</code>.
80      *
81      * @return The new immutable <code>AttributeSet</code>.
82      */

83     public static AttributeSet JavaDoc createImmutable(AttributeSet JavaDoc... sets) {
84         HashMap JavaDoc<Object JavaDoc, Object JavaDoc> map = new HashMap JavaDoc<Object JavaDoc, Object JavaDoc>();
85         
86         for(int i = sets.length - 1; i >= 0; i--) {
87             AttributeSet JavaDoc set = sets[i];
88             for(Enumeration JavaDoc<?> keys = set.getAttributeNames(); keys.hasMoreElements(); ) {
89                 Object JavaDoc attrKey = keys.nextElement();
90                 Object JavaDoc attrValue = set.getAttribute(attrKey);
91
92                 map.put(attrKey, attrValue);
93             }
94         }
95         
96         return new Immutable(map);
97     }
98
99     /**
100      * Creates a proxy <code>AttributeSet</code> that will delegate to the
101      * <code>AttributeSet</code>s passed in as a parameter. If the <code>AttributeSet</code>s
102      * contain attributes with the same name the composite <code>AttributeSet</code>
103      * will return value of the first attribute it will find going through
104      * the sets in the order as they were passed in.
105      *
106      * @param sets The <code>AttributeSet</code>s to delegate to.
107      *
108      * @return The new composite <code>AttributeSet</code> that will delegate
109      * to the <code>sets</code> passed in.
110      */

111     public static AttributeSet JavaDoc createComposite(AttributeSet JavaDoc... sets) {
112         if (sets.length == 0) {
113             return SimpleAttributeSet.EMPTY;
114         } else if (sets.length == 1) {
115             return sets[0];
116         } else {
117             ArrayList JavaDoc<AttributeSet JavaDoc> all = new ArrayList JavaDoc<AttributeSet JavaDoc>();
118
119             for(AttributeSet JavaDoc s : sets) {
120                 if (s instanceof AttributesUtilities.Composite) {
121                     all.addAll(((AttributesUtilities.Composite) s).getDelegates());
122                 } else if (s instanceof AttributesUtilities.Proxy) {
123                     all.add(((AttributesUtilities.Proxy) s).getDelegate());
124                 } else if (s != null && s != SimpleAttributeSet.EMPTY) {
125                     all.add(s);
126                 }
127             }
128
129             if (all.size() == 0) {
130                 return SimpleAttributeSet.EMPTY;
131             } else {
132                 return new Composite(all.toArray(new AttributeSet JavaDoc[all.size()]));
133             }
134         }
135     }
136
137     private static List JavaDoc<AttributeSet JavaDoc> dismantle(AttributeSet JavaDoc set) {
138         ArrayList JavaDoc<AttributeSet JavaDoc> sets = new ArrayList JavaDoc<AttributeSet JavaDoc>();
139         
140         if (set instanceof Proxy) {
141             sets.addAll(dismantle(((Proxy) set).getDelegate()));
142         } else if (set instanceof Composite) {
143             List JavaDoc<AttributeSet JavaDoc> delegates = ((Composite) set).getDelegates();
144             for(AttributeSet JavaDoc delegate : delegates) {
145                 sets.addAll(dismantle(delegate));
146             }
147         } else {
148             sets.add(set);
149         }
150         
151         return sets;
152     }
153     
154     // ----------------------------------------------------------------------
155
// Private implementation
156
// ----------------------------------------------------------------------
157

158     private AttributesUtilities() {
159         // no-op, just to prevent instantiation
160
}
161     
162     private static class Immutable implements AttributeSet JavaDoc {
163         
164         private final HashMap JavaDoc<Object JavaDoc, Object JavaDoc> attribs;
165         private AttributeSet JavaDoc parent = null;
166
167         /** Creates a new instance of SmartAttributeSet */
168         private Immutable(HashMap JavaDoc<Object JavaDoc, Object JavaDoc> attribs) {
169             this.attribs = attribs == null ? new HashMap JavaDoc<Object JavaDoc, Object JavaDoc>() : attribs;
170         }
171
172         public synchronized void setResolveParent(AttributeSet JavaDoc parent) {
173             this.parent = parent;
174         }
175
176         public synchronized boolean containsAttributes(AttributeSet JavaDoc attributes) {
177             for(Enumeration JavaDoc names = attributes.getAttributeNames(); names.hasMoreElements(); ) {
178                 Object JavaDoc name = names.nextElement();
179                 Object JavaDoc value = attributes.getAttribute(name);
180
181                 if (!containsAttribute(name, value)) {
182                     return false;
183                 }
184             }
185
186             return true;
187         }
188
189         public synchronized boolean isEqual(AttributeSet JavaDoc attr) {
190             return containsAttributes(attr) && attr.containsAttributes(this);
191         }
192
193         public synchronized Object JavaDoc getAttribute(Object JavaDoc key) {
194
195             // Somebody is asking for the parent
196
if (AttributeSet.ResolveAttribute == key) {
197                 return parent;
198             }
199
200             // Get the normal value
201
if (attribs.containsKey(key)) {
202                 return attribs.get(key);
203             }
204
205             // Value not found, try parent if we have any
206
if (parent != null) {
207                 return parent.getAttribute(key);
208             } else {
209                 return null;
210             }
211         }
212
213         public synchronized boolean isDefined(Object JavaDoc key) {
214             return attribs.containsKey(key);
215         }
216
217         public synchronized boolean containsAttribute(Object JavaDoc key, Object JavaDoc value) {
218             if (attribs.containsKey(key)) {
219                 Object JavaDoc attrValue = attribs.get(key);
220                 if ((value == null && attrValue == null) ||
221                     (value != null && attrValue != null && value.equals(attrValue))
222                 ) {
223                     return true;
224                 }
225             }
226
227             return false;
228         }
229
230         public AttributeSet JavaDoc copyAttributes() {
231             return new Proxy(this);
232         }
233
234         /**
235          * This is really slow don't use it!
236          */

237         public synchronized int getAttributeCount() {
238             return attribs.size();
239         }
240
241         /**
242          * This is really slow don't use it!
243          */

244         public synchronized Enumeration JavaDoc<?> getAttributeNames() {
245             return Collections.enumeration(attribs.keySet());
246         }
247
248         public synchronized AttributeSet JavaDoc getResolveParent() {
249             return parent;
250         }
251
252     } // End of Immutable class
253

254     private static final class Proxy implements AttributeSet JavaDoc {
255         
256         private AttributeSet JavaDoc original;
257         
258         public Proxy(AttributeSet JavaDoc original) {
259             this.original = original;
260         }
261
262         public AttributeSet JavaDoc getDelegate() {
263             return original;
264         }
265         
266         public boolean isEqual(AttributeSet JavaDoc attr) {
267             return original.isEqual(attr);
268         }
269
270         public boolean containsAttributes(AttributeSet JavaDoc attributes) {
271             return original.containsAttributes(attributes);
272         }
273
274         public boolean isDefined(Object JavaDoc attrName) {
275             return original.isDefined(attrName);
276         }
277
278         public Object JavaDoc getAttribute(Object JavaDoc key) {
279             if (key instanceof String JavaDoc && key.equals(ATTR_DISMANTLED_STRUCTURE)) {
280                 return dismantle(this);
281             } else {
282                 return original.getAttribute(key);
283             }
284         }
285
286         public AttributeSet JavaDoc getResolveParent() {
287             return original.getResolveParent();
288         }
289
290         public Enumeration JavaDoc<?> getAttributeNames() {
291             return original.getAttributeNames();
292         }
293
294         public int getAttributeCount() {
295             return original.getAttributeCount();
296         }
297
298         public AttributeSet JavaDoc copyAttributes() {
299             return original.copyAttributes();
300         }
301
302         public boolean containsAttribute(Object JavaDoc name, Object JavaDoc value) {
303             return original.containsAttribute(name, value);
304         }
305     } // End of Proxy class
306

307     private static final class Composite implements AttributeSet JavaDoc {
308         
309         private final AttributeSet JavaDoc [] delegates;
310         
311         public Composite(AttributeSet JavaDoc... delegates) {
312             this.delegates = delegates;
313         }
314
315         public List JavaDoc<AttributeSet JavaDoc> getDelegates() {
316             return Arrays.asList(delegates);
317         }
318         
319         public boolean isEqual(AttributeSet JavaDoc attr) {
320             return containsAttributes(attr) && attr.containsAttributes(this);
321         }
322
323         public boolean containsAttributes(AttributeSet JavaDoc attributes) {
324             for(Enumeration JavaDoc<?> keys = attributes.getAttributeNames(); keys.hasMoreElements(); ) {
325                 Object JavaDoc key = keys.nextElement();
326                 Object JavaDoc value = attributes.getAttribute(key);
327                 
328                 if (!containsAttribute(key, value)) {
329                     return false;
330                 }
331             }
332             
333             return true;
334         }
335
336         public boolean isDefined(Object JavaDoc key) {
337             for(AttributeSet JavaDoc delegate : delegates) {
338                 if (delegate.isDefined(key)) {
339                     return true;
340                 }
341             }
342             
343             return false;
344         }
345
346         public Object JavaDoc getAttribute(Object JavaDoc key) {
347             if (key instanceof String JavaDoc && key.equals(ATTR_DISMANTLED_STRUCTURE)) {
348                 return dismantle(this);
349             }
350             
351             for(AttributeSet JavaDoc delegate : delegates) {
352                 if (delegate.isDefined(key)) {
353                     return delegate.getAttribute(key);
354                 }
355             }
356             
357             return null;
358         }
359
360         public AttributeSet JavaDoc getResolveParent() {
361             return null;
362         }
363
364         public Enumeration JavaDoc<?> getAttributeNames() {
365             return Collections.enumeration(getAllKeys());
366         }
367
368         public int getAttributeCount() {
369             return getAllKeys().size();
370         }
371
372         public AttributeSet JavaDoc copyAttributes() {
373             return createImmutable(delegates);
374         }
375
376         public boolean containsAttribute(Object JavaDoc key, Object JavaDoc value) {
377             for(AttributeSet JavaDoc delegate : delegates) {
378                 if (delegate.containsAttribute(key, value)) {
379                     return true;
380                 }
381             }
382             
383             return false;
384         }
385         
386         private Collection JavaDoc<?> getAllKeys() {
387             HashSet JavaDoc<Object JavaDoc> allKeys = new HashSet JavaDoc<Object JavaDoc>();
388             
389             for(AttributeSet JavaDoc delegate : delegates) {
390                 for(Enumeration JavaDoc<?> keys = delegate.getAttributeNames(); keys.hasMoreElements(); ) {
391                     Object JavaDoc key = keys.nextElement();
392                     allKeys.add(key);
393                 }
394             }
395             
396             return allKeys;
397         }
398     } // End of Composite class
399
}
400
Popular Tags