Project

General

Profile

Download (9.03 KB) Statistics
| Branch: | Tag: | Revision:
1
// $Id$
2
/**
3
* Copyright (C) 2007 EDIT
4
* European Distributed Institute of Taxonomy 
5
* http://www.e-taxonomy.eu
6
* 
7
* The contents of this file are subject to the Mozilla Public License Version 1.1
8
* See LICENSE.TXT at the top of this package for the full license terms.
9
*/
10

    
11
package eu.etaxonomy.cdm.api.service;
12

    
13
import java.sql.Connection;
14
import java.sql.ResultSet;
15
import java.sql.SQLException;
16
import java.sql.Statement;
17
import java.util.HashMap;
18
import java.util.Map;
19

    
20
import javax.sql.DataSource;
21

    
22
import org.apache.log4j.Logger;
23
import org.hibernate.SessionFactory;
24
import org.springframework.beans.BeansException;
25
import org.springframework.beans.factory.annotation.Autowired;
26
import org.springframework.context.ApplicationContext;
27
import org.springframework.context.ApplicationContextAware;
28
import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource;
29
import org.springframework.orm.hibernate4.SessionFactoryUtils;
30
import org.springframework.stereotype.Service;
31
import org.springframework.transaction.annotation.Transactional;
32

    
33
import eu.etaxonomy.cdm.api.application.CdmApplicationController;
34
import eu.etaxonomy.cdm.config.CdmPersistentSourceUtils;
35
import eu.etaxonomy.cdm.config.CdmSourceException;
36
import eu.etaxonomy.cdm.database.CdmDataSource;
37
import eu.etaxonomy.cdm.database.CdmPersistentDataSource;
38
import eu.etaxonomy.cdm.database.DataSourceNotFoundException;
39
import eu.etaxonomy.cdm.database.DatabaseTypeEnum;
40
import eu.etaxonomy.cdm.database.H2Mode;
41
import eu.etaxonomy.cdm.database.ICdmDataSource;
42
import eu.etaxonomy.cdm.model.common.init.TermNotFoundException;
43
import eu.etaxonomy.cdm.model.metadata.CdmMetaData.MetaDataPropertyName;
44
import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
45

    
46

    
47

    
48
/**
49
 * Implementation of service which provides functionality to directly access database 
50
 * related information.
51
 * 
52
 * @author a.mueller
53
 *
54
 */
55
@Service
56
@Transactional(readOnly = true)
57
public class DatabaseServiceHibernateImpl  implements IDatabaseService, ApplicationContextAware {
58
	private static final Logger logger = Logger.getLogger(DatabaseServiceHibernateImpl.class);
59
	
60
	private static final String TMP_DATASOURCE = "tmp"; 
61
	
62
	@Autowired
63
	private SessionFactory factory;
64
	
65
	@Autowired
66
	protected ApplicationContext appContext;
67
	
68
	private CdmApplicationController application;
69
	
70

    
71
	
72
	
73
	/* (non-Javadoc)
74
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#setApplicationController(eu.etaxonomy.cdm.api.application.CdmApplicationController)
75
	 */
76
	public void setApplicationController(CdmApplicationController cdmApplicationController){
77
		this.application = cdmApplicationController;
78
	}
79
	
80
	
81
	/* (non-Javadoc)
82
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#connectToDatasource(eu.etaxonomy.cdm.database.CdmDataSource)
83
	 */
84
	public boolean connectToDatasource(CdmPersistentDataSource dataSource) throws TermNotFoundException{
85
		this.application.changeDataSource(dataSource);
86
		logger.debug("DataSource changed to " + dataSource.getName());
87
		return true;
88
	}
89
	
90
	/* (non-Javadoc)
91
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#connectToDatabase(eu.etaxonomy.cdm.database.DatabaseTypeEnum, java.lang.String, java.lang.String, java.lang.String, java.lang.String, int)
92
	 */
93
	public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum, String server,
94
			String database, String username, String password, int port, String filePath, H2Mode mode, NomenclaturalCode code) throws TermNotFoundException  {
95
		ICdmDataSource dataSource = CdmDataSource.NewInstance(databaseTypeEnum, server, database, port, username, password, code);
96
		CdmPersistentDataSource tmpDataSource =  saveDataSource(TMP_DATASOURCE, dataSource);
97
		boolean result = connectToDatasource(tmpDataSource);
98
		CdmPersistentSourceUtils.delete(tmpDataSource);
99
		return result;
100
	}
101

    
102

    
103
	/* (non-Javadoc)
104
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#connectToDatabase(eu.etaxonomy.cdm.database.DatabaseTypeEnum, java.lang.String, java.lang.String, java.lang.String, java.lang.String)
105
	 */
106
	public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum, String server,
107
			String database, String username, String password)  throws TermNotFoundException {
108
		return connectToDatabase(databaseTypeEnum, server, database, username, password, databaseTypeEnum.getDefaultPort(), null, null, null) ;
109
	}
110
	
