X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=blobdiff_plain;f=publishing%2Forg.argeo.publishing.ui%2Fsrc%2Forg%2Fargeo%2Fdocbook%2FDbkUtils.java;h=151bf10db690a0ae538e95ab061fc10d42996892;hp=8426a80b7f32ba0dae0d91e54963a172d01f8209;hb=4d8967c70edd1051e97ebdc393cbe2cd59d2b8b6;hpb=4bd6cf0556f597ee73c8f13df45019ccf9e418a6 diff --git a/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java b/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java index 8426a80..151bf10 100644 --- a/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java +++ b/publishing/org.argeo.publishing.ui/src/org/argeo/docbook/DbkUtils.java @@ -1,20 +1,34 @@ package org.argeo.docbook; -import static org.argeo.docbook.DocBookType.para; +import static org.argeo.docbook.DbkType.para; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.nio.file.Files; +import java.nio.file.Path; + +import javax.jcr.ImportUUIDBehavior; import javax.jcr.Node; import javax.jcr.NodeIterator; +import javax.jcr.PathNotFoundException; import javax.jcr.RepositoryException; +import javax.jcr.ValueFormatException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.argeo.entity.EntityType; import org.argeo.jcr.Jcr; import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; import org.argeo.jcr.JcrxApi; /** Utilities around DocBook. */ public class DbkUtils { + private final static Log log = LogFactory.getLog(DbkUtils.class); + /** Get or add a DocBook element. */ - public static Node getOrAddDbk(Node parent, DocBookType child) { + public static Node getOrAddDbk(Node parent, DbkType child) { try { if (!parent.hasNode(child.get())) { return addDbk(parent, child); @@ -27,7 +41,7 @@ public class DbkUtils { } /** Add a DocBook element to this node. */ - public static Node addDbk(Node parent, DocBookType child) { + public static Node addDbk(Node parent, DbkType child) { try { Node node = parent.addNode(child.get(), child.get()); return node; @@ -37,24 +51,34 @@ public class DbkUtils { } /** Whether this DocBook element is of this type. */ - public static boolean isDbk(Node node, DocBookType type) { + public static boolean isDbk(Node node, DbkType type) { return Jcr.getName(node).equals(type.get()); } + /** Whether this node is a DocBook type. */ + public static boolean isDbk(Node node) { + String name = Jcr.getName(node); + for (DbkType type : DbkType.values()) { + if (name.equals(type.get())) + return true; + } + return false; + } + public static String getTitle(Node node) { - return JcrxApi.getXmlValue(node, DocBookType.title.get()); + return JcrxApi.getXmlValue(node, DbkType.title.get()); } public static void setTitle(Node node, String txt) { - Node titleNode = getOrAddDbk(node, DocBookType.title); + Node titleNode = getOrAddDbk(node, DbkType.title); JcrxApi.setXmlValue(node, titleNode, txt); } public static Node getMetadata(Node infoContainer) { try { - if (!infoContainer.hasNode(DocBookType.info.get())) + if (!infoContainer.hasNode(DbkType.info.get())) return null; - Node info = infoContainer.getNode(DocBookType.info.get()); + Node info = infoContainer.getNode(DbkType.info.get()); if (!info.hasNode(EntityType.local.get())) return null; return info.getNode(EntityType.local.get()); @@ -68,7 +92,7 @@ public class DbkUtils { NodeIterator baseSections = parent.getNodes(); while (baseSections.hasNext()) { Node n = baseSections.nextNode(); - String r = Jcr.get(n, DocBookNames.DBK_ROLE); + String r = Jcr.get(n, DbkAttr.role.name()); if (r != null && r.equals(role)) return n; } @@ -84,24 +108,51 @@ public class DbkUtils { return p; } - public static Node insertImageAfter(Node sibling) { + /** + * Removes a paragraph if it empty. The sesison is not saved. + * + * @return true if the paragraph was empty and it was removed + */ + public static boolean removeIfEmptyParagraph(Node node) { try { - - // FIXME make it more robust - if (DocBookType.imagedata.get().equals(sibling.getName())) { - sibling = sibling.getParent().getParent(); + if (isDbk(node, DbkType.para)) { + NodeIterator nit = node.getNodes(); + if (!nit.hasNext()) { + node.remove(); + return true; + } + Node first = nit.nextNode(); + if (nit.hasNext()) + return false; + if (first.getName().equals(Jcr.JCR_XMLTEXT)) { + String str = Jcr.get(first, Jcr.JCR_XMLCHARACTERS); + if (str != null && str.trim().equals("")) { + node.remove(); + return true; + } + } else { + return false; + } } + return false; + } catch (RepositoryException e) { + throw new JcrException("Cannot remove possibly empty paragraph", e); + } + } + + public static Node insertImageAfter(Node sibling) { + try { Node parent = sibling.getParent(); - Node mediaNode = addDbk(parent, DocBookType.mediaobject); + Node mediaNode = addDbk(parent, DbkType.mediaobject); // TODO optimise? parent.orderBefore(mediaNode.getName() + "[" + mediaNode.getIndex() + "]", sibling.getName() + "[" + sibling.getIndex() + "]"); parent.orderBefore(sibling.getName() + "[" + sibling.getIndex() + "]", mediaNode.getName() + "[" + mediaNode.getIndex() + "]"); - Node imageNode = addDbk(mediaNode, DocBookType.imageobject); - Node imageDataNode = addDbk(imageNode, DocBookType.imagedata); + Node imageNode = addDbk(mediaNode, DbkType.imageobject); + Node imageDataNode = addDbk(imageNode, DbkType.imagedata); // Node infoNode = imageNode.addNode(DocBookTypes.INFO, DocBookTypes.INFO); // Node fileNode = JcrUtils.copyBytesAsFile(mediaFolder, EntityType.box.get(), new byte[0]); // fileNode.addMixin(EntityType.box.get()); @@ -113,13 +164,91 @@ public class DbkUtils { // // TODO make it more robust and generic // String fileRef = mediaNode.getName(); // imageDataNode.setProperty(DocBookNames.DBK_FILEREF, fileRef); - return imageDataNode; + return mediaNode; + } catch (RepositoryException e) { + throw new JcrException("Cannot insert empty image after " + sibling, e); + } + } + + public static Node insertVideoAfter(Node sibling) { + try { + + Node parent = sibling.getParent(); + Node mediaNode = addDbk(parent, DbkType.mediaobject); + // TODO optimise? + parent.orderBefore(mediaNode.getName() + "[" + mediaNode.getIndex() + "]", + sibling.getName() + "[" + sibling.getIndex() + "]"); + parent.orderBefore(sibling.getName() + "[" + sibling.getIndex() + "]", + mediaNode.getName() + "[" + mediaNode.getIndex() + "]"); + + Node videoNode = addDbk(mediaNode, DbkType.videoobject); + Node videoDataNode = addDbk(videoNode, DbkType.videodata); + return mediaNode; } catch (RepositoryException e) { throw new JcrException("Cannot insert empty image after " + sibling, e); } } + public static String getMediaFileref(Node node) { + try { + Node mediadata; + if (node.hasNode(DbkType.imageobject.get())) { + mediadata = node.getNode(DbkType.imageobject.get()).getNode(DbkType.imagedata.get()); + } else if (node.hasNode(DbkType.videoobject.get())) { + mediadata = node.getNode(DbkType.videoobject.get()).getNode(DbkType.videodata.get()); + } else { + throw new IllegalArgumentException("Fileref not found in " + node); + } + + if (mediadata.hasProperty(DbkAttr.fileref.name())) { + return mediadata.getProperty(DbkAttr.fileref.name()).getString(); + } else { + return null; + } + } catch (RepositoryException e) { + throw new JcrException("Cannot retrieve file ref from " + node, e); + } + } + + public static void exportXml(Node node, OutputStream out) throws IOException { + try { + node.getSession().exportDocumentView(node.getPath(), out, false, false); + } catch (RepositoryException e) { + throw new JcrException("Cannot export " + node + " to XML", e); + } + } + + public static void exportToFs(Node baseNode, DbkType type, Path directory) { + String fileName = Jcr.getName(baseNode) + ".dbk.xml"; + Path filePath = directory.resolve(fileName); + Node docBookNode = Jcr.getNode(baseNode, type.get()); + if (docBookNode == null) + throw new IllegalArgumentException("No " + type.get() + " under " + baseNode); + try { + Files.createDirectories(directory); + try (OutputStream out = Files.newOutputStream(filePath)) { + exportXml(docBookNode, out); + } + JcrUtils.copyFilesToFs(baseNode, directory, true); + if (log.isDebugEnabled()) + log.debug("DocBook " + baseNode + " exported to " + filePath.toAbsolutePath()); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + public static void importXml(Node baseNode, InputStream in) throws IOException { + try { + baseNode.getSession().importXML(baseNode.getPath(), in, + ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING); + } catch (RepositoryException e) { + throw new JcrException("Cannot import XML to " + baseNode, e); + } + + } + /** Singleton. */ private DbkUtils() { } + }