/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-2009, 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.aggregate; import java.awt.RenderingHints.Key; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.Serializable; import java.net.URL; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import javax.xml.transform.TransformerException; import org.geotools.data.AbstractDataStoreFactory; import org.geotools.data.DataStore; import org.geotools.data.Repository; import org.geotools.util.KVP; /** * * * @source $URL$ */ public class AggregatingDataStoreFactory extends AbstractDataStoreFactory { public static final Param REPOSITORY_PARAM = new Param("repository", Repository.class, "The repository that will provide the store intances", true, null, new KVP(Param.LEVEL, "advanced")); public static final Param STORES_PARAM = new Param("stores", String[].class, "List of data stores to connect to", false, null, new KVP(Param.ELEMENT, String.class)); public static final Param TOLERATE_CONNECTION_FAILURE = new Param( "tolerate connection failure", Boolean.class, "Is failure to connect to a store tolerated", false, Boolean.TRUE); public static final Param NAMESPACE = new Param("namespace", String.class, "Namespace prefix", false); public static final Param PARALLELISM = new Param("parallelism", Integer.class, "Number of allowed concurrent queries on the delegate stores (unlimited by default)", false, new Integer(-1)); public static final Param CONFIGURATION = new Param("configuration", URL.class, "Location of the aggregated type configuration file", false, null); public static final Param CONFIGURATION_XML = new Param("configuration xml", String.class, "The aggregated type configuration, as a xml document in a string", false, null); public String getDisplayName() { return "Aggregating data store"; } public String getDescription() { return "Aggregates homologous feature types from separate data stores"; } public Param[] getParametersInfo() { return new Param[] { REPOSITORY_PARAM, NAMESPACE, CONFIGURATION, TOLERATE_CONNECTION_FAILURE, PARALLELISM }; } public boolean isAvailable() { return true; } public Map<Key, ?> getImplementationHints() { return null; } public DataStore createDataStore(Map<String, Serializable> params) throws IOException { Repository repository = lookup(REPOSITORY_PARAM, params, Repository.class); String[] stores = lookup(STORES_PARAM, params, String[].class); boolean tolerant = lookup(TOLERATE_CONNECTION_FAILURE, params, Boolean.class); String namespace = lookup(NAMESPACE, params, String.class); ExecutorService executor; int parallelism = lookup(PARALLELISM, params, Integer.class); if (parallelism <= 0) { executor = Executors.newCachedThreadPool(); } else { executor = Executors.newFixedThreadPool(parallelism); } List<AggregateTypeConfiguration> configs = null; URL configuration = lookup(CONFIGURATION, params, URL.class); if (configuration != null) { configs = new AggregateTypeParser().parseConfigurations(configuration.openStream()); } String configurationXml = lookup(CONFIGURATION_XML, params, String.class); if (configurationXml != null && !"".equals(configurationXml.trim())) { configs = new AggregateTypeParser().parseConfigurations(new ByteArrayInputStream( configurationXml.getBytes())); } AggregatingDataStore store = new AggregatingDataStore(repository, executor); store.setNamespaceURI(namespace); store.setTolerant(tolerant); if (stores != null) { store.autoConfigureStores(Arrays.asList(stores)); } if (configs != null) { for (AggregateTypeConfiguration config : configs) { store.addType(config); } } return store; } public List<AggregateTypeConfiguration> parseConfiguration(String xml) throws IOException { if (xml != null && !"".equals(xml.trim())) { return new AggregateTypeParser().parseConfigurations(new ByteArrayInputStream(xml .getBytes())); } else { return null; } } public String encodeConfiguration(List<AggregateTypeConfiguration> configs) throws IOException { try { AggregateTypeEncoder encoder = new AggregateTypeEncoder(); encoder.setIndentation(2); return encoder.transform(configs); } catch (TransformerException e) { throw new IOException("Failed to encode the configuration back in xml", e); } } public DataStore createNewDataStore(Map<String, Serializable> params) throws IOException { return createDataStore(params); } /** * Looks up a parameter, if not found it returns the default value, assuming there is one, or * null otherwise * * @param <T> * @param param * @param params * @param target * @return * @throws IOException */ <T> T lookup(Param param, Map<String, Serializable> params, Class<T> target) throws IOException { T result = (T) param.lookUp(params); if (result == null) { return (T) param.getDefaultValue(); } else { return result; } } }