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, Double
.valueOf(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, Double
.valueOf(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>'URL'</code> property.
95 public String URL
= null ;
97 * Representation of <code>'Info'</code> property.
99 public PropertyValue
[] Info
= null ;
101 * Representation of <code>'User'</code> property.
103 public String User
= null ;
105 * Representation of <code>'Password'</code> property.
107 public String Password
= null ;
109 * Representation of <code>'IsPasswordRequired'</code> property.
111 public Boolean IsPasswordRequired
= null ;
114 * Creates new <code>com.sun.star.sdb.DataSource</code> service
115 * instance and copies all fields (which are not null) to
116 * appropriate service properties.
117 * @return <code>com.sun.star.sdb.DataSource</code> service.
119 public Object
getDataSourceService() throws Exception
121 Object src
= xMSF
.createInstance("com.sun.star.sdb.DataSource") ;
123 XPropertySet props
= UnoRuntime
.queryInterface
124 (XPropertySet
.class, src
) ;
126 if (URL
!= null) props
.setPropertyValue("URL", URL
) ;
127 if (Info
!= null) props
.setPropertyValue("Info", Info
) ;
128 if (User
!= null) props
.setPropertyValue("User", User
) ;
129 if (Password
!= null) props
.setPropertyValue("Password", Password
) ;
130 if (IsPasswordRequired
!= null) props
.setPropertyValue("IsPasswordRequired", IsPasswordRequired
) ;
136 * Creates class instance.
137 * @param xMSF <code>XMultiServiceFactory</code>.
139 public DBTools(XMultiServiceFactory xMSF
)
143 Object cont
= xMSF
.createInstance("com.sun.star.sdb.DatabaseContext") ;
145 dbContext
= UnoRuntime
.queryInterface
146 (XNamingService
.class, cont
) ;
148 } catch (com
.sun
.star
.uno
.Exception e
) {
149 System
.out
.println("caught exception: " + e
);
154 * Returns new instance of <code>DataSourceInfo</code> class.
156 public DataSourceInfo
newDataSourceInfo() { return new DataSourceInfo() ;}
161 * Registers the datasource on the specified name in
162 * <code>DatabaseContext</code> service.
163 * @param name Name which dataSource will have in global context.
164 * @param dataSource <code>DataSource</code> object which is to
167 private void registerDB(String name
, Object dataSource
)
168 throws com
.sun
.star
.uno
.Exception
{
170 dbContext
.registerObject(name
, dataSource
) ;
175 * First tries to revoke the datasource with the specified
176 * name and then registers a new one.
177 * @param name Name which dataSource will have in global context.
178 * @param dataSource <code>DataSource</code> object which is to
181 public void reRegisterDB(String name
, Object dataSource
)
182 throws com
.sun
.star
.uno
.Exception
{
186 } catch (com
.sun
.star
.uno
.Exception e
) {}
188 XDocumentDataSource xDDS
= UnoRuntime
.queryInterface(XDocumentDataSource
.class, dataSource
);
189 XStorable store
= UnoRuntime
.queryInterface(XStorable
.class,
190 xDDS
.getDatabaseDocument());
191 String aFile
= utils
.getOfficeTemp(xMSF
) + name
+ ".odb";
192 store
.storeAsURL(aFile
, new PropertyValue
[] { });
194 registerDB(name
, dataSource
) ;
202 * Performs connection to DataSource specified.
203 * @param dbSource <code>com.sun.star.sdb.DataSource</code> service
204 * specified data source which must be already registered in the
205 * <code>DatabaseContext</code> service.
206 * @return Connection to the data source.
208 public XConnection
connectToSource(Object dbSource
)
209 throws com
.sun
.star
.uno
.Exception
{
211 Object handler
= xMSF
.createInstance("com.sun.star.sdb.InteractionHandler");
212 XInteractionHandler xHandler
= UnoRuntime
.queryInterface(XInteractionHandler
.class, handler
) ;
214 XCompletedConnection xSrcCon
= UnoRuntime
.queryInterface(XCompletedConnection
.class, dbSource
) ;
216 return xSrcCon
.connectWithCompletion(xHandler
) ;
220 * Convert system pathname to SOffice URL string
221 * (for example 'C:\Temp\DBDir\' -> 'file:///C|/Temp/DBDir/').
222 * (for example '\\server\Temp\DBDir\' -> 'file://server/Temp/DBDir/').
223 * Already converted string returned unchanged.
225 public static String
dirToUrl(String dir
) {
226 String retVal
= null;
227 if (dir
.startsWith("file:/")) retVal
= dir
;
229 retVal
= dir
.replace(':', '|').replace('\\', '/');
231 if (dir
.startsWith("\\\\")) {
232 retVal
= "file:" + retVal
;
235 else retVal
= "file:///" + retVal
;
241 * Revokes datasource from global DB context.
242 * @param name DataSource name to be revoked.
244 public void revokeDB(String name
) throws com
.sun
.star
.uno
.Exception
246 dbContext
.revokeObject(name
) ;
250 * Initializes test table specified of the connection specified
251 * using JDBC driver. Drops table with the name <code>tbl_name</code>,
252 * creates new table with this name and then inserts data from
253 * <code>TST_TABLE_VALUES</code> constant array. <p>
254 * Test table has some predefined format which includes as much
255 * field types as possible. For every column type constants
256 * {@link #TST_STRING TST_STRING}, {@link #TST_INT TST_INT}, etc.
257 * are declared for column index fast find.
258 * @param tbl_name Test table name.
260 public void initTestTableUsingJDBC(String tbl_name
, DataSourceInfo dsi
)
261 throws java
.sql
.SQLException
,
262 ClassNotFoundException
{
264 //register jdbc driver
265 if ( dsi
.Info
[0].Name
.equals("JavaDriverClass") ) {
266 Class
.forName((String
)dsi
.Info
[0].Value
);
268 Class
.forName(TST_JDBC_DRIVER
);
271 Connection connection
= null;
272 Statement statement
= null;
275 connection
= DriverManager
.getConnection(dsi
.URL
, dsi
.User
, dsi
.Password
);
277 statement
= connection
.createStatement();
280 dropMySQLTable(statement
, tbl_name
);
283 createMySQLTable(statement
, tbl_name
);
285 //insert some content
286 insertContentMySQLTable(statement
, tbl_name
);
288 if (statement
!= null)
292 if (connection
!= null)
298 * Inserts data from <code>TST_TABLE_VALUES</code> constant array
299 * to test table <code>tbl_name</code>.
300 * @param statement object used for executing a static SQL
301 * statement and obtaining the results produced by it.
302 * @param tbl_name Test table name.
304 private void insertContentMySQLTable(Statement statement
, String tbl_name
)
305 throws java
.sql
.SQLException
{
308 for(int i
= 0; i
< DBTools
.TST_TABLE_VALUES
.length
; i
++) {
309 StringBuilder query
= new StringBuilder("insert into " + tbl_name
+ " values (");
311 while(j
< DBTools
.TST_TABLE_VALUES
[i
].length
) {
315 Object value
= DBTools
.TST_TABLE_VALUES
[i
][j
];
316 if (value
instanceof String
||
317 value
instanceof Date
) {
320 if (value
instanceof Date
) {
321 Date date
= (Date
)value
;
322 query
.append(date
.Year
).append("-").append(date
.Month
).append(
323 "-").append(date
.Day
);
324 } else if (value
instanceof Boolean
) {
325 query
.append((((Boolean
)value
).booleanValue())
331 if (value
instanceof String
||
332 value
instanceof Date
) {
338 statement
.executeUpdate(query
.toString());
343 * Creates test table specified.
344 * Test table has some predefined format which includes as much
345 * field types as possible. For every column type constants
346 * {@link #TST_STRING TST_STRING}, {@link #TST_INT TST_INT}, etc.
347 * are declared for column index fast find.
348 * @param statement object used for executing a static SQL
349 * statement and obtaining the results produced by it.
350 * @param tbl_name Test table name.
352 private void createMySQLTable(Statement statement
, String tbl_name
)
353 throws java
.sql
.SQLException
{
355 final String empty_col_name
= "Column";
357 String query
= "create table " + tbl_name
+ " (";
358 for (int i
= 0; i
< TST_TABLE_VALUES
[0].length
; i
++) {
359 if (i
> 0) query
+= ",";
362 case TST_BINARY_STREAM
:
363 query
+= TST_BINARY_STREAM_F
+ " BLOB";
366 query
+= TST_BOOLEAN_F
+ " TINYINT";
368 case TST_CHARACTER_STREAM
:
369 query
+= TST_CHARACTER_STREAM_F
+ " TEXT";
372 query
+= TST_DATE_F
+ " DATE";
375 query
+= TST_DOUBLE_F
+ " DOUBLE";
378 query
+= TST_INT_F
+ " INT";
381 query
+= TST_STRING_F
+ " TEXT";
383 default: query
+= empty_col_name
+ (c
++) + " INT";
385 query
+= " NOT NULL AUTO_INCREMENT";
389 query
+= ", PRIMARY KEY (" + empty_col_name
+ "0)";
391 statement
.execute(query
);
396 * @param statement object used for executing a static SQL
397 * statement and obtaining the results produced by it.
398 * @param tbl_name Test table name.
400 private void dropMySQLTable(Statement statement
, String tbl_name
)
401 throws java
.sql
.SQLException
{
402 statement
.executeUpdate("drop table if exists " + tbl_name
);