schema update framework
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / LocalH2.java
1 /**
2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
5 *
6 * The contents of this file are subject to the Mozilla Public License Version 1.1
7 * See LICENSE.TXT at the top of this package for the full license terms.
8 */
9
10 package eu.etaxonomy.cdm.database;
11
12 import java.io.File;
13 import java.io.IOException;
14 import java.sql.Connection;
15 import java.sql.Driver;
16 import java.sql.DriverManager;
17 import java.sql.SQLException;
18 import java.util.Properties;
19
20 import javax.sql.DataSource;
21
22 import org.apache.commons.dbcp.BasicDataSource;
23 import org.apache.commons.pool.impl.GenericObjectPool;
24 import org.apache.log4j.Logger;
25 import org.h2.tools.Server;
26 import org.springframework.jdbc.CannotGetJdbcConnectionException;
27
28 import eu.etaxonomy.cdm.api.application.CdmApplicationUtils;
29 import eu.etaxonomy.cdm.model.name.NomenclaturalCode;
30
31
32 /**
33 * @author a.mueller
34 *
35 * IN WORK
36 *
37 */
38
39 public class LocalH2 extends BasicDataSource {
40 private static final Logger logger = Logger.getLogger(LocalH2.class);
41
42 private String sep = System.getProperty("file.separator");
43
44 /** url without database name */
45 protected String pureUrl = "jdbc:h2:";
46 /** database name */
47 protected String dbName = "cdm";
48 /** path, where database should be stored in the file system */
49 protected String databasePath = getDefaultPath();
50 /** Server instance */
51 protected Server h2Server;
52 /** if true starts server on init() */
53 protected boolean isStartServer = true;
54 /** makes the Server silent (no messages) */
55 protected boolean isSilent = true;
56 /** default driver class name */
57 protected String DEFAULT_DRIVER_CLASS_NAME = "org.h2.Driver";
58 String mode = H2Mode.EMBEDDED.toString();
59
60 private NomenclaturalCode nomenclaturalCode;
61
62 /**
63 *
64 */
65 public LocalH2() {
66 setDriverClassName(DEFAULT_DRIVER_CLASS_NAME);
67 setLocalUrl();
68 }
69
70 /**
71 * @param url
72 * @throws CannotGetJdbcConnectionException
73 */
74 public LocalH2(String url) throws CannotGetJdbcConnectionException {
75 super();
76 this.setUrl(url);
77 setDriverClassName(DEFAULT_DRIVER_CLASS_NAME);
78 }
79
80 /* FIXME This is a workaround to solve a problem with dbcp connection pooling.
81 * Remove this when dbcp connection pool gets configured correctly
82 *
83 * (non-Javadoc)
84 * @see org.apache.commons.dbcp.BasicDataSource#createDataSource()
85 */
86 @Override
87 protected synchronized DataSource createDataSource() throws SQLException {
88 super.createDataSource();
89 connectionPool.setWhenExhaustedAction(GenericObjectPool.WHEN_EXHAUSTED_GROW);
90 return dataSource;
91 }
92
93 /**
94 * @param url
95 * @param username
96 * @param password
97 * @throws CannotGetJdbcConnectionException
98 */
99 public LocalH2(String url, String username, String password)
100 throws CannotGetJdbcConnectionException {
101 this(url);
102 this.setUsername(username);
103 this.setPassword(password);
104 }
105
106 /**
107 * @param driverClassName
108 * @param url
109 * @param username
110 * @param password
111 * @throws CannotGetJdbcConnectionException
112 */
113 public LocalH2(String driverClassName, String url, String username,
114 String password) throws CannotGetJdbcConnectionException {
115 this(url, username, password);
116 this.setDriverClassName(driverClassName);
117 }
118
119 //** ********************************************************************************/
120
121 public void init(){
122 logger.info("LocalH2init");
123 if (true){ //starting sever is not necessary for H2
124 return;
125 }
126 if (isStartServer){
127 this.startH2Server();
128 }
129 }
130
131 public void destroy(){
132 this.stopH2Server();
133 }
134
135
136 //checks if h2-server is started, if not it will be started (taken over from hsqldb, maybe not necessary for H2
137 private void startH2Server(){
138 try {
139 Driver driver = DriverManager.getDriver(getUrl());
140 Properties prop = new Properties();
141 prop.setProperty("user", this.getUsername());
142 prop.setProperty("password", this.getPassword());
143 Connection con = driver.connect(getUrl(), prop);
144 if (con == null) {
145 logger.warn("Connection to URL " + getUrl() + " could not be established");
146 throw new SQLException();
147 }
148 } catch (SQLException e) {
149 try {
150 //server is probably not runing on the url (or login is wrong !!)
151 logger.info("Start H2Server");
152 String[] args = new String[] { "-trace" };
153 h2Server = Server.createTcpServer(args).start();
154 // h2Server.setDatabaseName(0, getDbName());
155 // h2Server.setDatabasePath(0, getDatabasePath());
156 h2Server.start();
157 } catch (SQLException sqle1) {
158 logger.error("SQL Exception when starting Local H2Server: "+ sqle1);
159 } catch (RuntimeException e1) {
160 logger.error("Local H2Server could not be started or connection to existing server could not be established.");
161 }
162 }
163 }
164
165
166 /**
167 * stops the Hsqldb Server
168 */
169 private void stopH2Server(){
170 if (h2Server != null){
171 logger.info("stop H2Server");
172 h2Server.stop();
173 }
174 }
175
176 private static final String getDefaultPath(){
177 File path;
178 try {
179 path = CdmApplicationUtils.getWritableResourceDir();
180 } catch (IOException e) {
181 logger.error(e);
182 throw new RuntimeException(e);
183 }
184 String subPath = File.separator + "h2" + File.separator + "LocalH2";
185 return path + subPath;
186 }
187
188 /**
189 * @return the dbPath
190 */
191 public String getDatabasePath() {
192 return databasePath;
193 }
194
195 /**
196 * @param dbPath the dbPath to set
197 */
198 public void setDatabasePath(String databasePath) {
199 if (databasePath.endsWith(sep)){
200 databasePath = databasePath + "localCdm";
201 }
202 this.databasePath = databasePath;
203 }
204
205 /**
206 * @return the isStartServer
207 */
208 public boolean isStartServer() {
209 return isStartServer;
210 }
211
212 /**
213 * @param isStartServer the isStartServer to set
214 */
215 public void setStartServer(boolean isStartServer) {
216 this.isStartServer = isStartServer;
217 }
218
219 public void setLocalUrl(){
220 String dbName = "cdmLocal";
221 String localUrlString = pureUrl + "file:" + getDefaultPath() + "/" + dbName;
222 logger.info("setLocalUrl: " + localUrlString);
223 setUrl(localUrlString);
224 }
225
226 public void setMode(String mode){
227 this.mode = mode;
228 }
229
230 public String getMode(){
231 return mode;
232 }
233
234 public void setNomenclaturalCode(NomenclaturalCode code){
235 this.nomenclaturalCode = code;
236 }
237
238
239 }