View Javadoc

1   /*
2    * $Id: MuleDerbyTestUtils.java 19191 2010-08-25 21:05:23Z tcarlson $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.tck.util;
12  
13  import org.mule.util.ClassUtils;
14  import org.mule.util.FileUtils;
15  
16  import java.io.File;
17  import java.io.IOException;
18  import java.lang.reflect.Method;
19  import java.net.URL;
20  import java.sql.Connection;
21  import java.sql.Driver;
22  import java.sql.DriverManager;
23  import java.sql.SQLException;
24  import java.sql.Statement;
25  import java.util.Properties;
26  
27  import javax.sql.DataSource;
28  
29  public class MuleDerbyTestUtils
30  {
31      private static final String DERBY_DRIVER_CLASS = "org.apache.derby.jdbc.EmbeddedDriver";
32      private static final String DERBY_DATASOURCE_CLASS = "org.apache.derby.jdbc.EmbeddedDataSource";
33      
34      //class cannot be instantiated
35      private MuleDerbyTestUtils()
36      {
37          super();
38      }
39      
40      //by default, set the derby home to the target directory
41      public static String setDerbyHome()
42      {
43          return setDerbyHome("target");
44      }
45      
46      public static String setDerbyHome(String path)
47      {
48          File derbySystemHome = new File(System.getProperty("user.dir"), path);
49          System.setProperty("derby.system.home",  derbySystemHome.getAbsolutePath());
50          return derbySystemHome.getAbsolutePath();
51      }
52      
53      /**
54       * Properly shutdown an embedded Derby database
55       * 
56       * @throws SQLException
57       * @see <h href="http://db.apache.org/derby/docs/10.3/devguide/tdevdvlp20349.html">Derby docs</a>
58       */
59      public static void stopDatabase() throws SQLException
60      {
61          try
62          {
63              // force loading the driver so it's available even if no prior connection to the
64              // database was made
65              ClassUtils.instanciateClass(DERBY_DRIVER_CLASS);
66  
67              DriverManager.getConnection("jdbc:derby:;shutdown=true");
68          }
69          catch (SQLException sqlex)
70          {
71              // this exception is documented to be thrown upon shutdown
72              if (!"XJ015".equals(sqlex.getSQLState()))
73              {
74                  throw sqlex;
75              }
76          }
77          catch (Exception ex)
78          {
79              // this can only happen when the driver class is not in classpath. In this case, just
80              // throw up
81              throw new RuntimeException(ex);
82          }
83      }
84      
85      public static void cleanupDerbyDb(String databaseName) throws IOException, SQLException
86      {
87          cleanupDerbyDb(setDerbyHome(), databaseName);
88      }
89      
90      public static void cleanupDerbyDb(String derbySystemHome, String databaseName) throws IOException, SQLException
91      {
92          stopDatabase();
93          FileUtils.deleteTree(new File(derbySystemHome + File.separator + databaseName));
94      }
95      
96      /** 
97       * Start a previously created (and stopped) database 
98       */
99      public static void startDataBase(String databaseName) throws Exception
100     {
101         Driver derbyDriver = (Driver) ClassUtils.instanciateClass(DERBY_DRIVER_CLASS);
102 
103         Method connectMethod = derbyDriver.getClass().getMethod("connect", String.class, Properties.class);
104 
105         String connectionName = "jdbc:derby:" + databaseName;
106         connectMethod.invoke(derbyDriver, connectionName, null);
107     }
108 
109     /**
110      * Create a new embedded database
111      * @param databaseName
112      * @throws SQLException
113      */
114     public static void createDataBase(String databaseName) throws SQLException
115     {
116         createDataBase(databaseName, (String[]) null);
117     }
118 
119     /**
120      * Create a new embedded database
121      * @param databaseName
122      * @param creationSql - SQL used to create and populate initial database tables
123      * @throws SQLException
124      */
125     public static void createDataBase(String databaseName, String creationSql) throws SQLException
126     {
127         createDataBase(databaseName, new String[] { creationSql } );
128     }
129     
130     /**
131      * Create a new embedded database
132      * @param databaseName
133      * @param creationSql - SQL used to create and populate initial database tables
134      * @throws SQLException
135      */
136     public static void createDataBase(String databaseName, String[] creationSql) throws SQLException
137     {
138         createDataBase(databaseName, creationSql, null);
139     }
140     
141     /**
142      * Create a new embedded database
143      * @param databaseName
144      * @param creationSql - SQL used to create and populate initial database tables
145      * @throws SQLException
146      */
147     public static void createDataBase(String databaseName, String[] creationSql, Properties properties) throws SQLException
148     {
149         // Do not use the EmbeddedDriver class here directly to avoid compile time references
150         // on derby.jar
151         try
152         {
153             String connectionName = "jdbc:derby:" + databaseName + ";create=true";
154             /*
155              * EmbeddedDriver derbyDriver = new EmbeddedDriver();
156              * derbyDriver.connect(connectionName, null);
157              */
158             Driver derbyDriver = (Driver) ClassUtils.instanciateClass(DERBY_DRIVER_CLASS);
159             Method connectMethod = derbyDriver.getClass().getMethod("connect", String.class, Properties.class);
160             connectMethod.invoke(derbyDriver, connectionName, properties);
161 
162             if (creationSql != null)
163             {
164                 /*
165                  * EmbeddedDataSource embeddedDS = new EmbeddedDataSource();
166                  * embeddedDS.setDatabaseName(databaseName);
167                  */
168                 DataSource embeddedDS = (DataSource) ClassUtils.instanciateClass(DERBY_DATASOURCE_CLASS);
169                 Method m = embeddedDS.getClass().getMethod("setDatabaseName", String.class);
170                 m.invoke(embeddedDS, databaseName);
171 
172                 Connection con = null;
173                 try
174                 {
175                     con = embeddedDS.getConnection();
176                     Statement st = con.createStatement();
177                     for (String aCreationSql : creationSql)
178                     {
179                         st.execute(aCreationSql);
180                     }
181                     con.commit();
182                 }
183                 finally
184                 {
185                     if (con != null && !con.isClosed())
186                     {
187                         con.close();
188                     }
189                 }
190             }
191         }
192         catch (Exception ex)
193         {
194             throw new RuntimeException("Error creating the database " + databaseName, ex);
195         }
196     }
197     
198     public static String loadDatabaseName(String propertiesLocation, String propertyName) throws IOException
199     {
200         Properties derbyProperties = new Properties();
201         URL resource = ClassUtils.getResource(propertiesLocation, MuleDerbyTestUtils.class);
202         derbyProperties.load(resource.openStream());
203         return derbyProperties.getProperty(propertyName);
204     }
205 
206     public static void defaultDerbyCleanAndInit(String propertiesLocation, String propertyName) throws IOException, SQLException
207     {
208         String derbyHome = setDerbyHome();
209         String dbName = loadDatabaseName(propertiesLocation, propertyName);
210         cleanupDerbyDb(derbyHome, dbName);
211         createDataBase(dbName);
212     }
213 }
214 
215