001    //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_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.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 (Mi, 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    }