Project

General

Profile

Download (8.77 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 org.apache.log4j.Logger;
21
import org.hibernate.SessionFactory;
22
import org.springframework.beans.BeansException;
23
import org.springframework.beans.factory.annotation.Autowired;
24
import org.springframework.context.ApplicationContext;
25
import org.springframework.context.ApplicationContextAware;
26
import org.springframework.jdbc.datasource.AbstractDriverBasedDataSource;
27
import org.springframework.orm.hibernate5.SessionFactoryUtils;
28
import org.springframework.stereotype.Service;
29
import org.springframework.transaction.annotation.Transactional;
30

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

    
44

    
45

    
46
/**
47
 * Implementation of service which provides functionality to directly access database
48
 * related information.
49
 *
50
 * @author a.mueller
51
 *
52
 */
53
@Service
54
@Transactional(readOnly = true)
55
public class DatabaseServiceHibernateImpl  implements IDatabaseService, ApplicationContextAware {
56
	private static final Logger logger = Logger.getLogger(DatabaseServiceHibernateImpl.class);
57

    
58
	private static final String TMP_DATASOURCE = "tmp";
59

    
60
	@Autowired
61
	private SessionFactory factory;
62

    
63
	@Autowired
64
	protected ApplicationContext appContext;
65

    
66
	private CdmApplicationController application;
67

    
68

    
69

    
70

    
71
	/* (non-Javadoc)
72
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#setApplicationController(eu.etaxonomy.cdm.api.application.CdmApplicationController)
73
	 */
74
	@Override
75
    public void setApplicationController(CdmApplicationController cdmApplicationController){
76
		this.application = cdmApplicationController;
77
	}
78

    
79

    
80
	/* (non-Javadoc)
81
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#connectToDatasource(eu.etaxonomy.cdm.database.CdmDataSource)
82
	 */
83
	@Override
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
	@Override
94
    public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum, String server,
95
			String database, String username, String password, int port, String filePath, H2Mode mode, NomenclaturalCode code) throws TermNotFoundException  {
96
		ICdmDataSource dataSource = CdmDataSource.NewInstance(databaseTypeEnum, server, database, port, username, password, code);
97
		CdmPersistentDataSource tmpDataSource =  saveDataSource(TMP_DATASOURCE, dataSource);
98
		boolean result = connectToDatasource(tmpDataSource);
99
		CdmPersistentSourceUtils.delete(tmpDataSource);
100
		return result;
101
	}
102

    
103

    
104
	/* (non-Javadoc)
105
	 * @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)
106
	 */
107
	@Override
108
    public boolean connectToDatabase(DatabaseTypeEnum databaseTypeEnum, String server,
109
			String database, String username, String password)  throws TermNotFoundException {
110
		return connectToDatabase(databaseTypeEnum, server, database, username, password, databaseTypeEnum.getDefaultPort(), null, null, null) ;
111
	}
112

    
113
	/* (non-Javadoc)
114
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#saveDataSource(java.lang.String, eu.etaxonomy.cdm.database.ICdmDataSource)
115
	 */
116
	@Override
117
    public CdmPersistentDataSource saveDataSource(String strDataSourceName,
118
			ICdmDataSource dataSource) {
119
		return CdmPersistentDataSource.save(strDataSourceName, dataSource);
120
	}
121

    
122
	/* (non-Javadoc)
123
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#updateDataSource(java.lang.String, eu.etaxonomy.cdm.database.CdmPersistentDataSource)
124
	 */
125
	@Override
126
    public CdmPersistentDataSource updateDataSource(String strDataSourceName,
127
			CdmPersistentDataSource dataSource) throws DataSourceNotFoundException {
128
		return CdmPersistentDataSource.update(strDataSourceName, dataSource);
129
	}
130

    
131
	/* (non-Javadoc)
132
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getUrl()
133
	 */
134
	@Override
135
    public String getUrl() {
136
		return getDataSource().getUrl();
137
	}
138

    
139
	/* (non-Javadoc)
140
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getUsername()
141
	 */
142
	@Override
143
    public String getUsername() {
144
		return getDataSource().getUsername();
145
	}
146

    
147
	/**
148
	 * Returns the AbstractDriverBasedDataSource from hibernate,
149
	 * generalized in order to also allow using SimpleDriverDataSource.
150
	 *
151
	 * @return the AbstractDriverBasedDataSource from the hibernate layer
152
	 */
153
	private AbstractDriverBasedDataSource getDataSource(){
154
		AbstractDriverBasedDataSource ds = (AbstractDriverBasedDataSource)SessionFactoryUtils.getDataSource(factory);
155
		return ds;
156
	}
157

    
158

    
159
	/* (non-Javadoc)
160
	 * @see org.springframework.context.ApplicationContextAware#setApplicationContext(org.springframework.context.ApplicationContext)
161
	 */
162
	@Override
163
    public void setApplicationContext(ApplicationContext applicationContext)
164
			throws BeansException {
165
		this.appContext = applicationContext;
166
	}
167

    
168

    
169

    
170
	/* (non-Javadoc)
171
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#getDbSchemaVersion()
172
	 */
173
	@Override
174
	public  String getDbSchemaVersion() throws CdmSourceException  {
175
		try {
176
			return (String)getSingleValue(MetaDataPropertyName.DB_SCHEMA_VERSION.getSqlQuery());
177
		} catch (SQLException e) {
178
			throw new CdmSourceException(e.getMessage());
179
		}
180
	}
181

    
182

    
183
	/* (non-Javadoc)
184
	 * @see eu.etaxonomy.cdm.api.service.IDatabaseService#isDbEmpty()
185
	 */
186
	@Override
187
	public boolean isDbEmpty() throws CdmSourceException {
188
		// Any CDM DB should have a schema version
189
		String dbSchemaVersion = getDbSchemaVersion();
190
		return (dbSchemaVersion == null || dbSchemaVersion.equals(""));
191
	}
192

    
193
    /**
194
     * Execute a SQL query which returns a single value
195
     *
196
     * @param query , which returns a single value
197
     * @return
198
     * @throws SQLException
199
     */
200
    private Object getSingleValue(String query) throws SQLException {
201
        String queryString = query == null? "(null)": query;
202
        //ResultSet resultSet = executeQuery(query);
203
        ResultSet resultSet = null;
204

    
205
        Connection connection = SessionFactoryUtils.getDataSource(factory).getConnection();
206
        if (connection != null){
207

    
208
            Statement statement = connection.createStatement();
209
            resultSet = statement.executeQuery(query);
210

    
211
            if (resultSet == null || resultSet.next() == false){
212
                logger.info("No record returned for query " +  queryString);
213
                return null;
214
            }
215
            if (resultSet.getMetaData().getColumnCount() != 1){
216
                logger.info("More than one column selected in query" +  queryString);
217
                //first value will be taken
218
            }
219
            Object object = resultSet.getObject(1);
220
            if (resultSet.next()){
221
                logger.info("Multiple results for query " +  queryString);
222
                //first row will be taken
223
            }
224
            // making sure we close all resources so we don't run out of
225
            // connections in the connection pool
226
            resultSet.close();
227
            statement.close();
228
            connection.close();
229

    
230
            return object;
231
        }else{
232
            throw new RuntimeException("Could not establish connection to database");
233
        }
234

    
235
    }
236

    
237

    
238
	@Override
239
	public Map<MetaDataPropertyName, String> getCdmMetadataMap() throws CdmSourceException {
240
		Map<MetaDataPropertyName, String> cdmMetaDataMap = new HashMap<MetaDataPropertyName, String>();
241

    
242
		for(MetaDataPropertyName mdpn : MetaDataPropertyName.values()){
243
			String value = null;
244
			try {
245
				value = (String)getSingleValue(mdpn.getSqlQuery());
246
			} catch (SQLException e) {
247
				throw new CdmSourceException(e.getMessage());
248
			}
249
			if(value != null) {
250
				cdmMetaDataMap.put(mdpn, value);
251
			}
252
		}
253
		return cdmMetaDataMap;
254
	}
255

    
256
}
(10-10/97)