1 /*******************************************************************************
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * VTT Technical Research Centre of Finland - initial API and implementation
11 *******************************************************************************/
12 package org.simantics.document;
14 import java.io.IOException;
15 import java.math.BigInteger;
16 import java.nio.file.Files;
17 import java.nio.file.Path;
18 import java.security.MessageDigest;
19 import java.security.NoSuchAlgorithmException;
20 import java.util.regex.Matcher;
21 import java.util.regex.Pattern;
23 import org.simantics.Simantics;
24 import org.simantics.databoard.Bindings;
25 import org.simantics.db.ReadGraph;
26 import org.simantics.db.Resource;
27 import org.simantics.db.common.request.PossibleIndexRoot;
28 import org.simantics.db.exception.DatabaseException;
29 import org.simantics.image2.ontology.ImageResource;
31 public class DocumentDialect {
33 final static public DocumentDialect INSTANCE = new DocumentDialect();
35 public static final String SIMANTICS_INTERNAL_URI_PREFIX = "http://simantics-internal/";
37 private static final String HTTP = "http://";
38 private static final String ROOT = "root:/";
39 private static final String IMAGE = "image";
40 private static final String MEDIA = "media";
42 final Pattern imageOrMediaPattern = Pattern.compile("\\[\\[([Ii]mage|[Mm]edia)(?::([^\\]]+))?\\]\\]");
44 private static String digest(byte[] bytes) throws NoSuchAlgorithmException {
45 MessageDigest md = MessageDigest.getInstance("MD5");
47 BigInteger number = new BigInteger(1, md.digest());
48 return number.toString(16);
51 private static String imageExtension(ReadGraph graph, Resource image) throws DatabaseException {
52 ImageResource IMAGE = ImageResource.getInstance(graph);
53 if (graph.isInstanceOf(image, IMAGE.PngImage))
55 else if (graph.isInstanceOf(image, IMAGE.JpegImage))
60 public String transform(ReadGraph graph, Resource res, String type, String options) {
62 String[] parts = options.split("\\|");
63 if (parts.length > 0) {
64 String uri = parts[0];
66 Resource indexRoot = graph.syncRequest(new PossibleIndexRoot(res));
67 if (indexRoot == null) return null;
68 String rootURI = graph.getURI(indexRoot);
70 uri = uri.replace(ROOT, rootURI);
72 // (Apros #12268) For more user-friendly linking, allow users to
73 // write white space as ' ' in the wiki-style image links instead
74 // of having to write %20.
75 uri = uri.replace(" ", "%20");
77 if (IMAGE.equals(type)) {
78 Resource image = graph.getPossibleResource(uri);
82 String extension = imageExtension(graph, image);
83 if (extension == null)
86 byte[] bytes = graph.getValue(image, Bindings.BYTE_ARRAY);
87 String digest = digest(bytes);
89 Path dir = Simantics.getTemporaryDirectory("documentImages").toPath();
90 Files.createDirectories(dir);
92 Path f = dir.resolve(digest + extension);
94 Files.write(f, bytes);
96 StringBuilder sb = new StringBuilder(128);
97 sb.append("[[File: ").append(f.toUri());
98 for (int i = 1; i < parts.length; i++)
99 sb.append("|").append(parts[i]);
101 return sb.toString();
102 } else if (MEDIA.equals(type)) {
103 Resource image = graph.getPossibleResource(uri);
107 StringBuilder sb = new StringBuilder();
108 sb.append("[").append(SIMANTICS_INTERNAL_URI_PREFIX).append(uri);
109 for (int i = 1; i < parts.length; i++)
110 sb.append(" ").append(parts[i]);
112 return sb.toString();
116 } catch (DatabaseException e) {
117 } catch (NoSuchAlgorithmException e) {
118 } catch (IOException e) {
124 public String apply(ReadGraph graph, Resource res, String markup) throws DatabaseException {
126 StringBuffer sb = new StringBuffer();
127 Matcher matcher = imageOrMediaPattern.matcher(markup);
128 while(matcher.find()) {
129 matcher.appendReplacement(sb, "");
130 String type = matcher.group(1);
131 String options = matcher.group(2);
132 String match = transform(graph, res, type.toLowerCase(), options);
133 if(match != null) sb.append(match);
134 else sb.append("[[Image:" + options + "]]");
136 matcher.appendTail(sb);
137 return sb.toString();