]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.simantics.g2d/src/org/simantics/g2d/image/ProviderUtils.java
Migrated source code from Simantics SVN
[simantics/platform.git] / bundles / org.simantics.g2d / src / org / simantics / g2d / image / ProviderUtils.java
1 /*******************************************************************************\r
2  * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
3  * in Industry THTH ry.\r
4  * All rights reserved. This program and the accompanying materials\r
5  * are made available under the terms of the Eclipse Public License v1.0\r
6  * which accompanies this distribution, and is available at\r
7  * http://www.eclipse.org/legal/epl-v10.html\r
8  *\r
9  * Contributors:\r
10  *     VTT Technical Research Centre of Finland - initial API and implementation\r
11  *******************************************************************************/\r
12 package org.simantics.g2d.image;\r
13 \r
14 import java.net.URL;\r
15 \r
16 import org.simantics.g2d.image.impl.CacheProvider;\r
17 import org.simantics.g2d.image.impl.ImageBundleFactory;\r
18 import org.simantics.g2d.image.impl.ImageProxy;\r
19 import org.simantics.g2d.image.impl.ImageURLFactory;\r
20 import org.simantics.g2d.image.impl.ProviderAsyncronizer;\r
21 import org.simantics.g2d.image.impl.ProviderProxier;\r
22 import org.simantics.g2d.image.impl.RasterizingProvider;\r
23 import org.simantics.utils.datastructures.cache.IFactory;\r
24 import org.simantics.utils.datastructures.cache.IProvider;\r
25 import org.simantics.utils.datastructures.cache.WeakCachedProvider;\r
26 \r
27 /**\r
28  * Image Provider Utilities offers methods for constructing chains of \r
29  * provider {@link Image} providers. \r
30  * <p>\r
31  * The nature of IProvider&lt;Image&gt; is at the same time \r
32  *    (a) description of the source of an image\r
33  *        e.g. at("https://www.simantics.org/simantics/simantics/logo.jpg") \r
34  *     \r
35  *    (b) method of acquiring the image from its source\r
36  *        e.g. Image i = provider.get();\r
37  * <p>\r
38  * IProviders are equals-comparable and can be used as keys in a map.\r
39  * eg.\r
40  * <pre>\r
41  *   map.put( at("https://www.simantics.org/simantics/simantics/logo.jpg"), obj1 );\r
42  *   ...\r
43  *   Object obj2 = map.get( at("https://www.simantics.org/simantics/simantics/logo.jpg") );\r
44  * </pre>\r
45  * <p>\r
46  * The difference between IProvider&lt;Image&gt; and IFactory&lt;Image&gt; is Factory\r
47  * always constructs a new instance and provider may either instantiate new instance\r
48  * or return cached result. \r
49  * \r
50  * In typical scenario the result of IFactory&lt;Image&gt; is cached using cacheResult().\r
51  * The cached result is stored weakly and therefore strong references are required.\r
52  * proxy() adds strong reference ({@link ImageProxy}) factory.   \r
53  * <p>\r
54  * Example:\r
55  * <pre>\r
56  *  IFactory&lt;Image&gt; prov = reference(weakCache(rasterize(asynchronize(at("https://www.simantics.org/simantics/simantics/logo.jpg")))));\r
57  * \r
58  *  Image handle = prov.get();\r
59  *  handle.addImageListener();\r
60  *  handle.paint();\r
61  *  handle = null;\r
62  * </pre>\r
63  * \r
64  *  handle instance would be a composition of the following instances:\r
65  *  <pre>\r
66  *    ImageProxy\r
67  *      AsyncImage\r
68  *        AWTImage\r
69  *          java.awt.image.BufferedImage\r
70  *  </pre>\r
71  *\r
72  * @See {@link ImageUtils}\r
73  * @author Toni Kalajainen <toni.kalajainen@vtt.fi>\r
74  */\r
75 public class ProviderUtils {\r
76 \r
77         /**\r
78          * Create provider that retrieves symbol from URL. \r
79          * Bitmap and SVG symbols are supported. The format of the image is determined\r
80          * by the suffix of the url. \r
81          * \r
82          * @param url\r
83          * @return\r
84          */\r
85         public static IFactory<Image> at(URL url)\r
86         {\r
87                 return new ImageURLFactory(url);\r
88         }\r
89         \r
90         /**\r
91          * Create image from bundle address. The bundle address is in format: \r
92          * "<bundleId/location/file.ext>" \r
93          * Image type is determined from the suffix (.svg .png .jpg etc supported).\r
94          * \r
95          * @param filename bundle address\r
96          * @return bundle image constructor\r
97          */\r
98         public static IFactory<Image> bundle(String filename)\r
99         {\r
100                 return new ImageBundleFactory(filename);\r
101         }       \r
102         \r
103         /**\r
104          * Caches the result of the provided image with a weak reference.\r
105          * The cached result will be garbage collected with out strong reference\r
106          * (See reference() ).\r
107          *  \r
108          * @return cache\r
109          */\r
110         public static IProvider<Image> cache(IProvider<Image> provider)\r
111         {\r
112                 return WeakCachedProvider.cache(provider);\r
113         }\r
114 \r
115         /**\r
116          * Creates a memory buffer backed raster of provided vector based image. \r
117          * For non-vector images this provider changes nothing.\r
118          * \r
119          * @param prov image provider\r
120          * @return provider that rasterizes the image\r
121          */\r
122         public static IFactory<Image> rasterize(IProvider<Image> prov) {\r
123                 return new RasterizingProvider(prov); \r
124         }\r
125         \r
126         /**\r
127          * Converts provider into asynchronized provider. It returns non-blocking result\r
128          * while at the same time acquires the actual image of the source provider \r
129          * in a thread. Once the image is complete the content of the result will be changed.\r
130          * Due to this model, the result is Volatile.   \r
131          * \r
132          * @param prov original provider\r
133          * @return asynchronous provider (constructs new image every time)\r
134          */\r
135         public static IFactory<Image> asynchronize(IProvider<Image> prov) {\r
136                 return new ProviderAsyncronizer(prov); \r
137         }\r
138 \r
139         /**\r
140          * Adds a strong reference (proxy instance) to the provider chain. \r
141          * Proxy handles are used with cache to ensure strong references to the\r
142          * weakly cached result.   \r
143          * \r
144          * @param prov original provider (cache provider)\r
145          * @return asynchronous provider (constructs new image every time)\r
146          */\r
147         public static IFactory<Image> reference(IProvider<Image> prov) {\r
148                 return new ProviderProxier(prov); \r
149         }\r
150         \r
151         /**\r
152          * Caches the constructed image weakly. Use proxy provider to create\r
153          * strong references to the cached image.\r
154          * \r
155          * @param prov \r
156          * @return caching provider\r
157          */\r
158         public static IProvider<Image> cache(IFactory<Image> prov) {\r
159                 return new CacheProvider(prov);\r
160         }\r
161 \r
162         /**\r
163          * Convenience method that \r
164          *  1. acquires image asynchronously in a thread\r
165          *  2. rasterizes the image to memory buffer, if necessary (it is vector format)\r
166          *  3. caches the resulted image\r
167          *  4. creates a strong reference for the cached image\r
168          *  \r
169          * The result of the factory instantiates proxy handles.\r
170          * Proxy handle returns constructed or cached image. \r
171          * The underlying image will be remain in memory until all handles are \r
172          * released (nulled).  \r
173          * \r
174          * Usage example:\r
175          *   IFactory<Image> i = convenience( at("https://www.simantics.org/simantics/simantics/logo.jpg") ); \r
176          *   i.paint();\r
177          *   i = null;\r
178          * \r
179          * @param originalFactory\r
180          * @return factory that instantiates disposable (nullable) handles \r
181          */\r
182         public static IFactory<Image> convenience(IFactory<Image> originalFactory) {\r
183                 return reference(cache(rasterize(asynchronize(originalFactory))));\r
184         }\r
185         public static IFactory<Image> convenience(URL url) {\r
186                 return reference(cache(rasterize(asynchronize(at(url)))));\r
187         }\r
188         public static IFactory<Image> convenience(String bundleAddress) {\r
189                 return reference(cache(rasterize(asynchronize(bundle(bundleAddress)))));\r
190         }\r
191         \r
192 }\r
193 \r