001    /* HTML.java -- HTML document tag constants
002       Copyright (C) 2002 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    
039    package javax.swing.text.html;
040    
041    import java.io.Serializable;
042    
043    import java.lang.reflect.Field;
044    import java.lang.reflect.Modifier;
045    
046    import java.util.Map;
047    import java.util.TreeMap;
048    
049    import javax.swing.text.AttributeSet;
050    
051    /**
052     * HTML attribute and tag definitions.
053     * @author Audrius Meskauskas (AudriusA@Bioinformatics.org)
054     */
055    public class HTML
056    {
057      /**
058       * Represents a HTML attribute.
059       */
060      public static final class Attribute
061      {
062        /**
063         * The action attribute
064         */
065        public static final Attribute ACTION = new Attribute("action");
066    
067        /**
068         * The align attribute
069         */
070        public static final Attribute ALIGN = new Attribute("align");
071    
072        /**
073         * The alink attribute
074         */
075        public static final Attribute ALINK = new Attribute("alink");
076    
077        /**
078         * The alt attribute
079         */
080        public static final Attribute ALT = new Attribute("alt");
081    
082        /**
083         * The archive attribute
084         */
085        public static final Attribute ARCHIVE = new Attribute("archive");
086    
087        /**
088         * The background attribute
089         */
090        public static final Attribute BACKGROUND = new Attribute("background");
091    
092        /**
093         * The bgcolor attribute
094         */
095        public static final Attribute BGCOLOR = new Attribute("bgcolor");
096    
097        /**
098         * The border attribute
099         */
100        public static final Attribute BORDER = new Attribute("border");
101    
102        /**
103         * The cellpadding attribute
104         */
105        public static final Attribute CELLPADDING = new Attribute("cellpadding");
106    
107        /**
108         * The cellspacing attribute
109         */
110        public static final Attribute CELLSPACING = new Attribute("cellspacing");
111    
112        /**
113         * The checked attribute
114         */
115        public static final Attribute CHECKED = new Attribute("checked");
116    
117        /**
118         * The class attribute
119         */
120        public static final Attribute CLASS = new Attribute("class");
121    
122        /**
123         * The classid attribute
124         */
125        public static final Attribute CLASSID = new Attribute("classid");
126    
127        /**
128         * The clear attribute
129         */
130        public static final Attribute CLEAR = new Attribute("clear");
131    
132        /**
133         * The code attribute
134         */
135        public static final Attribute CODE = new Attribute("code");
136    
137        /**
138         * The codebase attribute
139         */
140        public static final Attribute CODEBASE = new Attribute("codebase");
141    
142        /**
143         * The codetype attribute
144         */
145        public static final Attribute CODETYPE = new Attribute("codetype");
146    
147        /**
148         * The color attribute
149         */
150        public static final Attribute COLOR = new Attribute("color");
151    
152        /**
153         * The cols attribute
154         */
155        public static final Attribute COLS = new Attribute("cols");
156    
157        /**
158         * The colspan attribute
159         */
160        public static final Attribute COLSPAN = new Attribute("colspan");
161    
162        /**
163         * The comment attribute
164         */
165        public static final Attribute COMMENT = new Attribute("comment");
166    
167        /**
168         * The compact attribute
169         */
170        public static final Attribute COMPACT = new Attribute("compact");
171    
172        /**
173         * The content attribute
174         */
175        public static final Attribute CONTENT = new Attribute("content");
176    
177        /**
178         * The coords attribute
179         */
180        public static final Attribute COORDS = new Attribute("coords");
181    
182        /**
183         * The data attribute
184         */
185        public static final Attribute DATA = new Attribute("data");
186    
187        /**
188         * The declare attribute
189         */
190        public static final Attribute DECLARE = new Attribute("declare");
191    
192        /**
193         * The dir attribute
194         */
195        public static final Attribute DIR = new Attribute("dir");
196    
197        /**
198         * The dummy attribute
199         */
200        public static final Attribute DUMMY = new Attribute("dummy");
201    
202        /**
203         * The enctype attribute
204         */
205        public static final Attribute ENCTYPE = new Attribute("enctype");
206    
207        /**
208         * The endtag attribute
209         */
210        public static final Attribute ENDTAG = new Attribute("endtag");
211    
212        /**
213         *  The face attribute
214         */
215        public static final Attribute FACE = new Attribute("face");
216    
217        /**
218         *  The frameborder attribute
219         */
220        public static final Attribute FRAMEBORDER = new Attribute("frameborder");
221    
222        /**
223         *  The halign attribute
224         */
225        public static final Attribute HALIGN = new Attribute("halign");
226    
227        /**
228         *  The height attribute
229         */
230        public static final Attribute HEIGHT = new Attribute("height");
231    
232        /**
233         *  The href attribute
234         */
235        public static final Attribute HREF = new Attribute("href");
236    
237        /**
238         *  The hspace attribute
239         */
240        public static final Attribute HSPACE = new Attribute("hspace");
241    
242        /**
243         *  The http-equiv attribute
244         */
245        public static final Attribute HTTPEQUIV = new Attribute("http-equiv");
246    
247        /**
248         *  The id attribute
249         */
250        public static final Attribute ID = new Attribute("id");
251    
252        /**
253         *  The ismap attribute
254         */
255        public static final Attribute ISMAP = new Attribute("ismap");
256    
257        /**
258         *  The lang attribute
259         */
260        public static final Attribute LANG = new Attribute("lang");
261    
262        /**
263         *  The language attribute
264         */
265        public static final Attribute LANGUAGE = new Attribute("language");
266    
267        /**
268         *  The link attribute
269         */
270        public static final Attribute LINK = new Attribute("link");
271    
272        /**
273         *  The lowsrc attribute
274         */
275        public static final Attribute LOWSRC = new Attribute("lowsrc");
276    
277        /**
278         *  The marginheight attribute
279         */
280        public static final Attribute MARGINHEIGHT = new Attribute("marginheight");
281    
282        /**
283         *  The marginwidth attribute
284         */
285        public static final Attribute MARGINWIDTH = new Attribute("marginwidth");
286    
287        /**
288         *  The maxlength attribute
289         */
290        public static final Attribute MAXLENGTH = new Attribute("maxlength");
291    
292        /**
293         *  The media attribute
294         */
295        static final Attribute MEDIA = new Attribute("media");
296    
297        /**
298         *  The method attribute
299         */
300        public static final Attribute METHOD = new Attribute("method");
301    
302        /**
303         *  The multiple attribute
304         */
305        public static final Attribute MULTIPLE = new Attribute("multiple");
306    
307        /**
308         *  The n attribute
309         */
310        public static final Attribute N = new Attribute("n");
311    
312        /**
313         *  The name attribute
314         */
315        public static final Attribute NAME = new Attribute("name");
316    
317        /**
318         *  The nohref attribute
319         */
320        public static final Attribute NOHREF = new Attribute("nohref");
321    
322        /**
323         *  The noresize attribute
324         */
325        public static final Attribute NORESIZE = new Attribute("noresize");
326    
327        /**
328         *  The noshade attribute
329         */
330        public static final Attribute NOSHADE = new Attribute("noshade");
331    
332        /**
333         *  The nowrap attribute
334         */
335        public static final Attribute NOWRAP = new Attribute("nowrap");
336    
337        /**
338         *  The prompt attribute
339         */
340        public static final Attribute PROMPT = new Attribute("prompt");
341    
342        /**
343         *  The rel attribute
344         */
345        public static final Attribute REL = new Attribute("rel");
346    
347        /**
348         *  The rev attribute
349         */
350        public static final Attribute REV = new Attribute("rev");
351    
352        /**
353         *  The rows attribute
354         */
355        public static final Attribute ROWS = new Attribute("rows");
356    
357        /**
358         *  The rowspan attribute
359         */
360        public static final Attribute ROWSPAN = new Attribute("rowspan");
361    
362        /**
363         *  The scrolling attribute
364         */
365        public static final Attribute SCROLLING = new Attribute("scrolling");
366    
367        /**
368         *  The selected attribute
369         */
370        public static final Attribute SELECTED = new Attribute("selected");
371    
372        /**
373         *  The shape attribute
374         */
375        public static final Attribute SHAPE = new Attribute("shape");
376    
377        /**
378         *  The shapes attribute
379         */
380        public static final Attribute SHAPES = new Attribute("shapes");
381    
382        /**
383         *  The size attribute
384         */
385        public static final Attribute SIZE = new Attribute("size");
386    
387        /**
388         *  The src attribute
389         */
390        public static final Attribute SRC = new Attribute("src");
391    
392        /**
393         *  The standby attribute
394         */
395        public static final Attribute STANDBY = new Attribute("standby");
396    
397        /**
398         *  The start attribute
399         */
400        public static final Attribute START = new Attribute("start");
401    
402        /**
403         *  The style attribute
404         */
405        public static final Attribute STYLE = new Attribute("style");
406    
407        /**
408         *  The target attribute
409         */
410        public static final Attribute TARGET = new Attribute("target");
411    
412        /**
413         *  The text attribute
414         */
415        public static final Attribute TEXT = new Attribute("text");
416    
417        /**
418         *  The title attribute
419         */
420        public static final Attribute TITLE = new Attribute("title");
421    
422        /**
423         *  The type attribute
424         */
425        public static final Attribute TYPE = new Attribute("type");
426    
427        /**
428         *  The usemap attribute
429         */
430        public static final Attribute USEMAP = new Attribute("usemap");
431    
432        /**
433         *  The valign attribute
434         */
435        public static final Attribute VALIGN = new Attribute("valign");
436    
437        /**
438         *  The value attribute
439         */
440        public static final Attribute VALUE = new Attribute("value");
441    
442        /**
443         *  The valuetype attribute
444         */
445        public static final Attribute VALUETYPE = new Attribute("valuetype");
446    
447        /**
448         *  The version attribute
449         */
450        public static final Attribute VERSION = new Attribute("version");
451    
452        /**
453         *  The vlink attribute
454         */
455        public static final Attribute VLINK = new Attribute("vlink");
456    
457        /**
458         *  The vspace attribute
459         */
460        public static final Attribute VSPACE = new Attribute("vspace");
461    
462        /**
463         *  The width attribute
464         */
465        public static final Attribute WIDTH = new Attribute("width");
466    
467        /**
468         * This is used to reflect the pseudo class for the a tag.
469         */
470        static final Attribute PSEUDO_CLASS = new Attribute("_pseudo");
471    
472        /**
473         * This is used to reflect the dynamic class for the a tag.
474         */
475        static final Attribute DYNAMIC_CLASS = new Attribute("_dynamic");
476    
477        /**
478         * The attribute name.
479         */
480        private final String name;
481    
482        /**
483         * Creates the attribute with the given name.
484         */
485        private Attribute(String a_name)
486        {
487          name = a_name;
488        }
489    
490        /**
491         * Returns the attribute name. The names of the built-in attributes
492         * are always returned in lowercase.
493         */
494        public String toString()
495        {
496          return name;
497        }
498    
499        /**
500         *  Return an array of all attributes, declared in the HTML.Attribute
501         *  class. WARNING: attributes are the only public fields,
502         *  expected in this class.
503         */
504        static Attribute[] getAllAttributes()
505        {
506          Field[] f = Attribute.class.getFields();
507          Attribute[] attrs = new Attribute[ f.length ];
508          Field x;
509          int p = 0;
510          Attribute a;
511    
512          for (int i = 0; i < f.length; i++)
513            {
514              x = f [ i ];
515    
516              if ((x.getModifiers() & Modifier.STATIC) != 0)
517                {
518                  if (x.getType().equals(Attribute.class))
519                    {
520                      try
521                        {
522                          a = (Attribute) x.get(null);
523                          attrs [ p++ ] = a;
524                        }
525                      catch (Exception ex)
526                        {
527                          ex.printStackTrace(System.err);
528                          throw new Error("This should never happen, report a bug");
529                        }
530                    }
531                }
532            }
533    
534          return attrs;
535        }
536      }
537    
538      /**
539       * Represents a HTML tag.
540       */
541      public static class Tag
542      {
543        /**
544         * The &lt;a&gt; tag
545         */
546        public static final Tag A = new Tag("a");
547    
548        /**
549         * The &lt;address&gt; tag
550         */
551        public static final Tag ADDRESS = new Tag("address");
552    
553        /**
554         * The &lt;applet&gt; tag
555         */
556        public static final Tag APPLET = new Tag("applet");
557    
558        /**
559         * The &lt;area&gt; tag
560         */
561        public static final Tag AREA = new Tag("area");
562    
563        /**
564         * The &lt;b&gt; tag
565         */
566        public static final Tag B = new Tag("b");
567    
568        /**
569         * The &lt;base&gt; tag
570         */
571        public static final Tag BASE = new Tag("base");
572    
573        /**
574         * The &lt;basefont&gt; tag
575         */
576        public static final Tag BASEFONT = new Tag("basefont");
577    
578        /**
579         * The &lt;big&gt; tag
580         */
581        public static final Tag BIG = new Tag("big");
582    
583        /**
584         * The &lt;blockquote&gt; tag , breaks flow, block tag.
585         */
586        public static final Tag BLOCKQUOTE = new Tag("blockquote", BREAKS | BLOCK);
587    
588        /**
589         * The &lt;body&gt; tag , breaks flow, block tag.
590         */
591        public static final Tag BODY = new Tag("body", BREAKS | BLOCK);
592    
593        /**
594         * The &lt;br&gt; tag , breaks flow.
595         */
596        public static final Tag BR = new Tag("br", BREAKS);
597    
598        /**
599         * The &lt;caption&gt; tag
600         */
601        public static final Tag CAPTION = new Tag("caption");
602    
603        /**
604         * The &lt;center&gt; tag , breaks flow.
605         */
606        public static final Tag CENTER = new Tag("center", BREAKS);
607    
608        /**
609         * The &lt;cite&gt; tag
610         */
611        public static final Tag CITE = new Tag("cite");
612    
613        /**
614         * The &lt;code&gt; tag
615         */
616        public static final Tag CODE = new Tag("code");
617    
618        /**
619         * The &lt;dd&gt; tag , breaks flow, block tag.
620         */
621        public static final Tag DD = new Tag("dd", BREAKS | BLOCK);
622    
623        /**
624         * The &lt;dfn&gt; tag
625         */
626        public static final Tag DFN = new Tag("dfn");
627    
628        /**
629         * The &lt;dir&gt; tag , breaks flow, block tag.
630         */
631        public static final Tag DIR = new Tag("dir", BREAKS | BLOCK);
632    
633        /**
634         * The &lt;div&gt; tag , breaks flow, block tag.
635         */
636        public static final Tag DIV = new Tag("div", BREAKS | BLOCK);
637    
638        /**
639         * The &lt;dl&gt; tag , breaks flow, block tag.
640         */
641        public static final Tag DL = new Tag("dl", BREAKS | BLOCK);
642    
643        /**
644         * The &lt;dt&gt; tag , breaks flow, block tag.
645         */
646        public static final Tag DT = new Tag("dt", BREAKS | BLOCK);
647    
648        /**
649         * The &lt;em&gt; tag
650         */
651        public static final Tag EM = new Tag("em");
652    
653        /**
654         * The &lt;font&gt; tag
655         */
656        public static final Tag FONT = new Tag("font");
657    
658        /**
659         * The &lt;form&gt; tag , breaks flow.
660         */
661        public static final Tag FORM = new Tag("form", BREAKS);
662    
663        /**
664         * The &lt;frame&gt; tag
665         */
666        public static final Tag FRAME = new Tag("frame");
667    
668        /**
669         * The &lt;frameset&gt; tag
670         */
671        public static final Tag FRAMESET = new Tag("frameset");
672    
673        /**
674         * The &lt;h1&gt; tag , breaks flow, block tag.
675         */
676        public static final Tag H1 = new Tag("h1", BREAKS | BLOCK);
677    
678        /**
679         * The &lt;h2&gt; tag , breaks flow, block tag.
680         */
681        public static final Tag H2 = new Tag("h2", BREAKS | BLOCK);
682    
683        /**
684         * The &lt;h3&gt; tag , breaks flow, block tag.
685         */
686        public static final Tag H3 = new Tag("h3", BREAKS | BLOCK);
687    
688        /**
689         * The &lt;h4&gt; tag , breaks flow, block tag.
690         */
691        public static final Tag H4 = new Tag("h4", BREAKS | BLOCK);
692    
693        /**
694         * The &lt;h5&gt; tag , breaks flow, block tag.
695         */
696        public static final Tag H5 = new Tag("h5", BREAKS | BLOCK);
697    
698        /**
699         * The &lt;h6&gt; tag , breaks flow, block tag.
700         */
701        public static final Tag H6 = new Tag("h6", BREAKS | BLOCK);
702    
703        /**
704         * The &lt;head&gt; tag , breaks flow, block tag.
705         */
706        public static final Tag HEAD = new Tag("head", BREAKS | BLOCK);
707    
708        /**
709         * The &lt;hr&gt; tag , breaks flow.
710         */
711        public static final Tag HR = new Tag("hr", BREAKS);
712    
713        /**
714         * The &lt;html&gt; tag , breaks flow.
715         */
716        public static final Tag HTML = new Tag("html", BREAKS);
717    
718        /**
719         * The &lt;i&gt; tag
720         */
721        public static final Tag I = new Tag("i");
722    
723        /**
724         * The &lt;img&gt; tag
725         */
726        public static final Tag IMG = new Tag("img");
727    
728        /**
729         * The &lt;input&gt; tag
730         */
731        public static final Tag INPUT = new Tag("input");
732    
733        /**
734         * The &lt;isindex&gt; tag , breaks flow.
735         */
736        public static final Tag ISINDEX = new Tag("isindex", BREAKS);
737    
738        /**
739         * The &lt;kbd&gt; tag
740         */
741        public static final Tag KBD = new Tag("kbd");
742    
743        /**
744         * The &lt;li&gt; tag , breaks flow, block tag.
745         */
746        public static final Tag LI = new Tag("li", BREAKS | BLOCK);
747    
748        /**
749         * The &lt;link&gt; tag
750         */
751        public static final Tag LINK = new Tag("link");
752    
753        /**
754         * The &lt;map&gt; tag
755         */
756        public static final Tag MAP = new Tag("map");
757    
758        /**
759         * The &lt;menu&gt; tag , breaks flow, block tag.
760         */
761        public static final Tag MENU = new Tag("menu", BREAKS | BLOCK);
762    
763        /**
764         * The &lt;meta&gt; tag
765         */
766        public static final Tag META = new Tag("meta");
767    
768        /**
769         * The &lt;nobr&gt; tag
770         */
771        static final Tag NOBR = new Tag("nobr");
772    
773        /**
774         * The &lt;noframes&gt; tag , breaks flow, block tag.
775         */
776        public static final Tag NOFRAMES = new Tag("noframes", BREAKS | BLOCK);
777    
778        /**
779         * The &lt;object&gt; tag
780         */
781        public static final Tag OBJECT = new Tag("object");
782    
783        /**
784         * The &lt;ol&gt; tag , breaks flow, block tag.
785         */
786        public static final Tag OL = new Tag("ol", BREAKS | BLOCK);
787    
788        /**
789         * The &lt;option&gt; tag
790         */
791        public static final Tag OPTION = new Tag("option");
792    
793        /**
794         * The &lt;p&gt; tag , breaks flow, block tag.
795         */
796        public static final Tag P = new Tag("p", BREAKS | BLOCK);
797    
798        /**
799         * The &lt;param&gt; tag
800         */
801        public static final Tag PARAM = new Tag("param");
802    
803        /**
804         * The &lt;pre&gt; tag , breaks flow, block tag, preformatted.
805         */
806        public static final Tag PRE = new Tag("pre", BREAKS | BLOCK | PREFORMATTED);
807    
808        /**
809         * The &lt;s&gt; tag
810         */
811        public static final Tag S = new Tag("s");
812    
813        /**
814         * The &lt;samp&gt; tag
815         */
816        public static final Tag SAMP = new Tag("samp");
817    
818        /**
819         * The &lt;script&gt; tag
820         */
821        public static final Tag SCRIPT = new Tag("script");
822    
823        /**
824         * The &lt;select&gt; tag
825         */
826        public static final Tag SELECT = new Tag("select");
827    
828        /**
829         * The &lt;small&gt; tag
830         */
831        public static final Tag SMALL = new Tag("small");
832    
833        /**
834         * The &lt;span&gt; tag
835         */
836        public static final Tag SPAN = new Tag("span");
837    
838        /**
839         * The &lt;strike&gt; tag
840         */
841        public static final Tag STRIKE = new Tag("strike");
842    
843        /**
844         * The &lt;strong&gt; tag
845         */
846        public static final Tag STRONG = new Tag("strong");
847    
848        /**
849         * The &lt;style&gt; tag
850         */
851        public static final Tag STYLE = new Tag("style");
852    
853        /**
854         * The &lt;sub&gt; tag
855         */
856        public static final Tag SUB = new Tag("sub");
857    
858        /**
859         * The &lt;sup&gt; tag
860         */
861        public static final Tag SUP = new Tag("sup");
862    
863        /**
864         * The &lt;table&gt; tag , block tag.
865         */
866        public static final Tag TABLE = new Tag("table", BLOCK);
867    
868        /**
869         * The &lt;td&gt; tag , breaks flow, block tag.
870         */
871        public static final Tag TD = new Tag("td", BREAKS | BLOCK);
872    
873        /**
874         * The &lt;textarea&gt; tag , preformatted.
875         */
876        public static final Tag TEXTAREA = new Tag("textarea", PREFORMATTED);
877    
878        /**
879         * The &lt;th&gt; tag , breaks flow, block tag.
880         */
881        public static final Tag TH = new Tag("th", BREAKS | BLOCK);
882    
883        /**
884         * The &lt;title&gt; tag , breaks flow, block tag.
885         */
886        public static final Tag TITLE = new Tag("title", BREAKS | BLOCK);
887    
888        /**
889         * The &lt;tr&gt; tag , block tag.
890         */
891        public static final Tag TR = new Tag("tr", BLOCK);
892    
893        /**
894         * The &lt;tt&gt; tag
895         */
896        public static final Tag TT = new Tag("tt");
897    
898        /**
899         * The &lt;u&gt; tag
900         */
901        public static final Tag U = new Tag("u");
902    
903        /**
904         * The &lt;ul&gt; tag , breaks flow, block tag.
905         */
906        public static final Tag UL = new Tag("ul", BREAKS | BLOCK);
907    
908        /**
909         * The &lt;var&gt; tag
910         */
911        public static final Tag VAR = new Tag("var");
912    
913        /* Special tags */
914    
915        /**
916         * Total number of syntetic tags, delared in the Tag class.
917         * This must be adjusted if the new synthetic tags are declared.
918         * Otherwise the HTML.getAllTags() will not work as expected.
919         */
920        private static final int TOTAL_SYNTHETIC_TAGS = 3;
921    
922        /**
923         * All comments are labeled with this tag.
924         * This tag is not included into the array, returned by getAllTags().
925         * toString() returns 'comment'. HTML reader synthesizes this tag.
926         */
927        public static final Tag COMMENT = new Tag("comment", SYNTHETIC);
928    
929        /**
930         *  All text content is labeled with this tag.
931         *  This tag is not included into the array, returned by getAllTags().
932         *  toString() returns 'content'. HTML reader synthesizes this tag.
933         */
934        public static final Tag CONTENT = new Tag("content", SYNTHETIC);
935    
936        /**
937         * All text content must be in a paragraph element.
938         * If a paragraph didn't exist when content was encountered,
939         * a paragraph is manufactured.
940         * toString() returns 'p-implied'. HTML reader synthesizes this tag.
941         */
942        public static final Tag IMPLIED = new Tag("p-implied", SYNTHETIC);
943        final String name;
944        final int flags;
945    
946        /**
947         * Create the unitialised instance of HTML.Tag.
948         *
949         * The {@link #breaksFlow()}, {@link #isBlock()}
950         * and {@link #isPreformatted()} will always return false.
951         * The {@link #toString()} will return <code>null</code>.
952         *
953         * @since 1.3
954         */
955        public Tag()
956        {
957          name = null;
958          flags = 0;
959        }
960    
961        /**
962         * Creates a new Tag with the specified id, and with causesBreak
963         * and isBlock set to false.
964         */
965        protected Tag(String id)
966        {
967          name = id;
968          flags = 0;
969        }
970    
971        /**
972         * Creates a new Tag with the specified tag name and
973         * causesBreak and isBlock properties.
974         */
975        protected Tag(String id, boolean causesBreak, boolean isBlock)
976        {
977          int f = 0;
978    
979          if (causesBreak)
980            {
981              f |= BREAKS;
982            }
983    
984          if (isBlock)
985            {
986              f |= BLOCK;
987            }
988    
989          flags = f;
990          name = id;
991        }
992    
993        /**
994         * Create a tag taking flags.
995         */
996        Tag(String id, int a_flags)
997        {
998          name = id;
999          flags = a_flags;
1000        }
1001    
1002        /**
1003         * Returns true if this tag is a block tag, which is a tag used to
1004         * add structure to a document.
1005         */
1006        public boolean isBlock()
1007        {
1008          return (flags & BLOCK) != 0;
1009        }
1010    
1011        /**
1012         * Returns true if this tag is pre-formatted, which is true if
1013         * the tag is either PRE or TEXTAREA
1014         */
1015        public boolean isPreformatted()
1016        {
1017          return (flags & PREFORMATTED) != 0;
1018        }
1019    
1020        /**
1021         * Returns true if this tag causes a line break to the flow of text
1022         */
1023        public boolean breaksFlow()
1024        {
1025          return (flags & BREAKS) != 0;
1026        }
1027    
1028        /**
1029         * Returns the tag name. The names of the built-in tags are always
1030         * returned in lowercase.
1031         */
1032        public String toString()
1033        {
1034          return name;
1035        }
1036    
1037        /**
1038         * Return an array of HTML tags, declared in HTML.Tag class.
1039         * WARNING: This method expects that the Tags are the only
1040         * public fields declared in the Tag class.
1041         */
1042        static Tag[] getAllTags()
1043        {
1044          Field[] f = Tag.class.getFields();
1045          Field x;
1046    
1047          // The syntetic tags are not included.
1048          Tag[] tags = new Tag[ f.length - TOTAL_SYNTHETIC_TAGS ];
1049          int p = 0;
1050          Tag t;
1051    
1052          for (int i = 0; i < f.length; i++)
1053            {
1054              x = f [ i ];
1055    
1056              if ((x.getModifiers() & Modifier.STATIC) != 0)
1057                {
1058                  if (x.getType().equals(Tag.class))
1059                    {
1060                      try
1061                        {
1062                          t = (Tag) x.get(null);
1063    
1064                          if (!t.isSyntetic())
1065                            {
1066                              tags [ p++ ] = t;
1067                            }
1068                        }
1069                      catch (IllegalAccessException ex)
1070                        {
1071                          unexpected(ex);
1072                        }
1073                      catch (IllegalArgumentException ex)
1074                        {
1075                          unexpected(ex);
1076                        }
1077                    }
1078                }
1079            }
1080    
1081          return tags;
1082        }
1083    
1084        /**
1085         * Returns true for tags, generated by the html reader
1086         * (COMMENT, CONTENT and IMPLIED).
1087         */
1088        boolean isSyntetic()
1089        {
1090          return (flags & SYNTHETIC) != 0;
1091        }
1092    
1093        private static void unexpected(Exception ex)
1094                                throws Error
1095        {
1096          throw new Error("This should never happen, report a bug", ex);
1097        }
1098      }
1099    
1100      /**
1101       * Represents an unknown HTML tag.
1102       * @author Mark Wielaard (mark@klomp.org)
1103       */
1104      public static class UnknownTag
1105        extends Tag
1106        implements Serializable
1107      {
1108        private static final long serialVersionUID = -1534369342247250625L;
1109    
1110        /**
1111         * Creates a new UnknownTag with the specified name
1112         * @param name The tag name.
1113         *
1114         */
1115        public UnknownTag(String name)
1116        {
1117          super(name);
1118        }
1119      }
1120    
1121      /**
1122       * This value is returned for attributes without value that have no
1123       * default value defined in the DTD.
1124       */
1125      public static final String NULL_ATTRIBUTE_VALUE = "#DEFAULT";
1126    
1127      /* Package level html tag flags */
1128      static final int BREAKS = 1;
1129      static final int BLOCK = 2;
1130      static final int PREFORMATTED = 4;
1131      static final int SYNTHETIC = 8;
1132      private static Map<String,Tag> tagMap;
1133      private static Map<String,Attribute> attrMap;
1134    
1135      /**
1136       * The public constructor (does nothing). It it seldom required to have
1137       * an instance of this class, because all public fields and methods
1138       * are static.
1139       */
1140      public HTML()
1141      {
1142        // Nothing to do here.
1143      }
1144    
1145      /**
1146       * Returns the set of the recognized HTML attributes.
1147       */
1148      public static HTML.Attribute[] getAllAttributeKeys()
1149      {
1150        return Attribute.getAllAttributes();
1151      }
1152    
1153      /**
1154       * Returns the set of actual HTML tags that are recognized by
1155       * the default HTML reader. The returned array does not include the
1156       * COMMENT, CONTENT and IMPLIED tags.
1157       */
1158      public static HTML.Tag[] getAllTags()
1159      {
1160        return Tag.getAllTags();
1161      }
1162    
1163      /**
1164       * Returns an htl attribute constant for the given attribute name.
1165       * @param attName the attribute name, case insensitive
1166       */
1167      public static Attribute getAttributeKey(String attName)
1168      {
1169        if (attrMap == null)
1170          {
1171            // Create the map on demand.
1172            attrMap = new TreeMap<String,Attribute>();
1173    
1174            Attribute[] attrs = getAllAttributeKeys();
1175    
1176            for (int i = 0; i < attrs.length; i++)
1177              {
1178                attrMap.put(attrs [ i ].toString(), attrs [ i ]);
1179              }
1180          }
1181    
1182        return attrMap.get(attName.toLowerCase());
1183      }
1184    
1185      /**
1186       * Searches the value of given attribute in the provided set.
1187       * If the value is found (String type expected), tries to parse it as
1188       * an integer value. If succeded, returns the obtained integer value.
1189       *
1190       * For example:<p><code>
1191       * SimpleAttributeSet ase = new SimpleAttributeSet();
1192       * ase.addAttribute(HTML.getAttributeKey("size"),"222");
1193       * System.out.println(
1194       *  HTML.getIntegerAttributeValue
1195       *     (ase, HTML.getAttributeKey("size"), 333)); // prints "222"
1196       * System.out.println(
1197       *  HTML.getIntegerAttributeValue
1198       *     (ase, HTML.getAttributeKey("width"), 333)); // prints "333".
1199       * </code></p>
1200       *
1201       *
1202       * @param set The attribute set to search in. If the set contains the
1203       * given attribute, it must by a type of String.
1204       * @param attribute The html attribute to search in
1205       * @param defaultValue The value that is returned if the attribute is not
1206       * found in the given set or if the NumberFormatException was thrown
1207       * during the parsing.
1208       */
1209      public static int getIntegerAttributeValue(AttributeSet set,
1210                                                 HTML.Attribute attribute,
1211                                                 int defaultValue
1212                                                )
1213      {
1214        Object v = set.getAttribute(attribute);
1215    
1216        if (v == null)
1217          {
1218            return defaultValue;
1219          }
1220    
1221        try
1222          {
1223            return Integer.parseInt(v.toString().trim());
1224          }
1225        catch (Exception ex)
1226          {
1227            return defaultValue;
1228          }
1229      }
1230    
1231      /**
1232       * Returns a HTML tag constant for the given HTML attribute name.
1233       * If the tag is unknown, the null is returned.
1234       * @param tagName the tag name, case insensitive
1235       */
1236      public static Tag getTag(String tagName)
1237      {
1238        if (tagMap == null)
1239          {
1240            // Create the mao on demand.
1241            tagMap = new TreeMap<String,Tag>();
1242    
1243            Tag[] tags = getAllTags();
1244    
1245            for (int i = 0; i < tags.length; i++)
1246              {
1247                tagMap.put(tags [ i ].toString(), tags [ i ]);
1248              }
1249          }
1250    
1251        return tagMap.get(tagName.toLowerCase());
1252      }
1253    }