/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2014, Open Source Geospatial Foundation (OSGeo) * * 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.geotools.data.wfs.internal; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import javax.imageio.spi.ServiceRegistry; import org.geotools.data.wfs.WFSDataStoreFactory; import org.geotools.factory.FactoryNotFoundException; /** * Utility class to look up for a parser that can deal with a given WFS response and process it. * <p> * This class uses the usual GeoTools SPI (Service Provider Interface) mechanism to find out a * {@link WFSResponseFactory} for a given {@link WFSResponse}. As such, {@link WFSResponseFactory} * implementation may live outside this plugin as long as they're declared in it's own {code * /META-INF/services/org.geotools.data.wfs.protocol.wfs.WFSResponseParserFactory} text file. * </p> * * @author Gabriel Roldan (OpenGeo) * @version $Id$ * @since 2.6 * * * * @source $URL$ * http://svn.osgeo.org/geotools/trunk/modules/unsupported/wfs/src/main/java/org/geotools * /data/wfs/protocol/wfs/WFSExtensions.java $ */ @SuppressWarnings("nls") public class WFSExtensions { /** * The service registry for this manager. Will be initialized only when first needed. */ private static Set<WFSResponseFactory> registry; /** * Processes the result of a WFS operation and returns the parsed object. * <p> * The result can either be: * <ul> * <li>a {@link WFSException} exception if the WFS response was an exception report * <li>a {@link GetFeatureParser} if the WFS returned a FeatureCollection * </p> * * @param request * the WFS request that originated the given response * @param response * the handle to the WFS response contents * @return * @throws IOException */ // public static Object process(WFSResponse response) throws IOException { // // WFSRequest originatingRequest = response.getOriginatingRequest(); // WFSResponseFactory pf = findParserFactory(originatingRequest); // // WFSResponseParser parser = pf.createParser(response); // // Object result = parser.parse(response); // return result; // } /** * @param contentType * @param requestType * @param outputFormat * @return * @throws FactoryNotFoundException */ public static WFSResponseFactory findResponseFactory(final WFSRequest originatingRequest, final String contentType) { Iterator<WFSResponseFactory> serviceProviders; serviceProviders = getServiceProviders(); WFSResponseFactory factory; while (serviceProviders.hasNext()) { factory = serviceProviders.next(); if (factory.isAvailable()) { if (factory.canProcess(originatingRequest, contentType)) { return factory; } } } throw new FactoryNotFoundException("Can't find a response parser factory for " + originatingRequest.getOperation() + "/'" + contentType + "'"); } public static List<WFSResponseFactory> findResponseFactories(final WFSOperationType operation) { Iterator<WFSResponseFactory> serviceProviders = getServiceProviders(); List<WFSResponseFactory> matches = new ArrayList<WFSResponseFactory>(5); while (serviceProviders.hasNext()) { WFSResponseFactory factory = serviceProviders.next(); if (factory.isAvailable()) { if (factory.canProcess(operation)) { matches.add(factory); } } } return matches; } private static Iterator<WFSResponseFactory> getServiceProviders() { if (registry == null) { synchronized (WFSExtensions.class) { if (registry == null) { /* * Set the current thread's class loader to the one that actually loaded the * WDSDataStore and related classes for while the factory lookup is performed. * This way the module is friendlier to crazy class loader hierarchies like * OSGI/Eclipse */ final ClassLoader current = Thread.currentThread().getContextClassLoader(); try { final ClassLoader tempClassLoader = WFSDataStoreFactory.class .getClassLoader(); Thread.currentThread().setContextClassLoader(tempClassLoader); /* * Now that we're on the correct classloader lets perform the lookup */ Iterator<WFSResponseFactory> providers; providers = ServiceRegistry.lookupProviders(WFSResponseFactory.class); registry = new HashSet<WFSResponseFactory>(); while (providers.hasNext()) { WFSResponseFactory provider = providers.next(); registry.add(provider); } } finally { /* * And finally restore the original thread's class loader */ Thread.currentThread().setContextClassLoader(current); } } } } return registry.iterator(); } }