Improve links.
[gpl/argeo-suite.git] / publishing / org.argeo.publishing.ui / src / org / argeo / docbook / ui / DbkImageManager.java
index 2e72a3e767249711de4dd30c4a57fea505342f7b..25a466ab7695c3153cde5e565a28afb86a22422d 100644 (file)
 package org.argeo.docbook.ui;
 
+import static javax.jcr.Node.JCR_CONTENT;
+import static javax.jcr.Property.JCR_DATA;
+import static javax.jcr.nodetype.NodeType.NT_FILE;
+
 import java.io.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 
 import javax.jcr.Binary;
 import javax.jcr.Node;
 import javax.jcr.RepositoryException;
+import javax.jcr.nodetype.NodeType;
 
 import org.argeo.cms.ui.CmsImageManager;
+import org.argeo.cms.ui.util.CmsUiUtils;
 import org.argeo.cms.ui.util.DefaultImageManager;
+import org.argeo.docbook.DbkUtils;
+import org.argeo.docbook.DbkAttr;
+import org.argeo.docbook.DbkType;
 import org.argeo.entity.EntityNames;
+import org.argeo.entity.EntityType;
+import org.argeo.jcr.JcrException;
+import org.argeo.jcr.JcrUtils;
 import org.eclipse.swt.graphics.ImageData;
 import org.eclipse.swt.graphics.Point;
 
 /** Add DocBook images support to {@link CmsImageManager}. */
 public class DbkImageManager extends DefaultImageManager {
+       private Node baseFolder = null;
+
+       public DbkImageManager(Node baseFolder) {
+               this.baseFolder = baseFolder;
+       }
+
+       Node getImageDataNode(Node mediaObjectNode) throws RepositoryException {
+               if (mediaObjectNode.hasNode(DbkType.imageobject.get())) {
+                       Node imageDataNode = mediaObjectNode.getNode(DbkType.imageobject.get()).getNode(DbkType.imagedata.get());
+                       return imageDataNode;
+               } else {
+                       throw new IllegalStateException("No image data found for " + mediaObjectNode);
+               }
+       }
+
        @Override
        public Binary getImageBinary(Node node) throws RepositoryException {
-               Binary binary = super.getImageBinary(node);
-               return binary;
+               Node fileNode = null;
+               if (DbkUtils.isDbk(node, DbkType.mediaobject)) {
+                       Node imageDataNode = getImageDataNode(node);
+                       fileNode = getFileNode(imageDataNode);
+               }
+               if (node.isNodeType(NT_FILE)) {
+                       fileNode = node;
+               }
+               if (fileNode != null) {
+                       return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
+               } else {
+                       return null;
+               }
        }
 
-       public Point getImageSize(Node node) throws RepositoryException {
-               int width = node.hasProperty(EntityNames.SVG_WIDTH) ? (int) node.getProperty(EntityNames.SVG_WIDTH).getLong()
-                               : 0;
-               int height = node.hasProperty(EntityNames.SVG_HEIGHT) ? (int) node.getProperty(EntityNames.SVG_HEIGHT).getLong()
-                               : 0;
-               return new Point(width, height);
+       public Point getImageSize(Node mediaObjectNode) throws RepositoryException {
+               Node imageDataNode = getImageDataNode(mediaObjectNode);
+               Node fileNode = getFileNode(imageDataNode);
+               if (fileNode == null)
+                       return new Point(0, 0);
+               Point intrinsicSize;
+               if (fileNode.hasProperty(EntityNames.SVG_WIDTH) && fileNode.hasProperty(EntityNames.SVG_HEIGHT)) {
+                       int width = (int) fileNode.getProperty(EntityNames.SVG_WIDTH).getLong();
+                       int height = (int) fileNode.getProperty(EntityNames.SVG_HEIGHT).getLong();
+                       intrinsicSize = new Point(width, height);
+               } else {
+                       try (InputStream in = JcrUtils.getFileAsStream(fileNode)) {
+                               ImageData id = new ImageData(in);
+                               intrinsicSize = updateSize(fileNode, id);
+                       } catch (IOException e) {
+                               throw new RuntimeException("Cannot load file " + fileNode, e);
+                       }
+               }
+               // TODO interpret image data infos
+               return intrinsicSize;
        }
 
-       @Override
-       protected void processNewImageFile(Node fileNode, ImageData id) throws RepositoryException, IOException {
+       protected Point updateSize(Node fileNode, ImageData id) throws RepositoryException {
+               fileNode.addMixin(EntityType.box.get());
                fileNode.setProperty(EntityNames.SVG_WIDTH, id.width);
                fileNode.setProperty(EntityNames.SVG_HEIGHT, id.height);
+               return new Point(id.width, id.height);
+       }
+
+       @Override
+       protected void processNewImageFile(Node mediaObjectNode, Node fileNode, ImageData id)
+                       throws RepositoryException, IOException {
+               Node imageDataNode = getImageDataNode(mediaObjectNode);
+               updateSize(fileNode, id);
+               String filePath = fileNode.getPath();
+               String relPath = filePath.substring(baseFolder.getPath().length() + 1);
+               imageDataNode.setProperty(DbkAttr.fileref.name(), relPath);
+       }
+
+       @Override
+       public String getImageUrl(Node mediaObjectNode) throws RepositoryException {
+               Node imageDataNode = getImageDataNode(mediaObjectNode);
+               // TODO factorise
+               String fileref = null;
+               if (imageDataNode.hasProperty(DbkAttr.fileref.name()))
+                       fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString();
+               if (fileref == null)
+                       return null;
+               URI fileUri;
+               try {
+                       // FIXME it messes up with the '/'
+                       fileUri = new URI(URLEncoder.encode(fileref, StandardCharsets.UTF_8.toString()));
+               } catch (URISyntaxException | UnsupportedEncodingException e) {
+                       throw new IllegalArgumentException("File ref in " + imageDataNode + " is badly formatted", e);
+               }
+               if (fileUri.getScheme() != null)
+                       return fileUri.toString();
+               // local
+               Node fileNode = getFileNode(imageDataNode);
+               String url = CmsUiUtils.getDataPathForUrl(fileNode);
+               return url;
+       }
+
+       protected Node getFileNode(Node imageDataNode) throws RepositoryException {
+               // FIXME make URL use case more robust
+               String fileref = null;
+               if (imageDataNode.hasProperty(DbkAttr.fileref.name()))
+                       fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString();
+               if (fileref == null)
+                       return null;
+               Node fileNode;
+               if (fileref.startsWith("/"))
+                       fileNode = baseFolder.getSession().getNode(fileref);
+               else
+                       fileNode = baseFolder.getNode(fileref);
+               return fileNode;
        }
 
+       protected Node getMediaFolder() {
+               try {
+                       // TODO check edition status
+                       Node mediaFolder = JcrUtils.getOrAdd(baseFolder, EntityNames.MEDIA, NodeType.NT_FOLDER);
+                       return mediaFolder;
+               } catch (RepositoryException e) {
+                       throw new JcrException("Cannot get media folder", e);
+               }
+       }
 }