1 /*
2  * Copyright (c) 1998, 2013, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 package javax.swing.text.html;
26 
27 import java.io.*;
28 import java.util.Hashtable;
29 import javax.swing.text.AttributeSet;
30 import javax.swing.text.StyleConstants;
31 import javax.swing.text.StyleContext;
32 
33 /**
34  * Constants used in the <code>HTMLDocument</code>.  These
35  * are basically tag and attribute definitions.
36  *
37  * @author  Timothy Prinzing
38  * @author  Sunita Mani
39  *
40  */
41 public class HTML {
42 
43     /**
44      * Typesafe enumeration for an HTML tag.  Although the
45      * set of HTML tags is a closed set, we have left the
46      * set open so that people can add their own tag types
47      * to their custom parser and still communicate to the
48      * reader.
49      */
50     public static class Tag {
51 
52         /** @since 1.3 */
Tag()53         public Tag() {}
54 
55         /**
56          * Creates a new <code>Tag</code> with the specified <code>id</code>,
57          * and with <code>causesBreak</code> and <code>isBlock</code>
58          * set to <code>false</code>.
59          *
60          * @param id  the id of the new tag
61          */
Tag(String id)62         protected Tag(String id) {
63             this(id, false, false);
64         }
65 
66         /**
67          * Creates a new <code>Tag</code> with the specified <code>id</code>;
68          * <code>causesBreak</code> and <code>isBlock</code> are defined
69          * by the user.
70          *
71          * @param id the id of the new tag
72          * @param causesBreak  <code>true</code> if this tag
73          *    causes a break to the flow of data
74          * @param isBlock <code>true</code> if the tag is used
75          *    to add structure to a document
76          */
Tag(String id, boolean causesBreak, boolean isBlock)77         protected Tag(String id, boolean causesBreak, boolean isBlock) {
78             name = id;
79             this.breakTag = causesBreak;
80             this.blockTag = isBlock;
81         }
82 
83         /**
84          * Returns <code>true</code> if this tag is a block
85          * tag, which is a tag used to add structure to a
86          * document.
87          *
88          * @return <code>true</code> if this tag is a block
89          *   tag, otherwise returns <code>false</code>
90          */
isBlock()91         public boolean isBlock() {
92             return blockTag;
93         }
94 
95         /**
96          * Returns <code>true</code> if this tag causes a
97          * line break to the flow of data, otherwise returns
98          * <code>false</code>.
99          *
100          * @return <code>true</code> if this tag causes a
101          *   line break to the flow of data, otherwise returns
102          *   <code>false</code>
103          */
breaksFlow()104         public boolean breaksFlow() {
105             return breakTag;
106         }
107 
108         /**
109          * Returns <code>true</code> if this tag is pre-formatted,
110          * which is true if the tag is either <code>PRE</code> or
111          * <code>TEXTAREA</code>.
112          *
113          * @return <code>true</code> if this tag is pre-formatted,
114          *   otherwise returns <code>false</code>
115          */
isPreformatted()116         public boolean isPreformatted() {
117             return (this == PRE || this == TEXTAREA);
118         }
119 
120         /**
121          * Returns the string representation of the
122          * tag.
123          *
124          * @return the <code>String</code> representation of the tag
125          */
toString()126         public String toString() {
127             return name;
128         }
129 
130         /**
131          * Returns <code>true</code> if this tag is considered to be a paragraph
132          * in the internal HTML model. <code>false</code> - otherwise.
133          *
134          * @return <code>true</code> if this tag is considered to be a paragraph
135          *         in the internal HTML model. <code>false</code> - otherwise.
136          * @see HTMLDocument.HTMLReader.ParagraphAction
137          */
isParagraph()138         boolean isParagraph() {
139             return (
140                 this == P
141                    || this == IMPLIED
142                    || this == DT
143                    || this == H1
144                    || this == H2
145                    || this == H3
146                    || this == H4
147                    || this == H5
148                    || this == H6
149             );
150         }
151 
152         boolean blockTag;
153         boolean breakTag;
154         String name;
155         boolean unknown;
156 
157         // --- Tag Names -----------------------------------
158 
159         public static final Tag A = new Tag("a");
160         public static final Tag ADDRESS = new Tag("address");
161         public static final Tag APPLET = new Tag("applet");
162         public static final Tag AREA = new Tag("area");
163         public static final Tag B = new Tag("b");
164         public static final Tag BASE = new Tag("base");
165         public static final Tag BASEFONT = new Tag("basefont");
166         public static final Tag BIG = new Tag("big");
167         public static final Tag BLOCKQUOTE = new Tag("blockquote", true, true);
168         public static final Tag BODY = new Tag("body", true, true);
169         public static final Tag BR = new Tag("br", true, false);
170         public static final Tag CAPTION = new Tag("caption");
171         public static final Tag CENTER = new Tag("center", true, false);
172         public static final Tag CITE = new Tag("cite");
173         public static final Tag CODE = new Tag("code");
174         public static final Tag DD = new Tag("dd", true, true);
175         public static final Tag DFN = new Tag("dfn");
176         public static final Tag DIR = new Tag("dir", true, true);
177         public static final Tag DIV = new Tag("div", true, true);
178         public static final Tag DL = new Tag("dl", true, true);
179         public static final Tag DT = new Tag("dt", true, true);
180         public static final Tag EM = new Tag("em");
181         public static final Tag FONT = new Tag("font");
182         public static final Tag FORM = new Tag("form", true, false);
183         public static final Tag FRAME = new Tag("frame");
184         public static final Tag FRAMESET = new Tag("frameset");
185         public static final Tag H1 = new Tag("h1", true, true);
186         public static final Tag H2 = new Tag("h2", true, true);
187         public static final Tag H3 = new Tag("h3", true, true);
188         public static final Tag H4 = new Tag("h4", true, true);
189         public static final Tag H5 = new Tag("h5", true, true);
190         public static final Tag H6 = new Tag("h6", true, true);
191         public static final Tag HEAD = new Tag("head", true, true);
192         public static final Tag HR = new Tag("hr", true, false);
193         public static final Tag HTML = new Tag("html", true, false);
194         public static final Tag I = new Tag("i");
195         public static final Tag IMG = new Tag("img");
196         public static final Tag INPUT = new Tag("input");
197         public static final Tag ISINDEX = new Tag("isindex", true, false);
198         public static final Tag KBD = new Tag("kbd");
199         public static final Tag LI = new Tag("li", true, true);
200         public static final Tag LINK = new Tag("link");
201         public static final Tag MAP = new Tag("map");
202         public static final Tag MENU = new Tag("menu", true, true);
203         public static final Tag META = new Tag("meta");
204         /*public*/ static final Tag NOBR = new Tag("nobr");
205         public static final Tag NOFRAMES = new Tag("noframes", true, true);
206         public static final Tag OBJECT = new Tag("object");
207         public static final Tag OL = new Tag("ol", true, true);
208         public static final Tag OPTION = new Tag("option");
209         public static final Tag P = new Tag("p", true, true);
210         public static final Tag PARAM = new Tag("param");
211         public static final Tag PRE = new Tag("pre", true, true);
212         public static final Tag SAMP = new Tag("samp");
213         public static final Tag SCRIPT = new Tag("script");
214         public static final Tag SELECT = new Tag("select");
215         public static final Tag SMALL = new Tag("small");
216         public static final Tag SPAN = new Tag("span");
217         public static final Tag STRIKE = new Tag("strike");
218         public static final Tag S = new Tag("s");
219         public static final Tag STRONG = new Tag("strong");
220         public static final Tag STYLE = new Tag("style");
221         public static final Tag SUB = new Tag("sub");
222         public static final Tag SUP = new Tag("sup");
223         public static final Tag TABLE = new Tag("table", false, true);
224         public static final Tag TD = new Tag("td", true, true);
225         public static final Tag TEXTAREA = new Tag("textarea");
226         public static final Tag TH = new Tag("th", true, true);
227         public static final Tag TITLE = new Tag("title", true, true);
228         public static final Tag TR = new Tag("tr", false, true);
229         public static final Tag TT = new Tag("tt");
230         public static final Tag U = new Tag("u");
231         public static final Tag UL = new Tag("ul", true, true);
232         public static final Tag VAR = new Tag("var");
233 
234         /**
235          * All text content must be in a paragraph element.
236          * If a paragraph didn't exist when content was
237          * encountered, a paragraph is manufactured.
238          * <p>
239          * This is a tag synthesized by the HTML reader.
240          * Since elements are identified by their tag type,
241          * we create a some fake tag types to mark the elements
242          * that were manufactured.
243          */
244         public static final Tag IMPLIED = new Tag("p-implied");
245 
246         /**
247          * All text content is labeled with this tag.
248          * <p>
249          * This is a tag synthesized by the HTML reader.
250          * Since elements are identified by their tag type,
251          * we create a some fake tag types to mark the elements
252          * that were manufactured.
253          */
254         public static final Tag CONTENT = new Tag("content");
255 
256         /**
257          * All comments are labeled with this tag.
258          * <p>
259          * This is a tag synthesized by the HTML reader.
260          * Since elements are identified by their tag type,
261          * we create a some fake tag types to mark the elements
262          * that were manufactured.
263          */
264         public static final Tag COMMENT = new Tag("comment");
265 
266         static final Tag allTags[]  = {
267             A, ADDRESS, APPLET, AREA, B, BASE, BASEFONT, BIG,
268             BLOCKQUOTE, BODY, BR, CAPTION, CENTER, CITE, CODE,
269             DD, DFN, DIR, DIV, DL, DT, EM, FONT, FORM, FRAME,
270             FRAMESET, H1, H2, H3, H4, H5, H6, HEAD, HR, HTML,
271             I, IMG, INPUT, ISINDEX, KBD, LI, LINK, MAP, MENU,
272             META, NOBR, NOFRAMES, OBJECT, OL, OPTION, P, PARAM,
273             PRE, SAMP, SCRIPT, SELECT, SMALL, SPAN, STRIKE, S,
274             STRONG, STYLE, SUB, SUP, TABLE, TD, TEXTAREA,
275             TH, TITLE, TR, TT, U, UL, VAR
276         };
277 
278         static {
279             // Force HTMLs static initialize to be loaded.
280             getTag("html");
281         }
282     }
283 
284     // There is no unique instance of UnknownTag, so we allow it to be
285     // Serializable.
286     public static class UnknownTag extends Tag implements Serializable {
287 
288         /**
289          * Creates a new <code>UnknownTag</code> with the specified
290          * <code>id</code>.
291          * @param id the id of the new tag
292          */
UnknownTag(String id)293         public UnknownTag(String id) {
294             super(id);
295         }
296 
297         /**
298          * Returns the hash code which corresponds to the string
299          * for this tag.
300          */
hashCode()301         public int hashCode() {
302             return toString().hashCode();
303         }
304 
305         /**
306          * Compares this object to the specified object.
307          * The result is <code>true</code> if and only if the argument is not
308          * <code>null</code> and is an <code>UnknownTag</code> object
309          * with the same name.
310          *
311          * @param     obj   the object to compare this tag with
312          * @return    <code>true</code> if the objects are equal;
313          *            <code>false</code> otherwise
314          */
equals(Object obj)315         public boolean equals(Object obj) {
316             if (obj instanceof UnknownTag) {
317                 return toString().equals(obj.toString());
318             }
319             return false;
320         }
321 
writeObject(java.io.ObjectOutputStream s)322         private void writeObject(java.io.ObjectOutputStream s)
323                      throws IOException {
324             s.defaultWriteObject();
325             s.writeBoolean(blockTag);
326             s.writeBoolean(breakTag);
327             s.writeBoolean(unknown);
328             s.writeObject(name);
329         }
330 
readObject(ObjectInputStream s)331         private void readObject(ObjectInputStream s)
332             throws ClassNotFoundException, IOException {
333             s.defaultReadObject();
334             blockTag = s.readBoolean();
335             breakTag = s.readBoolean();
336             unknown = s.readBoolean();
337             name = (String)s.readObject();
338         }
339     }
340 
341     /**
342      * Typesafe enumeration representing an HTML
343      * attribute.
344      */
345     public static final class Attribute {
346 
347         /**
348          * Creates a new <code>Attribute</code> with the specified
349          * <code>id</code>.
350          *
351          * @param id the id of the new <code>Attribute</code>
352          */
Attribute(String id)353         Attribute(String id) {
354             name = id;
355         }
356 
357         /**
358          * Returns the string representation of this attribute.
359          * @return the string representation of this attribute
360          */
toString()361         public String toString() {
362             return name;
363         }
364 
365         private String name;
366 
367         public static final Attribute SIZE = new Attribute("size");
368         public static final Attribute COLOR = new Attribute("color");
369         public static final Attribute CLEAR = new Attribute("clear");
370         public static final Attribute BACKGROUND = new Attribute("background");
371         public static final Attribute BGCOLOR = new Attribute("bgcolor");
372         public static final Attribute TEXT = new Attribute("text");
373         public static final Attribute LINK = new Attribute("link");
374         public static final Attribute VLINK = new Attribute("vlink");
375         public static final Attribute ALINK = new Attribute("alink");
376         public static final Attribute WIDTH = new Attribute("width");
377         public static final Attribute HEIGHT = new Attribute("height");
378         public static final Attribute ALIGN = new Attribute("align");
379         public static final Attribute NAME = new Attribute("name");
380         public static final Attribute HREF = new Attribute("href");
381         public static final Attribute REL = new Attribute("rel");
382         public static final Attribute REV = new Attribute("rev");
383         public static final Attribute TITLE = new Attribute("title");
384         public static final Attribute TARGET = new Attribute("target");
385         public static final Attribute SHAPE = new Attribute("shape");
386         public static final Attribute COORDS = new Attribute("coords");
387         public static final Attribute ISMAP = new Attribute("ismap");
388         public static final Attribute NOHREF = new Attribute("nohref");
389         public static final Attribute ALT = new Attribute("alt");
390         public static final Attribute ID = new Attribute("id");
391         public static final Attribute SRC = new Attribute("src");
392         public static final Attribute HSPACE = new Attribute("hspace");
393         public static final Attribute VSPACE = new Attribute("vspace");
394         public static final Attribute USEMAP = new Attribute("usemap");
395         public static final Attribute LOWSRC = new Attribute("lowsrc");
396         public static final Attribute CODEBASE = new Attribute("codebase");
397         public static final Attribute CODE = new Attribute("code");
398         public static final Attribute ARCHIVE = new Attribute("archive");
399         public static final Attribute VALUE = new Attribute("value");
400         public static final Attribute VALUETYPE = new Attribute("valuetype");
401         public static final Attribute TYPE = new Attribute("type");
402         public static final Attribute CLASS = new Attribute("class");
403         public static final Attribute STYLE = new Attribute("style");
404         public static final Attribute LANG = new Attribute("lang");
405         public static final Attribute FACE = new Attribute("face");
406         public static final Attribute DIR = new Attribute("dir");
407         public static final Attribute DECLARE = new Attribute("declare");
408         public static final Attribute CLASSID = new Attribute("classid");
409         public static final Attribute DATA = new Attribute("data");
410         public static final Attribute CODETYPE = new Attribute("codetype");
411         public static final Attribute STANDBY = new Attribute("standby");
412         public static final Attribute BORDER = new Attribute("border");
413         public static final Attribute SHAPES = new Attribute("shapes");
414         public static final Attribute NOSHADE = new Attribute("noshade");
415         public static final Attribute COMPACT = new Attribute("compact");
416         public static final Attribute START = new Attribute("start");
417         public static final Attribute ACTION = new Attribute("action");
418         public static final Attribute METHOD = new Attribute("method");
419         public static final Attribute ENCTYPE = new Attribute("enctype");
420         public static final Attribute CHECKED = new Attribute("checked");
421         public static final Attribute MAXLENGTH = new Attribute("maxlength");
422         public static final Attribute MULTIPLE = new Attribute("multiple");
423         public static final Attribute SELECTED = new Attribute("selected");
424         public static final Attribute ROWS = new Attribute("rows");
425         public static final Attribute COLS = new Attribute("cols");
426         public static final Attribute DUMMY = new Attribute("dummy");
427         public static final Attribute CELLSPACING = new Attribute("cellspacing");
428         public static final Attribute CELLPADDING = new Attribute("cellpadding");
429         public static final Attribute VALIGN = new Attribute("valign");
430         public static final Attribute HALIGN = new Attribute("halign");
431         public static final Attribute NOWRAP = new Attribute("nowrap");
432         public static final Attribute ROWSPAN = new Attribute("rowspan");
433         public static final Attribute COLSPAN = new Attribute("colspan");
434         public static final Attribute PROMPT = new Attribute("prompt");
435         public static final Attribute HTTPEQUIV = new Attribute("http-equiv");
436         public static final Attribute CONTENT = new Attribute("content");
437         public static final Attribute LANGUAGE = new Attribute("language");
438         public static final Attribute VERSION = new Attribute("version");
439         public static final Attribute N = new Attribute("n");
440         public static final Attribute FRAMEBORDER = new Attribute("frameborder");
441         public static final Attribute MARGINWIDTH = new Attribute("marginwidth");
442         public static final Attribute MARGINHEIGHT = new Attribute("marginheight");
443         public static final Attribute SCROLLING = new Attribute("scrolling");
444         public static final Attribute NORESIZE = new Attribute("noresize");
445         public static final Attribute ENDTAG = new Attribute("endtag");
446         public static final Attribute COMMENT = new Attribute("comment");
447         static final Attribute MEDIA = new Attribute("media");
448 
449         static final Attribute allAttributes[] = {
450             FACE,
451             COMMENT,
452             SIZE,
453             COLOR,
454             CLEAR,
455             BACKGROUND,
456             BGCOLOR,
457             TEXT,
458             LINK,
459             VLINK,
460             ALINK,
461             WIDTH,
462             HEIGHT,
463             ALIGN,
464             NAME,
465             HREF,
466             REL,
467             REV,
468             TITLE,
469             TARGET,
470             SHAPE,
471             COORDS,
472             ISMAP,
473             NOHREF,
474             ALT,
475             ID,
476             SRC,
477             HSPACE,
478             VSPACE,
479             USEMAP,
480             LOWSRC,
481             CODEBASE,
482             CODE,
483             ARCHIVE,
484             VALUE,
485             VALUETYPE,
486             TYPE,
487             CLASS,
488             STYLE,
489             LANG,
490             DIR,
491             DECLARE,
492             CLASSID,
493             DATA,
494             CODETYPE,
495             STANDBY,
496             BORDER,
497             SHAPES,
498             NOSHADE,
499             COMPACT,
500             START,
501             ACTION,
502             METHOD,
503             ENCTYPE,
504             CHECKED,
505             MAXLENGTH,
506             MULTIPLE,
507             SELECTED,
508             ROWS,
509             COLS,
510             DUMMY,
511             CELLSPACING,
512             CELLPADDING,
513             VALIGN,
514             HALIGN,
515             NOWRAP,
516             ROWSPAN,
517             COLSPAN,
518             PROMPT,
519             HTTPEQUIV,
520             CONTENT,
521             LANGUAGE,
522             VERSION,
523             N,
524             FRAMEBORDER,
525             MARGINWIDTH,
526             MARGINHEIGHT,
527             SCROLLING,
528             NORESIZE,
529             MEDIA,
530             ENDTAG
531         };
532     }
533 
534     // The secret to 73, is that, given that the Hashtable contents
535     // never change once the static initialization happens, the initial size
536     // that the hashtable grew to was determined, and then that very size
537     // is used.
538     //
539     private static final Hashtable<String, Tag> tagHashtable = new Hashtable<String, Tag>(73);
540 
541     /** Maps from StyleConstant key to HTML.Tag. */
542     private static final Hashtable<Object, Tag> scMapping = new Hashtable<Object, Tag>(8);
543 
544     static {
545 
546         for (int i = 0; i < Tag.allTags.length; i++ ) {
tagHashtable.put(Tag.allTags[i].toString(), Tag.allTags[i])547             tagHashtable.put(Tag.allTags[i].toString(), Tag.allTags[i]);
548             StyleContext.registerStaticAttributeKey(Tag.allTags[i]);
549         }
550         StyleContext.registerStaticAttributeKey(Tag.IMPLIED);
551         StyleContext.registerStaticAttributeKey(Tag.CONTENT);
552         StyleContext.registerStaticAttributeKey(Tag.COMMENT);
553         for (int i = 0; i < Attribute.allAttributes.length; i++) {
554             StyleContext.registerStaticAttributeKey(Attribute.
555                                                     allAttributes[i]);
556         }
557         StyleContext.registerStaticAttributeKey(HTML.NULL_ATTRIBUTE_VALUE);
scMapping.put(StyleConstants.Bold, Tag.B)558         scMapping.put(StyleConstants.Bold, Tag.B);
scMapping.put(StyleConstants.Italic, Tag.I)559         scMapping.put(StyleConstants.Italic, Tag.I);
scMapping.put(StyleConstants.Underline, Tag.U)560         scMapping.put(StyleConstants.Underline, Tag.U);
scMapping.put(StyleConstants.StrikeThrough, Tag.STRIKE)561         scMapping.put(StyleConstants.StrikeThrough, Tag.STRIKE);
scMapping.put(StyleConstants.Superscript, Tag.SUP)562         scMapping.put(StyleConstants.Superscript, Tag.SUP);
scMapping.put(StyleConstants.Subscript, Tag.SUB)563         scMapping.put(StyleConstants.Subscript, Tag.SUB);
scMapping.put(StyleConstants.FontFamily, Tag.FONT)564         scMapping.put(StyleConstants.FontFamily, Tag.FONT);
scMapping.put(StyleConstants.FontSize, Tag.FONT)565         scMapping.put(StyleConstants.FontSize, Tag.FONT);
566     }
567 
568     /**
569      * Returns the set of actual HTML tags that
570      * are recognized by the default HTML reader.
571      * This set does not include tags that are
572      * manufactured by the reader.
573      */
getAllTags()574     public static Tag[] getAllTags() {
575         Tag[] tags = new Tag[Tag.allTags.length];
576         System.arraycopy(Tag.allTags, 0, tags, 0, Tag.allTags.length);
577         return tags;
578     }
579 
580     /**
581      * Fetches a tag constant for a well-known tag name (i.e. one of
582      * the tags in the set {A, ADDRESS, APPLET, AREA, B,
583      * BASE, BASEFONT, BIG,
584      * BLOCKQUOTE, BODY, BR, CAPTION, CENTER, CITE, CODE,
585      * DD, DFN, DIR, DIV, DL, DT, EM, FONT, FORM, FRAME,
586      * FRAMESET, H1, H2, H3, H4, H5, H6, HEAD, HR, HTML,
587      * I, IMG, INPUT, ISINDEX, KBD, LI, LINK, MAP, MENU,
588      * META, NOBR, NOFRAMES, OBJECT, OL, OPTION, P, PARAM,
589      * PRE, SAMP, SCRIPT, SELECT, SMALL, SPAN, STRIKE, S,
590      * STRONG, STYLE, SUB, SUP, TABLE, TD, TEXTAREA,
591      * TH, TITLE, TR, TT, U, UL, VAR}.  If the given
592      * name does not represent one of the well-known tags, then
593      * <code>null</code> will be returned.
594      *
595      * @param tagName the <code>String</code> name requested
596      * @return a tag constant corresponding to the <code>tagName</code>,
597      *    or <code>null</code> if not found
598      */
getTag(String tagName)599     public static Tag getTag(String tagName) {
600 
601         Tag t =  tagHashtable.get(tagName);
602         return (t == null ? null : t);
603     }
604 
605     /**
606      * Returns the HTML <code>Tag</code> associated with the
607      * <code>StyleConstants</code> key <code>sc</code>.
608      * If no matching <code>Tag</code> is found, returns
609      * <code>null</code>.
610      *
611      * @param sc the <code>StyleConstants</code> key
612      * @return tag which corresponds to <code>sc</code>, or
613      *   <code>null</code> if not found
614      */
getTagForStyleConstantsKey(StyleConstants sc)615     static Tag getTagForStyleConstantsKey(StyleConstants sc) {
616         return scMapping.get(sc);
617     }
618 
619     /**
620      * Fetches an integer attribute value.  Attribute values
621      * are stored as a string, and this is a convenience method
622      * to convert to an actual integer.
623      *
624      * @param attr the set of attributes to use to try to fetch a value
625      * @param key the key to use to fetch the value
626      * @param def the default value to use if the attribute isn't
627      *  defined or there is an error converting to an integer
628      */
getIntegerAttributeValue(AttributeSet attr, Attribute key, int def)629     public static int getIntegerAttributeValue(AttributeSet attr,
630                                                Attribute key, int def) {
631         int value = def;
632         String istr = (String) attr.getAttribute(key);
633         if (istr != null) {
634             try {
635                 value = Integer.valueOf(istr).intValue();
636             } catch (NumberFormatException e) {
637                 value = def;
638             }
639         }
640         return value;
641     }
642 
643     //  This is used in cases where the value for the attribute has not
644     //  been specified.
645     //
646     public static final String NULL_ATTRIBUTE_VALUE = "#DEFAULT";
647 
648     // size determined similar to size of tagHashtable
649     private static final Hashtable<String, Attribute> attHashtable = new Hashtable<String, Attribute>(77);
650 
651     static {
652 
653         for (int i = 0; i < Attribute.allAttributes.length; i++ ) {
attHashtable.put(Attribute.allAttributes[i].toString(), Attribute.allAttributes[i])654             attHashtable.put(Attribute.allAttributes[i].toString(), Attribute.allAttributes[i]);
655         }
656     }
657 
658     /**
659      * Returns the set of HTML attributes recognized.
660      * @return the set of HTML attributes recognized
661      */
getAllAttributeKeys()662     public static Attribute[] getAllAttributeKeys() {
663         Attribute[] attributes = new Attribute[Attribute.allAttributes.length];
664         System.arraycopy(Attribute.allAttributes, 0,
665                          attributes, 0, Attribute.allAttributes.length);
666         return attributes;
667     }
668 
669     /**
670      * Fetches an attribute constant for a well-known attribute name
671      * (i.e. one of the attributes in the set {FACE, COMMENT, SIZE,
672      * COLOR, CLEAR, BACKGROUND, BGCOLOR, TEXT, LINK, VLINK, ALINK,
673      * WIDTH, HEIGHT, ALIGN, NAME, HREF, REL, REV, TITLE, TARGET,
674      * SHAPE, COORDS, ISMAP, NOHREF, ALT, ID, SRC, HSPACE, VSPACE,
675      * USEMAP, LOWSRC, CODEBASE, CODE, ARCHIVE, VALUE, VALUETYPE,
676      * TYPE, CLASS, STYLE, LANG, DIR, DECLARE, CLASSID, DATA, CODETYPE,
677      * STANDBY, BORDER, SHAPES, NOSHADE, COMPACT, START, ACTION, METHOD,
678      * ENCTYPE, CHECKED, MAXLENGTH, MULTIPLE, SELECTED, ROWS, COLS,
679      * DUMMY, CELLSPACING, CELLPADDING, VALIGN, HALIGN, NOWRAP, ROWSPAN,
680      * COLSPAN, PROMPT, HTTPEQUIV, CONTENT, LANGUAGE, VERSION, N,
681      * FRAMEBORDER, MARGINWIDTH, MARGINHEIGHT, SCROLLING, NORESIZE,
682      * MEDIA, ENDTAG}).
683      * If the given name does not represent one of the well-known attributes,
684      * then <code>null</code> will be returned.
685      *
686      * @param attName the <code>String</code> requested
687      * @return the <code>Attribute</code> corresponding to <code>attName</code>
688      */
getAttributeKey(String attName)689     public static Attribute getAttributeKey(String attName) {
690         Attribute a = attHashtable.get(attName);
691         if (a == null) {
692           return null;
693         }
694         return a;
695     }
696 
697 }
698