1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package nl.hippo.portal.cms.site;
17
18 import java.io.IOException;
19 import java.io.InputStream;
20 import java.util.Collections;
21 import java.util.LinkedHashMap;
22 import java.util.List;
23 import java.util.Map;
24
25 import javax.xml.parsers.ParserConfigurationException;
26
27 import nl.hippo.portal.cms.CMSMetaData;
28 import nl.hippo.portal.cms.CMSMetaDataImpl;
29 import nl.hippo.portal.cms.CMSMetaDataItemImpl;
30
31 import org.apache.xerces.jaxp.DocumentBuilderFactoryImpl;
32 import org.w3c.dom.Document;
33 import org.w3c.dom.Node;
34 import org.w3c.dom.traversal.DocumentTraversal;
35 import org.w3c.dom.traversal.NodeFilter;
36 import org.w3c.dom.traversal.TreeWalker;
37 import org.xml.sax.SAXException;
38
39 public final class MetaDataLoader implements DocumentTransformer {
40
41 private static final String ELEMENT_NODE = "node";
42 private static final String ATTRIBUTE_ID = "id";
43 private static final String ATTRIBUTE_VALUE = "value";
44 private static final MetaDataLoader SINGLETON = new MetaDataLoader();
45
46 private MetaDataLoader() {
47 }
48
49 public Object transform(String name, InputStream documentStream, List documentPaths) throws SAXException, IOException,
50 ParserConfigurationException {
51 return getMetaData(name, documentStream);
52 }
53
54 public CMSMetaData getMetaData(String name, InputStream metaDataStream) throws SAXException,
55 ParserConfigurationException, IOException {
56 Document doc = DocumentBuilderFactoryImpl.newInstance().newDocumentBuilder().parse(metaDataStream);
57 Map metaDataMap = new LinkedHashMap();
58 Node root = doc.getDocumentElement();
59 DocumentTraversal traversal = (DocumentTraversal) doc;
60 TreeWalker walker = traversal.createTreeWalker(root, NodeFilter.SHOW_ALL, null, false);
61 Node node = walker.nextNode();
62 traverse(node, metaDataMap, null);
63 return new CMSMetaDataImpl(name, Collections.unmodifiableMap(metaDataMap));
64 }
65
66 private void traverse(Node node, Map metaDataMap, CMSMetaDataItemImpl parent) {
67 while (node != null) {
68 String nodeName = node.getNodeName();
69 if (ELEMENT_NODE.equals(nodeName)) {
70 CMSMetaDataItemImpl item = parseItem(metaDataMap, node, parent);
71 if (node.hasChildNodes())
72 traverse(node.getFirstChild(), metaDataMap, item);
73 }
74 node = node.getNextSibling();
75 }
76 }
77
78 private CMSMetaDataItemImpl parseItem(Map metaDataMap, Node node, CMSMetaDataItemImpl parent) {
79 CMSMetaDataItemImpl result = null;
80 Map attributes = XMLLoaderUtils.getAttributes(node);
81 String id = getId(attributes);
82 String value = getValue(attributes);
83 if (!isEmpty(id) && !isEmpty(value)) {
84 attributes.remove(ATTRIBUTE_ID);
85 attributes.remove(ATTRIBUTE_VALUE);
86 result = new CMSMetaDataItemImpl(id, value, Collections.unmodifiableMap(attributes));
87 metaDataMap.put(id, result);
88 if (parent != null)
89 parent.addChild(result);
90 }
91 return result;
92 }
93
94 private String getId(Map attributes) {
95 String result = (String) attributes.get(ATTRIBUTE_ID);
96 return result;
97 }
98
99 private String getValue(Map attributes) {
100 String result = (String) attributes.get(ATTRIBUTE_VALUE);
101 return result;
102 }
103
104 public static MetaDataLoader getInstance() {
105 return SINGLETON;
106 }
107
108 private static boolean isEmpty(String value) {
109 return value == null || value.length() == 0;
110 }
111 }