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.data.postgis;
017:
018: import java.io.IOException;
019: import java.sql.SQLException;
020: import java.util.Map;
021: import java.util.logging.Level;
022: import java.util.logging.Logger;
023:
024: import javax.sql.DataSource;
025:
026: import org.geotools.data.AbstractDataStoreFactory;
027: import org.geotools.data.DataSourceException;
028: import org.geotools.data.DataStore;
029: import org.geotools.data.jdbc.ConnectionPool;
030: import org.geotools.data.jdbc.datasource.DataSourceUtil;
031:
032: /**
033: * Builds instances of the versioned Postgis datastore
034: *
035: * @author aaime
036: * @since 2.4
037: *
038: */
039: public class VersionedPostgisDataStoreFactory extends
040: AbstractDataStoreFactory {
041:
042: /** The logger for the postgis module. */
043: protected static final Logger LOGGER = org.geotools.util.logging.Logging
044: .getLogger("org.geotools.data.postgis");
045:
046: /** Creates PostGIS-specific JDBC driver class. */
047: private static final String DRIVER_CLASS = "org.postgresql.Driver";
048:
049: public static final Param DBTYPE = new Param("dbtype",
050: String.class, "must be 'postgis-versioned'", true,
051: "postgis-versioned");
052:
053: public static final Param HOST = new Param("host", String.class,
054: "postgis host machine", true, "localhost");
055:
056: public static final Param PORT = new Param("port", Integer.class,
057: "postgis connection port (default is 5432)", true,
058: new Integer(5432));
059:
060: public static final Param DATABASE = new Param("database",
061: String.class, "postgis database");
062:
063: public static final Param SCHEMA = new Param("schema",
064: String.class, "postgis schema", false, "public");
065:
066: public static final Param USER = new Param("user", String.class,
067: "user name to login as");
068:
069: public static final Param PASSWD = new Param("passwd",
070: String.class, "password used to login", false);
071:
072: public static final Param NAMESPACE = new Param("namespace",
073: String.class, "namespace prefix used", false);
074:
075: public static final Param WKBENABLED = new Param("wkb enabled",
076: Boolean.class,
077: "set to true if Well Known Binary should be used to read PostGIS "
078: + "data (experimental)", false, new Boolean(true));
079:
080: public static final Param LOOSEBBOX = new Param("loose bbox",
081: Boolean.class,
082: "set to true if the Bounding Box should be 'loose', faster but "
083: + "not as deadly accurate", false,
084: new Boolean(true));
085:
086: public static final Param VERSIONALL = new Param(
087: "version enable all",
088: Boolean.class,
089: "set to true if you want all feature types to be version enabled on connection",
090: false, new Boolean(false));
091:
092: /** Array with all of the params */
093: static final Param[] arrayParameters = { DBTYPE, HOST, PORT,
094: DATABASE, USER, PASSWD, WKBENABLED, LOOSEBBOX, NAMESPACE,
095: VERSIONALL };
096:
097: /**
098: * Creates a new instance of PostgisDataStoreFactory
099: */
100: public VersionedPostgisDataStoreFactory() {
101: }
102:
103: public boolean canProcess(Map params) {
104: if (!super .canProcess(params)) {
105: return false; // was not in agreement with getParametersInfo
106: }
107: return ((String) params.get("dbtype"))
108: .equalsIgnoreCase("postgis-versioned");
109: }
110:
111: /**
112: * Construct a postgis data store using the params.
113: *
114: * @param params
115: * The full set of information needed to construct a live data
116: * source. Should have dbtype equal to postgis, as well as host,
117: * user, passwd, database, and table.
118: *
119: * @return The created DataSource, this may be null if the required resource
120: * was not found or if insufficent parameters were given. Note that
121: * canProcess() should have returned false if the problem is to do
122: * with insuficent parameters.
123: *
124: * @throws IOException
125: * See DataSourceException
126: * @throws DataSourceException
127: * Thrown if there were any problems creating or connecting the
128: * datasource.
129: */
130: public DataStore createDataStore(Map params) throws IOException {
131: // lookup will throw error message for
132: // miscoversion or lack of required param
133: //
134: String host = (String) HOST.lookUp(params);
135: String user = (String) USER.lookUp(params);
136: String passwd = (String) PASSWD.lookUp(params);
137: Integer port = (Integer) PORT.lookUp(params);
138: String schema = (String) SCHEMA.lookUp(params);
139: String database = (String) DATABASE.lookUp(params);
140: Boolean wkb_enabled = (Boolean) WKBENABLED.lookUp(params);
141: Boolean is_loose_bbox = (Boolean) LOOSEBBOX.lookUp(params);
142: String namespace = (String) NAMESPACE.lookUp(params);
143: Boolean versionAll = (Boolean) VERSIONALL.lookUp(params);
144:
145: // Try processing params first so we can get real IO
146: // error message back to the user
147: //
148: if (!canProcess(params)) {
149: throw new IOException("The parameters map isn't correct!!");
150: }
151:
152: String url = "jdbc:postgresql" + "://" + host + ":" + port
153: + "/" + database;
154: DataSource source = DataSourceUtil.buildDefaultDataSource(url,
155: "org.postgresql.Driver", user, passwd, "select now()");
156: VersionedPostgisDataStore dataStore = createDataStoreInternal(
157: source, namespace, schema);
158:
159: if (wkb_enabled != null) {
160: dataStore.setWKBEnabled(wkb_enabled.booleanValue());
161: }
162:
163: if (is_loose_bbox != null) {
164: dataStore.setLooseBbox(is_loose_bbox.booleanValue());
165: }
166:
167: if (versionAll != null && versionAll.booleanValue()) {
168: String[] typeNames = dataStore.getTypeNames();
169: for (int i = 0; i < typeNames.length; i++) {
170: if (typeNames[i]
171: .equals(VersionedPostgisDataStore.TBL_CHANGESETS))
172: continue;
173: try {
174: dataStore.setVersioned(typeNames[i], true, null,
175: null);
176: } catch (IOException e) {
177: LOGGER
178: .log(Level.SEVERE,
179: "Could not version enable: "
180: + typeNames[i], e);
181: }
182: }
183: }
184:
185: return dataStore;
186: }
187:
188: protected VersionedPostgisDataStore createDataStoreInternal(
189: DataSource dataSource, String namespace, String schema)
190: throws IOException {
191:
192: if (schema == null && namespace == null)
193: return new VersionedPostgisDataStore(dataSource);
194:
195: if (schema == null && namespace != null) {
196: return new VersionedPostgisDataStore(dataSource, namespace);
197: }
198:
199: return new VersionedPostgisDataStore(dataSource, schema,
200: namespace);
201: }
202:
203: /**
204: * Postgis cannot create a new database.
205: *
206: * @param params
207: *
208: *
209: * @throws IOException
210: * See UnsupportedOperationException
211: * @throws UnsupportedOperationException
212: * Cannot create new database
213: */
214: public DataStore createNewDataStore(Map params) throws IOException {
215: throw new UnsupportedOperationException(
216: "Postgis cannot create a new Database");
217: }
218:
219: public String getDisplayName() {
220: return "Versioning Postgis";
221: }
222:
223: /**
224: * Describe the nature of the datasource constructed by this factory.
225: *
226: * @return A human readable description that is suitable for inclusion in a
227: * list of available datasources.
228: */
229: public String getDescription() {
230: return "PostGIS spatial database with versioning support";
231: }
232:
233: /**
234: * Determines if the appropriate libraries are present for this datastore
235: * factory to successfully produce postgis datastores.
236: *
237: * @return <tt>true</tt> if the postgresql jar is on the classpath.
238: */
239: public boolean isAvailable() {
240: try {
241: Class.forName(DRIVER_CLASS);
242: } catch (ClassNotFoundException cnfe) {
243: return false;
244: }
245: return true;
246: }
247:
248: /**
249: * Describe parameters.
250: *
251: *
252: * @see org.geotools.data.DataStoreFactorySpi#getParametersInfo()
253: */
254: public Param[] getParametersInfo() {
255: return arrayParameters;
256: }
257: }
|