]> git.argeo.org Git - lgpl/argeo-commons.git/blob - DefaultImageManager.java
d7f3d7c03d8bf23497d37074332e1390f57524f3
[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.nio.file.Files;
13 import java.nio.file.Paths;
14
15 import javax.jcr.Binary;
16 import javax.jcr.Node;
17 import javax.jcr.Property;
18 import javax.jcr.RepositoryException;
19
20 import org.apache.commons.io.IOUtils;
21 import org.apache.commons.logging.Log;
22 import org.apache.commons.logging.LogFactory;
23 import org.argeo.api.cms.Cms2DSize;
24 import org.argeo.api.cms.CmsImageManager;
25 import org.argeo.jcr.JcrException;
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<Control, Node> {
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, Cms2DSize preferredSize) {
43 Cms2DSize imageSize = getImageSize(node);
44 Cms2DSize size;
45 String imgTag = null;
46 if (preferredSize == null || imageSize.getWidth() == 0 || imageSize.getHeight() == 0
47 || (preferredSize.getWidth() == 0 && preferredSize.getHeight() == 0)) {
48 if (imageSize.getWidth() != 0 && imageSize.getHeight() != 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.getWidth() != 0 && preferredSize.getHeight() != 0) {
58 // given size if completely provided
59 size = preferredSize;
60 } else {
61 // at this stage :
62 // image is completely known
63 assert imageSize.getWidth() != 0 && imageSize.getHeight() != 0;
64 // one and only one of the dimension as been specified
65 assert preferredSize.getWidth() == 0 || preferredSize.getHeight() == 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(new Point(size.getWidth(), size.getHeight()));
91 return loaded;
92 } else
93 loaded = false;
94
95 return loaded;
96 }
97
98 private Cms2DSize resizeTo(Cms2DSize orig, Cms2DSize constraints) {
99 if (constraints.getWidth() != 0 && constraints.getHeight() != 0) {
100 return constraints;
101 } else if (constraints.getWidth() == 0 && constraints.getHeight() == 0) {
102 return orig;
103 } else if (constraints.getHeight() == 0) {// force width
104 return new Cms2DSize(constraints.getWidth(),
105 scale(orig.getHeight(), orig.getWidth(), constraints.getWidth()));
106 } else if (constraints.getWidth() == 0) {// force height
107 return new Cms2DSize(scale(orig.getWidth(), orig.getHeight(), constraints.getHeight()),
108 constraints.getHeight());
109 }
110 throw new IllegalArgumentException("Cannot resize " + orig + " to " + constraints);
111 }
112
113 private int scale(int origDimension, int otherDimension, int otherConstraint) {
114 return Math.round(origDimension * divide(otherConstraint, otherDimension));
115 }
116
117 private float divide(int a, int b) {
118 return ((float) a) / ((float) b);
119 }
120
121 public Cms2DSize getImageSize(Node node) {
122 // TODO optimise
123 Image image = getSwtImage(node);
124 return new Cms2DSize(image.getBounds().width, image.getBounds().height);
125 }
126
127 /** @return null if not available */
128 @Override
129 public String getImageTag(Node node) {
130 return getImageTag(node, getImageSize(node));
131 }
132
133 private String getImageTag(Node node, Cms2DSize size) {
134 StringBuilder buf = getImageTagBuilder(node, size);
135 if (buf == null)
136 return null;
137 return buf.append("/>").toString();
138 }
139
140 /** @return null if not available */
141 @Override
142 public StringBuilder getImageTagBuilder(Node node, Cms2DSize size) {
143 return getImageTagBuilder(node, Integer.toString(size.getWidth()), Integer.toString(size.getHeight()));
144 }
145
146 /** @return null if not available */
147 private StringBuilder getImageTagBuilder(Node node, String width, String height) {
148 String url = getImageUrl(node);
149 if (url == null)
150 return null;
151 return CmsUiUtils.imgBuilder(url, width, height);
152 }
153
154 /** @return null if not available */
155 @Override
156 public String getImageUrl(Node node) {
157 return CmsUiUtils.getDataPathForUrl(node);
158 }
159
160 protected String getResourceName(Node node) {
161 try {
162 String workspace = node.getSession().getWorkspace().getName();
163 if (node.hasNode(JCR_CONTENT))
164 return workspace + '_' + node.getNode(JCR_CONTENT).getIdentifier();
165 else
166 return workspace + '_' + node.getIdentifier();
167 } catch (RepositoryException e) {
168 throw new JcrException(e);
169 }
170 }
171
172 public Binary getImageBinary(Node node) {
173 try {
174 if (node.isNodeType(NT_FILE)) {
175 return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
176 } else {
177 return null;
178 }
179 } catch (RepositoryException e) {
180 throw new JcrException(e);
181 }
182 }
183
184 public Image getSwtImage(Node node) {
185 InputStream inputStream = null;
186 Binary binary = getImageBinary(node);
187 if (binary == null)
188 return null;
189 try {
190 inputStream = binary.getStream();
191 return new Image(Display.getCurrent(), inputStream);
192 } catch (RepositoryException e) {
193 throw new JcrException(e);
194 } finally {
195 IOUtils.closeQuietly(inputStream);
196 JcrUtils.closeQuietly(binary);
197 }
198 }
199
200 @Override
201 public String uploadImage(Node context, Node parentNode, String fileName, InputStream in, String contentType) {
202 InputStream inputStream = null;
203 try {
204 String previousResourceName = null;
205 if (parentNode.hasNode(fileName)) {
206 Node node = parentNode.getNode(fileName);
207 previousResourceName = getResourceName(node);
208 if (node.hasNode(JCR_CONTENT)) {
209 node.getNode(JCR_CONTENT).remove();
210 node.addNode(JCR_CONTENT, NT_RESOURCE);
211 }
212 }
213
214 byte[] arr = IOUtils.toByteArray(in);
215 Node fileNode = JcrUtils.copyBytesAsFile(parentNode, fileName, arr);
216 inputStream = new ByteArrayInputStream(arr);
217 ImageData id = new ImageData(inputStream);
218 processNewImageFile(context, fileNode, id);
219
220 String mime = contentType != null ? contentType : Files.probeContentType(Paths.get(fileName));
221 if (mime != null) {
222 fileNode.getNode(JCR_CONTENT).setProperty(Property.JCR_MIMETYPE, mime);
223 }
224 fileNode.getSession().save();
225
226 // reset resource manager
227 ResourceManager resourceManager = RWT.getResourceManager();
228 if (previousResourceName != null && resourceManager.isRegistered(previousResourceName)) {
229 resourceManager.unregister(previousResourceName);
230 if (log.isDebugEnabled())
231 log.debug("Unregistered image " + previousResourceName);
232 }
233 return CmsUiUtils.getDataPath(fileNode);
234 } catch (IOException e) {
235 throw new RuntimeException("Cannot upload image " + fileName + " in " + parentNode, e);
236 } catch (RepositoryException e) {
237 throw new JcrException(e);
238 } finally {
239 IOUtils.closeQuietly(inputStream);
240 }
241 }
242
243 /** Does nothing by default. */
244 protected void processNewImageFile(Node context, Node fileNode, ImageData id)
245 throws RepositoryException, IOException {
246 }
247 }