1 /* CSS.java -- Provides CSS attributes
2    Copyright (C) 2005 Free Software Foundation, Inc.
3 
4 This file is part of GNU Classpath.
5 
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
10 
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING.  If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
20 
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library.  Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
25 
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module.  An independent module is a module which is not derived from
33 or based on this library.  If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so.  If you do not wish to do so, delete this
36 exception statement from your version. */
37 
38 package javax.swing.text.html;
39 
40 import gnu.javax.swing.text.html.css.BorderStyle;
41 import gnu.javax.swing.text.html.css.BorderWidth;
42 import gnu.javax.swing.text.html.css.CSSColor;
43 import gnu.javax.swing.text.html.css.FontSize;
44 import gnu.javax.swing.text.html.css.FontStyle;
45 import gnu.javax.swing.text.html.css.FontWeight;
46 import gnu.javax.swing.text.html.css.Length;
47 
48 import java.io.Serializable;
49 import java.util.HashMap;
50 import java.util.StringTokenizer;
51 
52 import javax.swing.text.MutableAttributeSet;
53 
54 /**
55  * Provides CSS attributes to be used by the HTML view classes. The constants
56  * defined here are used as keys for text attributes for use in
57  * {@link javax.swing.text.AttributeSet}s of {@link javax.swing.text.Element}s.
58  *
59  * @author Roman Kennke (kennke@aicas.com)
60  */
61 public class CSS implements Serializable
62 {
63   /**
64    * Returns an array of all CSS attributes.
65    *
66    * @return All available CSS.Attribute objects.
67    */
getAllAttributeKeys()68   public static CSS.Attribute[] getAllAttributeKeys()
69   {
70     Object[] src = Attribute.attributeMap.values().toArray();
71     CSS.Attribute[] dst = new CSS.Attribute[ src.length ];
72     System.arraycopy(src, 0, dst, 0, src.length);
73     return dst;
74   }
75 
76   /**
77    * Returns an a given CSS attribute.
78    *
79    * @param name - The name of the attribute.
80    * @return The CSS attribute with the given name, or <code>null</code> if
81    * no attribute with that name exists.
82    */
getAttribute(String name)83   public static CSS.Attribute getAttribute(String name)
84   {
85     return (CSS.Attribute)Attribute.attributeMap.get( name );
86   }
87 
88   public static final class Attribute
89   {
90     /**
91      * The CSS attribute 'background'.
92      */
93     public static final Attribute BACKGROUND =
94       new Attribute("background", false, null);
95 
96     /**
97      * The CSS attribute 'background-attachment'.
98      */
99     public static final Attribute BACKGROUND_ATTACHMENT =
100       new Attribute("background-attachment", false, "scroll");
101 
102     /**
103      * The CSS attribute 'background-color'.
104      */
105     public static final Attribute BACKGROUND_COLOR =
106       new Attribute("background-color", false, "transparent");
107 
108     /**
109      * The CSS attribute 'background-image'.
110      */
111     public static final Attribute BACKGROUND_IMAGE =
112       new Attribute("background-image", false, "none");
113 
114     /**
115      * The CSS attribute 'background-position'.
116      */
117     public static final Attribute BACKGROUND_POSITION =
118       new Attribute("background-position", false, null);
119 
120     /**
121      * The CSS attribute 'background-repeat'.
122      */
123     public static final Attribute BACKGROUND_REPEAT =
124       new Attribute("background-repeat", false, "repeat");
125 
126     /**
127      * The CSS attribute 'border'.
128      */
129     public static final Attribute BORDER = new Attribute("border", false, null);
130 
131     /**
132      * The CSS attribute 'border-bottom'.
133      */
134     public static final Attribute BORDER_BOTTOM =
135       new Attribute("border-bottom", false, null);
136 
137     /**
138      * The CSS attribute 'border-bottom-width'.
139      */
140     public static final Attribute BORDER_BOTTOM_WIDTH =
141       new Attribute("border-bottom-width", false, "medium");
142 
143     /**
144      * The CSS attribute 'border-color'.
145      */
146     public static final Attribute BORDER_COLOR =
147       new Attribute("border-color", false, "black");
148 
149     /**
150      * The CSS attribute 'border-left'.
151      */
152     public static final Attribute BORDER_LEFT =
153       new Attribute("border-left", false, null);
154 
155     /**
156      * The CSS attribute 'border-left-width'.
157      */
158     public static final Attribute BORDER_LEFT_WIDTH =
159       new Attribute("border-left-width", false, "medium");
160 
161     /**
162      * The CSS attribute 'border-right'.
163      */
164     public static final Attribute BORDER_RIGHT =
165       new Attribute("border-right", false, null);
166 
167     /**
168      * The CSS attribute 'border-right-width'.
169      */
170     public static final Attribute BORDER_RIGHT_WIDTH =
171       new Attribute("border-right-width", false, "medium");
172 
173     /**
174      * The CSS attribute 'border-style'.
175      */
176     public static final Attribute BORDER_STYLE =
177       new Attribute("border-style", false, "none");
178 
179     /**
180      * The CSS attribute 'border-top'.
181      */
182     public static final Attribute BORDER_TOP =
183       new Attribute("border-top", false, null);
184 
185     /**
186      * The CSS attribute 'border-top-width'.
187      */
188     public static final Attribute BORDER_TOP_WIDTH =
189       new Attribute("border-top-width", false, "medium");
190 
191     /**
192      * The CSS attribute 'border-width'.
193      */
194     public static final Attribute BORDER_WIDTH =
195       new Attribute("border-width", false, "medium");
196 
197     /**
198      * The CSS attribute 'clear'.
199      */
200     public static final Attribute CLEAR = new Attribute("clear", false, "none");
201 
202     /**
203      * The CSS attribute 'color'.
204      */
205     public static final Attribute COLOR = new Attribute("color", true, "black");
206 
207     /**
208      * The CSS attribute 'display'.
209      */
210     public static final Attribute DISPLAY =
211       new Attribute("display", false, "block");
212 
213     /**
214      * The CSS attribute 'float'.
215      */
216     public static final Attribute FLOAT = new Attribute("float", false, "none");
217 
218     /**
219      * The CSS attribute 'font'.
220      */
221     public static final Attribute FONT = new Attribute("font", true, null);
222 
223     /**
224      * The CSS attribute 'font-family'.
225      */
226     public static final Attribute FONT_FAMILY =
227       new Attribute("font-family", true, null);
228 
229     /**
230      * The CSS attribute 'font-size'.
231      */
232     public static final Attribute FONT_SIZE =
233       new Attribute("font-size", true, "medium");
234 
235     /**
236      * The CSS attribute 'font-style'.
237      */
238     public static final Attribute FONT_STYLE =
239       new Attribute("font-style", true, "normal");
240 
241     /**
242      * The CSS attribute 'font-variant'.
243      */
244     public static final Attribute FONT_VARIANT =
245       new Attribute("font-variant", true, "normal");
246 
247     /**
248      * The CSS attribute 'font-weight'.
249      */
250     public static final Attribute FONT_WEIGHT =
251       new Attribute("font-weight", true, "normal");
252 
253     /**
254      * The CSS attribute 'height'.
255      */
256     public static final Attribute HEIGHT =
257       new Attribute("height", false, "auto");
258 
259     /**
260      * The CSS attribute 'letter-spacing'.
261      */
262     public static final Attribute LETTER_SPACING =
263       new Attribute("letter-spacing", true, "normal");
264 
265     /**
266      * The CSS attribute 'line-height'.
267      */
268     public static final Attribute LINE_HEIGHT =
269       new Attribute("line-height", true, "normal");
270 
271     /**
272      * The CSS attribute 'list-style'.
273      */
274     public static final Attribute LIST_STYLE =
275       new Attribute("list-style", true, null);
276 
277     /**
278      * The CSS attribute 'list-style-image'.
279      */
280     public static final Attribute LIST_STYLE_IMAGE =
281       new Attribute("list-style-image", true, "none");
282 
283     /**
284      * The CSS attribute 'list-style-position'.
285      */
286     public static final Attribute LIST_STYLE_POSITION =
287       new Attribute("list-style-position", true, "outside");
288 
289     /**
290      * The CSS attribute 'list-style-type'.
291      */
292     public static final Attribute LIST_STYLE_TYPE =
293       new Attribute("list-style-type", true, "disc");
294 
295     /**
296      * The CSS attribute 'margin'.
297      */
298     public static final Attribute MARGIN = new Attribute("margin", false, null);
299 
300     /**
301      * The CSS attribute 'margin-bottom'.
302      */
303     public static final Attribute MARGIN_BOTTOM =
304       new Attribute("margin-bottom", false, "0");
305 
306     /**
307      * The CSS attribute 'margin-left'.
308      */
309     public static final Attribute MARGIN_LEFT =
310       new Attribute("margin-left", false, "0");
311 
312     /**
313      * The CSS attribute 'margin-right'.
314      */
315     public static final Attribute MARGIN_RIGHT =
316       new Attribute("margin-right", false, "0");
317 
318     /**
319      * The CSS attribute 'margin-top'.
320      */
321     public static final Attribute MARGIN_TOP =
322       new Attribute("margin-top", false, "0");
323 
324     /**
325      * The CSS attribute 'padding'.
326      */
327     public static final Attribute PADDING =
328       new Attribute("padding", false, null);
329 
330     /**
331      * The CSS attribute 'padding-bottom'.
332      */
333     public static final Attribute PADDING_BOTTOM =
334       new Attribute("padding-bottom", false, "0");
335 
336     /**
337      * The CSS attribute 'padding-left'.
338      */
339     public static final Attribute PADDING_LEFT =
340       new Attribute("padding-left", false, "0");
341 
342     /**
343      * The CSS attribute 'padding-right'.
344      */
345     public static final Attribute PADDING_RIGHT =
346       new Attribute("padding-right", false, "0");
347 
348     /**
349      * The CSS attribute 'padding-top'.
350      */
351     public static final Attribute PADDING_TOP =
352       new Attribute("padding-top", false, "0");
353 
354     /**
355      * The CSS attribute 'text-align'.
356      */
357     public static final Attribute TEXT_ALIGN =
358       new Attribute("text-align", true, null);
359 
360     /**
361      * The CSS attribute 'text-decoration'.
362      */
363     public static final Attribute TEXT_DECORATION =
364       new Attribute("text-decoration", true, "none");
365 
366     /**
367      * The CSS attribute 'text-indent'.
368      */
369     public static final Attribute TEXT_INDENT =
370       new Attribute("text-indent", true, "0");
371 
372     /**
373      * The CSS attribute 'text-transform'.
374      */
375     public static final Attribute TEXT_TRANSFORM =
376       new Attribute("text-transform", true, "none");
377 
378     /**
379      * The CSS attribute 'vertical-align'.
380      */
381     public static final Attribute VERTICAL_ALIGN =
382       new Attribute("vertical-align", false, "baseline");
383 
384     /**
385      * The CSS attribute 'white-space'.
386      */
387     public static final Attribute WHITE_SPACE =
388       new Attribute("white-space", true, "normal");
389 
390     /**
391      * The CSS attribute 'width'.
392      */
393     public static final Attribute WIDTH =
394       new Attribute("width", false, "auto");
395 
396     /**
397      * The CSS attribute 'word-spacing'.
398      */
399     public static final Attribute WORD_SPACING =
400       new Attribute("word-spacing", true, "normal");
401 
402     // Some GNU Classpath specific extensions.
403     static final Attribute BORDER_TOP_STYLE =
404       new Attribute("border-top-style", false, null);
405     static final Attribute BORDER_BOTTOM_STYLE =
406       new Attribute("border-bottom-style", false, null);
407     static final Attribute BORDER_LEFT_STYLE =
408       new Attribute("border-left-style", false, null);
409     static final Attribute BORDER_RIGHT_STYLE =
410       new Attribute("border-right-style", false, null);
411     static final Attribute BORDER_TOP_COLOR =
412       new Attribute("border-top-color", false, null);
413     static final Attribute BORDER_BOTTOM_COLOR =
414       new Attribute("border-bottom-color", false, null);
415     static final Attribute BORDER_LEFT_COLOR =
416       new Attribute("border-left-color", false, null);
417     static final Attribute BORDER_RIGHT_COLOR =
418       new Attribute("border-right-color", false, null);
419     static final Attribute BORDER_SPACING =
420       new Attribute("border-spacing", false, null);
421     static final Attribute POSITION =
422       new Attribute("position", false, null);
423     static final Attribute LEFT =
424       new Attribute("left", false, null);
425     static final Attribute RIGHT =
426       new Attribute("right", false, null);
427     static final Attribute TOP =
428       new Attribute("top", false, null);
429     static final Attribute BOTTOM =
430       new Attribute("bottom", false, null);
431 
432     /**
433      * The attribute string.
434      */
435     String attStr;
436 
437     /**
438      * Indicates if this attribute should be inherited from it's parent or
439      * not.
440      */
441     boolean isInherited;
442 
443     /**
444      * A default value for this attribute if one exists, otherwise null.
445      */
446     String defaultValue;
447 
448     /**
449      * A HashMap of all attributes.
450      */
451     static HashMap attributeMap;
452 
453     /**
454      * Creates a new Attribute instance with the specified values.
455      *
456      * @param attr the attribute string
457      * @param inherited if the attribute should be inherited or not
458      * @param def a default value; may be <code>null</code>
459      */
Attribute(String attr, boolean inherited, String def)460     Attribute(String attr, boolean inherited, String def)
461     {
462       attStr = attr;
463       isInherited = inherited;
464       defaultValue = def;
465       if( attributeMap == null)
466         attributeMap = new HashMap();
467       attributeMap.put( attr, this );
468     }
469 
470     /**
471      * Returns the string representation of this attribute as specified
472      * in the CSS specification.
473      */
toString()474     public String toString()
475     {
476       return attStr;
477     }
478 
479     /**
480      * Returns <code>true</code> if the attribute should be inherited from
481      * the parent, <code>false</code> otherwise.
482      *
483      * @return <code>true</code> if the attribute should be inherited from
484      *         the parent, <code>false</code> otherwise
485      */
isInherited()486     public boolean isInherited()
487     {
488       return isInherited;
489     }
490 
491     /**
492      * Returns the default value of this attribute if one exists,
493      * <code>null</code> otherwise.
494      *
495      * @return the default value of this attribute if one exists,
496      *         <code>null</code> otherwise
497      */
getDefaultValue()498     public String getDefaultValue()
499     {
500       return defaultValue;
501     }
502   }
503 
504   /**
505    * Maps attribute values (String) to some converter class, based on the
506    * key.
507    *
508    * @param att the key
509    * @param v the value
510    *
511    * @return the wrapped value
512    */
getValue(Attribute att, String v)513   static Object getValue(Attribute att, String v)
514   {
515     Object o;
516     if (att == Attribute.FONT_SIZE)
517       o = new FontSize(v);
518     else if (att == Attribute.FONT_WEIGHT)
519       o = new FontWeight(v);
520     else if (att == Attribute.FONT_STYLE)
521       o = new FontStyle(v);
522     else if (att == Attribute.COLOR || att == Attribute.BACKGROUND_COLOR
523              || att == Attribute.BORDER_COLOR
524              || att == Attribute.BORDER_TOP_COLOR
525              || att == Attribute.BORDER_BOTTOM_COLOR
526              || att == Attribute.BORDER_LEFT_COLOR
527              || att == Attribute.BORDER_RIGHT_COLOR)
528       o = new CSSColor(v);
529     else if (att == Attribute.MARGIN || att == Attribute.MARGIN_BOTTOM
530              || att == Attribute.MARGIN_LEFT || att == Attribute.MARGIN_RIGHT
531              || att == Attribute.MARGIN_TOP || att == Attribute.WIDTH
532              || att == Attribute.HEIGHT
533              || att == Attribute.PADDING || att == Attribute.PADDING_BOTTOM
534              || att == Attribute.PADDING_LEFT || att == Attribute.PADDING_RIGHT
535              || att == Attribute.PADDING_TOP
536              || att == Attribute.LEFT || att == Attribute.RIGHT
537              || att == Attribute.TOP || att == Attribute.BOTTOM)
538       o = new Length(v);
539     else if (att == Attribute.BORDER_WIDTH || att == Attribute.BORDER_TOP_WIDTH
540              || att == Attribute.BORDER_LEFT_WIDTH
541              || att == Attribute.BORDER_RIGHT_WIDTH
542              || att == Attribute.BORDER_BOTTOM_WIDTH)
543       o = new BorderWidth(v);
544     else
545       o = v;
546     return o;
547   }
548 
addInternal(MutableAttributeSet atts, Attribute a, String v)549   static void addInternal(MutableAttributeSet atts, Attribute a, String v)
550   {
551     if (a == Attribute.BACKGROUND)
552       parseBackgroundShorthand(atts, v);
553     else if (a == Attribute.PADDING)
554       parsePaddingShorthand(atts, v);
555     else if (a == Attribute.MARGIN)
556       parseMarginShorthand(atts, v);
557     else if (a == Attribute.BORDER || a == Attribute.BORDER_LEFT
558              || a == Attribute.BORDER_RIGHT || a == Attribute.BORDER_TOP
559              || a == Attribute.BORDER_BOTTOM)
560       parseBorderShorthand(atts, v, a);
561   }
562 
563   /**
564    * Parses the background shorthand and translates it to more specific
565    * background attributes.
566    *
567    * @param atts the attributes
568    * @param v the value
569    */
parseBackgroundShorthand(MutableAttributeSet atts, String v)570   private static void parseBackgroundShorthand(MutableAttributeSet atts,
571                                                String v)
572   {
573     StringTokenizer tokens = new StringTokenizer(v, " ");
574     while (tokens.hasMoreElements())
575       {
576         String token = tokens.nextToken();
577         if (CSSColor.isValidColor(token))
578           atts.addAttribute(Attribute.BACKGROUND_COLOR,
579                             new CSSColor(token));
580       }
581   }
582 
583   /**
584    * Parses the padding shorthand and translates to the specific padding
585    * values.
586    *
587    * @param atts the attributes
588    * @param v the actual value
589    */
parsePaddingShorthand(MutableAttributeSet atts, String v)590   private static void parsePaddingShorthand(MutableAttributeSet atts, String v)
591   {
592     StringTokenizer tokens = new StringTokenizer(v, " ");
593     int numTokens = tokens.countTokens();
594     if (numTokens == 1)
595       {
596         Length l = new Length(tokens.nextToken());
597         atts.addAttribute(Attribute.PADDING_BOTTOM, l);
598         atts.addAttribute(Attribute.PADDING_LEFT, l);
599         atts.addAttribute(Attribute.PADDING_RIGHT, l);
600         atts.addAttribute(Attribute.PADDING_TOP, l);
601       }
602     else if (numTokens == 2)
603       {
604         Length l1 = new Length(tokens.nextToken());
605         Length l2 = new Length(tokens.nextToken());
606         atts.addAttribute(Attribute.PADDING_BOTTOM, l1);
607         atts.addAttribute(Attribute.PADDING_TOP, l1);
608         atts.addAttribute(Attribute.PADDING_LEFT, l2);
609         atts.addAttribute(Attribute.PADDING_RIGHT, l2);
610       }
611     else if (numTokens == 3)
612       {
613         Length l1 = new Length(tokens.nextToken());
614         Length l2 = new Length(tokens.nextToken());
615         Length l3 = new Length(tokens.nextToken());
616         atts.addAttribute(Attribute.PADDING_TOP, l1);
617         atts.addAttribute(Attribute.PADDING_LEFT, l2);
618         atts.addAttribute(Attribute.PADDING_RIGHT, l2);
619         atts.addAttribute(Attribute.PADDING_BOTTOM, l3);
620       }
621     else
622       {
623         Length l1 = new Length(tokens.nextToken());
624         Length l2 = new Length(tokens.nextToken());
625         Length l3 = new Length(tokens.nextToken());
626         Length l4 = new Length(tokens.nextToken());
627         atts.addAttribute(Attribute.PADDING_TOP, l1);
628         atts.addAttribute(Attribute.PADDING_RIGHT, l2);
629         atts.addAttribute(Attribute.PADDING_BOTTOM, l3);
630         atts.addAttribute(Attribute.PADDING_LEFT, l4);
631       }
632   }
633 
634   /**
635    * Parses the margin shorthand and translates to the specific margin
636    * values.
637    *
638    * @param atts the attributes
639    * @param v the actual value
640    */
parseMarginShorthand(MutableAttributeSet atts, String v)641   private static void parseMarginShorthand(MutableAttributeSet atts, String v)
642   {
643     StringTokenizer tokens = new StringTokenizer(v, " ");
644     int numTokens = tokens.countTokens();
645     if (numTokens == 1)
646       {
647         Length l = new Length(tokens.nextToken());
648         atts.addAttribute(Attribute.MARGIN_BOTTOM, l);
649         atts.addAttribute(Attribute.MARGIN_LEFT, l);
650         atts.addAttribute(Attribute.MARGIN_RIGHT, l);
651         atts.addAttribute(Attribute.MARGIN_TOP, l);
652       }
653     else if (numTokens == 2)
654       {
655         Length l1 = new Length(tokens.nextToken());
656         Length l2 = new Length(tokens.nextToken());
657         atts.addAttribute(Attribute.MARGIN_BOTTOM, l1);
658         atts.addAttribute(Attribute.MARGIN_TOP, l1);
659         atts.addAttribute(Attribute.MARGIN_LEFT, l2);
660         atts.addAttribute(Attribute.MARGIN_RIGHT, l2);
661       }
662     else if (numTokens == 3)
663       {
664         Length l1 = new Length(tokens.nextToken());
665         Length l2 = new Length(tokens.nextToken());
666         Length l3 = new Length(tokens.nextToken());
667         atts.addAttribute(Attribute.MARGIN_TOP, l1);
668         atts.addAttribute(Attribute.MARGIN_LEFT, l2);
669         atts.addAttribute(Attribute.MARGIN_RIGHT, l2);
670         atts.addAttribute(Attribute.MARGIN_BOTTOM, l3);
671       }
672     else
673       {
674         Length l1 = new Length(tokens.nextToken());
675         Length l2 = new Length(tokens.nextToken());
676         Length l3 = new Length(tokens.nextToken());
677         Length l4 = new Length(tokens.nextToken());
678         atts.addAttribute(Attribute.MARGIN_TOP, l1);
679         atts.addAttribute(Attribute.MARGIN_RIGHT, l2);
680         atts.addAttribute(Attribute.MARGIN_BOTTOM, l3);
681         atts.addAttribute(Attribute.MARGIN_LEFT, l4);
682       }
683   }
684 
685   /**
686    * Parses the CSS border shorthand attribute and translates it to the
687    * more specific border attributes.
688    *
689    * @param atts the attribute
690    * @param value the value
691    */
parseBorderShorthand(MutableAttributeSet atts, String value, Attribute cssAtt)692   private static void parseBorderShorthand(MutableAttributeSet atts,
693                                            String value, Attribute cssAtt)
694   {
695     StringTokenizer tokens = new StringTokenizer(value, " ");
696     while (tokens.hasMoreTokens())
697       {
698         String token = tokens.nextToken();
699         if (BorderStyle.isValidStyle(token))
700           {
701             if (cssAtt == Attribute.BORDER_LEFT || cssAtt == Attribute.BORDER)
702               atts.addAttribute(Attribute.BORDER_LEFT_STYLE, token);
703             if (cssAtt == Attribute.BORDER_RIGHT || cssAtt == Attribute.BORDER)
704               atts.addAttribute(Attribute.BORDER_RIGHT_STYLE, token);
705             if (cssAtt == Attribute.BORDER_BOTTOM || cssAtt == Attribute.BORDER)
706               atts.addAttribute(Attribute.BORDER_BOTTOM_STYLE, token);
707             if (cssAtt == Attribute.BORDER_TOP || cssAtt == Attribute.BORDER)
708               atts.addAttribute(Attribute.BORDER_TOP_STYLE, token);
709           }
710         else if (BorderWidth.isValid(token))
711           {
712             BorderWidth w = new BorderWidth(token);
713             if (cssAtt == Attribute.BORDER_LEFT || cssAtt == Attribute.BORDER)
714               atts.addAttribute(Attribute.BORDER_LEFT_WIDTH, w);
715             if (cssAtt == Attribute.BORDER_RIGHT || cssAtt == Attribute.BORDER)
716               atts.addAttribute(Attribute.BORDER_RIGHT_WIDTH, w);
717             if (cssAtt == Attribute.BORDER_BOTTOM || cssAtt == Attribute.BORDER)
718               atts.addAttribute(Attribute.BORDER_BOTTOM_WIDTH, w);
719             if (cssAtt == Attribute.BORDER_TOP || cssAtt == Attribute.BORDER)
720               atts.addAttribute(Attribute.BORDER_TOP_WIDTH, w);
721           }
722         else if (CSSColor.isValidColor(token))
723           {
724             CSSColor c = new CSSColor(token);
725             if (cssAtt == Attribute.BORDER_LEFT || cssAtt == Attribute.BORDER)
726               atts.addAttribute(Attribute.BORDER_LEFT_COLOR, c);
727             if (cssAtt == Attribute.BORDER_RIGHT || cssAtt == Attribute.BORDER)
728               atts.addAttribute(Attribute.BORDER_RIGHT_COLOR, c);
729             if (cssAtt == Attribute.BORDER_BOTTOM || cssAtt == Attribute.BORDER)
730               atts.addAttribute(Attribute.BORDER_BOTTOM_COLOR, c);
731             if (cssAtt == Attribute.BORDER_TOP || cssAtt == Attribute.BORDER)
732               atts.addAttribute(Attribute.BORDER_TOP_COLOR, c);
733           }
734       }
735   }
736 }
737