0001: /*
0002: * GeoTools - OpenSource mapping toolkit
0003: * http://geotools.org
0004: * (C) 2005-2006, GeoTools Project Managment Committee (PMC)
0005: * (C) 2005, Institut de Recherche pour le Développement
0006: *
0007: * This library is free software; you can redistribute it and/or
0008: * modify it under the terms of the GNU Lesser General Public
0009: * License as published by the Free Software Foundation;
0010: * version 2.1 of the License.
0011: *
0012: * This library is distributed in the hope that it will be useful,
0013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
0014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0015: * Lesser General Public License for more details.
0016: */
0017: package org.geotools.referencing.factory;
0018:
0019: // J2SE dependencies
0020: import java.util.Set;
0021: import java.util.Map;
0022: import java.util.List;
0023: import java.util.ArrayList;
0024: import java.util.Collection;
0025: import java.util.Collections;
0026: import java.util.logging.Level;
0027: import java.util.logging.LogRecord;
0028: import javax.units.Unit;
0029:
0030: // OpenGIS dependencies
0031: import org.opengis.metadata.extent.Extent;
0032: import org.opengis.metadata.citation.Citation;
0033: import org.opengis.referencing.NoSuchAuthorityCodeException;
0034: import org.opengis.util.InternationalString;
0035: import org.opengis.parameter.ParameterDescriptor;
0036: import org.opengis.referencing.IdentifiedObject;
0037: import org.opengis.referencing.AuthorityFactory;
0038: import org.opengis.referencing.FactoryException;
0039: import org.opengis.referencing.cs.*;
0040: import org.opengis.referencing.crs.*;
0041: import org.opengis.referencing.datum.*;
0042: import org.opengis.referencing.operation.*;
0043:
0044: // Geotools dependencies
0045: import org.geotools.factory.Hints;
0046: import org.geotools.factory.Factory;
0047: import org.geotools.factory.AbstractFactory;
0048: import org.geotools.factory.OptionalFactory;
0049: import org.geotools.factory.FactoryRegistryException;
0050: import org.geotools.metadata.iso.citation.Citations;
0051: import org.geotools.referencing.CRS;
0052: import org.geotools.referencing.ReferencingFactoryFinder;
0053: import org.geotools.resources.i18n.Logging;
0054: import org.geotools.resources.i18n.LoggingKeys;
0055: import org.geotools.resources.i18n.ErrorKeys;
0056: import org.geotools.resources.i18n.Errors;
0057: import org.geotools.resources.Utilities;
0058:
0059: /**
0060: * An authority factory which delegates {@linkplain CoordinateReferenceSystem CRS},
0061: * {@linkplain CoordinateSystem CS} or {@linkplain Datum datum} objects creation to
0062: * some other factory implementations.
0063: * <p>
0064: * All constructors are protected because this class must be subclassed in order to determine
0065: * which of the {@link DatumAuthorityFactory}, {@link CSAuthorityFactory} and
0066: * {@link CRSAuthorityFactory} interfaces to implement.
0067: *
0068: * @since 2.2
0069: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/AuthorityFactoryAdapter.java $
0070: * @version $Id: AuthorityFactoryAdapter.java 26212 2007-07-12 02:34:18Z jgarnett $
0071: * @author Martin Desruisseaux
0072: */
0073: public class AuthorityFactoryAdapter extends AbstractAuthorityFactory
0074: implements OptionalFactory {
0075: /**
0076: * List of hint keys related to authority factories.
0077: */
0078: private static final Hints.Key[] TYPES = new Hints.Key[] {
0079: Hints.CRS_AUTHORITY_FACTORY, Hints.CS_AUTHORITY_FACTORY,
0080: Hints.DATUM_AUTHORITY_FACTORY,
0081: Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY };
0082:
0083: /**
0084: * The underlying {@linkplain Datum datum} authority factory,
0085: * or {@code null} if none.
0086: *
0087: * @deprecated Use {@link #getDatumAuthorityFactory} instead.
0088: * This field will become private in Geotools 2.5.
0089: */
0090: protected final DatumAuthorityFactory datumFactory;
0091:
0092: /**
0093: * The underlying {@linkplain CoordinateSystem coordinate system} authority factory,
0094: * or {@code null} if none.
0095: *
0096: * @deprecated Use {@link #getCSAuthorityFactory} instead.
0097: * This field will become private in Geotools 2.5.
0098: */
0099: protected final CSAuthorityFactory csFactory;
0100:
0101: /**
0102: * The underlying {@linkplain CoordinateReferenceSystem coordinate reference system}
0103: * authority factory, or {@code null} if none.
0104: *
0105: * @deprecated Use {@link #getCRSAuthorityFactory} instead.
0106: * This field will become private in Geotools 2.5.
0107: */
0108: protected final CRSAuthorityFactory crsFactory;
0109:
0110: /**
0111: * The underlying {@linkplain CoordinateOperation coordinate operation} authority factory,
0112: * or {@code null} if none.
0113: *
0114: * @deprecated Use {@link #getCoordinateOperationAuthorityFactory} instead.
0115: * This field will become private in Geotools 2.5.
0116: */
0117: protected final CoordinateOperationAuthorityFactory operationFactory;
0118:
0119: /**
0120: * A set of low-level factories to be used if none were found in {@link #datumFactory},
0121: * {@link #csFactory}, {@link #crsFactory} or {@link #operationFactory}. Will be created
0122: * only when first needed.
0123: *
0124: * @see #getFactoryContainer
0125: */
0126: private transient ReferencingFactoryContainer factories;
0127:
0128: /**
0129: * Creates a wrapper around no factory. This constructor should never be used except by
0130: * subclasses overriding the <code>get</code><var>Foo</var><code>AuthorityFactory</code>
0131: * methods.
0132: *
0133: * @param priority The priority for this factory, as a number between
0134: * {@link #MINIMUM_PRIORITY MINIMUM_PRIORITY} and
0135: * {@link #MAXIMUM_PRIORITY MAXIMUM_PRIORITY} inclusive.
0136: */
0137: AuthorityFactoryAdapter(final int priority) {
0138: super (priority);
0139: datumFactory = null;
0140: csFactory = null;
0141: crsFactory = null;
0142: operationFactory = null;
0143: }
0144:
0145: /**
0146: * Creates a wrapper around the specified factory. The {@link #priority priority} field
0147: * will be set to the same value than the specified factory. Subclasses should override
0148: * the {@link #getPriority() getPriority()} method if they want to set a higher or lower
0149: * priority for this instance.
0150: *
0151: * @param factory The factory to wrap.
0152: */
0153: protected AuthorityFactoryAdapter(final AuthorityFactory factory) {
0154: this (factory, null);
0155: }
0156:
0157: /**
0158: * For {@link FallbackAuthorityFactory} constructor only.
0159: */
0160: AuthorityFactoryAdapter(final AuthorityFactory factory,
0161: final AuthorityFactory fallback) {
0162: this (
0163: (factory instanceof CRSAuthorityFactory) ? (CRSAuthorityFactory) factory
0164: : (fallback instanceof CRSAuthorityFactory) ? (CRSAuthorityFactory) fallback
0165: : null,
0166: (factory instanceof CSAuthorityFactory) ? (CSAuthorityFactory) factory
0167: : (fallback instanceof CSAuthorityFactory) ? (CSAuthorityFactory) fallback
0168: : null,
0169: (factory instanceof DatumAuthorityFactory) ? (DatumAuthorityFactory) factory
0170: : (fallback instanceof DatumAuthorityFactory) ? (DatumAuthorityFactory) fallback
0171: : null,
0172: (factory instanceof CoordinateOperationAuthorityFactory) ? (CoordinateOperationAuthorityFactory) factory
0173: : (fallback instanceof CoordinateOperationAuthorityFactory) ? (CoordinateOperationAuthorityFactory) fallback
0174: : null);
0175: }
0176:
0177: /**
0178: * Creates a wrapper around the specified factories. The {@link #priority priority} field will
0179: * be set to the highest priority found in the specified factories. Subclasses should override
0180: * the {@link #getPriority() getPriority()} method if they want to set a higher or lower
0181: * priority for this instance.
0182: *
0183: * @param crsFactory The {@linkplain CoordinateReferenceSystem coordinate reference system}
0184: * authority factory, or {@code null}.
0185: * @param csFactory The {@linkplain CoordinateSystem coordinate system} authority factory,
0186: * or {@code null}.
0187: * @param datumFactory The {@linkplain Datum datum} authority factory, or {@code null}.
0188: * @param opFactory The {@linkplain CoordinateOperation coordinate operation} authority
0189: * factory, or {@code null}.
0190: */
0191: protected AuthorityFactoryAdapter(
0192: final CRSAuthorityFactory crsFactory,
0193: final CSAuthorityFactory csFactory,
0194: final DatumAuthorityFactory datumFactory,
0195: final CoordinateOperationAuthorityFactory opFactory) {
0196: super (Math.max(getPriority(datumFactory), Math.max(
0197: getPriority(csFactory), Math
0198: .max(getPriority(crsFactory),
0199: getPriority(opFactory)))));
0200:
0201: if (this instanceof CRSAuthorityFactory) {
0202: ensureNonNull("crsFactory", crsFactory);
0203: }
0204: if (this instanceof CSAuthorityFactory) {
0205: ensureNonNull("csFactory", csFactory);
0206: }
0207: if (this instanceof DatumAuthorityFactory) {
0208: ensureNonNull("datumFactory", datumFactory);
0209: }
0210: if (this instanceof CoordinateOperationAuthorityFactory) {
0211: ensureNonNull("opFactory", opFactory);
0212: }
0213: store(Hints.DATUM_AUTHORITY_FACTORY,
0214: this .datumFactory = datumFactory);
0215: store(Hints.CS_AUTHORITY_FACTORY, this .csFactory = csFactory);
0216: store(Hints.CRS_AUTHORITY_FACTORY, this .crsFactory = crsFactory);
0217: store(Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY,
0218: this .operationFactory = opFactory);
0219: }
0220:
0221: /**
0222: * Returns the priority of the specified factory, or {@link #NORMAL_PRIORITY} if unknown.
0223: */
0224: private static int getPriority(final AuthorityFactory factory) {
0225: return (factory instanceof AbstractFactory) ? ((AbstractFactory) factory)
0226: .getPriority()
0227: : NORMAL_PRIORITY;
0228: }
0229:
0230: /**
0231: * Adds the specified factory to the set of hints, if non null.
0232: */
0233: private void store(final Hints.Key key,
0234: final AuthorityFactory factory) {
0235: if (factory != null) {
0236: if (hints.put(key, factory) != null) {
0237: // Should never happen since 'hints' should be initially empty.
0238: throw new AssertionError(key);
0239: }
0240: }
0241: }
0242:
0243: /**
0244: * Creates a wrappers around the default factories for the specified authority.
0245: * The factories are fetched using {@link ReferencingFactoryFinder}.
0246: *
0247: * @param authority The authority to wraps (example: {@code "EPSG"}). If {@code null},
0248: * then all authority factories must be explicitly specified in the
0249: * set of hints.
0250: * @param userHints An optional set of hints, or {@code null} if none.
0251: * @throws FactoryRegistryException if at least one factory can not be obtained.
0252: *
0253: * @since 2.4
0254: */
0255: protected AuthorityFactoryAdapter(final String authority,
0256: final Hints userHints) throws FactoryRegistryException {
0257: this (
0258: ReferencingFactoryFinder.getCRSAuthorityFactory(
0259: authority, trim(userHints,
0260: Hints.CRS_AUTHORITY_FACTORY)),
0261: ReferencingFactoryFinder.getCSAuthorityFactory(
0262: authority, trim(userHints,
0263: Hints.CS_AUTHORITY_FACTORY)),
0264: ReferencingFactoryFinder.getDatumAuthorityFactory(
0265: authority, trim(userHints,
0266: Hints.DATUM_AUTHORITY_FACTORY)),
0267: ReferencingFactoryFinder
0268: .getCoordinateOperationAuthorityFactory(
0269: authority,
0270: trim(
0271: userHints,
0272: Hints.COORDINATE_OPERATION_AUTHORITY_FACTORY)));
0273: }
0274:
0275: /**
0276: * Removes every {@code *_AUTHORITY_FACTORY} hints except the specified one. The removal,
0277: * if needed, is performed in a copy of the supplied hints in order to keep user's map
0278: * unmodified.
0279: * <p>
0280: * This removal is performed because {@code *_AUTHORITY_FACTORY} hints are typically supplied
0281: * to the above constructor in order to initialize the {@link #crsFactory}, {@link #csFactory},
0282: * <cite>etc.</cite> fields. But because the same map of hints is used for every call to {@code
0283: * ReferencingFactoryFinder.getFooAuthorityFactory(...)}, if we don't perform this removal, then
0284: * the {@code CRS_AUTHORITY_FACTORY} hint is taken in account for fetching other factories like
0285: * {@link CSAuthorityFactory}. We may think that it is not a problem since CS authority factory
0286: * should not care about {@code CRS_AUTHORITY_FACTORY} hint. But... our EPSG authority factory
0287: * implements both {@link CRSAuthorityFactory} and {@link CSAuthorityFactory} interfaces, so
0288: * our {@link CSAuthorityFactory} implementation do have CRS-related hints.
0289: * <p>
0290: * Conclusion: if we do not remove those hints, it typically leads to failure to find
0291: * a CS authority factory using this specific CRS authority factory. We may argue that
0292: * this is a Geotools design problem. Maybe... this is not a trivial issue. So we are
0293: * better to not document that in public API for now.
0294: *
0295: * @param userHints The user hints to trim. This map will never be modified.
0296: * @param keep The hint to <strong>not</strong> remove.
0297: * @return A copy of {@code userHints} without the authority hints, or {@code userHints}
0298: * if no change were required.
0299: */
0300: private static Hints trim(final Hints userHints,
0301: final Hints.Key keep) {
0302: Hints reduced = userHints;
0303: if (userHints != null) {
0304: for (int i = 0; i < TYPES.length; i++) {
0305: final Hints.Key key = TYPES[i];
0306: if (!keep.equals(key)) {
0307: if (reduced == userHints) {
0308: if (!userHints.containsKey(key)) {
0309: continue;
0310: }
0311: // Copies the map only if we need to modify it.
0312: reduced = new Hints(userHints);
0313: }
0314: reduced.remove(key);
0315: }
0316: }
0317: }
0318: return reduced;
0319: }
0320:
0321: /**
0322: * Returns the {@linkplain #hints hints} extented will all hints specified in dependencies.
0323: */
0324: private Hints hints() {
0325: final Hints extended = new Hints(hints);
0326: addAll(operationFactory, extended);
0327: addAll(datumFactory, extended);
0328: addAll(csFactory, extended);
0329: addAll(crsFactory, extended);
0330: extended.putAll(hints); // Gives precedence to the hints from this class.
0331: return extended;
0332: }
0333:
0334: /**
0335: * Adds all hints from the specified factory into the specified set of hints.
0336: */
0337: private static void addAll(final AuthorityFactory factory,
0338: final Hints hints) {
0339: if (factory instanceof Factory) {
0340: hints.putAll(((Factory) factory).getImplementationHints());
0341: }
0342: }
0343:
0344: /**
0345: * Returns the direct dependencies. The returned list contains the backing store specified
0346: * at construction time, or the exception if the backing store can't be obtained.
0347: */
0348: //@Override
0349: Collection/*<?>*/dependencies() {
0350: final List/*<?>*/dep = new ArrayList(4);
0351: Object factory;
0352: try {
0353: factory = getAuthorityFactory(null);
0354: } catch (FactoryException e) {
0355: factory = e;
0356: }
0357: dep.add(factory);
0358: return dep;
0359: }
0360:
0361: /**
0362: * If this factory is a wrapper for the specified factory that do not add any additional
0363: * {@linkplain #getAuthorityCodes authority codes}, returns {@code true}. This method is
0364: * for {@link FallbackAuthorityFactory} internal use only and should not be public. We
0365: * expect only a simple check, so we don't invoke the {@code getFooAuthorityFactory(...)}
0366: * methods.
0367: */
0368: //@Override
0369: boolean sameAuthorityCodes(final AuthorityFactory factory) {
0370: if (!isCodeMethodOverriden()) {
0371: /*
0372: * Tests wrapped factories only if the 'toBackingFactoryCode(String)' method is not
0373: * overwritten, otherwise we can't assume that the authority codes are the same. The
0374: * impact on the main subclasses are usually as below:
0375: *
0376: * URN_AuthorityFactory - excluded
0377: * HTTP_AuthorityFactory - excluded
0378: * OrderedAxisAuthorityFactory - make the test below
0379: * FallbackAuthorityFactory - make the test below
0380: *
0381: * Note: in the particular case of FallbackAuthorityFactory, we test the
0382: * primary factory only, not the fallback. This behavior matches the
0383: * FallbackAuthorityFactory.create(boolean,int,Iterator) need, which
0384: * will process this case in a special way.
0385: */
0386: if (sameAuthorityCodes(crsFactory, factory)
0387: && sameAuthorityCodes(csFactory, factory)
0388: && sameAuthorityCodes(datumFactory, factory)
0389: && sameAuthorityCodes(operationFactory, factory)) {
0390: return true;
0391: }
0392: }
0393: return super .sameAuthorityCodes(factory);
0394: }
0395:
0396: /**
0397: * Helper methods for {@link #sameAuthorityCodes(AuthorityFactory)} and
0398: * {@link FallbackAuthorityFactory#create(boolean,int,Iterator)} implementations. If there is no
0399: * backing store, returns {@code true} in order to take in account only the backing stores that
0400: * are assigned. This behavior match the need of the above-cited implementations.
0401: */
0402: static boolean sameAuthorityCodes(
0403: final AuthorityFactory backingStore,
0404: final AuthorityFactory factory) {
0405: if (backingStore instanceof AbstractAuthorityFactory) {
0406: if (((AbstractAuthorityFactory) backingStore)
0407: .sameAuthorityCodes(factory)) {
0408: return true;
0409: }
0410: }
0411: return (factory == backingStore) || (backingStore == null);
0412: }
0413:
0414: /**
0415: * Returns {@code true} if this factory is ready for use. This default implementation
0416: * checks the availability of CRS, CS, datum and operation authority factories specified
0417: * at construction time.
0418: */
0419: public boolean isAvailable() {
0420: return isAvailable(crsFactory) && isAvailable(csFactory)
0421: && isAvailable(datumFactory)
0422: && isAvailable(operationFactory);
0423: }
0424:
0425: /**
0426: * Checks the availability of the specified factory.
0427: */
0428: private static boolean isAvailable(final AuthorityFactory factory) {
0429: return !(factory instanceof OptionalFactory)
0430: || ((OptionalFactory) factory).isAvailable();
0431: }
0432:
0433: /**
0434: * Replaces the specified unit, if applicable.
0435: * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0436: */
0437: Unit replace(Unit units) throws FactoryException {
0438: return units;
0439: }
0440:
0441: /**
0442: * Replaces (if needed) the specified axis by a new one.
0443: * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0444: */
0445: CoordinateSystemAxis replace(CoordinateSystemAxis axis)
0446: throws FactoryException {
0447: return axis;
0448: }
0449:
0450: /**
0451: * Replaces (if needed) the specified coordinate system by a new one.
0452: * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0453: */
0454: CoordinateSystem replace(CoordinateSystem cs)
0455: throws FactoryException {
0456: return cs;
0457: }
0458:
0459: /**
0460: * Replaces (if needed) the specified datum by a new one.
0461: * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0462: */
0463: Datum replace(Datum datum) throws FactoryException {
0464: return datum;
0465: }
0466:
0467: /**
0468: * Replaces (if needed) the specified coordinate reference system.
0469: * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0470: */
0471: CoordinateReferenceSystem replace(CoordinateReferenceSystem crs)
0472: throws FactoryException {
0473: return crs;
0474: }
0475:
0476: /**
0477: * Replaces (if needed) the specified coordinate operation.
0478: * To be overridden with {@code protected} access by {@link TransformedAuthorityFactory}.
0479: */
0480: CoordinateOperation replace(CoordinateOperation operation)
0481: throws FactoryException {
0482: return operation;
0483: }
0484:
0485: /**
0486: * Delegates the work to an appropriate {@code replace} method for the given object.
0487: */
0488: private IdentifiedObject replaceObject(final IdentifiedObject object)
0489: throws FactoryException {
0490: if (object instanceof CoordinateReferenceSystem) {
0491: return replace((CoordinateReferenceSystem) object);
0492: }
0493: if (object instanceof CoordinateSystem) {
0494: return replace((CoordinateSystem) object);
0495: }
0496: if (object instanceof CoordinateSystemAxis) {
0497: return replace((CoordinateSystemAxis) object);
0498: }
0499: if (object instanceof Datum) {
0500: return replace((Datum) object);
0501: }
0502: if (object instanceof CoordinateOperation) {
0503: return replace((CoordinateOperation) object);
0504: }
0505: return object;
0506: }
0507:
0508: /**
0509: * Returns one of the underlying factories as an instance of the GeoTools implementation. If
0510: * there is none of them, then returns {@code null} or throws an exception if {@code caller}
0511: * is not null.
0512: */
0513: private AbstractAuthorityFactory getGeotoolsFactory(
0514: final String caller, final String code)
0515: throws FactoryException {
0516: final AuthorityFactory candidate = getAuthorityFactory(code);
0517: if (candidate instanceof AbstractAuthorityFactory) {
0518: return (AbstractAuthorityFactory) candidate;
0519: }
0520: if (caller == null) {
0521: return null;
0522: }
0523: throw new FactoryException(Errors.format(
0524: ErrorKeys.GEOTOOLS_EXTENSION_REQUIRED_$1, caller));
0525: }
0526:
0527: /**
0528: * Returns a description of the underlying backing store, or {@code null} if unknow.
0529: *
0530: * @throws FactoryException if a failure occured while fetching the engine description.
0531: */
0532: public String getBackingStoreDescription() throws FactoryException {
0533: final AbstractAuthorityFactory factory = getGeotoolsFactory(
0534: null, null);
0535: return (factory != null) ? factory.getBackingStoreDescription()
0536: : null;
0537: }
0538:
0539: /**
0540: * Returns the vendor responsible for creating this factory implementation.
0541: */
0542: public Citation getVendor() {
0543: return getAuthorityFactory().getVendor();
0544: }
0545:
0546: /**
0547: * Returns the organization or party responsible for definition and maintenance of the
0548: * database.
0549: */
0550: public Citation getAuthority() {
0551: return getAuthorityFactory().getAuthority();
0552: }
0553:
0554: /**
0555: * Returns the set of authority code for the specified type.
0556: *
0557: * @todo We should returns the union of authority codes from all underlying factories.
0558: */
0559: public Set/*<String>*/getAuthorityCodes(final Class type)
0560: throws FactoryException {
0561: return getAuthorityFactory(null).getAuthorityCodes(type);
0562: }
0563:
0564: /**
0565: * Returns a description for the object identified by the specified code.
0566: */
0567: public InternationalString getDescriptionText(final String code)
0568: throws FactoryException {
0569: return getAuthorityFactory(code).getDescriptionText(
0570: toBackingFactoryCode(code));
0571: }
0572:
0573: /**
0574: * Returns an arbitrary object from a code.
0575: *
0576: * @see #createCoordinateReferenceSystem
0577: * @see #createDatum
0578: * @see #createEllipsoid
0579: * @see #createUnit
0580: */
0581: public IdentifiedObject createObject(final String code)
0582: throws FactoryException {
0583: return replaceObject(getAuthorityFactory(code).createObject(
0584: toBackingFactoryCode(code)));
0585: }
0586:
0587: /**
0588: * Returns an arbitrary {@linkplain Datum datum} from a code.
0589: *
0590: * @see #createGeodeticDatum
0591: * @see #createVerticalDatum
0592: * @see #createTemporalDatum
0593: */
0594: public Datum createDatum(final String code) throws FactoryException {
0595: return replace(getDatumAuthorityFactory(code).createDatum(
0596: toBackingFactoryCode(code)));
0597: }
0598:
0599: /**
0600: * Creates a {@linkplain EngineeringDatum engineering datum} from a code.
0601: *
0602: * @see #createEngineeringCRS
0603: */
0604: public EngineeringDatum createEngineeringDatum(final String code)
0605: throws FactoryException {
0606: return (EngineeringDatum) replace(getDatumAuthorityFactory(code)
0607: .createEngineeringDatum(toBackingFactoryCode(code)));
0608: }
0609:
0610: /**
0611: * Creates a {@linkplain ImageDatum image datum} from a code.
0612: *
0613: * @see #createImageCRS
0614: */
0615: public ImageDatum createImageDatum(final String code)
0616: throws FactoryException {
0617: return (ImageDatum) replace(getDatumAuthorityFactory(code)
0618: .createImageDatum(toBackingFactoryCode(code)));
0619: }
0620:
0621: /**
0622: * Creates a {@linkplain VerticalDatum vertical datum} from a code.
0623: *
0624: * @see #createVerticalCRS
0625: */
0626: public VerticalDatum createVerticalDatum(final String code)
0627: throws FactoryException {
0628: return (VerticalDatum) replace(getDatumAuthorityFactory(code)
0629: .createVerticalDatum(toBackingFactoryCode(code)));
0630: }
0631:
0632: /**
0633: * Creates a {@linkplain TemporalDatum temporal datum} from a code.
0634: *
0635: * @see #createTemporalCRS
0636: */
0637: public TemporalDatum createTemporalDatum(final String code)
0638: throws FactoryException {
0639: return (TemporalDatum) replace(getDatumAuthorityFactory(code)
0640: .createTemporalDatum(toBackingFactoryCode(code)));
0641: }
0642:
0643: /**
0644: * Returns a {@linkplain GeodeticDatum geodetic datum} from a code.
0645: *
0646: * @see #createEllipsoid
0647: * @see #createPrimeMeridian
0648: * @see #createGeographicCRS
0649: * @see #createProjectedCRS
0650: */
0651: public GeodeticDatum createGeodeticDatum(final String code)
0652: throws FactoryException {
0653: return (GeodeticDatum) replace(getDatumAuthorityFactory(code)
0654: .createGeodeticDatum(toBackingFactoryCode(code)));
0655: }
0656:
0657: /**
0658: * Returns an {@linkplain Ellipsoid ellipsoid} from a code.
0659: *
0660: * @see #createGeodeticDatum
0661: */
0662: public Ellipsoid createEllipsoid(final String code)
0663: throws FactoryException {
0664: return getDatumAuthorityFactory(code).createEllipsoid(
0665: toBackingFactoryCode(code));
0666: }
0667:
0668: /**
0669: * Returns a {@linkplain PrimeMeridian prime meridian} from a code.
0670: *
0671: * @see #createGeodeticDatum
0672: */
0673: public PrimeMeridian createPrimeMeridian(final String code)
0674: throws FactoryException {
0675: return getDatumAuthorityFactory(code).createPrimeMeridian(
0676: toBackingFactoryCode(code));
0677: }
0678:
0679: /**
0680: * Returns a {@linkplain Extent extent} (usually an area of validity) from a code.
0681: */
0682: public Extent createExtent(final String code)
0683: throws FactoryException {
0684: return getGeotoolsFactory("createExtent", code).createExtent(
0685: toBackingFactoryCode(code));
0686: }
0687:
0688: /**
0689: * Returns an arbitrary {@linkplain CoordinateSystem coordinate system} from a code.
0690: */
0691: public CoordinateSystem createCoordinateSystem(final String code)
0692: throws FactoryException {
0693: return replace(getCSAuthorityFactory(code)
0694: .createCoordinateSystem(toBackingFactoryCode(code)));
0695: }
0696:
0697: /**
0698: * Creates a cartesian coordinate system from a code.
0699: */
0700: public CartesianCS createCartesianCS(final String code)
0701: throws FactoryException {
0702: return (CartesianCS) replace(getCSAuthorityFactory(code)
0703: .createCartesianCS(toBackingFactoryCode(code)));
0704: }
0705:
0706: /**
0707: * Creates a polar coordinate system from a code.
0708: */
0709: public PolarCS createPolarCS(final String code)
0710: throws FactoryException {
0711: return (PolarCS) replace(getCSAuthorityFactory(code)
0712: .createPolarCS(toBackingFactoryCode(code)));
0713: }
0714:
0715: /**
0716: * Creates a cylindrical coordinate system from a code.
0717: */
0718: public CylindricalCS createCylindricalCS(final String code)
0719: throws FactoryException {
0720: return (CylindricalCS) replace(getCSAuthorityFactory(code)
0721: .createCylindricalCS(toBackingFactoryCode(code)));
0722: }
0723:
0724: /**
0725: * Creates a spherical coordinate system from a code.
0726: */
0727: public SphericalCS createSphericalCS(final String code)
0728: throws FactoryException {
0729: return (SphericalCS) replace(getCSAuthorityFactory(code)
0730: .createSphericalCS(toBackingFactoryCode(code)));
0731: }
0732:
0733: /**
0734: * Creates an ellipsoidal coordinate system from a code.
0735: */
0736: public EllipsoidalCS createEllipsoidalCS(final String code)
0737: throws FactoryException {
0738: return (EllipsoidalCS) replace(getCSAuthorityFactory(code)
0739: .createEllipsoidalCS(toBackingFactoryCode(code)));
0740: }
0741:
0742: /**
0743: * Creates a vertical coordinate system from a code.
0744: */
0745: public VerticalCS createVerticalCS(final String code)
0746: throws FactoryException {
0747: return (VerticalCS) replace(getCSAuthorityFactory(code)
0748: .createVerticalCS(toBackingFactoryCode(code)));
0749: }
0750:
0751: /**
0752: * Creates a temporal coordinate system from a code.
0753: */
0754: public TimeCS createTimeCS(final String code)
0755: throws FactoryException {
0756: return (TimeCS) replace(getCSAuthorityFactory(code)
0757: .createTimeCS(toBackingFactoryCode(code)));
0758: }
0759:
0760: /**
0761: * Returns a {@linkplain CoordinateSystemAxis coordinate system axis} from a code.
0762: */
0763: public CoordinateSystemAxis createCoordinateSystemAxis(
0764: final String code) throws FactoryException {
0765: return replace(getCSAuthorityFactory(code)
0766: .createCoordinateSystemAxis(toBackingFactoryCode(code)));
0767: }
0768:
0769: /**
0770: * Returns an {@linkplain Unit unit} from a code.
0771: */
0772: public Unit createUnit(final String code) throws FactoryException {
0773: return replace(getCSAuthorityFactory(code).createUnit(
0774: toBackingFactoryCode(code)));
0775: }
0776:
0777: /**
0778: * Returns an arbitrary {@linkplain CoordinateReferenceSystem coordinate reference system}
0779: * from a code.
0780: *
0781: * @see #createGeographicCRS
0782: * @see #createProjectedCRS
0783: * @see #createVerticalCRS
0784: * @see #createTemporalCRS
0785: * @see #createCompoundCRS
0786: */
0787: public CoordinateReferenceSystem createCoordinateReferenceSystem(
0788: final String code) throws FactoryException {
0789: return replace(getCRSAuthorityFactory(code)
0790: .createCoordinateReferenceSystem(
0791: toBackingFactoryCode(code)));
0792: }
0793:
0794: /**
0795: * Creates a 3D coordinate reference system from a code.
0796: */
0797: public CompoundCRS createCompoundCRS(final String code)
0798: throws FactoryException {
0799: return (CompoundCRS) replace(getCRSAuthorityFactory(code)
0800: .createCompoundCRS(toBackingFactoryCode(code)));
0801: }
0802:
0803: /**
0804: * Creates a derived coordinate reference system from a code.
0805: */
0806: public DerivedCRS createDerivedCRS(final String code)
0807: throws FactoryException {
0808: return (DerivedCRS) replace(getCRSAuthorityFactory(code)
0809: .createDerivedCRS(toBackingFactoryCode(code)));
0810: }
0811:
0812: /**
0813: * Creates a {@linkplain EngineeringCRS engineering coordinate reference system} from a code.
0814: */
0815: public EngineeringCRS createEngineeringCRS(final String code)
0816: throws FactoryException {
0817: return (EngineeringCRS) replace(getCRSAuthorityFactory(code)
0818: .createEngineeringCRS(toBackingFactoryCode(code)));
0819: }
0820:
0821: /**
0822: * Returns a {@linkplain GeographicCRS geographic coordinate reference system} from a code.
0823: */
0824: public GeographicCRS createGeographicCRS(final String code)
0825: throws FactoryException {
0826: return (GeographicCRS) replace(getCRSAuthorityFactory(code)
0827: .createGeographicCRS(toBackingFactoryCode(code)));
0828: }
0829:
0830: /**
0831: * Returns a {@linkplain GeocentricCRS geocentric coordinate reference system} from a code.
0832: */
0833: public GeocentricCRS createGeocentricCRS(final String code)
0834: throws FactoryException {
0835: return (GeocentricCRS) replace(getCRSAuthorityFactory(code)
0836: .createGeocentricCRS(toBackingFactoryCode(code)));
0837: }
0838:
0839: /**
0840: * Creates a {@linkplain ImageCRS image coordinate reference system} from a code.
0841: */
0842: public ImageCRS createImageCRS(final String code)
0843: throws FactoryException {
0844: return (ImageCRS) replace(getCRSAuthorityFactory(code)
0845: .createImageCRS(toBackingFactoryCode(code)));
0846: }
0847:
0848: /**
0849: * Returns a {@linkplain ProjectedCRS projected coordinate reference system} from a code.
0850: */
0851: public ProjectedCRS createProjectedCRS(final String code)
0852: throws FactoryException {
0853: return (ProjectedCRS) replace(getCRSAuthorityFactory(code)
0854: .createProjectedCRS(toBackingFactoryCode(code)));
0855: }
0856:
0857: /**
0858: * Creates a {@linkplain TemporalCRS temporal coordinate reference system} from a code.
0859: */
0860: public TemporalCRS createTemporalCRS(final String code)
0861: throws FactoryException {
0862: return (TemporalCRS) replace(getCRSAuthorityFactory(code)
0863: .createTemporalCRS(toBackingFactoryCode(code)));
0864: }
0865:
0866: /**
0867: * Creates a {@linkplain VerticalCRS vertical coordinate reference system} from a code.
0868: */
0869: public VerticalCRS createVerticalCRS(final String code)
0870: throws FactoryException {
0871: return (VerticalCRS) replace(getCRSAuthorityFactory(code)
0872: .createVerticalCRS(toBackingFactoryCode(code)));
0873: }
0874:
0875: /**
0876: * Creates a parameter descriptor from a code.
0877: */
0878: public ParameterDescriptor createParameterDescriptor(
0879: final String code) throws FactoryException {
0880: return getGeotoolsFactory("createParameterDescriptor", code)
0881: .createParameterDescriptor(toBackingFactoryCode(code));
0882: }
0883:
0884: /**
0885: * Creates an operation method from a code.
0886: */
0887: public OperationMethod createOperationMethod(final String code)
0888: throws FactoryException {
0889: return getGeotoolsFactory("createOperationMethod", code)
0890: .createOperationMethod(toBackingFactoryCode(code));
0891: }
0892:
0893: /**
0894: * Creates an operation from a single operation code.
0895: */
0896: public CoordinateOperation createCoordinateOperation(
0897: final String code) throws FactoryException {
0898: return replace(getCoordinateOperationAuthorityFactory(code)
0899: .createCoordinateOperation(toBackingFactoryCode(code)));
0900: }
0901:
0902: /**
0903: * Creates an operation from coordinate reference system codes.
0904: */
0905: public Set/*<CoordinateOperation>*/createFromCoordinateReferenceSystemCodes(
0906: final String sourceCode, final String targetCode)
0907: throws FactoryException {
0908: final CoordinateOperationAuthorityFactory factory, check;
0909: factory = getCoordinateOperationAuthorityFactory(sourceCode);
0910: check = getCoordinateOperationAuthorityFactory(targetCode);
0911: if (factory != check) {
0912: /*
0913: * No coordinate operation because of mismatched factories. This is not
0914: * illegal - the result is an empty set - but it is worth to notify the
0915: * user since this case has some chances to be an user error.
0916: */
0917: final LogRecord record = Logging
0918: .format(
0919: Level.WARNING,
0920: LoggingKeys.MISMATCHED_COORDINATE_OPERATION_FACTORIES_$2,
0921: sourceCode, targetCode);
0922: record
0923: .setSourceMethodName("createFromCoordinateReferenceSystemCodes");
0924: record.setSourceClassName(AuthorityFactoryAdapter.class
0925: .getName());
0926: LOGGER.log(record);
0927: return Collections.EMPTY_SET;
0928: }
0929: return factory.createFromCoordinateReferenceSystemCodes(
0930: toBackingFactoryCode(sourceCode),
0931: toBackingFactoryCode(targetCode));
0932: }
0933:
0934: /**
0935: * Returns a finder which can be used for looking up unidentified objects.
0936: * The default implementation delegates the lookups to the underlying factory.
0937: *
0938: * @since 2.4
0939: */
0940: //@Override
0941: public IdentifiedObjectFinder getIdentifiedObjectFinder(
0942: final Class/*<? extends IdentifiedObject>*/type)
0943: throws FactoryException {
0944: return new Finder(type);
0945: }
0946:
0947: /**
0948: * A {@link IdentifiedObjectFinder} which tests
0949: * {@linkplain AuthorityFactoryAdapter#replaceObject modified objects}
0950: * in addition of original object.
0951: */
0952: class Finder extends IdentifiedObjectFinder.Adapter {
0953: /**
0954: * Creates a finder for the underlying backing store.
0955: */
0956: protected Finder(
0957: final Class/*<? extends IdentifiedObject>*/type)
0958: throws FactoryException {
0959: super (getGeotoolsFactory("getIdentifiedObjectFinder", null)
0960: .getIdentifiedObjectFinder(type));
0961: }
0962:
0963: /**
0964: * Returns {@code candidate}, or an object derived from {@code candidate}, if it is
0965: * {@linkplain CRS#equalsIgnoreMetadata equals ignoring metadata} to the specified
0966: * model. Otherwise returns {@code null}.
0967: *
0968: * @throws FactoryException if an error occured while creating a derived object.
0969: */
0970: //@Override
0971: protected IdentifiedObject deriveEquivalent(
0972: final IdentifiedObject candidate,
0973: final IdentifiedObject model) throws FactoryException {
0974: final IdentifiedObject modified = replaceObject(candidate);
0975: if (modified != candidate) {
0976: if (CRS.equalsIgnoreMetadata(modified, model)) {
0977: return modified;
0978: }
0979: }
0980: return super .deriveEquivalent(candidate, model);
0981: }
0982: }
0983:
0984: /**
0985: * Creates an exception for a missing factory. We actually returns an instance of
0986: * {@link NoSuchAuthorityCodeException} because this kind of exception is treated
0987: * especially by {@link FallbackAuthorityFactory}.
0988: */
0989: private FactoryException missingFactory(final Class category,
0990: final String code) {
0991: return new NoSuchAuthorityCodeException(Errors.format(
0992: ErrorKeys.FACTORY_NOT_FOUND_$1, Utilities
0993: .getShortName(category)), Citations
0994: .getIdentifier(getAuthority()), trimAuthority(code));
0995: }
0996:
0997: /**
0998: * For internal use by {@link #getAuthority} and {@link #getVendor} only. Its only purpose
0999: * is to catch the {@link FactoryException} for methods that don't allow it. The protected
1000: * method should be used instead when this exception is allowed.
1001: */
1002: private AuthorityFactory getAuthorityFactory() {
1003: try {
1004: return getAuthorityFactory(null);
1005: } catch (FactoryException cause) {
1006: IllegalStateException e = new IllegalStateException(Errors
1007: .format(ErrorKeys.UNDEFINED_PROPERTY));
1008: e.initCause(cause); // TODO: inline when we will be allowed to compile for J2SE 1.5.
1009: throw e;
1010: }
1011: }
1012:
1013: /**
1014: * Returns an authority factory of the specified type. This method delegates to:
1015: * <ul>
1016: * <li>{@link #getCRSAuthorityFactory} if {@code type} is
1017: * {@code CRSAuthorityFactory.class};</li>
1018: * <li>{@link #getCSAuthorityFactory} if {@code type} is
1019: * {@code CSAuthorityFactory.class};</li>
1020: * <li>{@link #getDatumAuthorityFactory} if {@code type} is
1021: * {@code DatumAuthorityFactory.class};</li>
1022: * <li>{@link #CoordinateOperationAuthorityFactory} if {@code type} is
1023: * {@code CoordinateOperationAuthorityFactory.class};</li>
1024: * </ul>
1025: *
1026: * @throws IllegalArgumentException if the specified {@code type} is invalid.
1027: * @throws FactoryException if no suitable factory were found.
1028: */
1029: AuthorityFactory getAuthorityFactory(
1030: final Class/*<T extends AuthorityFactory>*/type,
1031: final String code) throws FactoryException {
1032: if (CRSAuthorityFactory.class.equals(type)) {
1033: return getCRSAuthorityFactory(code);
1034: }
1035: if (CSAuthorityFactory.class.equals(type)) {
1036: return getCSAuthorityFactory(code);
1037: }
1038: if (DatumAuthorityFactory.class.equals(type)) {
1039: return getDatumAuthorityFactory(code);
1040: }
1041: if (CoordinateOperationAuthorityFactory.class.equals(type)) {
1042: return getCoordinateOperationAuthorityFactory(code);
1043: }
1044: throw new IllegalArgumentException(Errors.format(
1045: ErrorKeys.ILLEGAL_ARGUMENT_$2, "type", type));
1046: }
1047:
1048: /**
1049: * Returns a generic object factory to use for the specified code. The default implementation
1050: * returns one of the factory specified at construction time. Subclasses can override
1051: * this method in order to select a different factory implementation depending on the
1052: * code value.
1053: * <p>
1054: * <strong>Note:</strong> The value of the {@code code} argument given to this
1055: * method may be {@code null} when a factory is needed for some global task,
1056: * like {@link #getAuthorityCodes} method execution.
1057: *
1058: * @param code The authority code given to this class. Note that the code to be given
1059: * to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1060: * @return A factory for the specified authority code (never {@code null}).
1061: * @throws FactoryException if no suitable factory were found.
1062: *
1063: * @since 2.4
1064: */
1065: protected AuthorityFactory getAuthorityFactory(final String code)
1066: throws FactoryException {
1067: if (crsFactory != null)
1068: return crsFactory;
1069: if (csFactory != null)
1070: return csFactory;
1071: if (datumFactory != null)
1072: return datumFactory;
1073: if (operationFactory != null)
1074: return operationFactory;
1075: throw missingFactory(AuthorityFactory.class, code);
1076: }
1077:
1078: /**
1079: * Returns the datum factory to use for the specified code. The default implementation
1080: * always returns the factory specified at construction time. Subclasses can override
1081: * this method in order to select a different factory implementation depending on the
1082: * code value.
1083: *
1084: * @param code The authority code given to this class. Note that the code to be given
1085: * to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1086: * @return A factory for the specified authority code (never {@code null}).
1087: * @throws FactoryException if no datum factory were specified at construction time.
1088: *
1089: * @since 2.4
1090: */
1091: protected DatumAuthorityFactory getDatumAuthorityFactory(
1092: final String code) throws FactoryException {
1093: if (datumFactory == null) {
1094: throw missingFactory(DatumAuthorityFactory.class, code);
1095: }
1096: return datumFactory;
1097: }
1098:
1099: /**
1100: * Returns the coordinate system factory to use for the specified code. The default
1101: * implementation always returns the factory specified at construction time. Subclasses
1102: * can override this method in order to select a different factory implementation
1103: * depending on the code value.
1104: *
1105: * @param code The authority code given to this class. Note that the code to be given
1106: * to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1107: * @return A factory for the specified authority code (never {@code null}).
1108: * @throws FactoryException if no coordinate system factory were specified at construction time.
1109: *
1110: * @since 2.4
1111: */
1112: protected CSAuthorityFactory getCSAuthorityFactory(final String code)
1113: throws FactoryException {
1114: if (csFactory == null) {
1115: throw missingFactory(CSAuthorityFactory.class, code);
1116: }
1117: return csFactory;
1118: }
1119:
1120: /**
1121: * Returns the coordinate reference system factory to use for the specified code. The default
1122: * implementation always returns the factory specified at construction time. Subclasses can
1123: * override this method in order to select a different factory implementation depending on
1124: * the code value.
1125: *
1126: * @param code The authority code given to this class. Note that the code to be given
1127: * to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1128: * @return A factory for the specified authority code (never {@code null}).
1129: * @throws FactoryException if no coordinate reference system factory were specified
1130: * at construction time.
1131: *
1132: * @since 2.4
1133: */
1134: protected CRSAuthorityFactory getCRSAuthorityFactory(
1135: final String code) throws FactoryException {
1136: if (crsFactory == null) {
1137: throw missingFactory(CRSAuthorityFactory.class, code);
1138: }
1139: return crsFactory;
1140: }
1141:
1142: /**
1143: * Returns the coordinate operation factory to use for the specified code. The default
1144: * implementation always returns the factory specified at construction time. Subclasses can
1145: * override this method in order to select a different factory implementation depending on
1146: * the code value.
1147: *
1148: * @param code The authority code given to this class. Note that the code to be given
1149: * to the returned factory {@linkplain #toBackingFactoryCode may be different}.
1150: * @return A factory for the specified authority code (never {@code null}).
1151: * @throws FactoryException if no coordinate operation factory were specified
1152: * at construction time.
1153: *
1154: * @since 2.4
1155: */
1156: protected CoordinateOperationAuthorityFactory getCoordinateOperationAuthorityFactory(
1157: final String code) throws FactoryException {
1158: if (operationFactory == null) {
1159: throw missingFactory(
1160: CoordinateOperationAuthorityFactory.class, code);
1161: }
1162: return operationFactory;
1163: }
1164:
1165: /**
1166: * Returns a coordinate operation factory for this adapter. This method will try to fetch
1167: * this information from the coordinate operation authority factory, or will returns the
1168: * default one if no explicit factory were found.
1169: */
1170: final CoordinateOperationFactory getCoordinateOperationFactory()
1171: throws FactoryException {
1172: if (operationFactory instanceof Factory) {
1173: final Factory factory = (Factory) operationFactory;
1174: final Map hints = factory.getImplementationHints();
1175: final Object candidate = hints
1176: .get(Hints.COORDINATE_OPERATION_FACTORY);
1177: if (candidate instanceof CoordinateOperationFactory) {
1178: return (CoordinateOperationFactory) candidate;
1179: }
1180: }
1181: return ReferencingFactoryFinder
1182: .getCoordinateOperationFactory(hints());
1183: }
1184:
1185: /**
1186: * Suggests a low-level factory group. If {@code crs} is {@code true}, then this method will
1187: * try to fetch the factory group from the CRS authority factory. Otherwise it will try to
1188: * fetch the factory group from the CS authority factory. This is used by subclasses like
1189: * {@link TransformedAuthorityFactory} that need low-level access to factories. Do not change
1190: * this method into a public one; we would need a better API before to do such thing.
1191: */
1192: final ReferencingFactoryContainer getFactoryContainer(
1193: final boolean crs) {
1194: final AuthorityFactory factory;
1195: if (crs) {
1196: factory = crsFactory;
1197: } else {
1198: factory = csFactory;
1199: }
1200: if (factory instanceof DirectAuthorityFactory) {
1201: return ((DirectAuthorityFactory) factory).factories;
1202: }
1203: // No predefined factory group. Create one.
1204: if (factories == null) {
1205: factories = ReferencingFactoryContainer.instance(hints());
1206: }
1207: return factories;
1208: }
1209:
1210: /**
1211: * Returns the code to be given to the wrapped factories. This method is automatically
1212: * invoked by all {@code create} methods before to forward the code to the
1213: * {@linkplain #getCRSAuthorityFactory CRS}, {@linkplain #getCSAuthorityFactory CS},
1214: * {@linkplain #getDatumAuthorityFactory datum} or {@linkplain #operationFactory operation}
1215: * factory. The default implementation returns the {@code code} unchanged.
1216: *
1217: * @param code The code given to this factory.
1218: * @return The code to give to the underlying factories.
1219: * @throws FactoryException if the code can't be converted.
1220: *
1221: * @since 2.4
1222: */
1223: protected String toBackingFactoryCode(final String code)
1224: throws FactoryException {
1225: return code;
1226: }
1227:
1228: /**
1229: * Returns {@code true} if the {@link #toBackingFactoryCode} method is overriden.
1230: */
1231: final boolean isCodeMethodOverriden() {
1232: final Class[] arguments = new Class[] { String.class };
1233: for (Class type = getClass(); !AuthorityFactoryAdapter.class
1234: .equals(type); type = type.getSuperclass()) {
1235: try {
1236: type.getDeclaredMethod("toBackingFactoryCode",
1237: arguments);
1238: } catch (NoSuchMethodException e) {
1239: // The method is not overriden in this class.
1240: // Checks in the super-class.
1241: continue;
1242: } catch (SecurityException e) {
1243: // We are not allowed to get this information.
1244: // Conservatively assumes that the method is overriden.
1245: }
1246: return true;
1247: }
1248: return false;
1249: }
1250: }
|