001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2003-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.data;
017:
018: // J2SE dependencies
019: import java.io.IOException;
020: import java.util.Collections;
021: import java.util.HashMap;
022: import java.util.Map;
023:
024: import org.geotools.data.DataStoreFactorySpi.Param;
025: import org.geotools.parameter.Parameter;
026: import org.geotools.parameter.DefaultParameterDescriptor;
027: import org.geotools.parameter.DefaultParameterDescriptorGroup;
028: import org.geotools.parameter.FloatParameter;
029: import org.opengis.parameter.GeneralParameterValue;
030: import org.opengis.parameter.ParameterDescriptorGroup;
031:
032: /**
033: * A best of toolkit for DataStoreFactory implementors.
034: * <p>
035: * Will also allow me to mess with the interface API without breaking every
036: * last DataStoreFactorySpi out there.
037: * </p>
038: * <p>
039: * The default implementations often hinge around the use of
040: * getParameterInfo and the correct use of Param by your subclass.
041: * </p>
042: * <p>
043: * You still have to implement a few methods:
044: * </p>
045: * <pre><code>
046: * public DataSourceMetadataEnity createMetadata( Map params ) throws IOException {
047: * String host = (String) HOST.lookUp(params);
048: * String user = (String) USER.lookUp(params);
049: * Integer port = (Integer) PORT.lookUp(params);
050: * String database = (String) DATABASE.lookUp(params);
051: *
052: * String description = "Connection to "+getDisplayName()+" on "+host+" as "+user ;
053: * return new DataSourceMetadataEnity( host+":"+port, database, description );
054: * }</code></pre>
055: *
056: * @author Jody Garnett, Refractions Research
057: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/main/src/main/java/org/geotools/data/AbstractDataStoreFactory.java $
058: */
059: public abstract class AbstractDataStoreFactory implements
060: DataStoreFactorySpi {
061:
062: /** Default Implementation abuses the naming convention.
063: * <p>
064: * Will return <code>Foo</code> for
065: * <code>org.geotools.data.foo.FooFactory</code>.
066: * </p>
067: * @return return display name based on class name
068: */
069: public String getDisplayName() {
070: String name = this .getClass().getName();
071:
072: name = name.substring(name.lastIndexOf('.'));
073: if (name.endsWith("Factory")) {
074: name = name.substring(0, name.length() - 7);
075: } else if (name.endsWith("FactorySpi")) {
076: name = name.substring(0, name.length() - 10);
077: }
078: return name;
079: }
080:
081: /**
082: * Default implementation verifies the Map against the Param information.
083: * <p>
084: * It will ensure that:
085: * <ul>
086: * <li>params is not null
087: * <li>Everything is of the correct type (or upcovertable
088: * to the correct type without Error)
089: * <li>Required Parameters are present
090: * </ul>
091: * </p>
092: * <p>
093: * <p>
094: * Why would you ever want to override this method?
095: * If you want to check that a expected file exists and is a directory.
096: * </p>
097: * Overrride:
098: * <pre><code>
099: * public boolean canProcess( Map params ) {
100: * if( !super.canProcess( params ) ){
101: * return false; // was not in agreement with getParametersInfo
102: * }
103: * // example check
104: * File file = (File) DIRECTORY.lookup( params ); // DIRECTORY is a param
105: * return file.exists() && file.isDirectory();
106: * }
107: * </code></pre>
108: * @param params
109: * @return true if params is in agreement with getParametersInfo, override for additional checks.
110: */
111: public boolean canProcess(Map params) {
112: if (params == null) {
113: return false;
114: }
115: Param arrayParameters[] = getParametersInfo();
116: for (int i = 0; i < arrayParameters.length; i++) {
117: Param param = arrayParameters[i];
118: Object value;
119: if (!params.containsKey(param.key)) {
120: if (param.required) {
121: return false; // missing required key!
122: } else {
123: continue;
124: }
125: }
126: try {
127: value = param.lookUp(params);
128: } catch (IOException e) {
129: // could not upconvert/parse to expected type!
130: // even if this parameter is not required
131: // we are going to refuse to process
132: // these params
133: return false;
134: }
135: if (value == null) {
136: if (param.required) {
137: return (false);
138: }
139: } else {
140: if (!param.type.isInstance(value)) {
141: return false; // value was not of the required type
142: }
143: }
144: }
145: return true;
146: }
147:
148: /**
149: * Defaults to true, only a few datastores need to check for drivers.
150: *
151: * @return <code>true</code>, override to check for drivers etc...
152: */
153: public boolean isAvailable() {
154: return true;
155: }
156:
157: public ParameterDescriptorGroup getParameters() {
158: Param params[] = getParametersInfo();
159: DefaultParameterDescriptor parameters[] = new DefaultParameterDescriptor[params.length];
160: for (int i = 0; i < params.length; i++) {
161: Param param = params[i];
162: parameters[i] = new ParamDescriptor(params[i]);
163: }
164: Map properties = new HashMap();
165: properties.put("name", getDisplayName());
166: properties.put("remarks", getDescription());
167: return new DefaultParameterDescriptorGroup(properties,
168: parameters);
169: }
170:
171: /**
172: * Returns the implementation hints. The default implementation returns en empty map.
173: */
174: public Map getImplementationHints() {
175: return Collections.EMPTY_MAP;
176: }
177: }
178:
179: class ParamDescriptor extends DefaultParameterDescriptor {
180: private static final long serialVersionUID = 1L;
181: Param param;
182:
183: public ParamDescriptor(Param param) {
184: super (param.key, param.description, param.sample,
185: param.required);
186: this .param = param;
187: }
188:
189: public GeneralParameterValue createValue() {
190: if (Double.TYPE.equals(getValueClass())) {
191: return new FloatParameter(this ) {
192: protected Object valueOf(String text)
193: throws IOException {
194: return param.handle(text);
195: }
196: };
197: }
198: return new Parameter(this ) {
199: protected Object valueOf(String text) throws IOException {
200: return param.handle(text);
201: }
202: };
203: }
204: };
|