Wed, 31 Oct 2012 13:48:15 -0700
8001664: refactor javadoc to use abstraction to handle files
Reviewed-by: darcy
1 /*
2 * Copyright (c) 2010, 2012, 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 */
26 package com.sun.tools.doclets.formats.html.markup;
28 import java.io.IOException;
29 import java.io.Writer;
30 import java.util.*;
32 import com.sun.tools.doclets.internal.toolkit.Content;
33 import com.sun.tools.doclets.internal.toolkit.util.*;
35 /**
36 * Class for generating HTML tree for javadoc output.
37 *
38 * <p><b>This is NOT part of any supported API.
39 * If you write code that depends on this, you do so at your own risk.
40 * This code and its internal interfaces are subject to change or
41 * deletion without notice.</b>
42 *
43 * @author Bhavesh Patel
44 */
45 public class HtmlTree extends Content {
47 private HtmlTag htmlTag;
48 private Map<HtmlAttr,String> attrs = Collections.<HtmlAttr,String>emptyMap();
49 private List<Content> content = Collections.<Content>emptyList();
50 public static final Content EMPTY = new StringContent("");
52 /**
53 * Constructor to construct HtmlTree object.
54 *
55 * @param tag HTML tag for the HtmlTree object
56 */
57 public HtmlTree(HtmlTag tag) {
58 htmlTag = nullCheck(tag);
59 }
61 /**
62 * Constructor to construct HtmlTree object.
63 *
64 * @param tag HTML tag for the HtmlTree object
65 * @param contents contents to be added to the tree
66 */
67 public HtmlTree(HtmlTag tag, Content... contents) {
68 this(tag);
69 for (Content content: contents)
70 addContent(content);
71 }
73 /**
74 * Adds an attribute for the HTML tag.
75 *
76 * @param attrName name of the attribute
77 * @param attrValue value of the attribute
78 */
79 public void addAttr(HtmlAttr attrName, String attrValue) {
80 if (attrs.isEmpty())
81 attrs = new LinkedHashMap<HtmlAttr,String>();
82 attrs.put(nullCheck(attrName), nullCheck(attrValue));
83 }
85 /**
86 * Adds a style for the HTML tag.
87 *
88 * @param style style to be added
89 */
90 public void addStyle(HtmlStyle style) {
91 addAttr(HtmlAttr.CLASS, style.toString());
92 }
94 /**
95 * Adds content for the HTML tag.
96 *
97 * @param tagContent tag content to be added
98 */
99 public void addContent(Content tagContent) {
100 if (tagContent == HtmlTree.EMPTY || tagContent.isValid()) {
101 if (content.isEmpty())
102 content = new ArrayList<Content>();
103 content.add(tagContent);
104 }
105 }
107 /**
108 * This method adds a string content to the htmltree. If the last content member
109 * added is a StringContent, append the string to that StringContent or else
110 * create a new StringContent and add it to the html tree.
111 *
112 * @param stringContent string content that needs to be added
113 */
114 public void addContent(String stringContent) {
115 if (!content.isEmpty()) {
116 Content lastContent = content.get(content.size() - 1);
117 if (lastContent instanceof StringContent)
118 lastContent.addContent(stringContent);
119 else
120 addContent(new StringContent(stringContent));
121 }
122 else
123 addContent(new StringContent(stringContent));
124 }
126 /**
127 * Generates an HTML anchor tag.
128 *
129 * @param ref reference url for the anchor tag
130 * @param body content for the anchor tag
131 * @return an HtmlTree object
132 */
133 public static HtmlTree A(String ref, Content body) {
134 HtmlTree htmltree = new HtmlTree(HtmlTag.A, nullCheck(body));
135 htmltree.addAttr(HtmlAttr.HREF, nullCheck(ref));
136 return htmltree;
137 }
139 /**
140 * Generates an HTML anchor tag with name attribute and content.
141 *
142 * @param name name for the anchor tag
143 * @param body content for the anchor tag
144 * @return an HtmlTree object
145 */
146 public static HtmlTree A_NAME(String name, Content body) {
147 HtmlTree htmltree = HtmlTree.A_NAME(name);
148 htmltree.addContent(nullCheck(body));
149 return htmltree;
150 }
152 /**
153 * Generates an HTML anchor tag with name attribute.
154 *
155 * @param name name for the anchor tag
156 * @return an HtmlTree object
157 */
158 public static HtmlTree A_NAME(String name) {
159 HtmlTree htmltree = new HtmlTree(HtmlTag.A);
160 htmltree.addAttr(HtmlAttr.NAME, nullCheck(name));
161 return htmltree;
162 }
164 /**
165 * Generates a CAPTION tag with some content.
166 *
167 * @param body content for the tag
168 * @return an HtmlTree object for the CAPTION tag
169 */
170 public static HtmlTree CAPTION(Content body) {
171 HtmlTree htmltree = new HtmlTree(HtmlTag.CAPTION, nullCheck(body));
172 return htmltree;
173 }
175 /**
176 * Generates a CODE tag with some content.
177 *
178 * @param body content for the tag
179 * @return an HtmlTree object for the CODE tag
180 */
181 public static HtmlTree CODE(Content body) {
182 HtmlTree htmltree = new HtmlTree(HtmlTag.CODE, nullCheck(body));
183 return htmltree;
184 }
186 /**
187 * Generates a DD tag with some content.
188 *
189 * @param body content for the tag
190 * @return an HtmlTree object for the DD tag
191 */
192 public static HtmlTree DD(Content body) {
193 HtmlTree htmltree = new HtmlTree(HtmlTag.DD, nullCheck(body));
194 return htmltree;
195 }
197 /**
198 * Generates a DL tag with some content.
199 *
200 * @param body content for the tag
201 * @return an HtmlTree object for the DL tag
202 */
203 public static HtmlTree DL(Content body) {
204 HtmlTree htmltree = new HtmlTree(HtmlTag.DL, nullCheck(body));
205 return htmltree;
206 }
208 /**
209 * Generates a DIV tag with the style class attributes. It also encloses
210 * a content.
211 *
212 * @param styleClass stylesheet class for the tag
213 * @param body content for the tag
214 * @return an HtmlTree object for the DIV tag
215 */
216 public static HtmlTree DIV(HtmlStyle styleClass, Content body) {
217 HtmlTree htmltree = new HtmlTree(HtmlTag.DIV, nullCheck(body));
218 if (styleClass != null)
219 htmltree.addStyle(styleClass);
220 return htmltree;
221 }
223 /**
224 * Generates a DIV tag with some content.
225 *
226 * @param body content for the tag
227 * @return an HtmlTree object for the DIV tag
228 */
229 public static HtmlTree DIV(Content body) {
230 return DIV(null, body);
231 }
233 /**
234 * Generates a DT tag with some content.
235 *
236 * @param body content for the tag
237 * @return an HtmlTree object for the DT tag
238 */
239 public static HtmlTree DT(Content body) {
240 HtmlTree htmltree = new HtmlTree(HtmlTag.DT, nullCheck(body));
241 return htmltree;
242 }
244 /**
245 * Generates a EM tag with some content.
246 *
247 * @param body content to be added to the tag
248 * @return an HtmlTree object for the EM tag
249 */
250 public static HtmlTree EM(Content body) {
251 HtmlTree htmltree = new HtmlTree(HtmlTag.EM, nullCheck(body));
252 return htmltree;
253 }
255 /**
256 * Generates a FRAME tag.
257 *
258 * @param src the url of the document to be shown in the frame
259 * @param name specifies the name of the frame
260 * @param title the title for the frame
261 * @param scrolling specifies whether to display scrollbars in the frame
262 * @return an HtmlTree object for the FRAME tag
263 */
264 public static HtmlTree FRAME(String src, String name, String title, String scrolling) {
265 HtmlTree htmltree = new HtmlTree(HtmlTag.FRAME);
266 htmltree.addAttr(HtmlAttr.SRC, nullCheck(src));
267 htmltree.addAttr(HtmlAttr.NAME, nullCheck(name));
268 htmltree.addAttr(HtmlAttr.TITLE, nullCheck(title));
269 if (scrolling != null)
270 htmltree.addAttr(HtmlAttr.SCROLLING, scrolling);
271 return htmltree;
272 }
274 /**
275 * Generates a Frame tag.
276 *
277 * @param src the url of the document to be shown in the frame
278 * @param name specifies the name of the frame
279 * @param title the title for the frame
280 * @return an HtmlTree object for the SPAN tag
281 */
282 public static HtmlTree FRAME(String src, String name, String title) {
283 return FRAME(src, name, title, null);
284 }
286 /**
287 * Generates a FRAMESET tag.
288 *
289 * @param cols the size of columns in the frameset
290 * @param rows the size of rows in the frameset
291 * @param title the title for the frameset
292 * @param onload the script to run when the document loads
293 * @return an HtmlTree object for the FRAMESET tag
294 */
295 public static HtmlTree FRAMESET(String cols, String rows, String title, String onload) {
296 HtmlTree htmltree = new HtmlTree(HtmlTag.FRAMESET);
297 if (cols != null)
298 htmltree.addAttr(HtmlAttr.COLS, cols);
299 if (rows != null)
300 htmltree.addAttr(HtmlAttr.ROWS, rows);
301 htmltree.addAttr(HtmlAttr.TITLE, nullCheck(title));
302 htmltree.addAttr(HtmlAttr.ONLOAD, nullCheck(onload));
303 return htmltree;
304 }
306 /**
307 * Generates a heading tag (h1 to h6) with the title and style class attributes. It also encloses
308 * a content.
309 *
310 * @param headingTag the heading tag to be generated
311 * @param printTitle true if title for the tag needs to be printed else false
312 * @param styleClass stylesheet class for the tag
313 * @param body content for the tag
314 * @return an HtmlTree object for the tag
315 */
316 public static HtmlTree HEADING(HtmlTag headingTag, boolean printTitle,
317 HtmlStyle styleClass, Content body) {
318 HtmlTree htmltree = new HtmlTree(headingTag, nullCheck(body));
319 if (printTitle)
320 htmltree.addAttr(HtmlAttr.TITLE, Util.stripHtml(body.toString()));
321 if (styleClass != null)
322 htmltree.addStyle(styleClass);
323 return htmltree;
324 }
326 /**
327 * Generates a heading tag (h1 to h6) with style class attribute. It also encloses
328 * a content.
329 *
330 * @param headingTag the heading tag to be generated
331 * @param styleClass stylesheet class for the tag
332 * @param body content for the tag
333 * @return an HtmlTree object for the tag
334 */
335 public static HtmlTree HEADING(HtmlTag headingTag, HtmlStyle styleClass, Content body) {
336 return HEADING(headingTag, false, styleClass, body);
337 }
339 /**
340 * Generates a heading tag (h1 to h6) with the title attribute. It also encloses
341 * a content.
342 *
343 * @param headingTag the heading tag to be generated
344 * @param printTitle true if the title for the tag needs to be printed else false
345 * @param body content for the tag
346 * @return an HtmlTree object for the tag
347 */
348 public static HtmlTree HEADING(HtmlTag headingTag, boolean printTitle, Content body) {
349 return HEADING(headingTag, printTitle, null, body);
350 }
352 /**
353 * Generates a heading tag (h1 to h6) with some content.
354 *
355 * @param headingTag the heading tag to be generated
356 * @param body content for the tag
357 * @return an HtmlTree object for the tag
358 */
359 public static HtmlTree HEADING(HtmlTag headingTag, Content body) {
360 return HEADING(headingTag, false, null, body);
361 }
363 /**
364 * Generates an HTML tag with lang attribute. It also adds head and body
365 * content to the HTML tree.
366 *
367 * @param lang language for the HTML document
368 * @param head head for the HTML tag
369 * @param body body for the HTML tag
370 * @return an HtmlTree object for the HTML tag
371 */
372 public static HtmlTree HTML(String lang, Content head, Content body) {
373 HtmlTree htmltree = new HtmlTree(HtmlTag.HTML, nullCheck(head), nullCheck(body));
374 htmltree.addAttr(HtmlAttr.LANG, nullCheck(lang));
375 return htmltree;
376 }
378 /**
379 * Generates a I tag with some content.
380 *
381 * @param body content for the tag
382 * @return an HtmlTree object for the I tag
383 */
384 public static HtmlTree I(Content body) {
385 HtmlTree htmltree = new HtmlTree(HtmlTag.I, nullCheck(body));
386 return htmltree;
387 }
389 /**
390 * Generates a LI tag with some content.
391 *
392 * @param body content for the tag
393 * @return an HtmlTree object for the LI tag
394 */
395 public static HtmlTree LI(Content body) {
396 return LI(null, body);
397 }
399 /**
400 * Generates a LI tag with some content.
401 *
402 * @param styleClass style for the tag
403 * @param body content for the tag
404 * @return an HtmlTree object for the LI tag
405 */
406 public static HtmlTree LI(HtmlStyle styleClass, Content body) {
407 HtmlTree htmltree = new HtmlTree(HtmlTag.LI, nullCheck(body));
408 if (styleClass != null)
409 htmltree.addStyle(styleClass);
410 return htmltree;
411 }
413 /**
414 * Generates a LINK tag with the rel, type, href and title attributes.
415 *
416 * @param rel relevance of the link
417 * @param type type of link
418 * @param href the path for the link
419 * @param title title for the link
420 * @return an HtmlTree object for the LINK tag
421 */
422 public static HtmlTree LINK(String rel, String type, String href, String title) {
423 HtmlTree htmltree = new HtmlTree(HtmlTag.LINK);
424 htmltree.addAttr(HtmlAttr.REL, nullCheck(rel));
425 htmltree.addAttr(HtmlAttr.TYPE, nullCheck(type));
426 htmltree.addAttr(HtmlAttr.HREF, nullCheck(href));
427 htmltree.addAttr(HtmlAttr.TITLE, nullCheck(title));
428 return htmltree;
429 }
431 /**
432 * Generates a META tag with the http-equiv, content and charset attributes.
433 *
434 * @param httpEquiv http equiv attribute for the META tag
435 * @param content type of content
436 * @param charSet character set used
437 * @return an HtmlTree object for the META tag
438 */
439 public static HtmlTree META(String httpEquiv, String content, String charSet) {
440 HtmlTree htmltree = new HtmlTree(HtmlTag.META);
441 htmltree.addAttr(HtmlAttr.HTTP_EQUIV, nullCheck(httpEquiv));
442 htmltree.addAttr(HtmlAttr.CONTENT, nullCheck(content));
443 htmltree.addAttr(HtmlAttr.CHARSET, nullCheck(charSet));
444 return htmltree;
445 }
447 /**
448 * Generates a META tag with the name and content attributes.
449 *
450 * @param name name attribute
451 * @param content type of content
452 * @return an HtmlTree object for the META tag
453 */
454 public static HtmlTree META(String name, String content) {
455 HtmlTree htmltree = new HtmlTree(HtmlTag.META);
456 htmltree.addAttr(HtmlAttr.NAME, nullCheck(name));
457 htmltree.addAttr(HtmlAttr.CONTENT, nullCheck(content));
458 return htmltree;
459 }
461 /**
462 * Generates a NOSCRIPT tag with some content.
463 *
464 * @param body content of the noscript tag
465 * @return an HtmlTree object for the NOSCRIPT tag
466 */
467 public static HtmlTree NOSCRIPT(Content body) {
468 HtmlTree htmltree = new HtmlTree(HtmlTag.NOSCRIPT, nullCheck(body));
469 return htmltree;
470 }
472 /**
473 * Generates a P tag with some content.
474 *
475 * @param body content of the Paragraph tag
476 * @return an HtmlTree object for the P tag
477 */
478 public static HtmlTree P(Content body) {
479 return P(null, body);
480 }
482 /**
483 * Generates a P tag with some content.
484 *
485 * @param styleClass style of the Paragraph tag
486 * @param body content of the Paragraph tag
487 * @return an HtmlTree object for the P tag
488 */
489 public static HtmlTree P(HtmlStyle styleClass, Content body) {
490 HtmlTree htmltree = new HtmlTree(HtmlTag.P, nullCheck(body));
491 if (styleClass != null)
492 htmltree.addStyle(styleClass);
493 return htmltree;
494 }
496 /**
497 * Generates a SMALL tag with some content.
498 *
499 * @param body content for the tag
500 * @return an HtmlTree object for the SMALL tag
501 */
502 public static HtmlTree SMALL(Content body) {
503 HtmlTree htmltree = new HtmlTree(HtmlTag.SMALL, nullCheck(body));
504 return htmltree;
505 }
507 /**
508 * Generates a STRONG tag with some content.
509 *
510 * @param body content for the tag
511 * @return an HtmlTree object for the STRONG tag
512 */
513 public static HtmlTree STRONG(Content body) {
514 HtmlTree htmltree = new HtmlTree(HtmlTag.STRONG, nullCheck(body));
515 return htmltree;
516 }
518 /**
519 * Generates a SPAN tag with some content.
520 *
521 * @param body content for the tag
522 * @return an HtmlTree object for the SPAN tag
523 */
524 public static HtmlTree SPAN(Content body) {
525 return SPAN(null, body);
526 }
528 /**
529 * Generates a SPAN tag with style class attribute and some content.
530 *
531 * @param styleClass style class for the tag
532 * @param body content for the tag
533 * @return an HtmlTree object for the SPAN tag
534 */
535 public static HtmlTree SPAN(HtmlStyle styleClass, Content body) {
536 HtmlTree htmltree = new HtmlTree(HtmlTag.SPAN, nullCheck(body));
537 if (styleClass != null)
538 htmltree.addStyle(styleClass);
539 return htmltree;
540 }
542 /**
543 * Generates a Table tag with border, width and summary attributes and
544 * some content.
545 *
546 * @param border border for the table
547 * @param width width of the table
548 * @param summary summary for the table
549 * @param body content for the table
550 * @return an HtmlTree object for the TABLE tag
551 */
552 public static HtmlTree TABLE(int border, int width, String summary,
553 Content body) {
554 HtmlTree htmltree = new HtmlTree(HtmlTag.TABLE, nullCheck(body));
555 htmltree.addAttr(HtmlAttr.BORDER, Integer.toString(border));
556 htmltree.addAttr(HtmlAttr.WIDTH, Integer.toString(width));
557 htmltree.addAttr(HtmlAttr.SUMMARY, nullCheck(summary));
558 return htmltree;
559 }
561 /**
562 * Generates a Table tag with style class, border, cell padding,
563 * cellspacing and summary attributes and some content.
564 *
565 * @param styleClass style of the table
566 * @param border border for the table
567 * @param cellPadding cell padding for the table
568 * @param cellSpacing cell spacing for the table
569 * @param summary summary for the table
570 * @param body content for the table
571 * @return an HtmlTree object for the TABLE tag
572 */
573 public static HtmlTree TABLE(HtmlStyle styleClass, int border, int cellPadding,
574 int cellSpacing, String summary, Content body) {
575 HtmlTree htmltree = new HtmlTree(HtmlTag.TABLE, nullCheck(body));
576 if (styleClass != null)
577 htmltree.addStyle(styleClass);
578 htmltree.addAttr(HtmlAttr.BORDER, Integer.toString(border));
579 htmltree.addAttr(HtmlAttr.CELLPADDING, Integer.toString(cellPadding));
580 htmltree.addAttr(HtmlAttr.CELLSPACING, Integer.toString(cellSpacing));
581 htmltree.addAttr(HtmlAttr.SUMMARY, nullCheck(summary));
582 return htmltree;
583 }
585 /**
586 * Generates a Table tag with border, cell padding,
587 * cellspacing and summary attributes and some content.
588 *
589 * @param border border for the table
590 * @param cellPadding cell padding for the table
591 * @param cellSpacing cell spacing for the table
592 * @param summary summary for the table
593 * @param body content for the table
594 * @return an HtmlTree object for the TABLE tag
595 */
596 public static HtmlTree TABLE(int border, int cellPadding,
597 int cellSpacing, String summary, Content body) {
598 return TABLE(null, border, cellPadding, cellSpacing, summary, body);
599 }
601 /**
602 * Generates a TD tag with style class attribute and some content.
603 *
604 * @param styleClass style for the tag
605 * @param body content for the tag
606 * @return an HtmlTree object for the TD tag
607 */
608 public static HtmlTree TD(HtmlStyle styleClass, Content body) {
609 HtmlTree htmltree = new HtmlTree(HtmlTag.TD, nullCheck(body));
610 if (styleClass != null)
611 htmltree.addStyle(styleClass);
612 return htmltree;
613 }
615 /**
616 * Generates a TD tag for an HTML table with some content.
617 *
618 * @param body content for the tag
619 * @return an HtmlTree object for the TD tag
620 */
621 public static HtmlTree TD(Content body) {
622 return TD(null, body);
623 }
625 /**
626 * Generates a TH tag with style class and scope attributes and some content.
627 *
628 * @param styleClass style for the tag
629 * @param scope scope of the tag
630 * @param body content for the tag
631 * @return an HtmlTree object for the TH tag
632 */
633 public static HtmlTree TH(HtmlStyle styleClass, String scope, Content body) {
634 HtmlTree htmltree = new HtmlTree(HtmlTag.TH, nullCheck(body));
635 if (styleClass != null)
636 htmltree.addStyle(styleClass);
637 htmltree.addAttr(HtmlAttr.SCOPE, nullCheck(scope));
638 return htmltree;
639 }
641 /**
642 * Generates a TH tag with scope attribute and some content.
643 *
644 * @param scope scope of the tag
645 * @param body content for the tag
646 * @return an HtmlTree object for the TH tag
647 */
648 public static HtmlTree TH(String scope, Content body) {
649 return TH(null, scope, body);
650 }
652 /**
653 * Generates a TITLE tag with some content.
654 *
655 * @param body content for the tag
656 * @return an HtmlTree object for the TITLE tag
657 */
658 public static HtmlTree TITLE(Content body) {
659 HtmlTree htmltree = new HtmlTree(HtmlTag.TITLE, nullCheck(body));
660 return htmltree;
661 }
663 /**
664 * Generates a TR tag for an HTML table with some content.
665 *
666 * @param body content for the tag
667 * @return an HtmlTree object for the TR tag
668 */
669 public static HtmlTree TR(Content body) {
670 HtmlTree htmltree = new HtmlTree(HtmlTag.TR, nullCheck(body));
671 return htmltree;
672 }
674 /**
675 * Generates a UL tag with the style class attribute and some content.
676 *
677 * @param styleClass style for the tag
678 * @param body content for the tag
679 * @return an HtmlTree object for the UL tag
680 */
681 public static HtmlTree UL(HtmlStyle styleClass, Content body) {
682 HtmlTree htmltree = new HtmlTree(HtmlTag.UL, nullCheck(body));
683 htmltree.addStyle(nullCheck(styleClass));
684 return htmltree;
685 }
687 /**
688 * {@inheritDoc}
689 */
690 public boolean isEmpty() {
691 return (!hasContent() && !hasAttrs());
692 }
694 /**
695 * Returns true if the HTML tree has content.
696 *
697 * @return true if the HTML tree has content else return false
698 */
699 public boolean hasContent() {
700 return (!content.isEmpty());
701 }
703 /**
704 * Returns true if the HTML tree has attributes.
705 *
706 * @return true if the HTML tree has attributes else return false
707 */
708 public boolean hasAttrs() {
709 return (!attrs.isEmpty());
710 }
712 /**
713 * Returns true if the HTML tree has a specific attribute.
714 *
715 * @param attrName name of the attribute to check within the HTML tree
716 * @return true if the HTML tree has the specified attribute else return false
717 */
718 public boolean hasAttr(HtmlAttr attrName) {
719 return (attrs.containsKey(attrName));
720 }
722 /**
723 * Returns true if the HTML tree is valid. This check is more specific to
724 * standard doclet and not exactly similar to W3C specifications. But it
725 * ensures HTML validation.
726 *
727 * @return true if the HTML tree is valid
728 */
729 public boolean isValid() {
730 switch (htmlTag) {
731 case A :
732 return (hasAttr(HtmlAttr.NAME) || (hasAttr(HtmlAttr.HREF) && hasContent()));
733 case BR :
734 return (!hasContent() && (!hasAttrs() || hasAttr(HtmlAttr.CLEAR)));
735 case FRAME :
736 return (hasAttr(HtmlAttr.SRC) && !hasContent());
737 case HR :
738 return (!hasContent());
739 case IMG :
740 return (hasAttr(HtmlAttr.SRC) && hasAttr(HtmlAttr.ALT) && !hasContent());
741 case LINK :
742 return (hasAttr(HtmlAttr.HREF) && !hasContent());
743 case META :
744 return (hasAttr(HtmlAttr.CONTENT) && !hasContent());
745 default :
746 return hasContent();
747 }
748 }
750 /**
751 * Returns true if the element is an inline element.
752 *
753 * @return true if the HTML tag is an inline element
754 */
755 public boolean isInline() {
756 return (htmlTag.blockType == HtmlTag.BlockType.INLINE);
757 }
759 /**
760 * {@inheritDoc}
761 */
762 @Override
763 public boolean write(Writer out, boolean atNewline) throws IOException {
764 if (!isInline() && !atNewline)
765 out.write(DocletConstants.NL);
766 String tagString = htmlTag.toString();
767 out.write("<");
768 out.write(tagString);
769 Iterator<HtmlAttr> iterator = attrs.keySet().iterator();
770 HtmlAttr key;
771 String value = "";
772 while (iterator.hasNext()) {
773 key = iterator.next();
774 value = attrs.get(key);
775 out.write(" ");
776 out.write(key.toString());
777 if (!value.isEmpty()) {
778 out.write("=\"");
779 out.write(value);
780 out.write("\"");
781 }
782 }
783 out.write(">");
784 boolean nl = false;
785 for (Content c : content)
786 nl = c.write(out, nl);
787 if (htmlTag.endTagRequired()) {
788 out.write("</");
789 out.write(tagString);
790 out.write(">");
791 }
792 if (!isInline()) {
793 out.write(DocletConstants.NL);
794 return true;
795 } else {
796 return false;
797 }
798 }
799 }