]> git.argeo.org Git - gpl/argeo-suite.git/blob - docbook/DbkTextInterpreter.java
Prepare next development cycle
[gpl/argeo-suite.git] / docbook / DbkTextInterpreter.java
1 package org.argeo.app.swt.docbook;
2
3 import static org.argeo.app.docbook.DbkAcrUtils.isDbk;
4 import static org.argeo.app.docbook.DbkType.para;
5 import static org.argeo.app.docbook.DbkType.title;
6
7 import java.io.IOException;
8 import java.io.StringReader;
9 import java.io.StringWriter;
10 import java.util.List;
11
12 import javax.xml.parsers.DocumentBuilderFactory;
13 import javax.xml.transform.Result;
14 import javax.xml.transform.Source;
15 import javax.xml.transform.TransformerException;
16 import javax.xml.transform.TransformerFactory;
17 import javax.xml.transform.stream.StreamResult;
18
19 import org.apache.commons.io.IOUtils;
20 import org.argeo.api.acr.Content;
21 import org.argeo.app.docbook.DbkType;
22
23 /** Based on HTML with a few Wiki-like shortcuts. */
24 public class DbkTextInterpreter implements TextInterpreter {
25
26 private TransformerFactory transformerFactory = TransformerFactory.newDefaultInstance();
27
28 private String linkCssClass = DbkType.link.name();
29
30 @Override
31 public void write(Content node, String content) {
32 if (isDbk(node, para) || isDbk(node, title)) {
33 String raw = convertToStorage(node, content);
34 validateBeforeStoring(raw);
35
36 String jcrUuid = null;// node.getIdentifier();
37 // if (node.hasProperty(Property.JCR_UUID))
38 // jcrUuid = node.getProperty(Property.JCR_UUID).getString();
39 // else {
40 // // TODO use time based
41 // jcrUuid = UUID.randomUUID().toString();
42 // node.setProperty(Property.JCR_UUID, jcrUuid);
43 // node.getSession().save();
44 // }
45
46 StringBuilder namespaces = new StringBuilder();
47 namespaces.append(" xmlns:dbk=\"http://docbook.org/ns/docbook\"");
48 namespaces.append(" xmlns:jcr=\"http://www.jcp.org/jcr/1.0\"");
49 namespaces.append(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"");
50 raw = "<" + node.getName() + " jcr:uuid=\"" + jcrUuid + "\"" + namespaces + ">" + raw + "</"
51 + node.getName() + ">";
52 // System.out.println(raw);
53 // try (InputStream in = new ByteArrayInputStream(raw.getBytes(StandardCharsets.UTF_8))) {
54 // node.getSession().importXML(node.getParent().getPath(), in,
55 // ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING);
56 // // node.getSession().save();
57 // } catch (IOException e) {
58 // throw new IllegalArgumentException("Cannot parse raw content of " + node, e);
59 // }
60
61 // try {
62 // DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
63 // Document document;
64 // try (Reader in = new StringReader(raw)) {
65 // document = documentBuilder.parse(new InputSource(in));
66 // }
67 // NodeList nl = document.getChildNodes();
68 // for (int i = 0; i < nl.getLength(); i++) {
69 // org.w3c.dom.Node n = nl.item(i);
70 // if (node instanceof Text) {
71 //
72 // }
73 // }
74 // } catch (ParserConfigurationException | SAXException | IOException e) {
75 // throw new IllegalArgumentException("Cannot parse raw content of " + node, e);
76 // }
77
78 // Node jcrText;
79 // if (!node.hasNode(Jcr.JCR_XMLTEXT))
80 // jcrText = node.addNode(Jcr.JCR_XMLTEXT, JcrxType.JCRX_XMLTEXT);
81 // else
82 // jcrText = node.getNode(Jcr.JCR_XMLTEXT);
83 // jcrText.setProperty(Jcr.JCR_XMLCHARACTERS, raw);
84 } else {
85 throw new IllegalArgumentException("Don't know how to interpret " + node);
86 }
87 }
88
89 @Override
90 public String read(Content item) {
91 String raw = raw(item);
92 return convertFromStorage(item, raw);
93 }
94
95 @Override
96 public String raw(Content node) {
97 if (isDbk(node, para) || isDbk(node, title)) {
98 Source source = node.adapt(Source.class);
99
100 StringWriter stringWriter = new StringWriter();
101 Result result = new StreamResult(stringWriter);
102
103 try {
104 transformerFactory.newTransformer().transform(source, result);
105 return stringWriter.toString();
106 } catch (TransformerException e) {
107 throw new RuntimeException("Could not convert " + node + " to XML", e);
108 }
109
110 // StringBuilder sb = new StringBuilder();
111 // readXml(node, sb);
112 // NodeIterator nit = node.getNodes();
113 // while (nit.hasNext()) {
114 // Node child = nit.nextNode();
115 // if (child.getName().equals(Jcr.JCR_XMLTEXT)) {
116 // Node jcrText = node.getNode(Jcr.JCR_XMLTEXT);
117 // String txt = jcrText.getProperty(Jcr.JCR_XMLCHARACTERS).getString();
118 // // TODO make it more robust
119 // // txt = txt.replace("\n", "").replace("\t", "");
120 // txt = txt.replace("\t", " ");
121 // sb.append(txt);
122 // } else {
123 // try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
124 // child.getSession().exportDocumentView(child.getPath(), out, true, false);
125 // sb.append(new String(out.toByteArray(), StandardCharsets.UTF_8));
126 // } catch (IOException e) {
127 // throw new IllegalStateException("Cannot export " + child, e);
128 // }
129 // }
130 // }
131 // return sb.toString();
132 } else {
133 throw new IllegalArgumentException("Don't know how to interpret " + node);
134 }
135 }
136
137 // private void readXml(Content node, StringBuilder sb){
138 //
139 // NodeIterator nit = node.getNodes();
140 // while (nit.hasNext()) {
141 // Node child = nit.nextNode();
142 // if (child.getName().equals(Jcr.JCR_XMLTEXT)) {
143 // String txt = child.getProperty(Jcr.JCR_XMLCHARACTERS).getString();
144 // // TODO make it more robust
145 // // txt = txt.replace("\n", "").replace("\t", "");
146 // txt = txt.replace("\t", " ");
147 // sb.append(txt);
148 // } else {
149 // sb.append('<').append(child.getName());
150 // PropertyIterator pit = child.getProperties();
151 // properties: while (pit.hasNext()) {
152 // Property p = pit.nextProperty();
153 // if (p.getName().startsWith("jcr:"))
154 // continue properties;
155 // sb.append(' ').append(p.getName()).append("=\"").append(p.getString()).append('\"');
156 // }
157 // sb.append('>');
158 // readXml(child, sb);
159 //// try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
160 //// child.getSession().exportDocumentView(child.getPath(), out, true, false);
161 //// sb.append(new String(out.toByteArray(), StandardCharsets.UTF_8));
162 //// } catch (IOException e) {
163 //// throw new IllegalStateException("Cannot export " + child, e);
164 //// }
165 // sb.append("</").append(child.getName()).append('>');
166 // }
167 // }
168 // }
169
170 private void readAsSimpleHtml(Content node, StringBuilder sb) {
171 // NodeIterator nit = node.getNodes();
172 // while (nit.hasNext()) {
173 // Node child = nit.nextNode();
174 // if (child.getName().equals(Jcr.JCR_XMLTEXT)) {
175 // String txt = child.getProperty(Jcr.JCR_XMLCHARACTERS).getString();
176 // // TODO make it more robust
177 // // txt = txt.replace("\n", "").replace("\t", "");
178 // txt = txt.replace("\t", " ");
179 // String html = textToSimpleHtml(txt);
180 // sb.append(html);
181 // } else if (child.getName().equals(DbkType.link.get())) {
182 // if (child.hasProperty(DbkAttr.XLINK_HREF)) {
183 // String href = child.getProperty(DbkAttr.XLINK_HREF).getString();
184 // // TODO deal with other forbidden XML characters?
185 // href = href.replace("&", "&amp;");
186 // sb.append("<a class='" + linkCssClass + "' href='").append(href).append("'>");
187 // readAsSimpleHtml(child, sb);
188 // sb.append("</a>");
189 // }
190 // } else {
191 // // ignore
192 // }
193 // }
194 }
195
196 private String textToSimpleHtml(String raw) {
197 // FIXME the saved data should be corrected instead.
198 if (raw.indexOf('&') >= 0) {
199 raw = raw.replace("&", "&amp;");
200 }
201 if (raw.indexOf('<') >= 0) {
202 raw = raw.replace("<", "&lt;");
203 }
204 if (raw.indexOf('>') >= 0) {
205 raw = raw.replace(">", "&gt;");
206 }
207 if (raw.indexOf('\"') >= 0) {
208 raw = raw.replace("\"", "&quot;");
209 }
210 if (raw.indexOf('\'') >= 0) {
211 raw = raw.replace("\'", "&apos;");
212 }
213 // raw = "<span style='text-align:justify'>" + raw + "</span>";
214 if (raw.length() == 0)
215 return raw;
216 try (StringReader reader = new StringReader(raw)) {
217 List<String> lines = IOUtils.readLines(reader);
218 if (lines.size() == 1)
219 return lines.get(0);
220 StringBuilder sb = new StringBuilder(raw.length() + lines.size() * BR_LENGTH);
221 for (int i = 0; i < lines.size(); i++) {
222 if (i != 0)
223 sb.append("<br/>");
224 sb.append(lines.get(i));
225 }
226 return sb.toString();
227 } catch (IOException e) {
228 throw new RuntimeException(e);
229 }
230 }
231
232 final static int BR_LENGTH = "<br/>".length();
233
234 public String readSimpleHtml(Content item) {
235 StringBuilder sb = new StringBuilder();
236 // sb.append("<div style='text-align: justify;'>");
237 readAsSimpleHtml(item, sb);
238 // sb.append("</div>");
239 // System.out.println(sb);
240 return sb.toString();
241 }
242
243 // EXTENSIBILITY
244 /**
245 * To be overridden, in order to make sure that only valid strings are being
246 * stored.
247 */
248 protected void validateBeforeStoring(String raw) {
249 }
250
251 /** To be overridden, in order to support additional formatting. */
252 protected String convertToStorage(Content item, String content) {
253 return content;
254
255 }
256
257 /** To be overridden, in order to support additional formatting. */
258 protected String convertFromStorage(Content item, String content) {
259 return content;
260 }
261 }