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