~ubuntu-branches/ubuntu/saucy/libhtmlcleaner-java/saucy-proposed

« back to all changes in this revision

Viewing changes to src/main/java/org/htmlcleaner/JDomSerializer.java

  • Committer: Package Import Robot
  • Author(s): Alexandre Rossi
  • Date: 2011-05-26 15:05:58 UTC
  • Revision ID: package-import@ubuntu.com-20110526150558-scdb2th5p2rmw1op
Tags: upstream-2.2
ImportĀ upstreamĀ versionĀ 2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
package org.htmlcleaner;
 
2
 
 
3
import org.jdom.*;
 
4
 
 
5
import java.util.HashMap;
 
6
import java.util.Iterator;
 
7
import java.util.List;
 
8
import java.util.Map;
 
9
 
 
10
/**
 
11
 * <p>JDom serializer - creates xml JDom instance out of the TagNode.</p>
 
12
 */
 
13
public class JDomSerializer {
 
14
 
 
15
    private DefaultJDOMFactory factory;
 
16
 
 
17
    protected CleanerProperties props;
 
18
    protected boolean escapeXml = true;
 
19
 
 
20
    public JDomSerializer(CleanerProperties props, boolean escapeXml) {
 
21
        this.props = props;
 
22
        this.escapeXml = escapeXml;
 
23
    }
 
24
 
 
25
    public JDomSerializer(CleanerProperties props) {
 
26
        this(props, true);
 
27
    }
 
28
 
 
29
    public Document createJDom(TagNode rootNode) {
 
30
        this.factory = new DefaultJDOMFactory();
 
31
        Element rootElement = createElement(rootNode);
 
32
        Document document = this.factory.document(rootElement);
 
33
 
 
34
        setAttributes(rootNode, rootElement);
 
35
 
 
36
        createSubnodes(rootElement, rootNode.getChildren());
 
37
 
 
38
        return document;
 
39
    }
 
40
 
 
41
    private Element createElement(TagNode node) {
 
42
        String name = node.getName();
 
43
        boolean nsAware = props.isNamespacesAware();
 
44
        String prefix = Utils.getXmlNSPrefix(name);
 
45
        Map<String, String> nsDeclarations = node.getNamespaceDeclarations();
 
46
        String nsURI = null;
 
47
        if (prefix != null) {
 
48
            name = Utils.getXmlName(name);
 
49
            if (nsAware) {
 
50
                if (nsDeclarations != null) {
 
51
                    nsURI = nsDeclarations.get(prefix);
 
52
                }
 
53
                if (nsURI == null) {
 
54
                    nsURI = node.getNamespaceURIOnPath(prefix);
 
55
                }
 
56
                if (nsURI == null) {
 
57
                    nsURI = prefix;
 
58
                }
 
59
            }
 
60
        } else {
 
61
            if (nsAware) {
 
62
                if (nsDeclarations != null) {
 
63
                    nsURI = nsDeclarations.get("");
 
64
                }
 
65
                if (nsURI == null) {
 
66
                    nsURI = node.getNamespaceURIOnPath(prefix);
 
67
                }
 
68
            }
 
69
        }
 
70
 
 
71
        Element element;
 
72
        if (nsAware && nsURI != null) {
 
73
            Namespace ns = prefix == null ? Namespace.getNamespace(nsURI) : Namespace.getNamespace(prefix, nsURI);
 
74
            element = factory.element(name, ns);
 
75
        } else {
 
76
            element = factory.element(name);
 
77
        }
 
78
 
 
79
        if (nsAware) {
 
80
            defineNamespaceDeclarations(node, element);
 
81
        }
 
82
        return element;
 
83
    }
 
84
 
 
85
    private void defineNamespaceDeclarations(TagNode node, Element element) {
 
86
        Map<String, String> nsDeclarations = node.getNamespaceDeclarations();
 
87
        if (nsDeclarations != null) {
 
88
            for (Map.Entry<String, String> nsEntry: nsDeclarations.entrySet()) {
 
89
                String nsPrefix = nsEntry.getKey();
 
90
                String nsURI = nsEntry.getValue();
 
91
                Namespace ns = nsPrefix == null || "".equals(nsPrefix) ? Namespace.getNamespace(nsURI) : Namespace.getNamespace(nsPrefix, nsURI);
 
92
                element.addNamespaceDeclaration(ns);
 
93
            }
 
94
        }
 
95
    }
 
96
 
 
97
    private void setAttributes(TagNode node, Element element) {
 
98
        for (Map.Entry<String, String> entry: node.getAttributes().entrySet()) {
 
99
            String attrName = entry.getKey();
 
100
            String attrValue = entry.getValue();
 
101
            if (escapeXml) {
 
102
                attrValue = Utils.escapeXml(attrValue, props, true);
 
103
            }
 
104
            String attPrefix = Utils.getXmlNSPrefix(attrName);
 
105
            Namespace ns = null;
 
106
            if (attPrefix != null) {
 
107
                attrName = Utils.getXmlName(attrName);
 
108
                if (props.isNamespacesAware()) {
 
109
                    String nsURI = node.getNamespaceURIOnPath(attPrefix);
 
110
                    if (nsURI == null) {
 
111
                        nsURI = attPrefix;
 
112
                    }
 
113
                    ns = Namespace.getNamespace(attPrefix, nsURI);
 
114
                }
 
115
            }
 
116
            if (ns == null) {
 
117
                element.setAttribute(attrName, attrValue);
 
118
            } else {
 
119
                element.setAttribute(attrName, attrValue, ns);
 
120
            }
 
121
        }
 
122
    }
 
123
 
 
124
    private void createSubnodes(Element element, List tagChildren) {
 
125
        if (tagChildren != null) {
 
126
            Iterator it = tagChildren.iterator();
 
127
            while (it.hasNext()) {
 
128
                Object item = it.next();
 
129
                if (item instanceof CommentNode) {
 
130
                    CommentNode commentNode = (CommentNode) item;
 
131
                    Comment comment = factory.comment( commentNode.getContent().toString() );
 
132
                    element.addContent(comment);
 
133
                } else if (item instanceof ContentNode) {
 
134
                    String nodeName = element.getName();
 
135
                    String content = item.toString();
 
136
                    boolean specialCase = props.isUseCdataForScriptAndStyle() &&
 
137
                                          ("script".equalsIgnoreCase(nodeName) || "style".equalsIgnoreCase(nodeName));
 
138
                    if (escapeXml && !specialCase) {
 
139
                        content = Utils.escapeXml(content, props, true);
 
140
                    }
 
141
                    Text text = specialCase ? factory.cdata(content) : factory.text(content);
 
142
                    element.addContent(text);
 
143
                } else if (item instanceof TagNode) {
 
144
                    TagNode subTagNode = (TagNode) item;
 
145
                    Element subelement = createElement(subTagNode);
 
146
 
 
147
                    setAttributes(subTagNode, subelement);
 
148
 
 
149
                    // recursively create subnodes
 
150
                    createSubnodes(subelement, subTagNode.getChildren());
 
151
 
 
152
                    element.addContent(subelement);
 
153
                } else if (item instanceof List) {
 
154
                    List sublist = (List) item;
 
155
                    createSubnodes(element, sublist);
 
156
                }
 
157
            }
 
158
        }
 
159
    }
 
160
 
 
161
}