1 package org
.argeo
.docbook
;
3 import static org
.argeo
.docbook
.DbkType
.para
;
5 import java
.io
.IOException
;
6 import java
.io
.OutputStream
;
7 import java
.nio
.file
.Files
;
8 import java
.nio
.file
.Path
;
10 import javax
.jcr
.Node
;
11 import javax
.jcr
.NodeIterator
;
12 import javax
.jcr
.RepositoryException
;
14 import org
.apache
.commons
.logging
.Log
;
15 import org
.apache
.commons
.logging
.LogFactory
;
16 import org
.argeo
.entity
.EntityType
;
17 import org
.argeo
.jcr
.Jcr
;
18 import org
.argeo
.jcr
.JcrException
;
19 import org
.argeo
.jcr
.JcrUtils
;
20 import org
.argeo
.jcr
.JcrxApi
;
22 /** Utilities around DocBook. */
23 public class DbkUtils
{
24 private final static Log log
= LogFactory
.getLog(DbkUtils
.class);
26 /** Get or add a DocBook element. */
27 public static Node
getOrAddDbk(Node parent
, DbkType child
) {
29 if (!parent
.hasNode(child
.get())) {
30 return addDbk(parent
, child
);
32 return parent
.getNode(child
.get());
34 } catch (RepositoryException e
) {
35 throw new JcrException("Cannot get or add element " + child
.get() + " to " + parent
, e
);
39 /** Add a DocBook element to this node. */
40 public static Node
addDbk(Node parent
, DbkType child
) {
42 Node node
= parent
.addNode(child
.get(), child
.get());
44 } catch (RepositoryException e
) {
45 throw new JcrException("Cannot add element " + child
.get() + " to " + parent
, e
);
49 /** Whether this DocBook element is of this type. */
50 public static boolean isDbk(Node node
, DbkType type
) {
51 return Jcr
.getName(node
).equals(type
.get());
54 public static String
getTitle(Node node
) {
55 return JcrxApi
.getXmlValue(node
, DbkType
.title
.get());
58 public static void setTitle(Node node
, String txt
) {
59 Node titleNode
= getOrAddDbk(node
, DbkType
.title
);
60 JcrxApi
.setXmlValue(node
, titleNode
, txt
);
63 public static Node
getMetadata(Node infoContainer
) {
65 if (!infoContainer
.hasNode(DbkType
.info
.get()))
67 Node info
= infoContainer
.getNode(DbkType
.info
.get());
68 if (!info
.hasNode(EntityType
.local
.get()))
70 return info
.getNode(EntityType
.local
.get());
71 } catch (RepositoryException e
) {
72 throw new JcrException("Cannot retrieve metadata from " + infoContainer
, e
);
76 public static Node
getChildByRole(Node parent
, String role
) {
78 NodeIterator baseSections
= parent
.getNodes();
79 while (baseSections
.hasNext()) {
80 Node n
= baseSections
.nextNode();
81 String r
= Jcr
.get(n
, DbkAttr
.role
.name());
82 if (r
!= null && r
.equals(role
))
86 } catch (RepositoryException e
) {
87 throw new JcrException("Cannot get child from " + parent
+ " with role " + role
, e
);
91 public static Node
addParagraph(Node node
, String txt
) {
92 Node p
= addDbk(node
, para
);
93 JcrxApi
.setXmlValue(node
, p
, txt
);
97 public static Node
insertImageAfter(Node sibling
) {
100 // FIXME make it more robust
101 if (DbkType
.imagedata
.get().equals(sibling
.getName())) {
102 sibling
= sibling
.getParent().getParent();
105 Node parent
= sibling
.getParent();
106 Node mediaNode
= addDbk(parent
, DbkType
.mediaobject
);
108 parent
.orderBefore(mediaNode
.getName() + "[" + mediaNode
.getIndex() + "]",
109 sibling
.getName() + "[" + sibling
.getIndex() + "]");
110 parent
.orderBefore(sibling
.getName() + "[" + sibling
.getIndex() + "]",
111 mediaNode
.getName() + "[" + mediaNode
.getIndex() + "]");
113 Node imageNode
= addDbk(mediaNode
, DbkType
.imageobject
);
114 Node imageDataNode
= addDbk(imageNode
, DbkType
.imagedata
);
115 // Node infoNode = imageNode.addNode(DocBookTypes.INFO, DocBookTypes.INFO);
116 // Node fileNode = JcrUtils.copyBytesAsFile(mediaFolder, EntityType.box.get(), new byte[0]);
117 // fileNode.addMixin(EntityType.box.get());
118 // fileNode.setProperty(EntityNames.SVG_WIDTH, 0);
119 // fileNode.setProperty(EntityNames.SVG_LENGTH, 0);
120 // fileNode.addMixin(NodeType.MIX_MIMETYPE);
122 // // we assume this is a folder next to the main DocBook document
123 // // TODO make it more robust and generic
124 // String fileRef = mediaNode.getName();
125 // imageDataNode.setProperty(DocBookNames.DBK_FILEREF, fileRef);
126 return imageDataNode
;
127 } catch (RepositoryException e
) {
128 throw new JcrException("Cannot insert empty image after " + sibling
, e
);
132 public static void exportXml(Node node
, OutputStream out
) throws IOException
{
134 node
.getSession().exportDocumentView(node
.getPath(), out
, false, false);
135 } catch (RepositoryException e
) {
136 throw new JcrException("Cannot export " + node
+ " to XML", e
);
140 public static void exportToFs(Node baseNode
, DbkType type
, Path directory
) {
141 String fileName
= Jcr
.getName(baseNode
) + ".dbk.xml";
142 Path filePath
= directory
.resolve(fileName
);
143 Node docBookNode
= Jcr
.getNode(baseNode
, type
.get());
144 if (docBookNode
== null)
145 throw new IllegalArgumentException("No " + type
.get() + " under " + baseNode
);
147 Files
.createDirectories(directory
);
148 try (OutputStream out
= Files
.newOutputStream(filePath
)) {
149 exportXml(docBookNode
, out
);
151 JcrUtils
.copyFilesToFs(baseNode
, directory
, true);
152 if (log
.isDebugEnabled())
153 log
.debug("DocBook " + baseNode
+ " exported to " + filePath
.toAbsolutePath());
154 } catch (IOException e
) {
155 throw new RuntimeException(e
);