001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2007, GeoTools Project Managment Committee (PMC)
005: *
006: * This library is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU Lesser General Public
008: * License as published by the Free Software Foundation;
009: * version 2.1 of the License.
010: *
011: * This library is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * Lesser General Public License for more details.
015: */
016: package org.geotools.referencing.factory;
017:
018: // OpenGIS dependencies
019: import org.opengis.metadata.citation.Citation;
020: import org.opengis.referencing.FactoryException;
021: import org.opengis.referencing.NoSuchAuthorityCodeException;
022: import org.opengis.referencing.crs.CRSAuthorityFactory;
023: import org.opengis.referencing.cs.CSAuthorityFactory;
024: import org.opengis.referencing.datum.DatumAuthorityFactory;
025: import org.opengis.referencing.operation.CoordinateOperationAuthorityFactory;
026:
027: // Geotools dependencies
028: import org.geotools.factory.Hints;
029: import org.geotools.util.GenericName;
030: import org.geotools.metadata.iso.citation.Citations;
031: import org.geotools.resources.i18n.ErrorKeys;
032: import org.geotools.resources.i18n.Errors;
033:
034: /**
035: * Wraps {@linkplain AllAuthoritiesFactory all factories} in a {@code "http://www.opengis.net/"}
036: * name space. An exemple of complete URL is {@code "http://www.opengis.net/gml/srs/epsg.xml#4326"}.
037: * <p>
038: * Implementation note: this class requires some cooperation from the
039: * {@link AllAuthoritiesFactory#getSeparator} method, since the separator is not the usual
040: * {@value org.geotools.util.GenericName#DEFAULT_SEPARATOR} character.
041: *
042: * @since 2.4
043: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/factory/HTTP_AuthorityFactory.java $
044: * @version $Id: HTTP_AuthorityFactory.java 29058 2008-02-03 17:47:07Z desruisseaux $
045: * @author Martin Desruisseaux
046: *
047: * @deprecated This class will move in a <code>org.geotools.referencing.factory.<strong>web</strong></code>
048: * package in Geotools 2.5, in order to put together other web-related factories.
049: * Don't use this class directly. You should not need to anyway - use
050: * {@link org.geotools.referencing.ReferencingFactoryFinder} instead, which will
051: * continue to work no matter where this class is located.
052: */
053: public class HTTP_AuthorityFactory extends AuthorityFactoryAdapter
054: implements CRSAuthorityFactory, CSAuthorityFactory,
055: DatumAuthorityFactory, CoordinateOperationAuthorityFactory {
056: /**
057: * The base URL, which is {@value}.
058: */
059: public static final String BASE_URL = "http://www.opengis.net/gml/srs/";
060:
061: /**
062: * Creates a default wrapper.
063: */
064: public HTTP_AuthorityFactory() {
065: this ((Hints) null);
066: }
067:
068: /**
069: * Creates a wrapper using the specified hints. For strict compliance with OGC
070: * definition of CRS defined by URL, the supplied hints should contains at least the
071: * {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER FORCE_LONGITUDE_FIRST_AXIS_ORDER} hint
072: * with value {@link Boolean#FALSE FALSE}.
073: *
074: * @param userHints The hints to be given to backing factories.
075: */
076: public HTTP_AuthorityFactory(final Hints userHints) {
077: this (getFactory(userHints, "http"));
078: }
079:
080: /**
081: * Creates a wrapper around the specified factory. The supplied factory is given unchanged
082: * to the {@linkplain AuthorityFactoryAdapter#AuthorityFactoryAdapter(AuthorityFactory)
083: * super class constructor}.
084: */
085: public HTTP_AuthorityFactory(final AllAuthoritiesFactory factory) {
086: super (factory);
087: }
088:
089: /**
090: * Returns {@code false} if {@link Hints#FORCE_LONGITUDE_FIRST_AXIS_ORDER} should be set to
091: * {@link Boolean#FALSE}. This method compares {@link Hints#FORCE_AXIS_ORDER_HONORING} with
092: * the specified authority.
093: *
094: * @param hints The hints to use (may be {@code null}).
095: * @param authority The authority factory under creation.
096: *
097: * @todo Should not looks at system hints; this is {@link ReferencingFactoryFinder}'s job.
098: */
099: static boolean defaultAxisOrderHints(final Hints hints,
100: final String authority) {
101: Object value = null;
102: if (hints != null) {
103: value = hints.get(Hints.FORCE_AXIS_ORDER_HONORING);
104: }
105: if (value == null) {
106: value = Hints
107: .getSystemDefault(Hints.FORCE_AXIS_ORDER_HONORING);
108: }
109: if (value instanceof CharSequence) {
110: final String list = value.toString();
111: int i = 0;
112: while ((i = list.indexOf(authority, i)) >= 0) {
113: if (i == 0
114: || !Character.isJavaIdentifierPart(list
115: .charAt(i - 1))) {
116: final int j = i + authority.length();
117: if (j == list.length()
118: || !Character.isJavaIdentifierPart(list
119: .charAt(j))) {
120: // Found the authority in the list: we need to use the global setting.
121: return true;
122: }
123: }
124: i++;
125: }
126: }
127: return false;
128: }
129:
130: /**
131: * Returns a factory from the specified hints. Used by {@link URN_AuthorityFactory}
132: * constructor as well.
133: */
134: static AllAuthoritiesFactory getFactory(Hints hints,
135: final String authority) {
136: if (!defaultAxisOrderHints(hints, authority)) {
137: hints = new Hints(hints);
138: hints.put(Hints.FORCE_LONGITUDE_FIRST_AXIS_ORDER,
139: Boolean.FALSE);
140: }
141: return new AllAuthoritiesFactory(hints);
142: }
143:
144: /**
145: * Returns the authority, which contains the {@code "http://www.opengis.net"} identifier.
146: */
147: public Citation getAuthority() {
148: return Citations.HTTP_OGC;
149: }
150:
151: /**
152: * Removes the URL base ({@value #BASE_URL}) from the specified code
153: * before to pass it to the wrapped factories.
154: *
155: * @param code The code given to this factory.
156: * @return The code to give to the underlying factories.
157: * @throws FactoryException if the code can't be converted.
158: */
159: protected String toBackingFactoryCode(String code)
160: throws FactoryException {
161: code = code.trim();
162: final int length = BASE_URL.length();
163: if (code.regionMatches(true, 0, BASE_URL, 0, length)) {
164: code = code.substring(length);
165: if (code.indexOf('/') < 0) {
166: final int split = code.indexOf('#');
167: if (split >= 0 && code.indexOf('#', split + 1) < 0) {
168: String authority = code.substring(0, split).trim();
169: final int ext = authority.lastIndexOf('.');
170: if (ext > 0) {
171: // Removes the extension part (typically ".xml")
172: authority = authority.substring(0, ext);
173: }
174: code = code.substring(split + 1).trim();
175: code = authority + GenericName.DEFAULT_SEPARATOR
176: + code;
177: return code;
178: }
179: }
180: }
181: throw new NoSuchAuthorityCodeException(Errors.format(
182: ErrorKeys.ILLEGAL_ARGUMENT_$2, "code", code), BASE_URL,
183: code);
184: }
185: }
|