111
	/* (non-Javadoc)
112
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#saveDataSource(java.lang.String, eu.etaxonomy.cdm.database.ICdmDataSource)
113
	 */
114
	public CdmPersistentDataSource saveDataSource(String strDataSourceName,
115
			ICdmDataSource dataSource) {
116
		return CdmPersistentDataSource.save(strDataSourceName, dataSource);
117
	}
118
	
119
	/* (non-Javadoc)
120
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#updateDataSource(java.lang.String, eu.etaxonomy.cdm.database.CdmPersistentDataSource)
121
	 */
122
	public CdmPersistentDataSource updateDataSource(String strDataSourceName,
123
			CdmPersistentDataSource dataSource) throws DataSourceNotFoundException {
124
		return CdmPersistentDataSource.update(strDataSourceName, dataSource);
125
	}
126

    
127
	/* (non-Javadoc)
128
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getUrl()
129
	 */
130
	public String getUrl() {
131
		return getDataSource().getUrl();
132
	}
133

    
134
	/* (non-Javadoc)
135
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getUsername()
136
	 */
137
	public String getUsername() {
138
		return getDataSource().getUsername();
139
	}
140

    
141
	/**
142
	 * Returns the AbstractDriverBasedDataSource from hibernate,
143
	 * generalized in order to also allow using SimpleDriverDataSource.
144
	 * 
145
	 * @return the AbstractDriverBasedDataSource from the hibernate layer 
146
	 */
147
	private AbstractDriverBasedDataSource getDataSource(){
148
		AbstractDriverBasedDataSource ds = (AbstractDriverBasedDataSource)SessionFactoryUtils.getDataSource(factory);
149
		return ds;
150
	}
151

    
152

    
153
	/* (non-Javadoc)
154
	 * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
155
	 */
156
	public void setApplicationContext(ApplicationContext applicationContext)
157
			throws BeansException {
158
		this.appContext = applicationContext;
159
	}
160
	
161
	
162
	
163
	/* (non-Javadoc)
164
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getDbSchemaVersion()
165
	 */
166
	@Override
167
	public  String getDbSchemaVersion() throws CdmSourceException  {		
168
		try {
169
			return (String)getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION.getSqlQuery());
170
		} catch (SQLException e) {
171
			throw new CdmSourceException(e.getMessage());	
172
		}
173
	}
174
	
175
    
176
	/* (non-Javadoc)
177
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#isDbEmpty()
178
	 */
179
	@Override
180
	public boolean isDbEmpty() throws CdmSourceException {
181
		// Any CDM DB should have a schema version
182
		String dbSchemaVersion = (String) getDbSchemaVersion();		
183
		return (dbSchemaVersion == null || dbSchemaVersion.equals(""));
184
	}
185
	
186
    /**
187
     * Execute a SQL query which returns a single value
188
     * 
189
     * @param query , which returns a single value
190
     * @return
191
     * @throws SQLException
192
     */
193
    private Object getSingleValue(String query) throws SQLException {
194
        String queryString = query == null? "(null)": query;
195
        //ResultSet resultSet = executeQuery(query);
196
        ResultSet resultSet = null;
197
        
198
        Connection connection = SessionFactoryUtils.getDataSource(factory).getConnection();
199
        if (connection != null){
200
        	             	
201
            Statement statement = connection.createStatement();
202
            resultSet = statement.executeQuery(query);         
203
            
204
            if (resultSet == null || resultSet.next() == false){
205
                logger.info("No record returned for query " +  queryString);
206
                return null;
207
            }
208
            if (resultSet.getMetaData().getColumnCount() != 1){
209
                logger.info("More than one column selected in query" +  queryString);
210
                //first value will be taken
211
            }
212
            Object object = resultSet.getObject(1);
213
            if (resultSet.next()){
214
                logger.info("Multiple results for query " +  queryString);
215
                //first row will be taken
216
            }
217
            // making sure we close all resources so we don't run out of
218
            // connections in the connection pool
219
            resultSet.close();
220
            statement.close();
221
            connection.close();
222
            
223
            return object;
224
        }else{
225
            throw new RuntimeException("Could not establish connection to database");
226
        }
227

    
228
    }
229

    
230

    
231
	@Override
232
	public Map<MetaDataPropertyName, String> getCdmMetadataMap() throws CdmSourceException {
233
		Map<MetaDataPropertyName, String> cdmMetaDataMap = new HashMap<MetaDataPropertyName, String>();
234
		
235
		for(MetaDataPropertyName mdpn : MetaDataPropertyName.values()){
236
			String value = null;
237
			try {
238
				value = (String)getSingleValue(mdpn.getSqlQuery());
239
			} catch (SQLException e) {
240
				throw new CdmSourceException(e.getMessage());
241
			}			
242
			if(value != null) {
243
				cdmMetaDataMap.put(mdpn, value);
244
			}
245
		}
246
		return cdmMetaDataMap;
247
	}
248

    
249
}
(10-10/84)