001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2002-2006, 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.gml3;
017:
018: import org.eclipse.xsd.XSDSchema;
019: import org.eclipse.xsd.util.XSDSchemaLocationResolver;
020: import java.io.File;
021: import java.io.IOException;
022: import org.geotools.xml.BindingConfiguration;
023: import org.geotools.xml.Configuration;
024: import org.geotools.xs.XSConfiguration;
025:
026: /**
027: * An xml configuration for application schemas.
028: * <p>
029: * This Configuration expects the namespace and schema location URI of the main
030: * xsd file for a given application schema and is able to resolve the schema
031: * location for the includes and imports as well as they're defined as relative
032: * paths and the provided <code>schemaLocation</code> is a file URI.
033: * </p>
034: *
035: * @author Justin Deoliveira, The Open Planning Project
036: * @author Gabriel Roldan, Axios Engineering
037: * @version $Id: ApplicationSchemaConfiguration.java 27504 2007-10-15 22:38:02Z
038: * groldan $
039: * @since 2.4
040: */
041: public class ApplicationSchemaConfiguration extends Configuration {
042: /** application schema namespace */
043: private String namespace;
044:
045: /** location of the application schema itself */
046: private String schemaLocation;
047:
048: public ApplicationSchemaConfiguration(String namespace,
049: String schemaLocation) {
050: assert namespace != null;
051: assert schemaLocation != null;
052: this .namespace = namespace;
053: this .schemaLocation = schemaLocation;
054: addDependency(new XSConfiguration());
055: addDependency(new GMLConfiguration());
056: }
057:
058: public String getNamespaceURI() {
059: return namespace;
060: }
061:
062: public String getSchemaFileURL() {
063: return schemaLocation;
064: }
065:
066: public BindingConfiguration getBindingConfiguration() {
067: return null;
068: }
069:
070: /**
071: * Returns a {@link XSDSchemaLocationResolver} that expects to be asked for
072: * the location of the schema file for the imports and includes of the
073: * schema targeted by this configuration, and is able to resolve their
074: * actual locations as relative paths to
075: * {@link #getSchemaFileURL() this schema location}, if available.
076: *
077: * @return a {@link XSDSchemaLocationResolver} that
078: */
079: public XSDSchemaLocationResolver getSchemaLocationResolver() {
080: return new XSDSchemaLocationResolver() {
081: /**
082: * Uses the <code>schema.getSchemaLocation()</code>'s parent
083: * folder as the base folder to resolve <code>location</code> as a
084: * relative URI of.
085: * <p>
086: * This way, application schemas splitted over multiple files can be
087: * resolved based on the relative location of a given import or
088: * include.
089: * </p>
090: * <p>
091: * If the <code>location</code> is provided as argument but cannot
092: * be resolved to a relative location to
093: * <code>schema.getSchemaLocation()</code>, then
094: * <code>null</code> is returned and the caller shall utilize the
095: * absolute URL location to get the resource from, or some other
096: * sort of finding the actual schema location.
097: * </p>
098: *
099: * @param schema
100: * the schema being resolved
101: * @param uri
102: * the namespace being resolved. If its an empty string
103: * (i.e. the location refers to an include, and thus the
104: * uri to the same one than the schema), the schema one
105: * is used.
106: * @param location
107: * the xsd location, either of <code>schema</code>, an
108: * import or an include, for which to try resolving it as
109: * a relative path of the <code>schema</code> location.
110: * @return a file: style uri with the resolved schema location for
111: * the given one, or <code>null</code> if
112: * <code>location</code> can't be resolved as a relative
113: * path of the <code>schema</code> location.
114: */
115: public String resolveSchemaLocation(final XSDSchema schema,
116: final String uri, final String location) {
117: if (uri == null) {
118: throw new NullPointerException("got null uri");
119: }
120:
121: if (location == null) {
122: throw new NullPointerException("got null location");
123: }
124:
125: String schemaLocation;
126:
127: if (schema == null) {
128: if (ApplicationSchemaConfiguration.this .namespace
129: .equals(uri)) {
130: //about to resolve the root schema this configuration is meant for
131: schemaLocation = ApplicationSchemaConfiguration.this .schemaLocation;
132: } else {
133: throw new NullPointerException(
134: "got null schema");
135: }
136: } else {
137: // try to resolve location as a relative path
138: schemaLocation = schema.getSchemaLocation();
139:
140: if ("".equals(schemaLocation)) {
141: // is it an include of the root schema being resolved?
142: schemaLocation = ApplicationSchemaConfiguration.this .schemaLocation;
143: }
144: }
145:
146: String schemaLocationFolder;
147: int lastSlash = schemaLocation.lastIndexOf('/');
148:
149: if (lastSlash > 0) {
150: schemaLocationFolder = schemaLocation.substring(0,
151: lastSlash);
152: } else {
153: schemaLocationFolder = ".";
154: }
155:
156: if (schemaLocationFolder.startsWith("file:")) {
157: schemaLocationFolder = schemaLocationFolder
158: .substring(5);
159: }
160:
161: File locationFile = new File(schemaLocationFolder,
162: location);
163:
164: if (locationFile.exists()) {
165: try {
166: locationFile = locationFile.getCanonicalFile();
167: } catch (IOException e) {
168: throw new RuntimeException(
169: "Can't access file, might be "
170: + "access to file denied by security manager: "
171: + locationFile
172: .getAbsolutePath());
173: }
174:
175: String resolvedLocationUri = locationFile.toURI()
176: .toString();
177:
178: return resolvedLocationUri;
179: }
180:
181: return null;
182: }
183: };
184: }
185: }
|