Upload media in separate directory.
[gpl/argeo-suite.git] / publishing / org.argeo.publishing.ui / src / org / argeo / docbook / ui / DbkImageManager.java
index 2e72a3e767249711de4dd30c4a57fea505342f7b..2b57b4b9cf768883b8f53be7ac6f7843a9505dfc 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.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;
+       }
+
        @Override
        public Binary getImageBinary(Node node) throws RepositoryException {
-               Binary binary = super.getImageBinary(node);
-               return binary;
+               Node fileNode = null;
+               if (node.getName().equals(DocBookTypes.IMAGEDATA)) {
+                       fileNode = getFileNode(node);
+               }
+               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 imageDataNode) throws RepositoryException {
+               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 context, Node fileNode, ImageData id)
+                       throws RepositoryException, IOException {
+               updateSize(fileNode, id);
+               String filePath = fileNode.getPath();
+               String relPath = filePath.substring(baseFolder.getPath().length() + 1);
+               context.setProperty(DocBookNames.DBK_FILEREF, relPath);
+       }
+
+       @Override
+       public String getImageUrl(Node imageDataNode) throws RepositoryException {
+               // TODO factorise
+               String fileref = null;
+               if (imageDataNode.hasProperty(DocBookNames.DBK_FILEREF))
+                       fileref = imageDataNode.getProperty(DocBookNames.DBK_FILEREF).getString();
+               if (fileref == null)
+                       return null;
+               URI fileUri;
+               try {
+                       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.getDataPath(fileNode);
+               return url;
        }
 
+       protected Node getFileNode(Node imageDataNode) throws RepositoryException {
+               // FIXME make URL use case more robust
+               String fileref = null;
+               if (imageDataNode.hasProperty(DocBookNames.DBK_FILEREF))
+                       fileref = imageDataNode.getProperty(DocBookNames.DBK_FILEREF).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);
+               }
+       }
 }