]> git.argeo.org Git - gpl/argeo-suite.git/blob - publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java
Introduce multiple map vector layers.
[gpl/argeo-suite.git] / publishing / org.argeo.publishing.ui / src / org / argeo / docbook / DbkUtils.java
1 package org.argeo.docbook;
2
3 import static org.argeo.docbook.DbkType.para;
4
5 import java.io.IOException;
6 import java.io.InputStream;
7 import java.io.OutputStream;
8 import java.nio.file.Files;
9 import java.nio.file.Path;
10
11 import javax.jcr.ImportUUIDBehavior;
12 import javax.jcr.Node;
13 import javax.jcr.NodeIterator;
14 import javax.jcr.PathNotFoundException;
15 import javax.jcr.RepositoryException;
16 import javax.jcr.ValueFormatException;
17
18 import org.apache.commons.logging.Log;
19 import org.apache.commons.logging.LogFactory;
20 import org.argeo.entity.EntityType;
21 import org.argeo.jcr.Jcr;
22 import org.argeo.jcr.JcrException;
23 import org.argeo.jcr.JcrUtils;
24 import org.argeo.jcr.JcrxApi;
25
26 /** Utilities around DocBook. */
27 public class DbkUtils {
28 private final static Log log = LogFactory.getLog(DbkUtils.class);
29
30 /** Get or add a DocBook element. */
31 public static Node getOrAddDbk(Node parent, DbkType child) {
32 try {
33 if (!parent.hasNode(child.get())) {
34 return addDbk(parent, child);
35 } else {
36 return parent.getNode(child.get());
37 }
38 } catch (RepositoryException e) {
39 throw new JcrException("Cannot get or add element " + child.get() + " to " + parent, e);
40 }
41 }
42
43 /** Add a DocBook element to this node. */
44 public static Node addDbk(Node parent, DbkType child) {
45 try {
46 Node node = parent.addNode(child.get(), child.get());
47 return node;
48 } catch (RepositoryException e) {
49 throw new JcrException("Cannot add element " + child.get() + " to " + parent, e);
50 }
51 }
52
53 /** Whether this DocBook element is of this type. */
54 public static boolean isDbk(Node node, DbkType type) {
55 return Jcr.getName(node).equals(type.get());
56 }
57
58 /** Whether this node is a DocBook type. */
59 public static boolean isDbk(Node node) {
60 String name = Jcr.getName(node);
61 for (DbkType type : DbkType.values()) {
62 if (name.equals(type.get()))
63 return true;
64 }
65 return false;
66 }
67
68 public static String getTitle(Node node) {
69 return JcrxApi.getXmlValue(node, DbkType.title.get());
70 }
71
72 public static void setTitle(Node node, String txt) {
73 Node titleNode = getOrAddDbk(node, DbkType.title);
74 JcrxApi.setXmlValue(node, titleNode, txt);
75 }
76
77 public static Node getMetadata(Node infoContainer) {
78 try {
79 if (!infoContainer.hasNode(DbkType.info.get()))
80 return null;
81 Node info = infoContainer.getNode(DbkType.info.get());
82 if (!info.hasNode(EntityType.local.get()))
83 return null;
84 return info.getNode(EntityType.local.get());
85 } catch (RepositoryException e) {
86 throw new JcrException("Cannot retrieve metadata from " + infoContainer, e);
87 }
88 }
89
90 public static Node getChildByRole(Node parent, String role) {
91 try {
92 NodeIterator baseSections = parent.getNodes();
93 while (baseSections.hasNext()) {
94 Node n = baseSections.nextNode();
95 String r = Jcr.get(n, DbkAttr.role.name());
96 if (r != null && r.equals(role))
97 return n;
98 }
99 return null;
100 } catch (RepositoryException e) {
101 throw new JcrException("Cannot get child from " + parent + " with role " + role, e);
102 }
103 }
104
105 public static Node addParagraph(Node node, String txt) {
106 Node p = addDbk(node, para);
107 JcrxApi.setXmlValue(node, p, txt);
108 return p;
109 }
110
111 /**
112 * Removes a paragraph if it empty. The sesison is not saved.
113 *
114 * @return true if the paragraph was empty and it was removed
115 */
116 public static boolean removeIfEmptyParagraph(Node node) {
117 try {
118 if (isDbk(node, DbkType.para)) {
119 NodeIterator nit = node.getNodes();
120 if (!nit.hasNext()) {
121 node.remove();
122 return true;
123 }
124 Node first = nit.nextNode();
125 if (nit.hasNext())
126 return false;
127 if (first.getName().equals(Jcr.JCR_XMLTEXT)) {
128 String str = JcrxApi.getXmlValue(first);
129 if (str != null && str.trim().equals("")) {
130 node.remove();
131 return true;
132 }
133 } else {
134 return false;
135 }
136 }
137 return false;
138 } catch (RepositoryException e) {
139 throw new JcrException("Cannot remove possibly empty paragraph", e);
140 }
141 }
142
143 public static Node insertImageAfter(Node sibling) {
144 try {
145
146 Node parent = sibling.getParent();
147 Node mediaNode = addDbk(parent, DbkType.mediaobject);
148 // TODO optimise?
149 parent.orderBefore(mediaNode.getName() + "[" + mediaNode.getIndex() + "]",
150 sibling.getName() + "[" + sibling.getIndex() + "]");
151 parent.orderBefore(sibling.getName() + "[" + sibling.getIndex() + "]",
152 mediaNode.getName() + "[" + mediaNode.getIndex() + "]");
153
154 Node imageNode = addDbk(mediaNode, DbkType.imageobject);
155 Node imageDataNode = addDbk(imageNode, DbkType.imagedata);
156 // Node infoNode = imageNode.addNode(DocBookTypes.INFO, DocBookTypes.INFO);
157 // Node fileNode = JcrUtils.copyBytesAsFile(mediaFolder, EntityType.box.get(), new byte[0]);
158 // fileNode.addMixin(EntityType.box.get());
159 // fileNode.setProperty(EntityNames.SVG_WIDTH, 0);
160 // fileNode.setProperty(EntityNames.SVG_LENGTH, 0);
161 // fileNode.addMixin(NodeType.MIX_MIMETYPE);
162 //
163 // // we assume this is a folder next to the main DocBook document
164 // // TODO make it more robust and generic
165 // String fileRef = mediaNode.getName();
166 // imageDataNode.setProperty(DocBookNames.DBK_FILEREF, fileRef);
167 return mediaNode;
168 } catch (RepositoryException e) {
169 throw new JcrException("Cannot insert empty image after " + sibling, e);
170 }
171 }
172
173 public static Node insertVideoAfter(Node sibling) {
174 try {
175
176 Node parent = sibling.getParent();
177 Node mediaNode = addDbk(parent, DbkType.mediaobject);
178 // TODO optimise?
179 parent.orderBefore(mediaNode.getName() + "[" + mediaNode.getIndex() + "]",
180 sibling.getName() + "[" + sibling.getIndex() + "]");
181 parent.orderBefore(sibling.getName() + "[" + sibling.getIndex() + "]",
182 mediaNode.getName() + "[" + mediaNode.getIndex() + "]");
183
184 Node videoNode = addDbk(mediaNode, DbkType.videoobject);
185 Node videoDataNode = addDbk(videoNode, DbkType.videodata);
186 return mediaNode;
187 } catch (RepositoryException e) {
188 throw new JcrException("Cannot insert empty image after " + sibling, e);
189 }
190 }
191
192 public static String getMediaFileref(Node node) {
193 try {
194 Node mediadata;
195 if (node.hasNode(DbkType.imageobject.get())) {
196 mediadata = node.getNode(DbkType.imageobject.get()).getNode(DbkType.imagedata.get());
197 } else if (node.hasNode(DbkType.videoobject.get())) {
198 mediadata = node.getNode(DbkType.videoobject.get()).getNode(DbkType.videodata.get());
199 } else {
200 throw new IllegalArgumentException("Fileref not found in " + node);
201 }
202
203 if (mediadata.hasProperty(DbkAttr.fileref.name())) {
204 return mediadata.getProperty(DbkAttr.fileref.name()).getString();
205 } else {
206 return null;
207 }
208 } catch (RepositoryException e) {
209 throw new JcrException("Cannot retrieve file ref from " + node, e);
210 }
211 }
212
213 public static void exportXml(Node node, OutputStream out) throws IOException {
214 try {
215 node.getSession().exportDocumentView(node.getPath(), out, false, false);
216 } catch (RepositoryException e) {
217 throw new JcrException("Cannot export " + node + " to XML", e);
218 }
219 }
220
221 public static void exportToFs(Node baseNode, DbkType type, Path directory) {
222 String fileName = Jcr.getName(baseNode) + ".dbk.xml";
223 Path filePath = directory.resolve(fileName);
224 Node docBookNode = Jcr.getNode(baseNode, type.get());
225 if (docBookNode == null)
226 throw new IllegalArgumentException("No " + type.get() + " under " + baseNode);
227 try {
228 Files.createDirectories(directory);
229 try (OutputStream out = Files.newOutputStream(filePath)) {
230 exportXml(docBookNode, out);
231 }
232 JcrUtils.copyFilesToFs(baseNode, directory, true);
233 if (log.isDebugEnabled())
234 log.debug("DocBook " + baseNode + " exported to " + filePath.toAbsolutePath());
235 } catch (IOException e) {
236 throw new RuntimeException(e);
237 }
238 }
239
240 public static void importXml(Node baseNode, InputStream in) throws IOException {
241 try {
242 baseNode.getSession().importXML(baseNode.getPath(), in,
243 ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
244 } catch (RepositoryException e) {
245 throw new JcrException("Cannot import XML to " + baseNode, e);
246 }
247
248 }
249
250 /** Singleton. */
251 private DbkUtils() {
252 }
253
254 }