]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/acr/xml/DomContentProvider.java
Remove static default UUID factory
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / xml / DomContentProvider.java
1 package org.argeo.cms.acr.xml;
2
3 import java.io.IOException;
4 import java.io.OutputStream;
5 import java.util.ArrayList;
6 import java.util.Collections;
7 import java.util.Iterator;
8 import java.util.List;
9
10 import javax.xml.namespace.NamespaceContext;
11 import javax.xml.xpath.XPath;
12 import javax.xml.xpath.XPathConstants;
13 import javax.xml.xpath.XPathExpressionException;
14 import javax.xml.xpath.XPathFactory;
15
16 import org.argeo.api.acr.Content;
17 import org.argeo.api.acr.ContentNotFoundException;
18 import org.argeo.api.acr.CrName;
19 import org.argeo.api.acr.NamespaceUtils;
20 import org.argeo.api.acr.spi.ContentProvider;
21 import org.argeo.api.acr.spi.ProvidedContent;
22 import org.argeo.api.acr.spi.ProvidedSession;
23 import org.argeo.cms.acr.CmsContentRepository;
24 import org.w3c.dom.Document;
25 import org.w3c.dom.Element;
26 import org.w3c.dom.NodeList;
27
28 public class DomContentProvider implements ContentProvider, NamespaceContext {
29 private final Document document;
30
31 // XPath
32 // TODO centralise in some executor?
33 private final ThreadLocal<XPath> xPath;
34
35 private String mountPath;
36
37 public DomContentProvider(String mountPath, Document document) {
38 this.mountPath = mountPath;
39 this.document = document;
40 this.document.normalizeDocument();
41 XPathFactory xPathFactory = XPathFactory.newInstance();
42 xPath = new ThreadLocal<>() {
43
44 @Override
45 protected XPath initialValue() {
46 // TODO set the document as namespace context?
47 XPath res = xPathFactory.newXPath();
48 res.setNamespaceContext(DomContentProvider.this);
49 return res;
50 }
51 };
52 }
53
54 // @Override
55 // public Content get() {
56 // return new DomContent(this, document.getDocumentElement());
57 // }
58
59 // public Element createElement(String name) {
60 // return document.createElementNS(null, name);
61 //
62 // }
63
64 @Override
65 public ProvidedContent get(ProvidedSession session, String relativePath) {
66 if ("".equals(relativePath))
67 return new DomContent(session, this, document.getDocumentElement());
68
69 NodeList nodes = findContent(relativePath);
70 if (nodes.getLength() > 1)
71 throw new IllegalArgumentException("Multiple content found for " + relativePath + " under " + mountPath);
72 if (nodes.getLength() == 0)
73 throw new ContentNotFoundException("Path " + relativePath + " under " + mountPath + " was not found");
74 Element element = (Element) nodes.item(0);
75 return new DomContent(session, this, element);
76 }
77
78 protected NodeList findContent(String relativePath) {
79 if (relativePath.startsWith("/"))
80 throw new IllegalArgumentException("Relative path cannot start with /");
81 String xPathExpression = '/' + relativePath;
82 if ("/".equals(mountPath))
83 xPathExpression = "/" + CrName.root.qName() + xPathExpression;
84 try {
85 NodeList nodes = (NodeList) xPath.get().evaluate(xPathExpression, document, XPathConstants.NODESET);
86 return nodes;
87 } catch (XPathExpressionException e) {
88 throw new IllegalArgumentException("XPath expression " + xPathExpression + " cannot be evaluated", e);
89 }
90
91 }
92
93 @Override
94 public boolean exists(ProvidedSession session, String relativePath) {
95 if ("".equals(relativePath))
96 return true;
97 NodeList nodes = findContent(relativePath);
98 return nodes.getLength() != 0;
99 }
100
101 public void persist(ProvidedSession session) {
102 if (mountPath != null) {
103 Content mountPoint = session.getMountPoint(mountPath);
104 try (OutputStream out = mountPoint.open(OutputStream.class)) {
105 CmsContentRepository contentRepository = (CmsContentRepository) session.getRepository();
106 contentRepository.writeDom(document, out);
107 } catch (IOException e) {
108 throw new IllegalStateException("Cannot persist " + mountPath, e);
109 }
110 }
111 }
112
113 @Override
114 public String getMountPath() {
115 return mountPath;
116 }
117
118 public void registerPrefix(String prefix, String namespace) {
119 DomUtils.addNamespace(document.getDocumentElement(), prefix, namespace);
120 }
121
122 /*
123 * NAMESPACE CONTEXT
124 */
125 @Override
126 public String getNamespaceURI(String prefix) {
127 String namespaceURI = NamespaceUtils.getStandardNamespaceURI(prefix);
128 if (namespaceURI != null)
129 return namespaceURI;
130 return document.lookupNamespaceURI(prefix);
131 }
132
133 @Override
134 public String getPrefix(String namespaceURI) {
135 String prefix = NamespaceUtils.getStandardPrefix(namespaceURI);
136 if (prefix != null)
137 return prefix;
138 return document.lookupPrefix(namespaceURI);
139 }
140
141 @Override
142 public Iterator<String> getPrefixes(String namespaceURI) {
143 List<String> res = new ArrayList<>();
144 res.add(getPrefix(namespaceURI));
145 return Collections.unmodifiableList(res).iterator();
146 }
147
148 }