1 package org.apache.maven.doxia.sink;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import java.util.Collections;
23 import java.util.Enumeration;
24 import java.util.LinkedHashMap;
25 import java.util.Map;
26
27 import javax.swing.text.AttributeSet;
28
29
30
31
32
33
34
35
36 public class SinkEventAttributeSet
37 implements SinkEventAttributes, Cloneable
38 {
39
40
41
42 public static final SinkEventAttributes UNDERLINE;
43
44
45
46
47 public static final SinkEventAttributes OVERLINE;
48
49
50
51
52 public static final SinkEventAttributes LINETHROUGH;
53
54
55
56
57 public static final SinkEventAttributes BOXED;
58
59
60
61
62 public static final SinkEventAttributes BOLD;
63
64
65
66
67 public static final SinkEventAttributes ITALIC;
68
69
70
71
72 public static final SinkEventAttributes MONOSPACED;
73
74
75
76
77 public static final SinkEventAttributes LEFT;
78
79
80
81
82 public static final SinkEventAttributes RIGHT;
83
84
85
86
87 public static final SinkEventAttributes CENTER;
88
89
90
91
92 public static final SinkEventAttributes JUSTIFY;
93
94
95 static
96 {
97 UNDERLINE = new SinkEventAttributeSet( new String[] {DECORATION, "underline"} ).unmodifiable();
98 OVERLINE = new SinkEventAttributeSet( new String[] {DECORATION, "overline"} ).unmodifiable();
99 LINETHROUGH = new SinkEventAttributeSet( new String[] {DECORATION, "line-through"} ).unmodifiable();
100 BOXED = new SinkEventAttributeSet( new String[] {DECORATION, "boxed"} ).unmodifiable();
101
102 BOLD = new SinkEventAttributeSet( new String[] {STYLE, "bold"} ).unmodifiable();
103 ITALIC = new SinkEventAttributeSet( new String[] {STYLE, "italic"} ).unmodifiable();
104 MONOSPACED = new SinkEventAttributeSet( new String[] {STYLE, "monospaced"} ).unmodifiable();
105
106 LEFT = new SinkEventAttributeSet( new String[] {ALIGN, "left"} ).unmodifiable();
107 RIGHT = new SinkEventAttributeSet( new String[] {ALIGN, "right"} ).unmodifiable();
108 CENTER = new SinkEventAttributeSet( new String[] {ALIGN, "center"} ).unmodifiable();
109 JUSTIFY = new SinkEventAttributeSet( new String[] {ALIGN, "justify"} ).unmodifiable();
110 }
111
112 private Map<String, Object> attribs;
113
114 private AttributeSet resolveParent;
115
116
117
118
119 public SinkEventAttributeSet()
120 {
121 this( 5 );
122 }
123
124
125
126
127
128
129 public SinkEventAttributeSet( int size )
130 {
131 attribs = new LinkedHashMap<String, Object>( size );
132 }
133
134
135
136
137
138
139
140
141 public SinkEventAttributeSet( String... attributes )
142 {
143 int n = attributes.length;
144
145 if ( ( n % 2 ) != 0 )
146 {
147 throw new IllegalArgumentException( "Missing attribute!" );
148 }
149
150 attribs = new LinkedHashMap<String, Object>( n / 2 );
151
152 for ( int i = 0; i < n; i += 2 )
153 {
154 attribs.put( attributes[i], attributes[i + 1] );
155 }
156 }
157
158
159
160
161
162
163
164 public SinkEventAttributeSet( AttributeSet attributes )
165 {
166 attribs = new LinkedHashMap<String, Object>( attributes.getAttributeCount() );
167
168 Enumeration<?> names = attributes.getAttributeNames();
169
170 while ( names.hasMoreElements() )
171 {
172 Object name = names.nextElement();
173
174 attribs.put( name.toString(), attributes.getAttribute( name ) );
175 }
176 }
177
178
179
180
181
182
183
184
185
186
187 public SinkEventAttributeSet unmodifiable()
188 {
189 this.attribs = Collections.unmodifiableMap( attribs );
190
191 return this;
192 }
193
194
195
196
197
198
199 public boolean isEmpty()
200 {
201 return attribs.isEmpty();
202 }
203
204
205 public int getAttributeCount()
206 {
207 return attribs.size();
208 }
209
210
211 public boolean isDefined( Object attrName )
212 {
213 return attribs.containsKey( attrName );
214 }
215
216
217 public boolean isEqual( AttributeSet attr )
218 {
219 return ( ( getAttributeCount() == attr.getAttributeCount() )
220 && containsAttributes( attr ) );
221 }
222
223
224 public AttributeSet copyAttributes()
225 {
226 return ( (AttributeSet) clone() );
227 }
228
229
230 public Enumeration<String> getAttributeNames()
231 {
232 return Collections.enumeration( attribs.keySet() );
233 }
234
235
236 public Object getAttribute( Object key )
237 {
238 Object value = attribs.get( key );
239
240 if ( value == null )
241 {
242 AttributeSet parent = getResolveParent();
243
244 if ( parent != null )
245 {
246 value = parent.getAttribute( key );
247 }
248 }
249
250 return value;
251 }
252
253
254 public boolean containsAttribute( Object name, Object value )
255 {
256 return value.equals( getAttribute( name ) );
257 }
258
259
260 public boolean containsAttributes( AttributeSet attributes )
261 {
262 boolean result = true;
263
264 Enumeration<?> names = attributes.getAttributeNames();
265
266 while ( result && names.hasMoreElements() )
267 {
268 Object name = names.nextElement();
269 result = attributes.getAttribute( name ).equals( getAttribute( name ) );
270 }
271
272 return result;
273 }
274
275
276
277
278
279
280 public void addAttribute( Object name, Object value )
281 {
282 attribs.put( name.toString(), value );
283 }
284
285
286 public void addAttributes( AttributeSet attributes )
287 {
288 if ( attributes == null || attributes.getAttributeCount() == 0 )
289 {
290 return;
291 }
292
293 Enumeration<?> names = attributes.getAttributeNames();
294
295 while ( names.hasMoreElements() )
296 {
297 Object name = names.nextElement();
298
299 addAttribute( name, attributes.getAttribute( name ) );
300 }
301 }
302
303
304 public void removeAttribute( Object name )
305 {
306 attribs.remove( name );
307 }
308
309
310 public void removeAttributes( Enumeration<?> names )
311 {
312 while ( names.hasMoreElements() )
313 {
314 removeAttribute( names.nextElement() );
315 }
316 }
317
318
319 public void removeAttributes( AttributeSet attributes )
320 {
321 if ( attributes == null )
322 {
323 return;
324 }
325 else if ( attributes == this )
326 {
327 attribs.clear();
328 }
329 else
330 {
331 Enumeration<?> names = attributes.getAttributeNames();
332
333 while ( names.hasMoreElements() )
334 {
335 Object name = names.nextElement();
336 Object value = attributes.getAttribute( name );
337
338 if ( value.equals( getAttribute( name ) ) )
339 {
340 removeAttribute( name );
341 }
342 }
343 }
344 }
345
346
347 public AttributeSet getResolveParent()
348 {
349 return this.resolveParent;
350 }
351
352
353 public void setResolveParent( AttributeSet parent )
354 {
355 this.resolveParent = parent;
356 }
357
358
359 @Override
360 public Object clone()
361 {
362 SinkEventAttributeSet attr = new SinkEventAttributeSet( attribs.size() );
363 attr.attribs = new LinkedHashMap<String, Object>( attribs );
364
365 if ( resolveParent != null )
366 {
367 attr.resolveParent = resolveParent.copyAttributes();
368 }
369
370 return attr;
371 }
372
373
374 @Override
375 public int hashCode()
376 {
377 final int parentHash = ( resolveParent == null ? 0 : resolveParent.hashCode() );
378
379 return attribs.hashCode() + parentHash;
380 }
381
382
383 @Override
384 public boolean equals( Object obj )
385 {
386 if ( this == obj )
387 {
388 return true;
389 }
390
391 if ( obj instanceof SinkEventAttributeSet )
392 {
393 return isEqual( (SinkEventAttributeSet) obj );
394 }
395
396 return false;
397 }
398
399
400 @Override
401 public String toString()
402 {
403 StringBuilder s = new StringBuilder();
404 Enumeration<String> names = getAttributeNames();
405
406 while ( names.hasMoreElements() )
407 {
408 String key = names.nextElement();
409 String value = getAttribute( key ).toString();
410
411 s.append( ' ' ).append( key ).append( '=' ).append( value );
412 }
413
414 return s.toString();
415 }
416
417 }