]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.cms/src/org/argeo/cms/acr/AbstractContentRepository.java
Mini desktop graalvm packaging.
[lgpl/argeo-commons.git] / org.argeo.cms / src / org / argeo / cms / acr / AbstractContentRepository.java
1 package org.argeo.cms.acr;
2
3 import java.io.IOException;
4 import java.io.InputStream;
5 import java.io.OutputStream;
6 import java.nio.file.Files;
7 import java.nio.file.Path;
8 import java.util.Set;
9
10 import javax.xml.namespace.QName;
11 import javax.xml.parsers.DocumentBuilder;
12 import javax.xml.transform.OutputKeys;
13 import javax.xml.transform.Transformer;
14 import javax.xml.transform.TransformerException;
15 import javax.xml.transform.TransformerFactory;
16 import javax.xml.transform.dom.DOMSource;
17 import javax.xml.transform.stream.StreamResult;
18
19 import org.argeo.api.acr.Content;
20 import org.argeo.api.acr.CrName;
21 import org.argeo.api.acr.spi.ContentProvider;
22 import org.argeo.api.acr.spi.ProvidedContent;
23 import org.argeo.api.acr.spi.ProvidedRepository;
24 import org.argeo.api.cms.CmsLog;
25 import org.argeo.api.uuid.UuidFactory;
26 import org.argeo.cms.acr.xml.DomContentProvider;
27 import org.argeo.cms.acr.xml.DomUtils;
28 import org.w3c.dom.DOMException;
29 import org.w3c.dom.Document;
30 import org.w3c.dom.Element;
31 import org.xml.sax.SAXException;
32
33 /**
34 * Base implementation of a {@link ProvidedRepository}.
35 */
36 public abstract class AbstractContentRepository implements ProvidedRepository {
37 private final static CmsLog log = CmsLog.getLog(AbstractContentRepository.class);
38
39 private UuidFactory uuidFactory;
40
41 private MountManager mountManager;
42 private TypesManager typesManager;
43
44 private CmsContentSession systemSession;
45
46 // utilities
47 /** Should be used only to copy source and results. */
48 private TransformerFactory identityTransformerFactory = TransformerFactory.newInstance();
49
50 public final static String ACR_MOUNT_PATH_PROPERTY = "acr.mount.path";
51
52 public AbstractContentRepository() {
53 // types
54 typesManager = new TypesManager();
55 typesManager.init();
56 Set<QName> types = typesManager.listTypes();
57 if (log.isTraceEnabled())
58 for (QName type : types) {
59 log.trace(type + " - " + typesManager.getAttributeTypes(type));
60 }
61
62 }
63
64 protected abstract CmsContentSession newSystemSession();
65
66 public void start() {
67 systemSession = newSystemSession();
68 // mounts
69 mountManager = new MountManager(systemSession);
70 }
71
72 public void stop() {
73 systemSession.close();
74 systemSession = null;
75 }
76
77 /*
78 * REPOSITORY
79 */
80
81 public void addProvider(ContentProvider provider) {
82 mountManager.addStructuralContentProvider(provider);
83 }
84
85 public void registerTypes(String prefix, String namespaceURI, String schemaSystemId) {
86 typesManager.registerTypes(prefix, namespaceURI, schemaSystemId);
87 }
88
89 /*
90 * FACTORIES
91 */
92 public void initRootContentProvider(Path path) {
93 try {
94 // DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
95 // factory.setNamespaceAware(true);
96 // factory.setXIncludeAware(true);
97 // factory.setSchema(contentTypesManager.getSchema());
98 //
99 DocumentBuilder dBuilder = typesManager.newDocumentBuilder();
100
101 Document document;
102 // if (path != null && Files.exists(path)) {
103 // InputSource inputSource = new InputSource(path.toAbsolutePath().toUri().toString());
104 // inputSource.setEncoding(StandardCharsets.UTF_8.name());
105 // // TODO public id as well?
106 // document = dBuilder.parse(inputSource);
107 // } else {
108 document = dBuilder.newDocument();
109 Element root = document.createElementNS(CrName.CR_NAMESPACE_URI, CrName.ROOT.get().toPrefixedString());
110
111 for (String prefix : typesManager.getPrefixes().keySet()) {
112 // root.setAttributeNS(XMLConstants.XMLNS_ATTRIBUTE_NS_URI, XMLConstants.XMLNS_ATTRIBUTE + ":" + prefix,
113 // contentTypesManager.getPrefixes().get(prefix));
114 DomUtils.addNamespace(root, prefix, typesManager.getPrefixes().get(prefix));
115 }
116
117 document.appendChild(root);
118
119 // write it
120 if (path != null) {
121 try (OutputStream out = Files.newOutputStream(path)) {
122 writeDom(document, out);
123 }
124 }
125 // }
126
127 String mountPath = "/";
128 DomContentProvider contentProvider = new DomContentProvider(mountPath, document);
129 addProvider(contentProvider);
130 } catch (DOMException | IOException e) {
131 throw new IllegalStateException("Cannot init ACR root " + path, e);
132 }
133
134 }
135
136 public void writeDom(Document document, OutputStream out) throws IOException {
137 try {
138 Transformer transformer = identityTransformerFactory.newTransformer();
139 transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
140 transformer.setOutputProperty(OutputKeys.INDENT, "yes");
141
142 DOMSource source = new DOMSource(document);
143 typesManager.validate(source);
144 StreamResult result = new StreamResult(out);
145 transformer.transform(source, result);
146 } catch (TransformerException e) {
147 throw new IOException("Cannot write dom", e);
148 }
149 }
150
151 /*
152 * MOUNT MANAGEMENT
153 */
154
155 @Override
156 public ContentProvider getMountContentProvider(Content mountPoint, boolean initialize, QName... types) {
157 String mountPath = mountPoint.getPath();
158 // TODO check consistency with types
159
160 return mountManager.getOrAddMountedProvider(mountPath, (path) -> {
161 DocumentBuilder dBuilder = typesManager.newDocumentBuilder();
162 Document document;
163 if (initialize) {
164 QName firstType = types[0];
165 document = dBuilder.newDocument();
166 String prefix = ((ProvidedContent) mountPoint).getSession().getPrefix(firstType.getNamespaceURI());
167 Element root = document.createElementNS(firstType.getNamespaceURI(),
168 prefix + ":" + firstType.getLocalPart());
169 DomUtils.addNamespace(root, prefix, firstType.getNamespaceURI());
170 document.appendChild(root);
171 } else {
172 try (InputStream in = mountPoint.open(InputStream.class)) {
173 document = dBuilder.parse(in);
174 // TODO check consistency with types
175 } catch (IOException | SAXException e) {
176 throw new IllegalStateException("Cannot load mount from " + mountPoint, e);
177 }
178 }
179 DomContentProvider contentProvider = new DomContentProvider(path, document);
180 return contentProvider;
181 });
182 }
183
184 @Override
185 public boolean shouldMount(QName... types) {
186 if (types.length == 0)
187 return false;
188 QName firstType = types[0];
189 Set<QName> registeredTypes = typesManager.listTypes();
190 if (registeredTypes.contains(firstType))
191 return true;
192 return false;
193 }
194
195 MountManager getMountManager() {
196 return mountManager;
197 }
198
199 TypesManager getTypesManager() {
200 return typesManager;
201 }
202
203 public void setUuidFactory(UuidFactory uuidFactory) {
204 this.uuidFactory = uuidFactory;
205 }
206
207 }