]> git.argeo.org Git - lgpl/argeo-commons.git/blobdiff - org.argeo.cms.ui/src/org/argeo/cms/ui/internal/ImageManagerImpl.java
Split CMS and CMS UI
[lgpl/argeo-commons.git] / org.argeo.cms.ui / src / org / argeo / cms / ui / internal / ImageManagerImpl.java
diff --git a/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/ImageManagerImpl.java b/org.argeo.cms.ui/src/org/argeo/cms/ui/internal/ImageManagerImpl.java
new file mode 100644 (file)
index 0000000..92f237a
--- /dev/null
@@ -0,0 +1,263 @@
+package org.argeo.cms.ui.internal;
+
+import static javax.jcr.Node.JCR_CONTENT;
+import static javax.jcr.Property.JCR_DATA;
+import static javax.jcr.nodetype.NodeType.NT_FILE;
+import static javax.jcr.nodetype.NodeType.NT_RESOURCE;
+import static org.argeo.cms.CmsConstants.NO_IMAGE_SIZE;
+import static org.argeo.cms.CmsTypes.CMS_STYLED;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+import javax.activation.MimetypesFileTypeMap;
+import javax.jcr.Binary;
+import javax.jcr.Node;
+import javax.jcr.Property;
+import javax.jcr.RepositoryException;
+
+import org.apache.commons.io.IOUtils;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.argeo.cms.CmsException;
+import org.argeo.cms.CmsImageManager;
+import org.argeo.cms.CmsNames;
+import org.argeo.cms.CmsTypes;
+import org.argeo.cms.util.CmsUtils;
+import org.argeo.jcr.JcrUtils;
+import org.eclipse.rap.rwt.RWT;
+import org.eclipse.rap.rwt.service.ResourceManager;
+import org.eclipse.rap.rwt.widgets.FileUpload;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+/** Manages only public images so far. */
+public class ImageManagerImpl implements CmsImageManager, CmsNames {
+       private final static Log log = LogFactory.getLog(ImageManagerImpl.class);
+       private MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
+
+       public Boolean load(Node node, Control control, Point preferredSize)
+                       throws RepositoryException {
+               Point imageSize = getImageSize(node);
+               Point size;
+               String imgTag = null;
+               if (preferredSize == null || imageSize.x == 0 || imageSize.y == 0
+                               || (preferredSize.x == 0 && preferredSize.y == 0)) {
+                       if (imageSize.x != 0 && imageSize.y != 0) {
+                               // actual image size if completely known
+                               size = imageSize;
+                       } else {
+                               // no image if not completely known
+                               size = resizeTo(NO_IMAGE_SIZE,
+                                               preferredSize != null ? preferredSize : imageSize);
+                               imgTag = CmsUtils.noImg(size);
+                       }
+
+               } else if (preferredSize.x != 0 && preferredSize.y != 0) {
+                       // given size if completely provided
+                       size = preferredSize;
+               } else {
+                       // at this stage :
+                       // image is completely known
+                       assert imageSize.x != 0 && imageSize.y != 0;
+                       // one and only one of the dimension as been specified
+                       assert preferredSize.x == 0 || preferredSize.y == 0;
+                       size = resizeTo(imageSize, preferredSize);
+               }
+
+               boolean loaded = false;
+               if (control == null)
+                       return loaded;
+
+               if (control instanceof Label) {
+                       if (imgTag == null) {
+                               // IMAGE RETRIEVED HERE
+                               imgTag = getImageTag(node, size);
+                               //
+                               if (imgTag == null)
+                                       imgTag = CmsUtils.noImg(size);
+                               else
+                                       loaded = true;
+                       }
+
+                       Label lbl = (Label) control;
+                       lbl.setText(imgTag);
+                       // lbl.setSize(size);
+               } else if (control instanceof FileUpload) {
+                       FileUpload lbl = (FileUpload) control;
+                       lbl.setImage(CmsUtils.noImage(size));
+                       lbl.setSize(size);
+                       return loaded;
+               } else
+                       loaded = false;
+
+               return loaded;
+       }
+
+       private Point resizeTo(Point orig, Point constraints) {
+               if (constraints.x != 0 && constraints.y != 0) {
+                       return constraints;
+               } else if (constraints.x == 0 && constraints.y == 0) {
+                       return orig;
+               } else if (constraints.y == 0) {// force width
+                       return new Point(constraints.x,
+                                       scale(orig.y, orig.x, constraints.x));
+               } else if (constraints.x == 0) {// force height
+                       return new Point(scale(orig.x, orig.y, constraints.y),
+                                       constraints.y);
+               }
+               throw new CmsException("Cannot resize " + orig + " to " + constraints);
+       }
+
+       private int scale(int origDimension, int otherDimension, int otherConstraint) {
+               return Math.round(origDimension
+                               * divide(otherConstraint, otherDimension));
+       }
+
+       private float divide(int a, int b) {
+               return ((float) a) / ((float) b);
+       }
+
+       public Point getImageSize(Node node) throws RepositoryException {
+               return new Point(node.hasProperty(CMS_IMAGE_WIDTH) ? (int) node
+                               .getProperty(CMS_IMAGE_WIDTH).getLong() : 0,
+                               node.hasProperty(CMS_IMAGE_WIDTH) ? (int) node.getProperty(
+                                               CMS_IMAGE_HEIGHT).getLong() : 0);
+       }
+
+       /** @return null if not available */
+       @Override
+       public String getImageTag(Node node) throws RepositoryException {
+               return getImageTag(node, getImageSize(node));
+       }
+
+       private String getImageTag(Node node, Point size)
+                       throws RepositoryException {
+               StringBuilder buf = getImageTagBuilder(node, size);
+               if (buf == null)
+                       return null;
+               return buf.append("/>").toString();
+       }
+
+       /** @return null if not available */
+       @Override
+       public StringBuilder getImageTagBuilder(Node node, Point size)
+                       throws RepositoryException {
+               return getImageTagBuilder(node, Integer.toString(size.x),
+                               Integer.toString(size.y));
+       }
+
+       /** @return null if not available */
+       private StringBuilder getImageTagBuilder(Node node, String width,
+                       String height) throws RepositoryException {
+               String url = getImageUrl(node);
+               if (url == null)
+                       return null;
+               return CmsUtils.imgBuilder(url, width, height);
+       }
+
+       /** @return null if not available */
+       @Override
+       public String getImageUrl(Node node) throws RepositoryException {
+               return CmsUtils.getDataPath(node);
+               // String name = getResourceName(node);
+               // ResourceManager resourceManager = RWT.getResourceManager();
+               // if (!resourceManager.isRegistered(name)) {
+               // InputStream inputStream = null;
+               // Binary binary = getImageBinary(node);
+               // if (binary == null)
+               // return null;
+               // try {
+               // inputStream = binary.getStream();
+               // resourceManager.register(name, inputStream);
+               // } finally {
+               // IOUtils.closeQuietly(inputStream);
+               // JcrUtils.closeQuietly(binary);
+               // }
+               // if (log.isTraceEnabled())
+               // log.trace("Registered image " + name);
+               // }
+               // return resourceManager.getLocation(name);
+       }
+
+       protected String getResourceName(Node node) throws RepositoryException {
+               String workspace = node.getSession().getWorkspace().getName();
+               if (node.hasNode(JCR_CONTENT))
+                       return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
+               else
+                       return workspace + '_' + node.getIdentifier();
+       }
+
+       public Binary getImageBinary(Node node) throws RepositoryException {
+               if (node.isNodeType(NT_FILE))
+                       return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
+               else if (node.isNodeType(CMS_STYLED) && node.hasProperty(CMS_DATA)) {
+                       return node.getProperty(CMS_DATA).getBinary();
+               } else {
+                       return null;
+               }
+       }
+
+       public Image getSwtImage(Node node) throws RepositoryException {
+               InputStream inputStream = null;
+               Binary binary = getImageBinary(node);
+               if (binary == null)
+                       return null;
+               try {
+                       inputStream = binary.getStream();
+                       return new Image(Display.getCurrent(), inputStream);
+               } finally {
+                       IOUtils.closeQuietly(inputStream);
+                       JcrUtils.closeQuietly(binary);
+               }
+       }
+
+       @Override
+       public String uploadImage(Node parentNode, String fileName, InputStream in)
+                       throws RepositoryException {
+               InputStream inputStream = null;
+               try {
+                       String previousResourceName = null;
+                       if (parentNode.hasNode(fileName)) {
+                               Node node = parentNode.getNode(fileName);
+                               previousResourceName = getResourceName(node);
+                               if (node.hasNode(JCR_CONTENT)) {
+                                       node.getNode(JCR_CONTENT).remove();
+                                       node.addNode(JCR_CONTENT, NT_RESOURCE);
+                               }
+                       }
+
+                       byte[] arr = IOUtils.toByteArray(in);
+                       Node fileNode = JcrUtils.copyBytesAsFile(parentNode, fileName, arr);
+                       fileNode.addMixin(CmsTypes.CMS_IMAGE);
+
+                       inputStream = new ByteArrayInputStream(arr);
+                       ImageData id = new ImageData(inputStream);
+                       fileNode.setProperty(CMS_IMAGE_WIDTH, id.width);
+                       fileNode.setProperty(CMS_IMAGE_HEIGHT, id.height);
+                       fileNode.setProperty(Property.JCR_MIMETYPE,
+                                       fileTypeMap.getContentType(fileName));
+                       fileNode.getSession().save();
+
+                       // reset resource manager
+                       ResourceManager resourceManager = RWT.getResourceManager();
+                       if (previousResourceName != null
+                                       && resourceManager.isRegistered(previousResourceName)) {
+                               resourceManager.unregister(previousResourceName);
+                               if (log.isDebugEnabled())
+                                       log.debug("Unregistered image " + previousResourceName);
+                       }
+                       return getImageUrl(fileNode);
+               } catch (IOException e) {
+                       throw new CmsException("Cannot upload image " + fileName + " in "
+                                       + parentNode, e);
+               } finally {
+                       IOUtils.closeQuietly(inputStream);
+               }
+       }
+}