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 .
19 package mod
._dbaccess
;
21 import ifc
.sdb
._XCompletedExecution
;
23 import java
.io
.OutputStreamWriter
;
24 import java
.io
.PrintWriter
;
25 import java
.io
.UnsupportedEncodingException
;
26 import java
.util
.ArrayList
;
27 import lib
.StatusException
;
29 import lib
.TestEnvironment
;
30 import lib
.TestParameters
;
33 import util
.db
.DataSource
;
34 import util
.db
.DataSourceDescriptor
;
36 import com
.sun
.star
.beans
.PropertyValue
;
37 import com
.sun
.star
.beans
.XPropertySet
;
38 import com
.sun
.star
.frame
.XModel
;
39 import com
.sun
.star
.lang
.XComponent
;
40 import com
.sun
.star
.lang
.XMultiServiceFactory
;
41 import com
.sun
.star
.sdb
.CommandType
;
42 import com
.sun
.star
.sdb
.ParametersRequest
;
43 import com
.sun
.star
.sdb
.RowChangeEvent
;
44 import com
.sun
.star
.sdb
.XInteractionSupplyParameters
;
45 import com
.sun
.star
.sdbc
.SQLException
;
46 import com
.sun
.star
.sdbc
.XConnection
;
47 import com
.sun
.star
.sdbc
.XParameters
;
48 import com
.sun
.star
.sdbc
.XResultSet
;
49 import com
.sun
.star
.sdbc
.XResultSetUpdate
;
50 import com
.sun
.star
.sdbc
.XRow
;
51 import com
.sun
.star
.sdbc
.XRowSet
;
52 import com
.sun
.star
.sdbc
.XRowUpdate
;
53 import com
.sun
.star
.task
.XInteractionAbort
;
54 import com
.sun
.star
.task
.XInteractionContinuation
;
55 import com
.sun
.star
.task
.XInteractionRequest
;
56 import com
.sun
.star
.ucb
.AuthenticationRequest
;
57 import com
.sun
.star
.uno
.UnoRuntime
;
58 import com
.sun
.star
.uno
.XInterface
;
59 import com
.sun
.star
.util
.XCloseable
;
62 * Test for object which is represented by service
63 * <code>com.sun.star.sdb.RowSet</code>. <p>
65 * The following files used by this test :
67 * <li><b> TestDB/TestDB.dbf </b> : the database file with some
68 * predefined fields described in <code>util.DBTools</code>.
69 * The copy of this file is always made in temp directory for
70 * testing purposes.</li>
72 * The following parameters in ini-file used by this test:
74 * <li><code>test.db.url</code> - URL to MySQL database.
75 * For example: <code>mysql://mercury:3306/api_current</code></li>
76 * <li><code>test.db.user</code> - user for MySQL database</li>
77 * <li><code>test.db.password</code> - password for MySQL database</li>
80 * @see com.sun.star.sdbc.RowSet
81 * @see com.sun.star.sdbcx.XRowLocate
82 * @see com.sun.star.sdbc.XResultSetUpdate
83 * @see com.sun.star.util.XCancellable
84 * @see com.sun.star.sdbc.XParameters
85 * @see com.sun.star.sdbc.XResultSetMetaDataSupplier
86 * @see com.sun.star.sdbcx.XDeleteRows
87 * @see com.sun.star.sdbc.XCloseable
88 * @see com.sun.star.sdbcx.XColumnsSupplier
89 * @see com.sun.star.sdb.XResultSetAccess
90 * @see com.sun.star.sdbc.XResultSet
91 * @see com.sun.star.sdbc.XColumnLocate
92 * @see com.sun.star.sdbc.XRowSet
93 * @see com.sun.star.sdb.RowSet
94 * @see com.sun.star.sdbc.XRowUpdate
95 * @see com.sun.star.sdb.XRowSetApproveBroadcaster
96 * @see com.sun.star.beans.XPropertySet
97 * @see com.sun.star.sdbc.XRow
98 * @see com.sun.star.sdbc.XWarningsSupplier
99 * @see com.sun.star.lang.XComponent
100 * @see com.sun.star.sdbcx.ResultSet
101 * @see com.sun.star.sdbc.ResultSet
102 * @see ifc.sdbc._RowSet
103 * @see ifc.sdbcx._XRowLocate
104 * @see ifc.sdbc._XResultSetUpdate
105 * @see ifc.util._XCancellable
106 * @see ifc.sdbc._XParameters
107 * @see ifc.sdbc._XResultSetMetaDataSupplier
108 * @see ifc.sdbcx._XDeleteRows
109 * @see ifc.sdbc._XCloseable
110 * @see ifc.sdbcx._XColumnsSupplier
111 * @see ifc.sdb._XResultSetAccess
112 * @see ifc.sdbc._XResultSet
113 * @see ifc.sdbc._XColumnLocate
114 * @see ifc.sdbc._XRowSet
115 * @see ifc.sdb._RowSet
116 * @see ifc.sdbc._XRowUpdate
117 * @see ifc.sdb._XRowSetApproveBroadcaster
118 * @see ifc.beans._XPropertySet
119 * @see ifc.sdbc._XRow
120 * @see ifc.sdbc._XWarningsSupplier
121 * @see ifc.lang._XComponent
122 * @see ifc.sdbcx._ResultSet
123 * @see ifc.sdbc._ResultSet
125 public class ORowSet
extends TestCase
{
127 private static int uniqueSuffix
= 0 ;
128 private DBTools dbTools
= null ;
129 private static String origDB
= null ;
130 String tableName
= null;
131 DataSourceDescriptor srcInf
= null;
132 boolean isMySQLDB
= false;
133 protected static final String dbSourceName
= "ORowSetDataSource";
134 public XConnection m_connection
= null;
135 private Object m_rowSet
= null;
136 private DataSource m_dataSource
;
137 private String m_tableFile
;
140 * Initializes some class fields. Then creates DataSource, which serves
141 * as a single source for all tables created in the test.
142 * This DataSource then registered in the global
143 * <code>DatabaseContext</code> service. This data source's URL
144 * points to SOffice temp directory where tables are copied from
145 * <code>TestDocuments</code> directory on every environment
147 * To create DataSource for MySQL database next parameters required
150 * <li><code>test.db.url</code> - URL to MySQL database.
151 * For example: <code>mysql://mercury:3306/api_current</code></li>
152 * <li><code>test.db.user</code> - user for MySQL database</li>
153 * <li><code>test.db.password</code> - password for MySQL database</li>
156 * @throws StatusException if DataSource can not be created or
160 protected void initialize ( TestParameters Param
, PrintWriter _log
)
161 throws StatusException
163 XMultiServiceFactory orb
= Param
.getMSF();
165 String tmpDir
= utils
.getOfficeTemp( orb
);
167 origDB
= util
.utils
.getFullTestDocName("TestDB/testDB.dbf");
169 dbTools
= new DBTools( orb
);
171 // creating DataSource and registering it in DatabaseContext
172 String dbURL
= (String
) Param
.get("test.db.url");
173 String dbUser
= (String
) Param
.get("test.db.user");
174 String dbPassword
= (String
) Param
.get("test.db.password");
176 log
.println("Creating and registering DataSource ...");
177 srcInf
= new DataSourceDescriptor( orb
);
178 if (dbURL
!= null && dbUser
!= null && dbPassword
!= null)
181 log
.println("dbURL = " + dbURL
);
182 log
.println("dbUSER = " + dbUser
);
183 log
.println("dbPASSWORD = " + dbPassword
);
184 //DataSource for mysql db
185 tableName
= "soffice_test_table";
186 srcInf
.URL
= "jdbc:" + dbURL
;
187 srcInf
.IsPasswordRequired
= Boolean
.TRUE
;
188 srcInf
.Password
= dbPassword
;
189 srcInf
.User
= dbUser
;
190 PropertyValue
[] propInfo
= new PropertyValue
[1];
191 propInfo
[0] = new PropertyValue();
192 propInfo
[0].Name
= "JavaDriverClass";
193 propInfo
[0].Value
= "org.gjt.mm.mysql.Driver";
194 srcInf
.Info
= propInfo
;
198 srcInf
.URL
= "sdbc:dbase:" + DBTools
.dirToUrl(tmpDir
);
200 m_dataSource
= srcInf
.createDataSource();
201 m_dataSource
.registerAs( dbSourceName
, true );
205 * Creating a TestEnvironment for the interfaces to be tested.
206 * The database (DBF) file is copied from test document directory
207 * into SOffice temp dir with unique name for each environment
208 * creation. If the file can't be copied (is not released)
209 * then another unique name is used (file name suffix incremented
212 * <code>com.sun.star.sdb.RowSet</code> service created and its
213 * source is all rows from the current copy of the table. Then
214 * row set command ("select all rows from a table") is executed
215 * and cursor is positioned to the first row. <p>
217 * Object relations created :
219 * <li> <code>'ORowSet.Connection'</code> for
220 * internal component test usage. Is used for
221 * closing connection when cleaning up environment. </li>
222 * <li> <code>'XRowSetApproveBroadcaster.ApproveChecker'</code> for
223 * {@link ifc.sdb._XRowSetApproveBroadcaster} interface
224 * implementation which made actions required </li>
225 * <li> <code>'CurrentRowData'</code> for
226 * {@link ifc.sdbc._XRow}, {@link ifc.sdbc._XRowUpdate} :
227 * exports types and values of the current row data.</li>
228 * <li> <code>'XColumnLocate.ColumnName'</code> for
229 * {@link ifc.sdbc._XColumnLocate} :
230 * the name of the first column of the table.</li>
231 * <li> <code>'XParameters.ParamValues'</code> for
232 * {@link ifc.sdbc._XParameters} :
233 * Collection of parameter types presented in the query. </li>
234 * <li> <code>'XRowUpdate.XRow'</code> for
235 * {@link ifc.sdbc._XRowUpdate} :
236 * <code>XRow</code> interface of the current component.</li>
237 * <li> <code>'XResultSetUpdate.UpdateTester'</code> for
238 * {@link ifc.sdbc._XResultSetUpdate} </li>
241 * @see com.sun.star.sdb.DatabaseContext
242 * @see com.sun.star.sdb.DataSource
245 protected TestEnvironment
createTestEnvironment(TestParameters Param
,
246 PrintWriter log
) throws Exception
248 XMultiServiceFactory orb
= Param
.getMSF();
250 boolean envCreatedOK
= false ;
252 //initialize test table
255 DBTools
.DataSourceInfo legacyDescriptor
= dbTools
.newDataSourceInfo();
256 legacyDescriptor
.User
= srcInf
.User
;
257 legacyDescriptor
.Password
= srcInf
.Password
;
258 legacyDescriptor
.Info
= srcInf
.Info
;
259 legacyDescriptor
.URL
= srcInf
.URL
;
260 legacyDescriptor
.IsPasswordRequired
= srcInf
.IsPasswordRequired
;
261 dbTools
.initTestTableUsingJDBC(tableName
, legacyDescriptor
);
267 String tempFolder
= utils
.getOfficeTemp( orb
);
270 tableName
= "ORowSet_tmp" + uniqueSuffix
;
271 oldF
= utils
.getFullURL(origDB
);
272 newF
= tempFolder
+ tableName
+ ".dbf";
274 while ( !utils
.tryOverwriteFile( orb
, oldF
, newF
) );
280 m_rowSet
= orb
.createInstance("com.sun.star.sdb.RowSet");
282 XPropertySet rowSetProps
= UnoRuntime
.queryInterface( XPropertySet
.class, m_rowSet
);
284 log
.println("Trying to open: " + tableName
);
286 rowSetProps
.setPropertyValue("DataSourceName", dbSourceName
);
287 rowSetProps
.setPropertyValue("Command", tableName
);
288 rowSetProps
.setPropertyValue("CommandType",
289 Integer
.valueOf(CommandType
.TABLE
));
291 final XRowSet rowSet
= UnoRuntime
.queryInterface( XRowSet
.class, m_rowSet
);
293 m_connection
= UnoRuntime
.queryInterface( XConnection
.class, rowSetProps
.getPropertyValue("ActiveConnection") );
295 XResultSet xRes
= UnoRuntime
.queryInterface( XResultSet
.class, m_rowSet
);
298 log
.println( "creating a new environment for object" );
299 TestEnvironment tEnv
= new TestEnvironment( (XInterface
)m_rowSet
);
301 // Adding obj relation for XRowSetApproveBroadcaster test
303 final XResultSet resultSet
= UnoRuntime
.queryInterface( XResultSet
.class, m_rowSet
);
304 final XResultSetUpdate resultSetUpdate
= UnoRuntime
.queryInterface( XResultSetUpdate
.class, m_rowSet
);
305 final XRowUpdate rowUpdate
= UnoRuntime
.queryInterface(XRowUpdate
.class, m_rowSet
);
306 final PrintWriter logF
= log
;
307 tEnv
.addObjRelation( "XRowSetApproveBroadcaster.ApproveChecker",
308 new ifc
.sdb
._XRowSetApproveBroadcaster
.RowSetApproveChecker()
310 public void moveCursor()
314 resultSet
.beforeFirst();
315 resultSet
.afterLast();
318 catch (com
.sun
.star
.sdbc
.SQLException e
)
320 logF
.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.moveCursor() :");
321 e
.printStackTrace(logF
);
322 throw new StatusException( "RowSetApproveChecker.moveCursor failed", e
);
325 public RowChangeEvent
changeRow()
330 rowUpdate
.updateString(1, "ORowSetTest2");
331 resultSetUpdate
.updateRow();
333 catch (com
.sun
.star
.sdbc
.SQLException e
)
335 logF
.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.changeRow() :");
336 e
.printStackTrace(logF
);
337 throw new StatusException( "RowSetApproveChecker.changeRow failed", e
);
339 RowChangeEvent ev
= new RowChangeEvent();
340 ev
.Action
= com
.sun
.star
.sdb
.RowChangeAction
.UPDATE
;
345 public void changeRowSet()
349 // since we gave the row set a parametrized statement, we need to ensure the
350 // parameter is actually filled, otherwise we would get an empty result set,
351 // which would imply some further tests failing
352 XParameters rowSetParams
= UnoRuntime
.queryInterface( XParameters
.class, resultSet
);
353 rowSetParams
.setString( 1, "String2" );
357 catch (com
.sun
.star
.sdbc
.SQLException e
)
359 logF
.println("### _XRowSetApproveBroadcaster.RowSetApproveChecker.changeRowSet() :");
360 e
.printStackTrace(logF
);
361 throw new StatusException( "RowSetApproveChecker.changeRowSet failed", e
);
367 // Adding relations for XRow as a Vector with all data
368 // of current row of RowSet.
370 ArrayList
<Object
> rowData
= new ArrayList
<Object
>();
372 for (int i
= 0; i
< DBTools
.TST_TABLE_VALUES
[0].length
; i
++) {
373 rowData
.add(DBTools
.TST_TABLE_VALUES
[0][i
]);
376 // here XRef must be added
377 // here XBlob must be added
378 // here XClob must be added
379 // here XArray must be added
381 tEnv
.addObjRelation("CurrentRowData", rowData
);
383 // Adding relation for XColumnLocate ifc test
384 tEnv
.addObjRelation( "XColumnLocate.ColumnName", DBTools
.TST_STRING_F
);
386 // Adding relation for XCompletedExecution
387 tEnv
.addObjRelation( "InteractionHandlerChecker", new InteractionHandlerImpl() );
388 String sqlCommand
= isMySQLDB
389 ?
"SELECT Column0 FROM soffice_test_table WHERE ( ( Column0 = :param1 ) )"
390 : "SELECT \"_TEXT\" FROM \"" + tableName
+ "\" WHERE ( ( \"_TEXT\" = :param1 ) )";
391 rowSetProps
.setPropertyValue( "DataSourceName", dbSourceName
);
392 rowSetProps
.setPropertyValue( "Command", sqlCommand
);
393 rowSetProps
.setPropertyValue( "CommandType", Integer
.valueOf(CommandType
.COMMAND
) );
395 // Adding relation for XParameters ifc test
396 tEnv
.addObjRelation( "XParameters.ParamValues", new ArrayList
<String
>() );
398 // Adding relation for XRowUpdate
399 final XRow row
= UnoRuntime
.queryInterface( XRow
.class, m_rowSet
);
400 tEnv
.addObjRelation("XRowUpdate.XRow", row
);
402 // Adding relation for XResultSetUpdate
404 final XResultSet resultSet
= UnoRuntime
.queryInterface( XResultSet
.class, m_rowSet
);
405 final XRowUpdate rowUpdate
= UnoRuntime
.queryInterface( XRowUpdate
.class, m_rowSet
);
407 tEnv
.addObjRelation("XResultSetUpdate.UpdateTester",
408 new ifc
.sdbc
._XResultSetUpdate
.UpdateTester()
410 String lastUpdate
= null ;
412 public int rowCount() throws SQLException
414 int prevPos
= resultSet
.getRow();
416 int count
= resultSet
.getRow();
417 resultSet
.absolute(prevPos
);
422 public void update() throws SQLException
424 lastUpdate
= row
.getString(1);
426 rowUpdate
.updateString(1, lastUpdate
);
429 public boolean wasUpdated() throws SQLException
431 String getStr
= row
.getString(1);
432 return lastUpdate
.equals(getStr
);
435 public int currentRow() throws SQLException
437 return resultSet
.getRow();
443 envCreatedOK
= true ;
453 m_connection
.close();
457 System
.out
.println("caught exception: " + ex
);
462 } // finish method getTestEnvironment
465 * Closes connection of <code>RowSet</code> instance created.
468 protected void cleanup( TestParameters Param
, PrintWriter log
)
473 doing
= "revoking data source registration";
474 log
.println( doing
);
475 m_dataSource
.revokeRegistration();
477 doing
= "closing database document";
478 log
.println( doing
);
479 XModel databaseDocModel
= UnoRuntime
.queryInterface( XModel
.class,
480 m_dataSource
.getDatabaseDocument().getDatabaseDocument() );
481 String documentFile
= databaseDocModel
.getURL();
483 XCloseable closeModel
= UnoRuntime
.queryInterface( XCloseable
.class,
484 m_dataSource
.getDatabaseDocument().getDatabaseDocument() );
485 closeModel
.close( true );
487 if ( m_rowSet
!= null )
489 doing
= "disposing row set";
490 log
.println( doing
);
491 XComponent rowSetComponent
= UnoRuntime
.queryInterface( XComponent
.class, m_rowSet
);
492 rowSetComponent
.dispose();
497 doing
= "closing connection";
498 log
.println( doing
);
499 m_connection
.close();
501 catch (com
.sun
.star
.lang
.DisposedException e
)
503 log
.println( "already closed - okay." );
506 doing
= "deleting database file (" + documentFile
+ ")";
507 log
.println( doing
);
508 impl_deleteFile( documentFile
);
510 if ( m_tableFile
!= null )
512 doing
= "deleting dBase table file (" + m_tableFile
+ ")";
513 log
.println( doing
);
514 impl_deleteFile( m_tableFile
);
517 catch (com
.sun
.star
.uno
.Exception e
)
519 log
.println( "error: ");
520 e
.printStackTrace(log
);
524 private final void impl_deleteFile( final String _file
)
526 java
.io
.File file
= new java
.io
.File( _file
);
528 boolean bDeleteOk
= file
.delete();
529 if (!bDeleteOk
&& file
.exists())
534 * Implementation of interface _XCompletedExecution.CheckInteractionHandler
535 * for the XCompletedExecution test
536 * @see ifc.sdb._XCompletedExecution
538 private static class InteractionHandlerImpl
implements _XCompletedExecution
.CheckInteractionHandler
{
540 private boolean handlerWasUsed
= false;
541 private PrintWriter log
;
543 InteractionHandlerImpl() throws UnsupportedEncodingException
{
544 log
= new PrintWriter(new OutputStreamWriter(System
.out
, "UTF-8"));
547 public boolean checkInteractionHandler() {
548 return handlerWasUsed
;
551 public void handle(XInteractionRequest xInteractionRequest
) {
552 log
.println("### _XCompletedExecution.InteractionHandlerImpl: handle called.");
553 boolean abort
= false;
555 Object o
= xInteractionRequest
.getRequest();
556 if (o
instanceof ParametersRequest
) {
558 else if (o
instanceof AuthenticationRequest
) {
559 log
.println("### The request in XCompletedExecution is of type 'AuthenticationRequest'");
560 log
.println("### This is not implemented in ORowSet.InteractionHandlerImpl test -> abort.");
564 log
.println("### Unknown request:" + o
.toString());
565 log
.println("### This is not implemented in ORowSet.InteractionHandlerImpl test -> abort.");
569 XInteractionContinuation
[]xCont
= xInteractionRequest
.getContinuations();
570 XInteractionSupplyParameters xParamCallback
= null;
571 for(int i
=0; i
<xCont
.length
; i
++) {
573 XInteractionAbort xAbort
= null;
574 xAbort
= UnoRuntime
.queryInterface(XInteractionAbort
.class, xCont
[i
]);
580 xParamCallback
= UnoRuntime
.queryInterface(XInteractionSupplyParameters
.class, xCont
[i
]);
581 if (xParamCallback
!= null)
585 if (xParamCallback
!= null) {
586 log
.println("### _XCompletedExecution.InteractionHandlerImpl: supplying parameters.");
587 handlerWasUsed
= true;
588 PropertyValue
[] prop
= new PropertyValue
[1];
589 prop
[0] = new PropertyValue();
590 prop
[0].Name
= "param1";
591 prop
[0].Value
= "Hi.";
593 xParamCallback
.setParameters(prop
);
594 xParamCallback
.select();
596 else { // we should never reach this: abort has to be true first.
597 log
.println("### _XCompletedExecution.InteractionHandlerImpl: Got no " +
598 "'XInteractionSupplyParameters' and no 'XInteractionAbort'.");
602 public void setLog(PrintWriter log
) {