/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ package testlib.uno; import com.sun.star.beans.PropertyValue; import com.sun.star.beans.PropertyState; import com.sun.star.beans.XPropertySet; import com.sun.star.container.ElementExistException; import com.sun.star.container.XNameAccess; import com.sun.star.frame.XStorable; import com.sun.star.lang.XMultiServiceFactory; import com.sun.star.sdb.XDocumentDataSource; import com.sun.star.sdb.XOfficeDatabaseDocument; import com.sun.star.sdbc.SQLException; import com.sun.star.sdbc.XCloseable; import com.sun.star.sdbc.XConnection; import com.sun.star.sdbc.XDataSource; import com.sun.star.sdbc.XStatement; import com.sun.star.sdbcx.XAppend; import com.sun.star.sdbcx.XTablesSupplier; import com.sun.star.uno.UnoRuntime; import com.sun.star.util.CloseVetoException; import java.util.HashMap; import java.util.Iterator; import java.util.Set; import java.io.File; import org.openoffice.test.common.FileUtil; public class DBUtil { // the service factory protected static XMultiServiceFactory m_orb; // the URL of the temporary file used for the database document protected static String m_databaseDocumentFile; // the database document protected static XOfficeDatabaseDocument m_databaseDocument; // the data source belonging to the database document protected static XDataSource m_dataSource; // the default connection protected static XConnection m_connection; static public void createNewDocument(final XMultiServiceFactory orb) throws Exception { m_orb = orb; createDBDocument(); } static public void loadNewDocument(final XMultiServiceFactory orb, final String _existingDocumentURL) throws Exception { m_orb = orb; getDocument(_existingDocumentURL); } /** * creates an empty database document in a temporary location */ public static void createDBDocument() throws Exception { final File documentFile = File.createTempFile("testdb", ".odb"); if (documentFile.exists()) documentFile.delete(); m_databaseDocumentFile = FileUtil.getUrl(documentFile); m_databaseDocument = (XOfficeDatabaseDocument) UnoRuntime .queryInterface( XOfficeDatabaseDocument.class, m_orb.createInstance("com.sun.star.sdb.OfficeDatabaseDocument")); m_dataSource = m_databaseDocument.getDataSource(); final XPropertySet dsProperties = (XPropertySet) UnoRuntime .queryInterface(XPropertySet.class, m_databaseDocument.getDataSource()); dsProperties.setPropertyValue("URL", "sdbc:embedded:hsqldb"); final XStorable storable = (XStorable) UnoRuntime.queryInterface( XStorable.class, m_databaseDocument); storable.storeAsURL(m_databaseDocumentFile, new PropertyValue[] { new PropertyValue("PickListEntry", 0, false, PropertyState.DIRECT_VALUE) }); } public static void getDocument(final String _docURL) throws Exception { m_databaseDocumentFile = _docURL; final XNameAccess dbContext = (XNameAccess) UnoRuntime.queryInterface( XNameAccess.class, m_orb.createInstance("com.sun.star.sdb.DatabaseContext")); final XDocumentDataSource dataSource = (XDocumentDataSource) UnoRuntime.queryInterface( XDocumentDataSource.class, dbContext.getByName(_docURL)); m_databaseDocument = dataSource.getDatabaseDocument(); m_dataSource = m_databaseDocument.getDataSource(); } /** * drops the table with a given name * * @param _name * the name of the table to drop * @param _ifExists * TRUE if it should be dropped only when it exists. */ static public void dropTable(final String _name, final boolean _ifExists) throws SQLException { final StringBuffer dropStatement = new StringBuffer("DROP TABLE \""); dropStatement.append(_name); if (_ifExists) { dropStatement.append("\" IF EXISTS"); } executeSQL(dropStatement.toString()); } static public void createTable(String _name, HsqlColumnDescriptor[] _columns, final boolean _dropIfExists) throws SQLException { if (_dropIfExists) { dropTable(_name, true); } createTable(_name, _columns); } /** * creates a table */ static public void createTable(String _name, HsqlColumnDescriptor[] _columns) throws SQLException { StringBuffer createStatement = new StringBuffer( "CREATE CACHED TABLE \""); createStatement.append(_name); createStatement.append("\" ( "); String primaryKeyList = ""; final HashMap foreignKeys = new HashMap(); final HashMap foreignKeyRefs = new HashMap(); final HsqlColumnDescriptor[] columns = _columns; for (int i = 0; i < columns.length; ++i) { if (i > 0) { createStatement.append(", "); } createStatement.append("\"" + columns[i].getName()); createStatement.append("\" " + columns[i].getTypeName()); if (columns[i].isRequired()) { createStatement.append(" NOT NULL"); } if (columns[i].isPrimaryKey()) { if (primaryKeyList.length() > 0) { primaryKeyList += ", "; } primaryKeyList += "\"" + columns[i].getName() + "\""; } if (columns[i].isForeignKey()) { final String foreignTable = columns[i].getForeignTable(); String foreignKeysForTable = foreignKeys .containsKey(foreignTable) ? (String) foreignKeys .get(foreignTable) : ""; if (foreignKeysForTable.length() > 0) { foreignKeysForTable += ", "; } foreignKeysForTable += "\"" + columns[i].getName() + "\""; foreignKeys.put(foreignTable, foreignKeysForTable); final StringBuffer foreignKeyRefsForTable = new StringBuffer( foreignKeyRefs.containsKey(foreignTable) ? (String) foreignKeyRefs .get(foreignTable) : ""); if (foreignKeyRefsForTable.length() > 0) { foreignKeyRefsForTable.append(", "); } foreignKeyRefsForTable.append("\"" + columns[i].getForeignColumn() + "\""); foreignKeyRefs.put(foreignTable, foreignKeyRefsForTable.toString()); } } if (primaryKeyList.length() > 0) { createStatement.append(", PRIMARY KEY ("); createStatement.append(primaryKeyList); createStatement.append(')'); } final Set foreignKeyTables = foreignKeys.keySet(); for (final Iterator foreignKey = foreignKeyTables.iterator(); foreignKey .hasNext();) { final String foreignTable = (String) foreignKey.next(); createStatement.append(", FOREIGN KEY ("); createStatement.append((String) foreignKeys.get(foreignTable)); createStatement.append(") REFERENCES \""); createStatement.append(foreignTable); createStatement.append("\"("); createStatement.append((String) foreignKeyRefs.get(foreignTable)); createStatement.append(')'); } createStatement.append(')'); // System.err.println( createStatement ); executeSQL(createStatement.toString()); } /** * executes the given SQL statement via the defaultConnection */ static public void executeSQL(final String statementString) throws SQLException { final XStatement statement = defaultConnection().createStatement(); statement.execute(statementString); } /** * returns a connection to the database * * Multiple calls to this method return the same connection. The * DbaseDatabase object keeps the ownership of the connection, so you don't * need to (and should not) dispose/close it. */ static public XConnection defaultConnection() throws SQLException { if (m_connection == null) m_connection = m_databaseDocument.getDataSource().getConnection("", ""); return m_connection; } /** * closes the database document * * Any CloseVetoExceptions fired by third parties are ignored, and any * reference to the database document is released. */ static public void close() { // close connection final XCloseable closeConn = (XCloseable) UnoRuntime.queryInterface( XCloseable.class, m_connection != null ? m_connection : null); if (closeConn != null) { try { closeConn.close(); } catch (SQLException e) { } } m_connection = null; // close document final com.sun.star.util.XCloseable closeDoc = (com.sun.star.util.XCloseable) UnoRuntime .queryInterface(com.sun.star.util.XCloseable.class, m_databaseDocument); if (closeDoc != null) { try { closeDoc.close(true); } catch (CloseVetoException e) { } } m_databaseDocument = null; } /** * returns the underlying database document */ static public XOfficeDatabaseDocument getDatabaseDocument() { return m_databaseDocument; } static public String getDocumentURL() { return m_databaseDocumentFile; } }