Source code: com/sitemesh/parser/DOMPage.java
1 package com.sitemesh.parser;
2
3 import java.io.IOException;
4 import java.io.Writer;
5 import org.apache.xml.serialize.HTMLSerializer;
6 import org.apache.xml.serialize.Method;
7 import org.apache.xml.serialize.OutputFormat;
8 import org.w3c.dom.*;
9 import org.w3c.dom.html.*;
10
11 /**
12 * Implementation of {@link com.sitemesh.HTMLPage} that populates itself
13 * from a parsed DOM document.
14 *
15 * @author <a href="joe@truemesh.com">Joe Walnes</a>
16 * @version $Revision: 1.7 $
17 */
18 public class DOMPage extends AbstractHTMLPage {
19
20 /**
21 * BODY element.
22 */
23 private HTMLBodyElement bodyTag;
24
25 /**
26 * HEAD element.
27 */
28 private HTMLHeadElement headTag;
29
30 /**
31 * Entire Document.
32 */
33 private HTMLDocument document;
34
35 /**
36 * Create instance and set all initial properties and data.
37 *
38 * @param pageData Original page data
39 * @param document Parsed DOM HTML document.
40 */
41 public DOMPage( byte[] pageData, HTMLDocument document ) {
42 this.document = document;
43 this.pageData = pageData;
44 HTMLHtmlElement htmlTag = ( HTMLHtmlElement )document.getDocumentElement();
45 addAttributeList( null, htmlTag.getAttributes() );
46 addProperty( "title", document.getTitle() );
47 bodyTag = ( HTMLBodyElement )document.getBody();
48 addAttributeList( "body", bodyTag.getAttributes() );
49 {
50 NodeList htmlChildren = htmlTag.getChildNodes();
51 for ( int i = 0; i < htmlChildren.getLength(); i++ ) {
52 Node curr = htmlChildren.item( i );
53 if ( curr instanceof HTMLHeadElement ) {
54 headTag = ( HTMLHeadElement )curr;
55 break;
56 }
57 if ( curr instanceof HTMLBodyElement ) break;
58 }
59 }
60 if ( headTag != null ) {
61 NodeList metaTags = headTag.getChildNodes();
62 for ( int i = 0; i < metaTags.getLength(); i++ ) {
63 Node curr = metaTags.item( i );
64 if ( curr instanceof HTMLMetaElement ) {
65 HTMLMetaElement metaTag = ( HTMLMetaElement )curr;
66 String name = metaTag.getName();
67 String content = metaTag.getContent();
68 if ( name != null && name.length() > 0 && content != null && content.length() > 0 ) {
69 addProperty( "meta." + metaTag.getName(), metaTag.getContent() );
70 }
71 }
72 }
73 }
74 }
75
76 /**
77 * Iterate through the attributes of an element and add them as properties.
78 *
79 * @param prefix Prefix to add to key name (without '.').
80 * @param attribute Attributes of element.
81 */
82 private void addAttributeList( String prefix, NamedNodeMap attributes ) {
83 if ( prefix == null ) prefix = "";
84 if ( prefix.length() > 0 ) prefix += ".";
85 for ( int i = 0; i < attributes.getLength(); i++ ) {
86 Attr curr = ( Attr )attributes.item( i );
87 if ( curr.getValue() != null && curr.getValue().length() > 0 ) {
88 addProperty( prefix + curr.getName(), curr.getValue() );
89 }
90 }
91 }
92
93 /**
94 * Serialize an Element to a stream, but don't write outermost tags, only
95 * contents.
96 */
97 private void serialize( Writer out, Element element ) throws IOException {
98 OutputFormat format = new OutputFormat( Method.HTML, null, false );
99 DocumentFragment frag = document.createDocumentFragment();
100 NodeList children = element.getChildNodes();
101 for ( int i = 0; i < children.getLength(); i++ ) {
102 Node n = children.item( i );
103 if (n instanceof HTMLTitleElement) continue;
104 frag.appendChild( n.cloneNode( true ) );
105 }
106 HTMLSerializer serializer = new HTMLSerializer( out, format ) {
107 public void serializeNode( Node n ) {
108 _started = true;
109 super.serializeNode( n );
110 }
111 };
112 serializer.serialize( frag );
113 }
114
115 /**
116 * Serialize HEAD contents to stream.
117 */
118 public void writeHead( Writer out ) throws IOException {
119 serialize( out, headTag );
120 }
121
122 /**
123 * Serialize BODY contents to stream.
124 */
125 public void writeBody( Writer out ) throws IOException {
126 serialize( out, bodyTag );
127 }
128
129 }