1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 import com.sun.star.beans.PropertyValue;
29 import com.sun.star.beans.XPropertySet;
30 import com.sun.star.container.XNameAccess;
31 import com.sun.star.frame.XStorable;
32 import com.sun.star.frame.XModel;
33 import com.sun.star.sdb.XOfficeDatabaseDocument;
34 import com.sun.star.sdbc.SQLException;
35 import com.sun.star.sdbc.XCloseable;
36 import com.sun.star.sdbc.XConnection;
37 import com.sun.star.sdbc.XStatement;
38 import com.sun.star.uno.UnoRuntime;
39 import com.sun.star.io.IOException;
40 import com.sun.star.sdb.XDocumentDataSource;
41 import com.sun.star.sdbc.XDataSource;
42 import com.sun.star.uno.XComponentContext;
43 import java.io.File;
44 
45 import com.sun.star.util.CloseVetoException;
46 import java.io.File;
47 
48 /**
49  *
50  * @author fs93730
51  */
52 public class HsqlDatabase
53 {
54     XComponentContext       m_context;
55     // the URL of the temporary file used for the database document
56     String                  m_databaseDocumentFile;
57     // the database document
58     XOfficeDatabaseDocument m_databaseDocument;
59     // the data source belonging to the database document
60     // the default connection
61     XConnection             m_connection;
62 
63     // --------------------------------------------------------------------------------------------------------
64     public HsqlDatabase( XComponentContext _context ) throws Exception
65     {
66         m_context = _context;
67         createDBDocument();
68     }
69 
70     // --------------------------------------------------------------------------------------------------------
71     public HsqlDatabase( XComponentContext _context, String _existingDocumentURL ) throws Exception
72     {
73         m_context = _context;
74         createDBDocument( _existingDocumentURL );
75     }
76 
77     // --------------------------------------------------------------------------------------------------------
78     private void createDBDocument( String _docURL ) throws Exception
79     {
80         m_databaseDocumentFile = _docURL;
81 
82         XNameAccess dbContext = (XNameAccess)UnoRuntime.queryInterface( XNameAccess.class,
83             m_context.getServiceManager().createInstanceWithContext( "com.sun.star.sdb.DatabaseContext", m_context ) );
84         XDocumentDataSource dataSource = (XDocumentDataSource)UnoRuntime.queryInterface( XDocumentDataSource.class,
85             dbContext.getByName( _docURL ) );
86 
87         m_databaseDocument = dataSource.getDatabaseDocument();
88     }
89 
90     /** creates an empty database document in a temporary location
91      */
92     private void createDBDocument() throws Exception
93     {
94         File documentFile = File.createTempFile("testdb",".odb");
95         documentFile.deleteOnExit();
96         m_databaseDocumentFile = URLHelper.getFileURLFromSystemPath( documentFile );
97 
98         m_databaseDocument = (XOfficeDatabaseDocument)UnoRuntime.queryInterface(
99             XOfficeDatabaseDocument.class, m_context.getServiceManager().createInstanceWithContext(
100                 "com.sun.star.sdb.OfficeDatabaseDocument", m_context ) );
101 
102         XPropertySet dsProperties = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, m_databaseDocument.getDataSource() );
103         dsProperties.setPropertyValue("URL", "sdbc:embedded:hsqldb");
104 
105         XStorable storable = (XStorable)UnoRuntime.queryInterface( XStorable.class, m_databaseDocument );
106         storable.storeAsURL( m_databaseDocumentFile, new PropertyValue[]{} );
107     }
108 
109     /** returns a connection to the database
110      *
111      * Multiple calls to this method return the same connection. The HsqlDatabase object keeps
112      * the ownership of the connection, so you don't need to (and should not) dispose/close it.
113      *
114      */
115     public XConnection defaultConnection() throws SQLException
116     {
117         if ( m_connection != null )
118             return m_connection;
119         m_connection  = m_databaseDocument.getDataSource().getConnection(new String(),new String());
120         return m_connection;
121     }
122 
123     /** executes the given SQL statement via the defaultConnection
124      */
125     public void executeSQL( String statementString ) throws SQLException
126     {
127         XStatement statement = defaultConnection().createStatement();
128         statement.execute( statementString );
129     }
130 
131     /** stores the database document
132     */
133     public void store() throws IOException
134     {
135         if ( m_databaseDocument != null )
136         {
137             XStorable storeDoc = (XStorable)UnoRuntime.queryInterface( XStorable.class,
138                 m_databaseDocument );
139             storeDoc.store();
140         }
141     }
142 
143     /** closes the database document
144      *
145      *  Any CloseVetoExceptions fired by third parties are ignored, and any reference to the
146      *  database document is released.
147      */
148     public void close()
149     {
150         // close connection
151         XCloseable closeConn = (XCloseable)UnoRuntime.queryInterface( XCloseable.class,
152             m_connection );
153         if ( closeConn != null )
154         {
155             try
156             {
157                 closeConn.close();
158             }
159             catch( SQLException e )
160             {
161             }
162         }
163         m_connection = null;
164 
165         // close document
166         com.sun.star.util.XCloseable closeDoc = (com.sun.star.util.XCloseable)UnoRuntime.queryInterface(
167             com.sun.star.util.XCloseable.class, m_databaseDocument );
168         if ( closeDoc != null )
169         {
170             try
171             {
172                 closeDoc.close( true );
173             }
174             catch( CloseVetoException e )
175             {
176             }
177         }
178         m_databaseDocument = null;
179     }
180 
181     /** closes the document, and deletes the underlying file
182      */
183     public void closeAndDelete()
184     {
185         close();
186 
187         if ( m_databaseDocumentFile != null )
188         {
189             try
190             {
191                 File file = new File(m_databaseDocumentFile);
192                 file.delete();
193             }
194             catch(Exception e)
195             {
196             }
197             m_databaseDocumentFile = null;
198         }
199     }
200 
201     /** returns the underlying database document
202     */
203     public XOfficeDatabaseDocument getDatabaseDocument()
204     {
205         return m_databaseDocument;
206     }
207 
208     /** returns the associated data source
209      */
210     public XDataSource getDataSource()
211     {
212         return m_databaseDocument.getDataSource();
213     }
214 
215     /** returns the model interface of the underlying database document
216     */
217     XModel getModel()
218     {
219         return (XModel)UnoRuntime.queryInterface( XModel.class, m_databaseDocument );
220     }
221 
222     /** drops the table with a given name
223 
224         @param _name
225             the name of the table to drop
226         @param _ifExists
227             TRUE if it should be dropped only when it exists.
228     */
229     public void dropTable( String _name, boolean _ifExists ) throws SQLException
230     {
231         String dropStatement = "DROP TABLE \"" + _name;
232         if ( _ifExists )
233             dropStatement += "\" IF EXISTS";
234         executeSQL( dropStatement );
235     }
236 
237     /** returns the URL of the ODB document represented by this instance
238      */
239     public String getDocumentURL()
240     {
241         return m_databaseDocumentFile;
242     }
243 
244     /** creates a row set operating the database, with a given command/type
245      */
246     public RowSet createRowSet( int _commandType, String _command )
247     {
248         return new RowSet( m_context, getDocumentURL(), _commandType, _command );
249     }
250 
251     protected void finalize() throws Throwable
252     {
253         closeAndDelete();
254         super.finalize();
255     }
256 }
257