001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_testing/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.feature.FeatureCollection; 046 import org.deegree.model.filterencoding.Filter; 047 import org.deegree.model.spatialschema.Geometry; 048 import org.deegree.ogcwebservices.wfs.operation.Query; 049 050 import com.esri.sde.sdk.client.SeCoordinateReference; 051 import com.esri.sde.sdk.client.SeQuery; 052 import com.esri.sde.sdk.client.SeShape; 053 054 /** 055 * Datastore implementation for an ESRI SDE database. 056 * 057 * @author <a href="mailto:cpollmann@moss.de">Christoph Pollmann</a> 058 * @author last edited by: $Author: mschneider $ 059 * 060 * @version $Revision: 12032 $, $Date: 2008-05-29 18:27:00 +0200 (Do, 29. Mai 2008) $ 061 */ 062 public class SDEDatastore extends Datastore { 063 064 private static final ILogger LOG = LoggerFactory.getLogger( SDEDatastore.class ); 065 066 private SDEConnectionPool pool = null; 067 068 @Override 069 public AnnotationDocument getAnnotationParser() { 070 return new SQLAnnotationDocument( this.getClass() ); 071 } 072 073 @Override 074 public void configure( DatastoreConfiguration config ) 075 throws DatastoreException { 076 super.configure( config ); 077 this.pool = SDEConnectionPool.getInstance(); 078 } 079 080 @Override 081 public DatastoreConfiguration getConfiguration() { 082 return super.getConfiguration(); 083 } 084 085 @Override 086 public void bindSchema( MappedGMLSchema schema ) 087 throws DatastoreException { 088 super.bindSchema( schema ); 089 } 090 091 @Override 092 public MappedGMLSchema[] getSchemas() { 093 return super.getSchemas(); 094 } 095 096 @Override 097 public MappedFeatureType getFeatureType( QualifiedName ftName ) { 098 return super.getFeatureType( ftName ); 099 } 100 101 @Override 102 public void close() 103 throws DatastoreException { 104 pool = null; 105 } 106 107 @Override 108 public FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts ) 109 throws DatastoreException { 110 111 FeatureCollection result = null; 112 SDEConnection conn = acquireConnection(); 113 SDEQueryHandler queryHandler = new SDEQueryHandler( this, new TableAliasGenerator(), conn, rootFts, query ); 114 result = queryHandler.performQuery(); 115 return result; 116 } 117 118 @Override 119 public DatastoreTransaction acquireTransaction() 120 throws DatastoreException { 121 DatastoreTransaction transactionHandler = new SDETransaction( this, new TableAliasGenerator(), 122 acquireConnection() ); 123 return transactionHandler; 124 } 125 126 /** 127 * Returns a specific <code>WhereBuilder</code> implementation for SDE. 128 * 129 * @param rootFts 130 * @param aliases 131 * @param filter 132 * @param aliasGenerator 133 * @return a specific <code>WhereBuilder</code> implementation for SDE. 134 * @throws DatastoreException 135 */ 136 public SDEWhereBuilder getWhereBuilder( MappedFeatureType[] rootFts, String[] aliases, Filter filter, 137 TableAliasGenerator aliasGenerator ) 138 throws DatastoreException { 139 SDEWhereBuilder wb = new SDEWhereBuilder( rootFts, aliases, filter, aliasGenerator ); 140 return wb; 141 } 142 143 /** 144 * Converts a database specific geometry <code>Object</code> from the <code>ResultSet</code> to a deegree 145 * <code>Geometry</code>. 146 * 147 * @param value 148 * @return corresponding deegree geometry 149 * @throws DatastoreException 150 */ 151 public Geometry convertDBToDegreeGeometry( Object value ) 152 throws DatastoreException { 153 154 Geometry geometry = null; 155 if ( value != null ) { 156 try { 157 SeCoordinateReference coordRef = ( (SeShape) value ).getCoordRef(); 158 String desc = coordRef.getProjectionDescription(); 159 LOG.logDebug( "******* coordSys=" + desc + "****" ); 160 geometry = SDEAdapter.wrap( (SeShape) value ); 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 }