]> git.argeo.org Git - lgpl/argeo-commons.git/blob - DefaultImageManager.java
6c4a870c49752f26731be354a492e49d7260d7da
[lgpl/argeo-commons.git] / DefaultImageManager.java
1 package org.argeo.cms.ui.util;
2
3 import static javax.jcr.Node.JCR_CONTENT;
4 import static javax.jcr.Property.JCR_DATA;
5 import static javax.jcr.nodetype.NodeType.NT_FILE;
6 import static javax.jcr.nodetype.NodeType.NT_RESOURCE;
7 import static org.argeo.cms.ui.CmsConstants.NO_IMAGE_SIZE;
8
9 import java.io.ByteArrayInputStream;
10 import java.io.IOException;
11 import java.io.InputStream;
12 import java.net.MalformedURLException;
13 import java.net.URL;
14 import java.nio.file.Files;
15 import java.nio.file.Paths;
16
17 import javax.jcr.Binary;
18 import javax.jcr.Node;
19 import javax.jcr.Property;
20 import javax.jcr.RepositoryException;
21
22 import org.apache.commons.io.IOUtils;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25 import org.argeo.cms.ui.CmsImageManager;
26 import org.argeo.jcr.JcrUtils;
27 import org.eclipse.rap.rwt.RWT;
28 import org.eclipse.rap.rwt.service.ResourceManager;
29 import org.eclipse.rap.rwt.widgets.FileUpload;
30 import org.eclipse.swt.graphics.Image;
31 import org.eclipse.swt.graphics.ImageData;
32 import org.eclipse.swt.graphics.Point;
33 import org.eclipse.swt.widgets.Control;
34 import org.eclipse.swt.widgets.Display;
35 import org.eclipse.swt.widgets.Label;
36
37 /** Manages only public images so far. */
38 public class DefaultImageManager implements CmsImageManager {
39 private final static Log log = LogFactory.getLog(DefaultImageManager.class);
40 // private MimetypesFileTypeMap fileTypeMap = new MimetypesFileTypeMap();
41
42 public Boolean load(Node node, Control control, Point preferredSize) throws RepositoryException {
43 Point imageSize = getImageSize(node);
44 Point size;
45 String imgTag = null;
46 if (preferredSize == null || imageSize.x == 0 || imageSize.y == 0
47 || (preferredSize.x == 0 && preferredSize.y == 0)) {
48 if (imageSize.x != 0 && imageSize.y != 0) {
49 // actual image size if completely known
50 size = imageSize;
51 } else {
52 // no image if not completely known
53 size = resizeTo(NO_IMAGE_SIZE, preferredSize != null ? preferredSize : imageSize);
54 imgTag = CmsUiUtils.noImg(size);
55 }
56
57 } else if (preferredSize.x != 0 && preferredSize.y != 0) {
58 // given size if completely provided
59 size = preferredSize;
60 } else {
61 // at this stage :
62 // image is completely known
63 assert imageSize.x != 0 && imageSize.y != 0;
64 // one and only one of the dimension as been specified
65 assert preferredSize.x == 0 || preferredSize.y == 0;
66 size = resizeTo(imageSize, preferredSize);
67 }
68
69 boolean loaded = false;
70 if (control == null)
71 return loaded;
72
73 if (control instanceof Label) {
74 if (imgTag == null) {
75 // IMAGE RETRIEVED HERE
76 imgTag = getImageTag(node, size);
77 //
78 if (imgTag == null)
79 imgTag = CmsUiUtils.noImg(size);
80 else
81 loaded = true;
82 }
83
84 Label lbl = (Label) control;
85 lbl.setText(imgTag);
86 // lbl.setSize(size);
87 } else if (control instanceof FileUpload) {
88 FileUpload lbl = (FileUpload) control;
89 lbl.setImage(CmsUiUtils.noImage(size));
90 lbl.setSize(size);
91 return loaded;
92 } else
93 loaded = false;
94
95 return loaded;
96 }
97
98 private Point resizeTo(Point orig, Point constraints) {
99 if (constraints.x != 0 && constraints.y != 0) {
100 return constraints;
101 } else if (constraints.x == 0 && constraints.y == 0) {
102 return orig;
103 } else if (constraints.y == 0) {// force width
104 return new Point(constraints.x, scale(orig.y, orig.x, constraints.x));
105 } else if (constraints.x == 0) {// force height
106 return new Point(scale(orig.x, orig.y, constraints.y), constraints.y);
107 }
108 throw new IllegalArgumentException("Cannot resize " + orig + " to " + constraints);
109 }
110
111 private int scale(int origDimension, int otherDimension, int otherConstraint) {
112 return Math.round(origDimension * divide(otherConstraint, otherDimension));
113 }
114
115 private float divide(int a, int b) {
116 return ((float) a) / ((float) b);
117 }
118
119 public Point getImageSize(Node node) throws RepositoryException {
120 // TODO optimise
121 Image image = getSwtImage(node);
122 return new Point(image.getBounds().width, image.getBounds().height);
123 }
124
125 /** @return null if not available */
126 @Override
127 public String getImageTag(Node node) throws RepositoryException {
128 return getImageTag(node, getImageSize(node));
129 }
130
131 private String getImageTag(Node node, Point size) throws RepositoryException {
132 StringBuilder buf = getImageTagBuilder(node, size);
133 if (buf == null)
134 return null;
135 return buf.append("/>").toString();
136 }
137
138 /** @return null if not available */
139 @Override
140 public StringBuilder getImageTagBuilder(Node node, Point size) throws RepositoryException {
141 return getImageTagBuilder(node, Integer.toString(size.x), Integer.toString(size.y));
142 }
143
144 /** @return null if not available */
145 private StringBuilder getImageTagBuilder(Node node, String width, String height) throws RepositoryException {
146 String url = getImageUrl(node);
147 if (url == null)
148 return null;
149 return CmsUiUtils.imgBuilder(url, width, height);
150 }
151
152 /** @return null if not available */
153 @Override
154 public String getImageUrl(Node node) throws RepositoryException {
155 return CmsUiUtils.getDataPathForUrl(node);
156 }
157
158 protected String getResourceName(Node node) throws RepositoryException {
159 String workspace = node.getSession().getWorkspace().getName();
160 if (node.hasNode(JCR_CONTENT))
161 return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
162 else
163 return workspace + '_' + node.getIdentifier();
164 }
165
166 public Binary getImageBinary(Node node) throws RepositoryException {
167 if (node.isNodeType(NT_FILE)) {
168 return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
169 } else {
170 return null;
171 }
172 }
173
174 public Image getSwtImage(Node node) throws RepositoryException {
175 InputStream inputStream = null;
176 Binary binary = getImageBinary(node);
177 if (binary == null)
178 return null;
179 try {
180 inputStream = binary.getStream();
181 return new Image(Display.getCurrent(), inputStream);
182 } finally {
183 IOUtils.closeQuietly(inputStream);
184 JcrUtils.closeQuietly(binary);
185 }
186 }
187
188 @Override
189 public String uploadImage(Node context, Node parentNode, String fileName, InputStream in, String contentType)
190 throws RepositoryException {
191 InputStream inputStream = null;
192 try {
193 String previousResourceName = null;
194 if (parentNode.hasNode(fileName)) {
195 Node node = parentNode.getNode(fileName);
196 previousResourceName = getResourceName(node);
197 if (node.hasNode(JCR_CONTENT)) {
198 node.getNode(JCR_CONTENT).remove();
199 node.addNode(JCR_CONTENT, NT_RESOURCE);
200 }
201 }
202
203 byte[] arr = IOUtils.toByteArray(in);
204 Node fileNode = JcrUtils.copyBytesAsFile(parentNode, fileName, arr);
205 inputStream = new ByteArrayInputStream(arr);
206 ImageData id = new ImageData(inputStream);
207 processNewImageFile(context, fileNode, id);
208
209 String mime = contentType != null ? contentType : Files.probeContentType(Paths.get(fileName));
210 if (mime != null) {
211 fileNode.getNode(JCR_CONTENT).setProperty(Property.JCR_MIMETYPE, mime);
212 }
213 fileNode.getSession().save();
214
215 // reset resource manager
216 ResourceManager resourceManager = RWT.getResourceManager();
217 if (previousResourceName != null && resourceManager.isRegistered(previousResourceName)) {
218 resourceManager.unregister(previousResourceName);
219 if (log.isDebugEnabled())
220 log.debug("Unregistered image " + previousResourceName);
221 }
222 return CmsUiUtils.getDataPath(fileNode);
223 } catch (IOException e) {
224 throw new RuntimeException("Cannot upload image " + fileName + " in " + parentNode, e);
225 } finally {
226 IOUtils.closeQuietly(inputStream);
227 }
228 }
229
230 /** Does nothing by default. */
231 protected void processNewImageFile(Node context, Node fileNode, ImageData id)
232 throws RepositoryException, IOException {
233 }
234 }