/* * Geotoolkit - An Open Source Java GIS Toolkit * http://www.geotoolkit.org * * (C) 2003 - 2008, Open Source Geospatial Foundation (OSGeo) * (C) 2008 - 2009, Geomatys * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; * version 2.1 of the License. * * This library 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 * Lesser General Public License for more details. */ package org.geotoolkit.renderer.style; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.geom.Point2D; import java.awt.image.BufferedImage; import java.net.URI; import java.util.Arrays; import java.util.Iterator; import java.util.logging.Logger; import org.geotoolkit.factory.DynamicFactoryRegistry; import org.geotoolkit.factory.FactoryRegistry; /** * Searches for all available {@link ExternalGraphicFactory} and * {@link MarkFactory} implementations. * * <p> * In addition to implementing this interface dynamic symbol handlers should * have a services file: * <ul> * <li><code>META-INF/services/org.geotoolkit.renderer.style.MarkFactory</code> * if the are {@link MarkFactory} instances</li> * <li><code>META-INF/services/org.geotoolkit.renderer.style.ExternalGraphicFactory</code> * if the are {@link ExternalGraphicFactory} instances</li> * </ul> * </p> * * @module */ public final class DynamicSymbolFactoryFinder { /** The logger for the filter module. */ protected static final Logger LOGGER = org.apache.sis.util.logging.Logging .getLogger("org.geotoolkit.renderer.style"); /** * The service registry for this manager. Will be initialized only when * first needed. */ private static FactoryRegistry registry; private DynamicSymbolFactoryFinder() { } /** * @see org.geotoolkit.renderer.style.ExternalGraphicFactory#getImage(java.net.URI, java.lang.String, java.lang.Float, RenderingHints) */ public static BufferedImage getImage(final URI uri, final String mime, final Float size, final RenderingHints hints) throws Exception{ final Iterator<ExternalGraphicFactory> ite = getExternalGraphicFactories(); while(ite.hasNext()){ final ExternalGraphicFactory factory = ite.next(); if(factory.getSupportedMimeTypes().contains(mime)){ return factory.getImage(uri, mime, size, hints); } } return null; } /** * @see org.geotoolkit.renderer.style.ExternalGraphicFactory#getImage(java.net.URI, java.lang.String, java.lang.Float, RenderingHints) */ public static void renderImage(final URI uri, final String mime, final Float size, final Graphics2D g, final Point2D center,final RenderingHints hints) throws Exception{ final Iterator<ExternalGraphicFactory> ite = getExternalGraphicFactories(); while(ite.hasNext()){ final ExternalGraphicFactory factory = ite.next(); if(factory.getSupportedMimeTypes().contains(mime)){ factory.renderImage(uri, mime, size, g, center, hints); return; } } } /** * Finds all implementations of {@link MarkFactory} which have registered * using the services mechanism. * * @return An iterator over all discovered datastores which have registered * factories, and whose available method returns true. */ public static synchronized Iterator<MarkFactory> getMarkFactories() { return getServiceRegistry().getServiceProviders(MarkFactory.class, null, null, null); } /** * Finds all implementations of {@link ExternalGraphicFactory} which have * registered using the services mechanism. * * @return An iterator over all discovered datastores which have registered * factories, and whose available method returns true. */ public static synchronized Iterator<ExternalGraphicFactory> getExternalGraphicFactories() { return getServiceRegistry().getServiceProviders(ExternalGraphicFactory.class, null, null, null); } /** * Returns the service registry. The registry will be created the first time * this method is invoked. */ private static FactoryRegistry getServiceRegistry() { assert Thread.holdsLock(DynamicSymbolFactoryFinder.class); if (registry == null) { registry = new DynamicFactoryRegistry(Arrays.asList(new Class<?>[] { MarkFactory.class, ExternalGraphicFactory.class })); } return registry; } /** * Scans for factory plug-ins on the application class path. This method is * needed because the application class path can theoretically change, or * additional plug-ins may become available. Rather than re-scanning the * classpath on every invocation of the API, the class path is scanned * automatically only on the first invocation. Clients can call this method * to prompt a re-scan. Thus this method need only be invoked by * sophisticated applications which dynamically make new plug-ins available * at runtime. */ public static synchronized void scanForPlugins() { getServiceRegistry().scanForPlugins(); } }