/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2007-2008, 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. * * This package contains documentation from OpenGIS specifications. * OpenGIS consortium's work is fully acknowledged here. */ package org.geotools.referencing.factory; // J2SE dependencies import java.util.Set; import java.util.Arrays; import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; // OpenGIS dependencies import org.opengis.referencing.*; import org.opengis.referencing.cs.*; import org.opengis.referencing.crs.*; import org.opengis.referencing.datum.*; import org.opengis.referencing.operation.*; import org.opengis.parameter.ParameterDescriptor; // Geotools dependencies import org.geotools.resources.Classes; import org.geotools.resources.i18n.Errors; import org.geotools.resources.i18n.ErrorKeys; /** * Delegates object creations to one of the {@code create} methods in a backing * {@linkplain AuthorityFactory authority factory}. It is possible to use the generic * {@link AuthorityFactory#createObject createObject} method instead of this class, * but some factory implementations are more efficient when we use the most specific * {@code create} method. For example when using a * {@linkplain org.geotools.referencing.factory.epsg.DirectEpsgFactory EPSG factory backed * by a SQL database}, invoking {@link CRSAuthorityFactory#createCoordinateReferenceSystem * createCoordinateReferenceSystem} instead of {@link AuthorityFactory#createObject createObject} * method will reduce the amount of tables to be queried. *
* This class is useful when the same {@code create} method need to be invoked often, * but is unknown at compile time. It may also be used as a workaround for authority * factories that don't implement the {@code createObject} method. *
* Example: The following code creates a proxy which will delegates its work to the * {@link CRSAuthorityFactory#createGeographicCRS createGeographicCRS} method. * *
* * @since 2.4 * @source $URL$ * @version $Id$ * @author Martin Desruisseaux */ abstract class AuthorityFactoryProxy { /** * The types that factories can be create. The most * specific types must appear first in this list. */ private static final Class/* extends IdentifiedObject>*/[] TYPES = { CoordinateOperation .class, OperationMethod .class, ParameterDescriptor .class, ProjectedCRS .class, GeographicCRS .class, GeocentricCRS .class, ImageCRS .class, DerivedCRS .class, VerticalCRS .class, TemporalCRS .class, EngineeringCRS .class, CompoundCRS .class, CoordinateReferenceSystem.class, CoordinateSystemAxis .class, CartesianCS .class, EllipsoidalCS .class, SphericalCS .class, CylindricalCS .class, PolarCS .class, VerticalCS .class, TimeCS .class, CoordinateSystem .class, PrimeMeridian .class, Ellipsoid .class, GeodeticDatum .class, ImageDatum .class, VerticalDatum .class, TemporalDatum .class, EngineeringDatum .class, Datum .class, IdentifiedObject .class }; /** * Creates a new proxy. */ AuthorityFactoryProxy() { } /** * Returns a proxy instance which will create objects of the specified type using the * specified factory. * * @param factory The factory to use for object creations. * @param type The type of objects to be created by the proxy. */ public static AuthorityFactoryProxy getInstance(final AuthorityFactory factory, Class/* extends IdentifiedObject>*/ type) { AbstractAuthorityFactory.ensureNonNull("type", type); AbstractAuthorityFactory.ensureNonNull("factory", factory); type = getType(type); /* * Checks for some special cases for which a fast implementation is available. */ if (factory instanceof CRSAuthorityFactory) { final CRSAuthorityFactory crsFactory = (CRSAuthorityFactory) factory; if (type.equals( ProjectedCRS.class)) return new Projected(crsFactory); if (type.equals( GeographicCRS.class)) return new Geographic(crsFactory); if (type.equals(CoordinateReferenceSystem.class)) return new CRS(crsFactory); } /* * Fallback on the generic case using reflection. */ return new Default(factory, type); } /** * Returns the main GeoAPI interface implemented by an object of the specified type. * The {@code type} argument is often some implementation class like * {@link org.geotools.referencing.crs.DefaultProjectedCRS}. This method returns * the most specific GeoAPI interface implemented by {@code type}, providing that * a corresponding {@code create} method exists in some {@linkplain AuthorityFactory * authority factory}. For example this method may returns {@link ProjectedCRS} or * {@link DerivedCRS} class, but not {@link GeneralDerivedCRS}. * * @param type The implementation class. * @return The most specific GeoAPI interface implemented by {@code type}. * @throws IllegalArgumentException if the type doesn't implement a valid interface. */ public static Class/* extends IdentifiedObject>*/ getType( final Class/* extends IdentifiedObject>*/ type) throws IllegalArgumentException { for (int i=0; i* AuthorityFactory factory = ...; * AuthorityFactoryProxyproxy = * AuthorityFactoryProxy.getInstance(GeographicCRS.class, factory); * * String code = ...; * // Invokes CRSAuthorityFactory.createGeographicCRS(code); * GeographicCRS crs = proxy.create(code); *