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