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