001 //$HeadURL: http://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/io/datastore/sde/SDEDatastore.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2006 by: M.O.S.S. Computer Grafik Systeme GmbH
006 Hohenbrunner Weg 13
007 D-82024 Taufkirchen
008 http://www.moss.de/
009
010 This library is free software; you can redistribute it and/or
011 modify it under the terms of the GNU Lesser General Public
012 License as published by the Free Software Foundation; either
013 version 2.1 of the License, or (at your option) any later version.
014
015 This library is distributed in the hope that it will be useful,
016 but WITHOUT ANY WARRANTY; without even the implied warranty of
017 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
018 Lesser General Public License for more details.
019
020 You should have received a copy of the GNU Lesser General Public
021 License along with this library; if not, write to the Free Software
022 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
023
024 ---------------------------------------------------------------------------*/
025 package org.deegree.io.datastore.sde;
026
027 import org.deegree.datatypes.QualifiedName;
028 import org.deegree.framework.log.ILogger;
029 import org.deegree.framework.log.LoggerFactory;
030 import org.deegree.io.JDBCConnection;
031 import org.deegree.io.datastore.AnnotationDocument;
032 import org.deegree.io.datastore.Datastore;
033 import org.deegree.io.datastore.DatastoreConfiguration;
034 import org.deegree.io.datastore.DatastoreException;
035 import org.deegree.io.datastore.DatastoreTransaction;
036 import org.deegree.io.datastore.schema.MappedFeatureType;
037 import org.deegree.io.datastore.schema.MappedGMLSchema;
038 import org.deegree.io.datastore.sql.SQLAnnotationDocument;
039 import org.deegree.io.datastore.sql.SQLDatastoreConfiguration;
040 import org.deegree.io.datastore.sql.StatementBuffer;
041 import org.deegree.io.datastore.sql.TableAliasGenerator;
042 import org.deegree.io.sdeapi.SDEAdapter;
043 import org.deegree.io.sdeapi.SDEConnection;
044 import org.deegree.io.sdeapi.SDEConnectionPool;
045 import org.deegree.model.crs.CoordinateSystem;
046 import org.deegree.model.feature.FeatureCollection;
047 import org.deegree.model.filterencoding.Filter;
048 import org.deegree.model.spatialschema.Geometry;
049 import org.deegree.ogcwebservices.wfs.operation.Query;
050
051 import com.esri.sde.sdk.client.SeCoordinateReference;
052 import com.esri.sde.sdk.client.SeQuery;
053 import com.esri.sde.sdk.client.SeShape;
054
055 /**
056 * Datastore implementation for an ESRI SDE database.
057 *
058 * @author <a href="mailto:cpollmann@moss.de">Christoph Pollmann</a>
059 * @author last edited by: $Author: mschneider $
060 *
061 * @version $Revision: 23718 $, $Date: 2010-04-21 13:19:03 +0200 (Wed, 21 Apr 2010) $
062 */
063 public class SDEDatastore extends Datastore {
064
065 private static final ILogger LOG = LoggerFactory.getLogger( SDEDatastore.class );
066
067 private SDEConnectionPool pool = null;
068
069 @Override
070 public AnnotationDocument getAnnotationParser() {
071 return new SQLAnnotationDocument( this.getClass() );
072 }
073
074 @Override
075 public void configure( DatastoreConfiguration config )
076 throws DatastoreException {
077 super.configure( config );
078 this.pool = SDEConnectionPool.getInstance();
079 }
080
081 @Override
082 public DatastoreConfiguration getConfiguration() {
083 return super.getConfiguration();
084 }
085
086 @Override
087 public void bindSchema( MappedGMLSchema schema )
088 throws DatastoreException {
089 super.bindSchema( schema );
090 }
091
092 @Override
093 public MappedGMLSchema[] getSchemas() {
094 return super.getSchemas();
095 }
096
097 @Override
098 public MappedFeatureType getFeatureType( QualifiedName ftName ) {
099 return super.getFeatureType( ftName );
100 }
101
102 @Override
103 public void close()
104 throws DatastoreException {
105 pool = null;
106 }
107
108 @Override
109 public FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts )
110 throws DatastoreException {
111
112 FeatureCollection result = null;
113 SDEConnection conn = acquireConnection();
114 SDEQueryHandler queryHandler = new SDEQueryHandler( this, new TableAliasGenerator(), conn, rootFts, query );
115 result = queryHandler.performQuery();
116 releaseConnection( conn );
117 return result;
118 }
119
120 @Override
121 public DatastoreTransaction acquireTransaction()
122 throws DatastoreException {
123 DatastoreTransaction transactionHandler = new SDETransaction( this, new TableAliasGenerator(),
124 acquireConnection() );
125 return transactionHandler;
126 }
127
128 /**
129 * Returns a specific <code>WhereBuilder</code> implementation for SDE.
130 *
131 * @param rootFts
132 * @param aliases
133 * @param filter
134 * @param aliasGenerator
135 * @return a specific <code>WhereBuilder</code> implementation for SDE.
136 * @throws DatastoreException
137 */
138 public SDEWhereBuilder getWhereBuilder( MappedFeatureType[] rootFts, String[] aliases, Filter filter,
139 TableAliasGenerator aliasGenerator )
140 throws DatastoreException {
141 SDEWhereBuilder wb = new SDEWhereBuilder( rootFts, aliases, filter, aliasGenerator );
142 return wb;
143 }
144
145 /**
146 * Converts a database specific geometry <code>Object</code> from the <code>ResultSet</code> to a deegree
147 * <code>Geometry</code>.
148 *
149 * @param value
150 * @param coordinateSystem
151 * @return corresponding deegree geometry
152 * @throws DatastoreException
153 */
154 public Geometry convertDBToDegreeGeometry( Object value, CoordinateSystem coordinateSystem )
155 throws DatastoreException {
156
157 Geometry geometry = null;
158 if ( value != null ) {
159 try {
160 geometry = SDEAdapter.wrap( (SeShape) value, coordinateSystem );
161 } catch ( Exception e ) {
162 throw new DatastoreException( "Error converting SeShape to Geometry: " + e.getMessage() );
163 }
164 }
165 return geometry;
166 }
167
168 /**
169 * Converts a deegree <code>Geometry</code> to a database specific geometry <code>Object</code>.
170 *
171 * @param geometry
172 * @return corresponding database specific geometry object
173 * @throws DatastoreException
174 */
175 public Object convertDegreeToDBGeometry( Geometry geometry )
176 throws DatastoreException {
177 Object value = null;
178 if ( geometry != null ) {
179 try {
180 // TODO: SRS handling
181 SeCoordinateReference coordRef = new SeCoordinateReference();
182 value = SDEAdapter.export( geometry, coordRef );
183 } catch ( Exception e ) {
184 throw new DatastoreException( "Error converting Geometry to SeShape: " + e.getMessage(), e );
185 }
186 }
187 return value;
188 }
189
190 /**
191 * Returns the database connection requested for.
192 *
193 * @return Connection
194 * @throws DatastoreException
195 */
196 protected SDEConnection acquireConnection()
197 throws DatastoreException {
198 JDBCConnection jdbcConnection = ( (SQLDatastoreConfiguration) this.getConfiguration() ).getJDBCConnection();
199 SDEConnection conn = null;
200 try {
201 String url = jdbcConnection.getURL();
202 String[] tmp = url.split( ":" );
203 int instance = 5151;
204 if ( 2 == tmp.length ) {
205 url = tmp[0];
206 instance = Integer.parseInt( tmp[1] );
207 }
208 conn = pool.acquireConnection( url, instance, jdbcConnection.getSDEDatabase(),
209 jdbcConnection.getSDEVersion(), jdbcConnection.getUser(),
210 jdbcConnection.getPassword() );
211 } catch ( Exception e ) {
212 String msg = "Cannot acquire database connection: " + e.getMessage();
213 LOG.logInfo( msg );
214 throw new DatastoreException( msg, e );
215 }
216 return conn;
217 }
218
219 /**
220 * Releases the connection.
221 *
222 * @param conn
223 * Connection to be released.
224 * @throws DatastoreException
225 */
226 protected void releaseConnection( SDEConnection conn )
227 throws DatastoreException {
228 JDBCConnection jdbcConnection = ( (SQLDatastoreConfiguration) this.getConfiguration() ).getJDBCConnection();
229 try {
230 String url = jdbcConnection.getURL();
231 String[] tmp = url.split( ":" );
232 int instance = 5151;
233 if ( 2 == tmp.length ) {
234 url = tmp[0];
235 instance = Integer.parseInt( tmp[1] );
236 }
237 pool.releaseConnection( conn, url, instance, jdbcConnection.getSDEDatabase(),
238 jdbcConnection.getSDEVersion(), jdbcConnection.getUser() );
239 } catch ( Exception e ) {
240 String msg = "Cannot release database connection: " + e.getMessage();
241 LOG.logInfo( msg );
242 throw new DatastoreException( msg, e );
243 }
244 }
245
246 /**
247 * Converts the <code>StatementBuffer</code> into a <code>PreparedStatement</code>, which is initialized and
248 * ready to be performed.
249 *
250 * @param conn
251 * connection to be used to create the <code>PreparedStatement</code>
252 * @param statementBuffer
253 * @return the <code>PreparedStatment</code>, ready to be performed
254 */
255 public SeQuery prepareStatement( SDEConnection conn, StatementBuffer statementBuffer ) {
256 LOG.logDebug( "Preparing statement: " + statementBuffer.getQueryString() );
257
258 SeQuery query = null;
259 try {
260 query = new SeQuery( conn.getConnection() );
261 query.prepareSql( statementBuffer.getQueryString() );
262 } catch ( Exception e ) {
263 e.printStackTrace();
264 }
265
266 // TODO
267 return query;
268 }
269
270 @Override
271 public FeatureCollection performQuery( Query query, MappedFeatureType[] rootFts, DatastoreTransaction context )
272 throws DatastoreException {
273 throw new DatastoreException( "method invocation for sde not applicable" );
274 }
275
276 @Override
277 public void releaseTransaction( DatastoreTransaction ta )
278 throws DatastoreException {
279 releaseConnection( ( (SDETransaction) ta ).getConnection() );
280 }
281 }