]> git.argeo.org Git - gpl/argeo-suite.git/blob - DbkImageManager.java
1493223499b0e78e40bb469c1b7458a97b4c5071
[gpl/argeo-suite.git] / DbkImageManager.java
1 package org.argeo.app.ui.docbook;
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
7 import java.io.IOException;
8 import java.io.InputStream;
9 import java.io.UnsupportedEncodingException;
10 import java.net.URI;
11 import java.net.URISyntaxException;
12 import java.net.URLEncoder;
13 import java.nio.charset.StandardCharsets;
14
15 import javax.jcr.Binary;
16 import javax.jcr.Node;
17 import javax.jcr.RepositoryException;
18 import javax.jcr.nodetype.NodeType;
19
20 import org.argeo.api.cms.ux.Cms2DSize;
21 import org.argeo.api.cms.ux.CmsImageManager;
22 import org.argeo.app.api.EntityNames;
23 import org.argeo.app.api.EntityType;
24 import org.argeo.app.docbook.DbkAttr;
25 import org.argeo.app.docbook.DbkType;
26 import org.argeo.app.docbook.DbkUtils;
27 import org.argeo.cms.ui.util.CmsUiUtils;
28 import org.argeo.cms.ui.util.DefaultImageManager;
29 import org.argeo.jcr.JcrException;
30 import org.argeo.jcr.JcrUtils;
31 import org.eclipse.swt.graphics.ImageData;
32
33 /** Add DocBook images support to {@link CmsImageManager}. */
34 public class DbkImageManager extends DefaultImageManager {
35 private Node baseFolder = null;
36
37 public DbkImageManager(Node baseFolder) {
38 this.baseFolder = baseFolder;
39 }
40
41 Node getImageDataNode(Node mediaObjectNode) {
42 try {
43 if (mediaObjectNode.hasNode(DbkType.imageobject.get())) {
44 Node imageDataNode = mediaObjectNode.getNode(DbkType.imageobject.get())
45 .getNode(DbkType.imagedata.get());
46 return imageDataNode;
47 } else {
48 throw new IllegalStateException("No image data found for " + mediaObjectNode);
49 }
50 } catch (RepositoryException e) {
51 throw new JcrException(e);
52 }
53 }
54
55 @Override
56 public Binary getImageBinary(Node node) {
57 Node fileNode = null;
58 if (DbkUtils.isDbk(node, DbkType.mediaobject)) {
59 Node imageDataNode = getImageDataNode(node);
60 fileNode = getFileNode(imageDataNode);
61 }
62 try {
63 if (node.isNodeType(NT_FILE)) {
64 fileNode = node;
65 }
66 if (fileNode != null) {
67 return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary();
68 } else {
69 return null;
70 }
71 } catch (RepositoryException e) {
72 throw new JcrException(e);
73 }
74 }
75
76 public Cms2DSize getImageSize(Node mediaObjectNode) {
77 Node imageDataNode = getImageDataNode(mediaObjectNode);
78 Node fileNode = getFileNode(imageDataNode);
79 if (fileNode == null)
80 return new Cms2DSize(0, 0);
81 try {
82 Cms2DSize intrinsicSize;
83 if (fileNode.hasProperty(EntityNames.SVG_WIDTH) && fileNode.hasProperty(EntityNames.SVG_HEIGHT)) {
84 int width = (int) fileNode.getProperty(EntityNames.SVG_WIDTH).getLong();
85 int height = (int) fileNode.getProperty(EntityNames.SVG_HEIGHT).getLong();
86 intrinsicSize = new Cms2DSize(width, height);
87 } else {
88 try (InputStream in = JcrUtils.getFileAsStream(fileNode)) {
89 ImageData id = new ImageData(in);
90 intrinsicSize = updateSize(fileNode, id);
91 } catch (IOException e) {
92 throw new RuntimeException("Cannot load file " + fileNode, e);
93 }
94 }
95 // TODO interpret image data infos
96 return intrinsicSize;
97 } catch (RepositoryException e) {
98 throw new JcrException(e);
99 }
100 }
101
102 protected Cms2DSize updateSize(Node fileNode, ImageData id) throws RepositoryException {
103 fileNode.addMixin(EntityType.box.get());
104 fileNode.setProperty(EntityNames.SVG_WIDTH, id.width);
105 fileNode.setProperty(EntityNames.SVG_HEIGHT, id.height);
106 return new Cms2DSize(id.width, id.height);
107 }
108
109 @Override
110 protected void processNewImageFile(Node mediaObjectNode, Node fileNode, ImageData id)
111 throws RepositoryException, IOException {
112 Node imageDataNode = getImageDataNode(mediaObjectNode);
113 updateSize(fileNode, id);
114 String filePath = fileNode.getPath();
115 String relPath = filePath.substring(baseFolder.getPath().length() + 1);
116 imageDataNode.setProperty(DbkAttr.fileref.name(), relPath);
117 }
118
119 @Override
120 public String getImageUrl(Node mediaObjectNode) {
121 Node imageDataNode = getImageDataNode(mediaObjectNode);
122 // TODO factorise
123 String fileref = null;
124 try {
125 if (imageDataNode.hasProperty(DbkAttr.fileref.name()))
126 fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString();
127 } catch (RepositoryException e) {
128 throw new JcrException(e);
129 }
130 if (fileref == null)
131 return null;
132 URI fileUri;
133 try {
134 // FIXME it messes up with the '/'
135 fileUri = new URI(URLEncoder.encode(fileref, StandardCharsets.UTF_8.toString()));
136 } catch (URISyntaxException | UnsupportedEncodingException e) {
137 throw new IllegalArgumentException("File ref in " + imageDataNode + " is badly formatted", e);
138 }
139 if (fileUri.getScheme() != null)
140 return fileUri.toString();
141 // local
142 Node fileNode = getFileNode(imageDataNode);
143 String url = CmsUiUtils.getDataPathForUrl(fileNode);
144 return url;
145 }
146
147 protected Node getFileNode(Node imageDataNode) {
148 // FIXME make URL use case more robust
149 try {
150 String fileref = null;
151 if (imageDataNode.hasProperty(DbkAttr.fileref.name()))
152 fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString();
153 if (fileref == null)
154 return null;
155 Node fileNode;
156 if (fileref.startsWith("/"))
157 fileNode = baseFolder.getSession().getNode(fileref);
158 else
159 fileNode = baseFolder.getNode(fileref);
160 return fileNode;
161 } catch (RepositoryException e) {
162 throw new JcrException(e);
163 }
164 }
165
166 protected Node getMediaFolder() {
167 try {
168 // TODO check edition status
169 Node mediaFolder = JcrUtils.getOrAdd(baseFolder, EntityNames.MEDIA, NodeType.NT_FOLDER);
170 return mediaFolder;
171 } catch (RepositoryException e) {
172 throw new JcrException("Cannot get media folder", e);
173 }
174 }
175 }