2 * This file is part of the LibreOffice project.
4 * This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 * This file incorporates work covered by the following license notice:
10 * Licensed to the Apache Software Foundation (ASF) under one or more
11 * contributor license agreements. See the NOTICE file distributed
12 * with this work for additional information regarding copyright
13 * ownership. The ASF licenses this file to you under the Apache
14 * License, Version 2.0 (the "License"); you may not use this file
15 * except in compliance with the License. You may obtain a copy of
16 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 import com
.sun
.star
.uno
.Exception
;
22 import com
.sun
.star
.lang
.XMultiServiceFactory
;
23 import com
.sun
.star
.uno
.UnoRuntime
;
25 import com
.sun
.star
.beans
.PropertyValue
;
26 import com
.sun
.star
.beans
.XPropertySet
;
27 import com
.sun
.star
.sdbc
.XConnection
;
28 import com
.sun
.star
.util
.Date
;
29 import com
.sun
.star
.uno
.XNamingService
;
30 import com
.sun
.star
.task
.XInteractionHandler
;
31 import com
.sun
.star
.sdb
.XCompletedConnection
;
32 import com
.sun
.star
.frame
.XStorable
;
33 import com
.sun
.star
.sdb
.XDocumentDataSource
;
34 import java
.sql
.Statement
;
35 import java
.sql
.Connection
;
36 import java
.sql
.DriverManager
;
39 * Provides useful methods for working with SOffice databases.
40 * Database creation, data transferring, outputting information.
42 public class DBTools
{
44 private final XMultiServiceFactory xMSF
;
45 private XNamingService dbContext
;
47 public static final String TST_JDBC_DRIVER
= "org.gjt.mm.mysql.Driver";
49 // constants for TestDB table column indexes
50 public static final int TST_STRING
= 1 ;
51 public static final int TST_INT
= 2 ;
52 private static final int TST_DOUBLE
= 5 ;
53 private static final int TST_DATE
= 6 ;
54 private static final int TST_BOOLEAN
= 10 ;
55 private static final int TST_CHARACTER_STREAM
= 11 ;
56 private static final int TST_BINARY_STREAM
= 12 ;
58 // constants for TestDB columns names
59 public static final String TST_STRING_F
= "_TEXT" ;
60 public static final String TST_INT_F
= "_INT" ;
61 public static final String TST_DOUBLE_F
= "_DOUBLE" ;
62 public static final String TST_DATE_F
= "_DATE" ;
63 private static final String TST_BOOLEAN_F
= "_BOOL" ;
64 private static final String TST_CHARACTER_STREAM_F
= "_MEMO1" ;
65 public static final String TST_BINARY_STREAM_F
= "_MEMO2" ;
68 * Values for filling test table.
70 public static final Object
[][] TST_TABLE_VALUES
= new Object
[][] {
71 {"String1", Integer
.valueOf(1), null, null, new Double(1.1),
72 new Date((short) 1,(short) 1, (short) 2001), null, null, null,
73 Boolean
.TRUE
, null, null},
74 {"String2", Integer
.valueOf(2), null, null, new Double(1.2),
75 new Date((short) 2, (short) 1,(short) 2001), null, null, null,
76 Boolean
.FALSE
, null, null},
77 {null, null, null, null, null,
78 null, null, null, null,
83 * It's just a structure with some useful methods for representing
84 * <code>com.sun.star.sdb.DataSource</code> service. All this
85 * service's properties are stored in appropriate class fields.
86 * Class also allows to construct its instances using service
87 * information, and create new service instance upon class
89 * @see com.sun.star.sdb.DataSource
91 public class DataSourceInfo
{
93 * Representation of <code>'Name'</code> property.
95 public String Name
= null ;
97 * Representation of <code>'URL'</code> property.
99 public String URL
= null ;
101 * Representation of <code>'Info'</code> property.
103 public PropertyValue
[] Info
= null ;
105 * Representation of <code>'User'</code> property.
107 public String User
= null ;
109 * Representation of <code>'Password'</code> property.
111 public String Password
= null ;
113 * Representation of <code>'IsPasswordRequired'</code> property.
115 public Boolean IsPasswordRequired
= null ;
118 * Creates new <code>com.sun.star.sdb.DataSource</code> service
119 * instance and copies all fields (which are not null) to
120 * appropriate service properties.
121 * @return <code>com.sun.star.sdb.DataSource</code> service.
123 public Object
getDataSourceService() throws Exception
125 Object src
= xMSF
.createInstance("com.sun.star.sdb.DataSource") ;
127 XPropertySet props
= UnoRuntime
.queryInterface
128 (XPropertySet
.class, src
) ;
130 if (Name
!= null) props
.setPropertyValue("Name", Name
) ;
131 if (URL
!= null) props
.setPropertyValue("URL", URL
) ;
132 if (Info
!= null) props
.setPropertyValue("Info", Info
) ;
133 if (User
!= null) props
.setPropertyValue("User", User
) ;
134 if (Password
!= null) props
.setPropertyValue("Password", Password
) ;
135 if (IsPasswordRequired
!= null) props
.setPropertyValue("IsPasswordRequired", IsPasswordRequired
) ;
141 * Creates class instance.
142 * @param xMSF <code>XMultiServiceFactory</code>.
144 public DBTools(XMultiServiceFactory xMSF
)
148 Object cont
= xMSF
.createInstance("com.sun.star.sdb.DatabaseContext") ;
150 dbContext
= UnoRuntime
.queryInterface
151 (XNamingService
.class, cont
) ;
153 } catch (com
.sun
.star
.uno
.Exception e
) {
154 System
.out
.println("caught exception: " + e
);
159 * Returns new instance of <code>DataSourceInfo</code> class.
161 public DataSourceInfo
newDataSourceInfo() { return new DataSourceInfo() ;}
166 * Registers the datasource on the specified name in
167 * <code>DatabaseContext</code> service.
168 * @param name Name which dataSource will have in global context.
169 * @param dataSource <code>DataSource</code> object which is to
172 private void registerDB(String name
, Object dataSource
)
173 throws com
.sun
.star
.uno
.Exception
{
175 dbContext
.registerObject(name
, dataSource
) ;
180 * First tries to revoke the datasource with the specified
181 * name and then registers a new one.
182 * @param name Name which dataSource will have in global context.
183 * @param dataSource <code>DataSource</code> object which is to
186 public void reRegisterDB(String name
, Object dataSource
)
187 throws com
.sun
.star
.uno
.Exception
{
191 } catch (com
.sun
.star
.uno
.Exception e
) {}
193 XDocumentDataSource xDDS
= UnoRuntime
.queryInterface(XDocumentDataSource
.class, dataSource
);
194 XStorable store
= UnoRuntime
.queryInterface(XStorable
.class,
195 xDDS
.getDatabaseDocument());
196 String aFile
= utils
.getOfficeTemp(xMSF
) + name
+ ".odb";
197 store
.storeAsURL(aFile
, new PropertyValue
[] { });
199 registerDB(name
, dataSource
) ;
207 * Performs connection to DataSource specified.
208 * @param dbSource <code>com.sun.star.sdb.DataSource</code> service
209 * specified data source which must be already registered in the
210 * <code>DatabaseContext</code> service.
211 * @return Connection to the data source.
213 public XConnection
connectToSource(Object dbSource
)
214 throws com
.sun
.star
.uno
.Exception
{
216 Object handler
= xMSF
.createInstance("com.sun.star.sdb.InteractionHandler");
217 XInteractionHandler xHandler
= UnoRuntime
.queryInterface(XInteractionHandler
.class, handler
) ;
219 XCompletedConnection xSrcCon
= UnoRuntime
.queryInterface(XCompletedConnection
.class, dbSource
) ;
221 return xSrcCon
.connectWithCompletion(xHandler
) ;
225 * Convert system pathname to SOffice URL string
226 * (for example 'C:\Temp\DBDir\' -> 'file:///C|/Temp/DBDir/').
227 * (for example '\\server\Temp\DBDir\' -> 'file://server/Temp/DBDir/').
228 * Already converted string returned unchanged.
230 public static String
dirToUrl(String dir
) {
231 String retVal
= null;
232 if (dir
.startsWith("file:/")) retVal
= dir
;
234 retVal
= dir
.replace(':', '|').replace('\\', '/');
236 if (dir
.startsWith("\\\\")) {
237 retVal
= "file:" + retVal
;
240 else retVal
= "file:///" + retVal
;
246 * Revokes datasource from global DB context.
247 * @param name DataSource name to be revoked.
249 public void revokeDB(String name
) throws com
.sun
.star
.uno
.Exception
251 dbContext
.revokeObject(name
) ;
255 * Initializes test table specified of the connection specified
256 * using JDBC driver. Drops table with the name <code>tbl_name</code>,
257 * creates new table with this name and then inserts data from
258 * <code>TST_TABLE_VALUES</code> constant array. <p>
259 * Test table has some predefined format which includes as much
260 * field types as possible. For every column type constants
261 * {@link #TST_STRING TST_STRING}, {@link #TST_INT TST_INT}, etc.
262 * are declared for column index fast find.
263 * @param tbl_name Test table name.
265 public void initTestTableUsingJDBC(String tbl_name
, DataSourceInfo dsi
)
266 throws java
.sql
.SQLException
,
267 ClassNotFoundException
{
269 //register jdbc driver
270 if ( dsi
.Info
[0].Name
.equals("JavaDriverClass") ) {
271 Class
.forName((String
)dsi
.Info
[0].Value
);
273 Class
.forName(TST_JDBC_DRIVER
);
276 Connection connection
= null;
277 Statement statement
= null;
280 connection
= DriverManager
.getConnection(dsi
.URL
, dsi
.User
, dsi
.Password
);
282 statement
= connection
.createStatement();
285 dropMySQLTable(statement
, tbl_name
);
288 createMySQLTable(statement
, tbl_name
);
290 //insert some content
291 insertContentMySQLTable(statement
, tbl_name
);
293 if (statement
!= null)
297 if (connection
!= null)
303 * Inserts data from <code>TST_TABLE_VALUES</code> constant array
304 * to test table <code>tbl_name</code>.
305 * @param statement object used for executing a static SQL
306 * statement and obtaining the results produced by it.
307 * @param tbl_name Test table name.
309 private void insertContentMySQLTable(Statement statement
, String tbl_name
)
310 throws java
.sql
.SQLException
{
313 for(int i
= 0; i
< DBTools
.TST_TABLE_VALUES
.length
; i
++) {
314 StringBuilder query
= new StringBuilder("insert into " + tbl_name
+ " values (");
316 while(j
< DBTools
.TST_TABLE_VALUES
[i
].length
) {
320 Object value
= DBTools
.TST_TABLE_VALUES
[i
][j
];
321 if (value
instanceof String
||
322 value
instanceof Date
) {
325 if (value
instanceof Date
) {
326 Date date
= (Date
)value
;
327 query
.append(date
.Year
).append("-").append(date
.Month
).append(
328 "-").append(date
.Day
);
329 } else if (value
instanceof Boolean
) {
330 query
.append((((Boolean
)value
).booleanValue())
336 if (value
instanceof String
||
337 value
instanceof Date
) {
343 statement
.executeUpdate(query
.toString());
348 * Creates test table specified.
349 * Test table has some predefined format which includes as much
350 * field types as possible. For every column type constants
351 * {@link #TST_STRING TST_STRING}, {@link #TST_INT TST_INT}, etc.
352 * are declared for column index fast find.
353 * @param statement object used for executing a static SQL
354 * statement and obtaining the results produced by it.
355 * @param tbl_name Test table name.
357 private void createMySQLTable(Statement statement
, String tbl_name
)
358 throws java
.sql
.SQLException
{
360 final String empty_col_name
= "Column";
362 String query
= "create table " + tbl_name
+ " (";
363 for (int i
= 0; i
< TST_TABLE_VALUES
[0].length
; i
++) {
364 if (i
> 0) query
+= ",";
367 case TST_BINARY_STREAM
:
368 query
+= TST_BINARY_STREAM_F
+ " BLOB";
371 query
+= TST_BOOLEAN_F
+ " TINYINT";
373 case TST_CHARACTER_STREAM
:
374 query
+= TST_CHARACTER_STREAM_F
+ " TEXT";
377 query
+= TST_DATE_F
+ " DATE";
380 query
+= TST_DOUBLE_F
+ " DOUBLE";
383 query
+= TST_INT_F
+ " INT";
386 query
+= TST_STRING_F
+ " TEXT";
388 default: query
+= empty_col_name
+ (c
++) + " INT";
390 query
+= " NOT NULL AUTO_INCREMENT";
394 query
+= ", PRIMARY KEY (" + empty_col_name
+ "0)";
396 statement
.execute(query
);
401 * @param statement object used for executing a static SQL
402 * statement and obtaining the results produced by it.
403 * @param tbl_name Test table name.
405 private void dropMySQLTable(Statement statement
, String tbl_name
)
406 throws java
.sql
.SQLException
{
407 statement
.executeUpdate("drop table if exists " + tbl_name
);