--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.g2d.image;\r
+\r
+import java.net.URL;\r
+\r
+import org.simantics.g2d.image.impl.CacheProvider;\r
+import org.simantics.g2d.image.impl.ImageBundleFactory;\r
+import org.simantics.g2d.image.impl.ImageProxy;\r
+import org.simantics.g2d.image.impl.ImageURLFactory;\r
+import org.simantics.g2d.image.impl.ProviderAsyncronizer;\r
+import org.simantics.g2d.image.impl.ProviderProxier;\r
+import org.simantics.g2d.image.impl.RasterizingProvider;\r
+import org.simantics.utils.datastructures.cache.IFactory;\r
+import org.simantics.utils.datastructures.cache.IProvider;\r
+import org.simantics.utils.datastructures.cache.WeakCachedProvider;\r
+\r
+/**\r
+ * Image Provider Utilities offers methods for constructing chains of \r
+ * provider {@link Image} providers. \r
+ * <p>\r
+ * The nature of IProvider<Image> is at the same time \r
+ * (a) description of the source of an image\r
+ * e.g. at("https://www.simantics.org/simantics/simantics/logo.jpg") \r
+ * \r
+ * (b) method of acquiring the image from its source\r
+ * e.g. Image i = provider.get();\r
+ * <p>\r
+ * IProviders are equals-comparable and can be used as keys in a map.\r
+ * eg.\r
+ * <pre>\r
+ * map.put( at("https://www.simantics.org/simantics/simantics/logo.jpg"), obj1 );\r
+ * ...\r
+ * Object obj2 = map.get( at("https://www.simantics.org/simantics/simantics/logo.jpg") );\r
+ * </pre>\r
+ * <p>\r
+ * The difference between IProvider<Image> and IFactory<Image> is Factory\r
+ * always constructs a new instance and provider may either instantiate new instance\r
+ * or return cached result. \r
+ * \r
+ * In typical scenario the result of IFactory<Image> is cached using cacheResult().\r
+ * The cached result is stored weakly and therefore strong references are required.\r
+ * proxy() adds strong reference ({@link ImageProxy}) factory. \r
+ * <p>\r
+ * Example:\r
+ * <pre>\r
+ * IFactory<Image> prov = reference(weakCache(rasterize(asynchronize(at("https://www.simantics.org/simantics/simantics/logo.jpg")))));\r
+ * \r
+ * Image handle = prov.get();\r
+ * handle.addImageListener();\r
+ * handle.paint();\r
+ * handle = null;\r
+ * </pre>\r
+ * \r
+ * handle instance would be a composition of the following instances:\r
+ * <pre>\r
+ * ImageProxy\r
+ * AsyncImage\r
+ * AWTImage\r
+ * java.awt.image.BufferedImage\r
+ * </pre>\r
+ *\r
+ * @See {@link ImageUtils}\r
+ * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
+ */\r
+public class ProviderUtils {\r
+\r
+ /**\r
+ * Create provider that retrieves symbol from URL. \r
+ * Bitmap and SVG symbols are supported. The format of the image is determined\r
+ * by the suffix of the url. \r
+ * \r
+ * @param url\r
+ * @return\r
+ */\r
+ public static IFactory<Image> at(URL url)\r
+ {\r
+ return new ImageURLFactory(url);\r
+ }\r
+ \r
+ /**\r
+ * Create image from bundle address. The bundle address is in format: \r
+ * "<bundleId/location/file.ext>" \r
+ * Image type is determined from the suffix (.svg .png .jpg etc supported).\r
+ * \r
+ * @param filename bundle address\r
+ * @return bundle image constructor\r
+ */\r
+ public static IFactory<Image> bundle(String filename)\r
+ {\r
+ return new ImageBundleFactory(filename);\r
+ } \r
+ \r
+ /**\r
+ * Caches the result of the provided image with a weak reference.\r
+ * The cached result will be garbage collected with out strong reference\r
+ * (See reference() ).\r
+ * \r
+ * @return cache\r
+ */\r
+ public static IProvider<Image> cache(IProvider<Image> provider)\r
+ {\r
+ return WeakCachedProvider.cache(provider);\r
+ }\r
+\r
+ /**\r
+ * Creates a memory buffer backed raster of provided vector based image. \r
+ * For non-vector images this provider changes nothing.\r
+ * \r
+ * @param prov image provider\r
+ * @return provider that rasterizes the image\r
+ */\r
+ public static IFactory<Image> rasterize(IProvider<Image> prov) {\r
+ return new RasterizingProvider(prov); \r
+ }\r
+ \r
+ /**\r
+ * Converts provider into asynchronized provider. It returns non-blocking result\r
+ * while at the same time acquires the actual image of the source provider \r
+ * in a thread. Once the image is complete the content of the result will be changed.\r
+ * Due to this model, the result is Volatile. \r
+ * \r
+ * @param prov original provider\r
+ * @return asynchronous provider (constructs new image every time)\r
+ */\r
+ public static IFactory<Image> asynchronize(IProvider<Image> prov) {\r
+ return new ProviderAsyncronizer(prov); \r
+ }\r
+\r
+ /**\r
+ * Adds a strong reference (proxy instance) to the provider chain. \r
+ * Proxy handles are used with cache to ensure strong references to the\r
+ * weakly cached result. \r
+ * \r
+ * @param prov original provider (cache provider)\r
+ * @return asynchronous provider (constructs new image every time)\r
+ */\r
+ public static IFactory<Image> reference(IProvider<Image> prov) {\r
+ return new ProviderProxier(prov); \r
+ }\r
+ \r
+ /**\r
+ * Caches the constructed image weakly. Use proxy provider to create\r
+ * strong references to the cached image.\r
+ * \r
+ * @param prov \r
+ * @return caching provider\r
+ */\r
+ public static IProvider<Image> cache(IFactory<Image> prov) {\r
+ return new CacheProvider(prov);\r
+ }\r
+\r
+ /**\r
+ * Convenience method that \r
+ * 1. acquires image asynchronously in a thread\r
+ * 2. rasterizes the image to memory buffer, if necessary (it is vector format)\r
+ * 3. caches the resulted image\r
+ * 4. creates a strong reference for the cached image\r
+ * \r
+ * The result of the factory instantiates proxy handles.\r
+ * Proxy handle returns constructed or cached image. \r
+ * The underlying image will be remain in memory until all handles are \r
+ * released (nulled). \r
+ * \r
+ * Usage example:\r
+ * IFactory<Image> i = convenience( at("https://www.simantics.org/simantics/simantics/logo.jpg") ); \r
+ * i.paint();\r
+ * i = null;\r
+ * \r
+ * @param originalFactory\r
+ * @return factory that instantiates disposable (nullable) handles \r
+ */\r
+ public static IFactory<Image> convenience(IFactory<Image> originalFactory) {\r
+ return reference(cache(rasterize(asynchronize(originalFactory))));\r
+ }\r
+ public static IFactory<Image> convenience(URL url) {\r
+ return reference(cache(rasterize(asynchronize(at(url)))));\r
+ }\r
+ public static IFactory<Image> convenience(String bundleAddress) {\r
+ return reference(cache(rasterize(asynchronize(bundle(bundleAddress)))));\r
+ }\r
+ \r
+}\r
+\r