001    //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_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: 7468 $, $Date: 2007-06-05 16:33:13 +0200 (Di, 05 Jun 2007) $
061     */
062    public class SDEDatastore extends Datastore {
063    
064        protected static final ILogger LOG = LoggerFactory.getLogger( SDEDatastore.class );
065    
066        protected SDEConnectionPool pool = null;
067    
068        // /////////////////////////////////////////////////
069        // overwritten methods of class Datastore
070        // /////////////////////////////////////////////////
071    
072        @Override
073        public AnnotationDocument getAnnotationParser () {
074            return new SQLAnnotationDocument (SDEDatastore.class);
075        }    
076        
077        @Override
078        public void configure( DatastoreConfiguration config )
079                                throws DatastoreException {
080            super.configure( config );
081            this.pool = SDEConnectionPool.getInstance();
082        }
083    
084        @Override
085        public DatastoreConfiguration getConfiguration() {
086            return super.getConfiguration();
087        }
088    
089        @Override
090        public void bindSchema( MappedGMLSchema schema )
091                                throws DatastoreException {
092            super.bindSchema( schema );
093        }
094    
095        @Override
096        public MappedGMLSchema[] getSchemas() {
097            return super.getSchemas();
098        }
099    
100        @Override
101        public MappedFeatureType getFeatureType( QualifiedName ftName ) {
102            return super.getFeatureType( ftName );
103        }
104    
105        @Override
106        public void close()
107                                throws DatastoreException {
108            pool = null;
109        }
110    
111    
112        @Override
113        public FeatureCollection performQuery( final Query query, final MappedFeatureType[] rootFts )
114                                throws DatastoreException {
115    
116            FeatureCollection result = null;
117            SDEConnection conn = acquireConnection();
118            SDEQueryHandler queryHandler = new SDEQueryHandler( this, new TableAliasGenerator(), conn, rootFts, query );
119            result = queryHandler.performQuery();
120            return result;
121        }
122    
123        @Override
124        public DatastoreTransaction acquireTransaction()
125                                throws DatastoreException {
126            DatastoreTransaction transactionHandler = new SDETransaction( this, new TableAliasGenerator(),
127                                                                          acquireConnection() );
128            return transactionHandler;
129        }
130    
131        // /////////////////////////////////////////////////
132        // overwritten methods of class AbstractSQLDatastore
133        // /////////////////////////////////////////////////
134    
135        /**
136         * Returns a specific <code>WhereBuilder</code> implementation for SDE.
137         * 
138         * @param rootFts
139         * @param aliases 
140         * @param filter
141         * @param aliasGenerator
142         * @return a specific <code>WhereBuilder</code> implementation for SDE.
143         * @throws DatastoreException
144         */
145        public SDEWhereBuilder getWhereBuilder( MappedFeatureType[] rootFts, String[] aliases, Filter filter,
146                                                TableAliasGenerator aliasGenerator )
147                                throws DatastoreException {
148            SDEWhereBuilder wb = new SDEWhereBuilder( rootFts, aliases, filter, aliasGenerator );
149            return wb;
150        }
151    
152        /**
153         * Converts a database specific geometry <code>Object</code> from the <code>ResultSet</code>
154         * to a deegree <code>Geometry</code>.
155         * 
156         * @param value
157         * @return corresponding deegree geometry
158         * @throws DatastoreException
159         */
160        public Geometry convertDBToDegreeGeometry( Object value )
161                                throws DatastoreException {
162    
163            Geometry geometry = null;
164            if ( value != null ) {
165                try {
166                    SeCoordinateReference coordRef = ( (SeShape) value ).getCoordRef();
167                    String desc = coordRef.getProjectionDescription();
168                    LOG.logDebug( "******* coordSys=" + desc + "****" );
169                    geometry = SDEAdapter.wrap( (SeShape) value );
170                } catch ( Exception e ) {
171                    throw new DatastoreException( "Error converting SeShape to Geometry: " + e.getMessage() );
172                }
173            }
174            return geometry;
175        }
176    
177        /**
178         * Converts a deegree <code>Geometry</code> to a database specific geometry
179         * <code>Object</code>.
180         * 
181         * @param geometry
182         * @return corresponding database specific geometry object
183         * @throws DatastoreException
184         */
185        public Object convertDegreeToDBGeometry( Geometry geometry )
186                                throws DatastoreException {
187            Object value = null;
188            if ( geometry != null ) {
189                try {
190                    // TODO: SRS handling
191                    SeCoordinateReference coordRef = new SeCoordinateReference();
192                    value = SDEAdapter.export( geometry, coordRef );
193                } catch ( Exception e ) {
194                    throw new DatastoreException( "Error converting Geometry to SeShape: " + e.getMessage(), e );
195                }
196            }
197            return value;
198        }
199    
200        /**
201         * Returns the database connection requested for.
202         * 
203         * @return Connection
204         * @throws DatastoreException
205         */
206        protected SDEConnection acquireConnection()
207                                throws DatastoreException {
208            JDBCConnection jdbcConnection = ( (SQLDatastoreConfiguration) this.getConfiguration() ).getJDBCConnection();
209            SDEConnection conn = null;
210            try {
211                String url = jdbcConnection.getURL();
212                String[] tmp = url.split( ":" );
213                int instance = 5151;
214                if ( 2 == tmp.length ) {
215                    url = tmp[0];
216                    instance = Integer.parseInt( tmp[1] );
217                }
218                conn = pool.acquireConnection( url, instance, jdbcConnection.getSDEDatabase(),
219                                               jdbcConnection.getSDEVersion(), jdbcConnection.getUser(),
220                                               jdbcConnection.getPassword() );
221            } catch ( Exception e ) {
222                String msg = "Cannot acquire database connection: " + e.getMessage();
223                LOG.logInfo( msg );
224                throw new DatastoreException( msg, e );
225            }
226            return conn;
227        }
228    
229        /**
230         * Releases the connection.
231         * 
232         * @param conn
233         *            Connection to be released.
234         * @throws DatastoreException
235         */
236        protected void releaseConnection( SDEConnection conn )
237                                throws DatastoreException {
238            JDBCConnection jdbcConnection = ( (SQLDatastoreConfiguration) this.getConfiguration() ).getJDBCConnection();
239            try {
240                String url = jdbcConnection.getURL();
241                String[] tmp = url.split( ":" );
242                int instance = 5151;
243                if ( 2 == tmp.length ) {
244                    url = tmp[0];
245                    instance = Integer.parseInt( tmp[1] );
246                }
247                pool.releaseConnection( conn, url, instance, jdbcConnection.getSDEDatabase(),
248                                        jdbcConnection.getSDEVersion(), jdbcConnection.getUser() );
249            } catch ( Exception e ) {
250                String msg = "Cannot release database connection: " + e.getMessage();
251                LOG.logInfo( msg );
252                throw new DatastoreException( msg, e );
253            }
254        }
255    
256        /**
257         * Converts the <code>StatementBuffer</code> into a <code>PreparedStatement</code>, which
258         * is initialized and ready to be performed.
259         * 
260         * @param conn
261         *            connection to be used to create the <code>PreparedStatement</code>
262         * @param statementBuffer
263         * @return the <code>PreparedStatment</code>, ready to be performed
264         */
265        public SeQuery prepareStatement( SDEConnection conn, StatementBuffer statementBuffer ) {
266            LOG.logDebug( "Preparing statement: " + statementBuffer.getQueryString() );
267    
268            SeQuery query = null;
269            try {
270                query = new SeQuery( conn.getConnection() );
271                query.prepareSql( statementBuffer.getQueryString() );
272            } catch ( Exception e ) {
273                e.printStackTrace();
274            }
275    
276            // TODO
277            return query;
278        }
279    
280        @Override
281        public FeatureCollection performQuery( Query query, MappedFeatureType [] rootFts, DatastoreTransaction context )
282                                throws DatastoreException {
283            throw new DatastoreException( "method invocation for sde not applicable" );
284        }
285    
286        @Override
287        public void releaseTransaction( DatastoreTransaction ta )
288                                throws DatastoreException {
289            releaseConnection( ( (SDETransaction) ta ).getConnection() );
290        }
291    }