summaryrefslogtreecommitdiff
path: root/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java
diff options
context:
space:
mode:
authorErich Schubert <erich@debian.org>2012-06-02 17:47:03 +0200
committerAndrej Shadura <andrewsh@debian.org>2019-03-09 22:30:32 +0000
commit593eae6c91717eb9f4ff5088ba460dd4210509c0 (patch)
treed97e8cefb48773a382542e9e9d4a6796202a044a /src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java
parente580e42664ca92fbf8792bc39b8d59383db829fe (diff)
parentc36aa2a8fd31ca5e225ff30278e910070cd2c8c1 (diff)
Import Debian changes 0.5.0~beta2-1
elki (0.5.0~beta2-1) unstable; urgency=low * New upstream beta release. * Needs GNU Trove 3, in NEW. * Build with OpenJDK7, as OpenJDK6 complains. elki (0.5.0~beta1-1) unstable; urgency=low * New upstream beta release. * Needs GNU Trove 3, not yet in Debian (private package) * Build with OpenJDK7, as OpenJDK6 complains.
Diffstat (limited to 'src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java')
-rw-r--r--src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java249
1 files changed, 249 insertions, 0 deletions
diff --git a/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java
new file mode 100644
index 00000000..dd844165
--- /dev/null
+++ b/src/de/lmu/ifi/dbs/elki/visualization/batikutil/ThumbnailRegistryEntry.java
@@ -0,0 +1,249 @@
+package de.lmu.ifi.dbs.elki.visualization.batikutil;
+/*
+ This file is part of ELKI:
+ Environment for Developing KDD-Applications Supported by Index-Structures
+
+ Copyright (C) 2012
+ Ludwig-Maximilians-Universität München
+ Lehr- und Forschungseinheit für Datenbanksysteme
+ ELKI Development Team
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Affero General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Affero General Public License for more details.
+
+ You should have received a copy of the GNU Affero General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+import gnu.trove.iterator.TIntObjectIterator;
+import gnu.trove.map.TIntObjectMap;
+import gnu.trove.map.hash.TIntObjectHashMap;
+
+import java.awt.image.RenderedImage;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.ref.SoftReference;
+import java.util.Iterator;
+
+import org.apache.batik.ext.awt.image.GraphicsUtil;
+import org.apache.batik.ext.awt.image.renderable.Filter;
+import org.apache.batik.ext.awt.image.renderable.RedRable;
+import org.apache.batik.ext.awt.image.spi.AbstractRegistryEntry;
+import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
+import org.apache.batik.ext.awt.image.spi.MagicNumberRegistryEntry;
+import org.apache.batik.ext.awt.image.spi.URLRegistryEntry;
+import org.apache.batik.svggen.ErrorConstants;
+import org.apache.batik.util.ParsedURL;
+import org.apache.batik.util.ParsedURLData;
+import org.apache.batik.util.ParsedURLProtocolHandler;
+
+import de.lmu.ifi.dbs.elki.logging.Logging;
+
+/**
+ * Access images via an internal image registry.
+ *
+ * @author Erich Schubert
+ */
+public class ThumbnailRegistryEntry extends AbstractRegistryEntry implements URLRegistryEntry, ParsedURLProtocolHandler {
+ /**
+ * ELKI internal thumbnail protocol id.
+ */
+ public static final String INTERNAL_PROTOCOL = "thumb";
+
+ /**
+ * ELKI internal thumbnail protocol prefix
+ */
+ public static final String INTERNAL_PREFIX = INTERNAL_PROTOCOL + ":";
+
+ /**
+ * Mime type
+ */
+ public static final String INTERNAL_MIME_TYPE = "internal/thumb";
+
+ /**
+ * The priority of this entry.
+ */
+ public static final float PRIORITY = 1 * MagicNumberRegistryEntry.PRIORITY;
+
+ /**
+ * The logger class.
+ */
+ private static final Logging logger = Logging.getLogger(ThumbnailRegistryEntry.class);
+
+ /**
+ * The image cache.
+ */
+ private static final TIntObjectMap<SoftReference<RenderedImage>> images = new TIntObjectHashMap<SoftReference<RenderedImage>>();
+
+ /**
+ * Object counter
+ */
+ private static int counter = 1;
+
+ /**
+ * Constructor.
+ *
+ * Note: there will usually be two instances created. One for handling the
+ * image type, one for the URL handling. This is ok.
+ */
+ public ThumbnailRegistryEntry() {
+ super("Internal", PRIORITY, new String[0], new String[] { INTERNAL_MIME_TYPE });
+ if(logger.isDebuggingFiner()) {
+ logger.debugFiner("Registry initialized.");
+ }
+ }
+
+ /**
+ * Put an image into the repository (note: the repository is only keeping a
+ * weak reference!)
+ *
+ * @param img Image to put
+ * @return Key
+ */
+ public static int registerImage(RenderedImage img) {
+ synchronized(images) {
+ int key = counter;
+ counter++;
+ assert (images.get(key) == null);
+ images.put(key, new SoftReference<RenderedImage>(img));
+ // Reorganize map, purge old entries
+ if(counter % 50 == 49) {
+ for(TIntObjectIterator<SoftReference<RenderedImage>> iter = images.iterator(); iter.hasNext();) {
+ iter.advance();
+ if(iter.value() == null || iter.value().get() == null) {
+ iter.remove();
+ }
+ }
+ }
+ if(logger.isDebuggingFiner()) {
+ logger.debugFiner("Registered image: " + key);
+ }
+ return key;
+ }
+ }
+
+ @Override
+ public boolean isCompatibleURL(ParsedURL url) {
+ // logger.warning("isCompatible " + url.toString());
+ return isCompatibleURLStatic(url);
+ }
+
+ /**
+ * Test for a compatible URL.
+ *
+ * @param url URL
+ * @return Success code
+ */
+ public static boolean isCompatibleURLStatic(ParsedURL url) {
+ return url.getProtocol().equals(INTERNAL_PROTOCOL);
+ }
+
+ @Override
+ public Filter handleURL(ParsedURL url, boolean needRawData) {
+ Filter ret = handleURL(url);
+ if(ret != null) {
+ return ret;
+ }
+ // Image not found in registry.
+ return ImageTagRegistry.getBrokenLinkImage(ThumbnailRegistryEntry.this, ErrorConstants.ERR_IMAGE_DIR_DOES_NOT_EXIST, new Object[0]);
+ }
+
+ /**
+ * Statically handle the URL access.
+ *
+ * @param url URL to access
+ * @return Image, or null
+ */
+ public static Filter handleURL(ParsedURL url) {
+ if(logger.isDebuggingFiner()) {
+ logger.debugFiner("handleURL " + url.toString());
+ }
+ if(!isCompatibleURLStatic(url)) {
+ return null;
+ }
+ int id;
+ try {
+ id = Integer.parseInt(url.getPath());
+ }
+ catch(NumberFormatException e) {
+ return null;
+ }
+ SoftReference<RenderedImage> ref = images.get(id);
+ if(ref != null) {
+ RenderedImage ri = ref.get();
+ if(ri == null) {
+ logger.warning("Referenced image has expired from the cache!");
+ }
+ else {
+ return new RedRable(GraphicsUtil.wrap(ri));
+ }
+ }
+ // Image not found in registry.
+ return null;
+ }
+
+ /**
+ * URL representation for internal URLs.
+ *
+ * @author Erich Schubert
+ */
+ class InternalParsedURLData extends ParsedURLData {
+ /**
+ * Constructor.
+ */
+ public InternalParsedURLData(String id) {
+ super();
+ this.protocol = INTERNAL_PROTOCOL;
+ this.contentType = INTERNAL_MIME_TYPE;
+ this.path = id;
+ }
+
+ @Override
+ public String getContentType(String userAgent) {
+ return INTERNAL_MIME_TYPE;
+ }
+
+ @Override
+ public boolean complete() {
+ return true;
+ }
+
+ @SuppressWarnings("rawtypes")
+ @Override
+ public InputStream openStream(String userAgent, Iterator mimeTypes) throws IOException {
+ // Return null, since we don't want to use streams.
+ return null;
+ }
+ }
+
+ @Override
+ public ParsedURLData parseURL(String urlStr) {
+ if(logger.isDebuggingFinest()) {
+ logger.debugFinest("parseURL: " + urlStr);
+ }
+ if(urlStr.startsWith(INTERNAL_PREFIX)) {
+ InternalParsedURLData ret = new InternalParsedURLData(urlStr.substring(INTERNAL_PREFIX.length()));
+ return ret;
+ }
+ return null;
+ }
+
+ @Override
+ public ParsedURLData parseURL(ParsedURL basepurl, String urlStr) {
+ // Won't happen in a relative way anyway, and is not particularly
+ // supported (as the objects might be dropped from the cache)
+ return parseURL(urlStr);
+ }
+
+ @Override
+ public String getProtocolHandled() {
+ return INTERNAL_PROTOCOL;
+ }
+} \ No newline at end of file