X-Git-Url: https://git.argeo.org/?p=gpl%2Fargeo-suite.git;a=blobdiff_plain;f=org.argeo.app.ui%2Fsrc%2Forg%2Fargeo%2Fapp%2Fui%2Fdocbook%2FDbkImageManager.java;fp=org.argeo.app.ui%2Fsrc%2Forg%2Fargeo%2Fapp%2Fui%2Fdocbook%2FDbkImageManager.java;h=32bbdd9cf4cee3186d9a4009cc812d1fed0177b2;hp=0000000000000000000000000000000000000000;hb=6e56ffa34cb02ab04d028423aea342e3dfed4358;hpb=c285180bece610b2c2921d44fe14b6dde2123efa diff --git a/org.argeo.app.ui/src/org/argeo/app/ui/docbook/DbkImageManager.java b/org.argeo.app.ui/src/org/argeo/app/ui/docbook/DbkImageManager.java new file mode 100644 index 0000000..32bbdd9 --- /dev/null +++ b/org.argeo.app.ui/src/org/argeo/app/ui/docbook/DbkImageManager.java @@ -0,0 +1,175 @@ +package org.argeo.app.ui.docbook; + +import static javax.jcr.Node.JCR_CONTENT; +import static javax.jcr.Property.JCR_DATA; +import static javax.jcr.nodetype.NodeType.NT_FILE; + +import java.io.IOException; +import java.io.InputStream; +import java.io.UnsupportedEncodingException; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; + +import javax.jcr.Binary; +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.nodetype.NodeType; + +import org.argeo.api.cms.Cms2DSize; +import org.argeo.api.cms.CmsImageManager; +import org.argeo.app.api.EntityNames; +import org.argeo.app.api.EntityType; +import org.argeo.app.docbook.DbkAttr; +import org.argeo.app.docbook.DbkType; +import org.argeo.app.docbook.DbkUtils; +import org.argeo.cms.ui.util.CmsUiUtils; +import org.argeo.cms.ui.util.DefaultImageManager; +import org.argeo.jcr.JcrException; +import org.argeo.jcr.JcrUtils; +import org.eclipse.swt.graphics.ImageData; + +/** Add DocBook images support to {@link CmsImageManager}. */ +public class DbkImageManager extends DefaultImageManager { + private Node baseFolder = null; + + public DbkImageManager(Node baseFolder) { + this.baseFolder = baseFolder; + } + + Node getImageDataNode(Node mediaObjectNode) { + try { + if (mediaObjectNode.hasNode(DbkType.imageobject.get())) { + Node imageDataNode = mediaObjectNode.getNode(DbkType.imageobject.get()) + .getNode(DbkType.imagedata.get()); + return imageDataNode; + } else { + throw new IllegalStateException("No image data found for " + mediaObjectNode); + } + } catch (RepositoryException e) { + throw new JcrException(e); + } + } + + @Override + public Binary getImageBinary(Node node) { + Node fileNode = null; + if (DbkUtils.isDbk(node, DbkType.mediaobject)) { + Node imageDataNode = getImageDataNode(node); + fileNode = getFileNode(imageDataNode); + } + try { + if (node.isNodeType(NT_FILE)) { + fileNode = node; + } + if (fileNode != null) { + return node.getNode(JCR_CONTENT).getProperty(JCR_DATA).getBinary(); + } else { + return null; + } + } catch (RepositoryException e) { + throw new JcrException(e); + } + } + + public Cms2DSize getImageSize(Node mediaObjectNode) { + Node imageDataNode = getImageDataNode(mediaObjectNode); + Node fileNode = getFileNode(imageDataNode); + if (fileNode == null) + return new Cms2DSize(0, 0); + try { + Cms2DSize intrinsicSize; + if (fileNode.hasProperty(EntityNames.SVG_WIDTH) && fileNode.hasProperty(EntityNames.SVG_HEIGHT)) { + int width = (int) fileNode.getProperty(EntityNames.SVG_WIDTH).getLong(); + int height = (int) fileNode.getProperty(EntityNames.SVG_HEIGHT).getLong(); + intrinsicSize = new Cms2DSize(width, height); + } else { + try (InputStream in = JcrUtils.getFileAsStream(fileNode)) { + ImageData id = new ImageData(in); + intrinsicSize = updateSize(fileNode, id); + } catch (IOException e) { + throw new RuntimeException("Cannot load file " + fileNode, e); + } + } + // TODO interpret image data infos + return intrinsicSize; + } catch (RepositoryException e) { + throw new JcrException(e); + } + } + + protected Cms2DSize updateSize(Node fileNode, ImageData id) throws RepositoryException { + fileNode.addMixin(EntityType.box.get()); + fileNode.setProperty(EntityNames.SVG_WIDTH, id.width); + fileNode.setProperty(EntityNames.SVG_HEIGHT, id.height); + return new Cms2DSize(id.width, id.height); + } + + @Override + protected void processNewImageFile(Node mediaObjectNode, Node fileNode, ImageData id) + throws RepositoryException, IOException { + Node imageDataNode = getImageDataNode(mediaObjectNode); + updateSize(fileNode, id); + String filePath = fileNode.getPath(); + String relPath = filePath.substring(baseFolder.getPath().length() + 1); + imageDataNode.setProperty(DbkAttr.fileref.name(), relPath); + } + + @Override + public String getImageUrl(Node mediaObjectNode) { + Node imageDataNode = getImageDataNode(mediaObjectNode); + // TODO factorise + String fileref = null; + try { + if (imageDataNode.hasProperty(DbkAttr.fileref.name())) + fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString(); + } catch (RepositoryException e) { + throw new JcrException(e); + } + if (fileref == null) + return null; + URI fileUri; + try { + // FIXME it messes up with the '/' + fileUri = new URI(URLEncoder.encode(fileref, StandardCharsets.UTF_8.toString())); + } catch (URISyntaxException | UnsupportedEncodingException e) { + throw new IllegalArgumentException("File ref in " + imageDataNode + " is badly formatted", e); + } + if (fileUri.getScheme() != null) + return fileUri.toString(); + // local + Node fileNode = getFileNode(imageDataNode); + String url = CmsUiUtils.getDataPathForUrl(fileNode); + return url; + } + + protected Node getFileNode(Node imageDataNode) { + // FIXME make URL use case more robust + try { + String fileref = null; + if (imageDataNode.hasProperty(DbkAttr.fileref.name())) + fileref = imageDataNode.getProperty(DbkAttr.fileref.name()).getString(); + if (fileref == null) + return null; + Node fileNode; + if (fileref.startsWith("/")) + fileNode = baseFolder.getSession().getNode(fileref); + else + fileNode = baseFolder.getNode(fileref); + return fileNode; + } catch (RepositoryException e) { + throw new JcrException(e); + } + } + + protected Node getMediaFolder() { + try { + // TODO check edition status + Node mediaFolder = JcrUtils.getOrAdd(baseFolder, EntityNames.MEDIA, NodeType.NT_FOLDER); + return mediaFolder; + } catch (RepositoryException e) { + throw new JcrException("Cannot get media folder", e); + } + } +}