diff options
author | Oliver Bolte <obo@openoffice.org> | 2008-10-16 06:57:26 +0000 |
---|---|---|
committer | Oliver Bolte <obo@openoffice.org> | 2008-10-16 06:57:26 +0000 |
commit | 323b26c51adac28e86436bf3f5721cd3d68d56ae (patch) | |
tree | bf4b1a72e0a0fb54bab266ee91bba44c0152e2ee /dbaccess/qa | |
parent | CWS-TOOLING: integrate CWS cmcfixes49 (diff) | |
download | core-323b26c51adac28e86436bf3f5721cd3d68d56ae.tar.gz core-323b26c51adac28e86436bf3f5721cd3d68d56ae.zip |
CWS-TOOLING: integrate CWS odbmacros3
Diffstat (limited to 'dbaccess/qa')
-rw-r--r-- | dbaccess/qa/complex/dbaccess/CRMBasedTestCase.java | 11 | ||||
-rw-r--r-- | dbaccess/qa/complex/dbaccess/CRMDatabase.java | 2 | ||||
-rw-r--r-- | dbaccess/qa/complex/dbaccess/DatabaseDocument.java | 870 | ||||
-rw-r--r-- | dbaccess/qa/complex/dbaccess/Parser.java | 2 | ||||
-rw-r--r-- | dbaccess/qa/complex/dbaccess/QueryInQuery.java | 2 | ||||
-rwxr-xr-x | dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java | 2 | ||||
-rw-r--r-- | dbaccess/qa/complex/dbaccess/Storable.java | 106 | ||||
-rw-r--r-- | dbaccess/qa/complex/dbaccess/TestCase.java | 128 | ||||
-rw-r--r-- | dbaccess/qa/complex/dbaccess/dbaccess.sce | 2 |
9 files changed, 1006 insertions, 119 deletions
diff --git a/dbaccess/qa/complex/dbaccess/CRMBasedTestCase.java b/dbaccess/qa/complex/dbaccess/CRMBasedTestCase.java index 032b2891eaad..edcb62579aac 100644 --- a/dbaccess/qa/complex/dbaccess/CRMBasedTestCase.java +++ b/dbaccess/qa/complex/dbaccess/CRMBasedTestCase.java @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: CRMBasedTestCase.java,v $ - * $Revision: 1.2 $ + * $Revision: 1.1.6.6 $ * * This file is part of OpenOffice.org. * @@ -35,17 +35,11 @@ import com.sun.star.uno.UnoRuntime; import java.util.logging.Level; import java.util.logging.Logger; -public abstract class CRMBasedTestCase extends complexlib.ComplexTestCase +public abstract class CRMBasedTestCase extends TestCase { protected CRMDatabase m_database; // -------------------------------------------------------------------------------------------------------- - protected final XMultiServiceFactory getORB() - { - return (XMultiServiceFactory)param.getMSF(); - } - - // -------------------------------------------------------------------------------------------------------- protected void createTestCase() { try @@ -79,6 +73,7 @@ public abstract class CRMBasedTestCase extends complexlib.ComplexTestCase } } + // -------------------------------------------------------------------------------------------------------- /** creates a SingleSelectQueryComposer for our connection */ protected final XSingleSelectQueryComposer createQueryComposer() throws com.sun.star.uno.Exception diff --git a/dbaccess/qa/complex/dbaccess/CRMDatabase.java b/dbaccess/qa/complex/dbaccess/CRMDatabase.java index 6f24de212cda..057d44e2692a 100644 --- a/dbaccess/qa/complex/dbaccess/CRMDatabase.java +++ b/dbaccess/qa/complex/dbaccess/CRMDatabase.java @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: CRMDatabase.java,v $ - * $Revision: 1.7 $ + * $Revision: 1.6.2.1 $ * * This file is part of OpenOffice.org. * diff --git a/dbaccess/qa/complex/dbaccess/DatabaseDocument.java b/dbaccess/qa/complex/dbaccess/DatabaseDocument.java new file mode 100644 index 000000000000..0d12fd33b763 --- /dev/null +++ b/dbaccess/qa/complex/dbaccess/DatabaseDocument.java @@ -0,0 +1,870 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: DatabaseDocument.java,v $ + * $Revision: 1.1.2.9 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package complex.dbaccess; + +import com.sun.star.awt.XTopWindow; +import com.sun.star.awt.XTopWindow; +import com.sun.star.beans.PropertyState; +import com.sun.star.document.DocumentEvent; +import com.sun.star.lang.XEventListener; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.script.XStorageBasedLibraryContainer; +import com.sun.star.task.XInteractionRequest; +import com.sun.star.uno.Exception; +import com.sun.star.uno.Type; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.frame.XStorable; +import com.sun.star.beans.PropertyValue; +import com.sun.star.beans.XPropertySet; +import com.sun.star.container.XNameContainer; +import com.sun.star.container.XSet; +import com.sun.star.document.XDocumentEventBroadcaster; +import com.sun.star.document.XDocumentEventListener; +import com.sun.star.document.XEmbeddedScripts; +import com.sun.star.document.XEventsSupplier; +import com.sun.star.document.XScriptInvocationContext; +import com.sun.star.frame.DoubleInitializationException; +import com.sun.star.lang.XComponent; +import com.sun.star.frame.XComponentLoader; +import com.sun.star.frame.XDispatch; +import com.sun.star.frame.XDispatchProvider; +import com.sun.star.frame.XFrame; +import com.sun.star.frame.XLoadable; +import com.sun.star.frame.XModel; +import com.sun.star.frame.XModel2; +import com.sun.star.frame.XTitle; +import com.sun.star.lang.EventObject; +import com.sun.star.lang.NotInitializedException; +import com.sun.star.lang.XServiceInfo; +import com.sun.star.lang.XSingleComponentFactory; +import com.sun.star.lang.XTypeProvider; +import com.sun.star.script.provider.XScriptProviderSupplier; +import com.sun.star.sdb.XFormDocumentsSupplier; +import com.sun.star.sdb.XOfficeDatabaseDocument; +import com.sun.star.sdb.XReportDocumentsSupplier; +import com.sun.star.task.DocumentMacroConfirmationRequest; +import com.sun.star.task.XInteractionApprove; +import com.sun.star.task.XInteractionContinuation; +import com.sun.star.task.XInteractionHandler; +import com.sun.star.uno.XComponentContext; +import com.sun.star.util.CloseVetoException; +import com.sun.star.util.URL; +import com.sun.star.util.XChangesBatch; +import com.sun.star.util.XCloseable; +import com.sun.star.util.XModifiable; +import com.sun.star.util.XURLTransformer; +import connectivity.tools.*; +import helper.FileTools; +import java.io.File; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; +import java.util.Iterator; +import java.util.Vector; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class DatabaseDocument extends TestCase implements com.sun.star.document.XDocumentEventListener +{ + private XComponent m_callbackFactory = null; + private Vector m_documentEvents = new Vector(); + private Vector m_globalEvents = new Vector(); + + // for those states, see testDocumentEvents + private static short STATE_NOT_STARTED = 0; + private static short STATE_LOADING_DOC = 1; + private static short STATE_MACRO_EXEC_APPROVED = 2; + private static short STATE_ON_LOAD_RECEIVED = 3; + private short m_loadDocState = STATE_NOT_STARTED; + + // ======================================================================================================== + /** a helper class which can be used by the Basic scripts in our test documents + * to notify us of events in this document + */ + private class CallbackComponent implements XDocumentEventListener, XTypeProvider + { + public void documentEventOccured( DocumentEvent _event ) + { + onDocumentEvent( _event ); + } + + public void disposing( com.sun.star.lang.EventObject _Event ) + { + // not interested in + } + + public Type[] getTypes() + { + Class interfaces[] = getClass().getInterfaces(); + Type types[] = new Type[interfaces.length]; + for(int i = 0; i < interfaces.length; ++ i) + { + types[i] = new Type(interfaces[i]); + } + return types; + } + + public byte[] getImplementationId() + { + return getClass().toString().getBytes(); + } + }; + + // ======================================================================================================== + private static String getCallbackComponentServiceName() + { + return "org.openoffice.complex.dbaccess.EventCallback"; + } + + // ======================================================================================================== + /** a factory for a CallbackComponent + */ + private class CallbackComponentFactory implements XSingleComponentFactory, XServiceInfo, XComponent + { + private Vector m_eventListeners = new Vector(); + + public Object createInstanceWithContext( XComponentContext _context ) throws Exception + { + return new CallbackComponent(); + } + + public Object createInstanceWithArgumentsAndContext( Object[] arg0, XComponentContext _context ) throws Exception + { + return createInstanceWithContext( _context ); + } + + public String getImplementationName() + { + return "org.openoffice.complex.dbaccess.CallbackComponent"; + } + + public boolean supportsService( String _service ) + { + return _service.equals( getCallbackComponentServiceName() ); + } + + public String[] getSupportedServiceNames() + { + return new String[] { getCallbackComponentServiceName() }; + } + + public void dispose() + { + EventObject event = new EventObject( this ); + + Vector eventListenersCopy = (Vector)m_eventListeners.clone(); + Iterator iter = eventListenersCopy.iterator(); + while ( iter.hasNext() ) + { + ((XEventListener)iter.next()).disposing( event ); + } + } + + public void addEventListener( XEventListener _listener ) + { + if ( _listener != null ) + m_eventListeners.add( _listener ); + } + + public void removeEventListener( XEventListener _listener ) + { + m_eventListeners.remove( _listener ); + } + }; + + // ======================================================================================================== + private class MacroExecutionApprove implements XInteractionHandler + { + private XInteractionHandler m_defaultHandler = null; + + MacroExecutionApprove( XMultiServiceFactory _factory ) + { + try + { + m_defaultHandler = (XInteractionHandler)UnoRuntime.queryInterface( XInteractionHandler.class, + _factory.createInstance( "com.sun.star.sdb.InteractionHandler" ) ); + } + catch ( Exception ex ) + { + Logger.getLogger( DatabaseDocument.class.getName() ).log( Level.SEVERE, null, ex ); + } + } + + public void handle( XInteractionRequest _request ) + { + Object request = _request.getRequest(); + if ( !( request instanceof DocumentMacroConfirmationRequest ) && ( m_defaultHandler != null ) ) + { + m_defaultHandler.handle( _request ); + return; + } + + assureEquals( "interaction handleer called in wrong state", STATE_LOADING_DOC, m_loadDocState ); + + // auto-approve + XInteractionContinuation continuations[] = _request.getContinuations(); + for ( int i=0; i<continuations.length; ++i ) + { + XInteractionApprove approve = (XInteractionApprove)UnoRuntime.queryInterface( XInteractionApprove.class, + continuations[i] ); + if ( approve != null ) + { + approve.select(); + m_loadDocState = STATE_MACRO_EXEC_APPROVED; + break; + } + } + } + }; + + // ======================================================================================================== + // -------------------------------------------------------------------------------------------------------- + public String[] getTestMethodNames() + { + return new String[] + { + "testLoadable", + "testDocumentEvents", + "testGlobalEvents" + }; + } + + // -------------------------------------------------------------------------------------------------------- + public String getTestObjectName() + { + return "DatabaseDocument"; + } + + public void before() + { + super.before(); + + try + { + // at our service factory, insert a new factory for our CallbackComponent + // this will allow the Basic code in our test documents to call back into this test case + // here, by just instantiating this service + XSet globalFactory = (XSet)UnoRuntime.queryInterface( + XSet.class, getORB() ); + m_callbackFactory = new CallbackComponentFactory(); + globalFactory.insert( m_callbackFactory ); + + // register ourself as listener at the global event broadcaster + XDocumentEventBroadcaster broadcaster = (XDocumentEventBroadcaster)UnoRuntime.queryInterface( + XDocumentEventBroadcaster.class, getORB().createInstance( "com.sun.star.frame.GlobalEventBroadcaster" ) ); + broadcaster.addDocumentEventListener( this ); + } + catch( Exception e ) + { + System.err.println( "could not create the test case, error message:\n" + e.getMessage() ); + e.printStackTrace( System.err ); + failed( "failed to create the test case" ); + } + } + + // -------------------------------------------------------------------------------------------------------- + public void after() + { + super.after(); + + try + { + // dispose our callback factory. This will automatically remove it from our service + // factory + m_callbackFactory.dispose(); + + // revoke ourself as listener at the global event broadcaster + XDocumentEventBroadcaster broadcaster = (XDocumentEventBroadcaster) UnoRuntime.queryInterface( + XDocumentEventBroadcaster.class, getORB().createInstance( "com.sun.star.frame.GlobalEventBroadcaster" ) ); + broadcaster.removeDocumentEventListener( this ); + } + catch ( Exception e ) + { + System.err.println( "could not close the test case, error message:\n" + e.getMessage() ); + e.printStackTrace( System.err ); + failed( "failed to close the test case" ); + } + } + + // -------------------------------------------------------------------------------------------------------- + private class UnoMethodDescriptor + { + public Class unoInterfaceClass = null; + public String methodName = null; + + public UnoMethodDescriptor( Class _class, String _method ) + { + unoInterfaceClass = _class; + methodName = _method; + } + } + + // -------------------------------------------------------------------------------------------------------- + private void impl_checkDocumentInitState( Object _document, boolean _isInitialized ) + { + // things you cannot do with an uninitialized document: + UnoMethodDescriptor[] unsupportedMethods = new UnoMethodDescriptor[] { + new UnoMethodDescriptor( XStorable.class, "store" ), + new UnoMethodDescriptor( XFormDocumentsSupplier.class, "getFormDocuments" ), + new UnoMethodDescriptor( XReportDocumentsSupplier.class, "getReportDocuments" ), + new UnoMethodDescriptor( XScriptInvocationContext.class, "getScriptContainer" ), + new UnoMethodDescriptor( XScriptProviderSupplier.class, "getScriptProvider" ), + new UnoMethodDescriptor( XEventsSupplier.class, "getEvents" ), + new UnoMethodDescriptor( XTitle.class, "getTitle" ), + new UnoMethodDescriptor( XModel2.class, "getControllers" ) + // (there's much more than this, but we cannot list all methods here, can we ...) + }; + + for ( int i=0; i<unsupportedMethods.length; ++i) + { + verifyExpectedException( _document, unsupportedMethods[i].unoInterfaceClass, + unsupportedMethods[i].methodName, new Object[]{}, _isInitialized ? null : NotInitializedException.class ); + } + } + + // -------------------------------------------------------------------------------------------------------- + private String impl_correctFileURL( String _URL ) + { + String returnURL = _URL; + if ( ( returnURL.indexOf( "file:/" ) == 0 ) && ( returnURL.indexOf( "file:///" ) == -1 ) ) + { + // for some reason, the URLs here in Java start with "file:/" only, instead of "file:///" + // Some of the office code doesn't like this ... + returnURL = "file:///" + returnURL.substring( 6 ); + } + return returnURL; + } + + // -------------------------------------------------------------------------------------------------------- + private String impl_copyTempFile( String _sourceURL ) throws IOException + { + String targetURL = createTempFileURL(); + try + { + FileTools.copyFile( new File( new URI( _sourceURL ) ), new File( new URI( targetURL ) ) ); + } + catch ( URISyntaxException e ) { } + + return impl_correctFileURL( targetURL ); + } + + // -------------------------------------------------------------------------------------------------------- + private XModel impl_createDocument( ) throws Exception + { + XModel databaseDoc = (XModel)UnoRuntime.queryInterface( XModel.class, + getORB().createInstance( "com.sun.star.sdb.OfficeDatabaseDocument" ) ); + + // should not be initialized here - we did neither initNew nor load nor storeAsURL it + impl_checkDocumentInitState( databaseDoc, false ); + + return databaseDoc; + } + + // -------------------------------------------------------------------------------------------------------- + private void impl_closeDocument( XModel _databaseDoc ) throws CloseVetoException, IOException, Exception + { + XCloseable closeDoc = (XCloseable)UnoRuntime.queryInterface( XCloseable.class, + _databaseDoc ); + closeDoc.close( true ); + } + + // -------------------------------------------------------------------------------------------------------- + private XModel impl_createEmptyEmbeddedHSQLDocument() throws Exception, IOException + { + XModel databaseDoc = (XModel)UnoRuntime.queryInterface( XModel.class, + getORB().createInstance( "com.sun.star.sdb.OfficeDatabaseDocument" ) ); + XStorable storeDoc = (XStorable)UnoRuntime.queryInterface( XStorable.class, databaseDoc ); + + // verify the document rejects API calls which require it to be initialized + impl_checkDocumentInitState( databaseDoc, false ); + + // though the document is not initialized, you can ask for the location, the URL, and the args + String location = storeDoc.getLocation(); + String url = databaseDoc.getURL(); + PropertyValue[] args = databaseDoc.getArgs(); + // they should be all empty at this time + assureEquals( "location is expected to be empty here", "", location ); + assureEquals( "URL is expected to be empty here", "", url ); + assureEquals( "Args are expected to be empty here", 0, args.length ); + + // and, you should be able to set properties at the data source + XOfficeDatabaseDocument dataSourceAccess = (XOfficeDatabaseDocument)UnoRuntime.queryInterface( + XOfficeDatabaseDocument.class, databaseDoc ); + XPropertySet dsProperties = (XPropertySet)UnoRuntime.queryInterface( + XPropertySet.class, dataSourceAccess.getDataSource() ); + dsProperties.setPropertyValue( "URL", "sdbc:embedded:hsqldb" ); + + String documentURL = createTempFileURL(); + storeDoc.storeAsURL( documentURL, new PropertyValue[0] ); + + // now that the document is stored, ... + // ... its URL should be correct + assureEquals( "wrong URL after storing the document", documentURL, databaseDoc.getURL() ); + // ... it should be initialized + impl_checkDocumentInitState( databaseDoc, true ); + + return databaseDoc; + } + + // -------------------------------------------------------------------------------------------------------- + public void testLoadable() throws Exception, IOException + { + XModel databaseDoc = impl_createEmptyEmbeddedHSQLDocument(); + String documentURL = databaseDoc.getURL(); + + // there's three methods how you can initialize a database document: + + // .................................................................... + // 1. XStorable::storeAsURL + // (this is for compatibility reasons, to not break existing code) + // this test is already made in impl_createEmptyEmbeddedHSQLDocument + + // .................................................................... + // 2. XLoadable::load + databaseDoc = (XModel)UnoRuntime.queryInterface( XModel.class, + getORB().createInstance( "com.sun.star.sdb.OfficeDatabaseDocument" ) ); + documentURL = impl_copyTempFile( documentURL ); + // load the doc, and verify it's initialized then, and has the proper URL + XLoadable loadDoc = (XLoadable)UnoRuntime.queryInterface( XLoadable.class, databaseDoc ); + loadDoc.load( new PropertyValue[] { new PropertyValue( "URL", 0, documentURL, PropertyState.DIRECT_VALUE ) } ); + databaseDoc.attachResource( documentURL, new PropertyValue[0] ); + + assureEquals( "wrong URL after loading the document", documentURL, databaseDoc.getURL() ); + impl_checkDocumentInitState( databaseDoc, true ); + + // and while we are here ... initilizing the same document again should not be possible + verifyExpectedException( databaseDoc, XLoadable.class, "initNew", new Object[0], + DoubleInitializationException.class ); + verifyExpectedException( databaseDoc, XLoadable.class, "load", new Object[] { new PropertyValue[0] }, + DoubleInitializationException.class ); + + // .................................................................... + // 3. XLoadable::initNew + impl_closeDocument( databaseDoc ); + databaseDoc = impl_createDocument(); + loadDoc = (XLoadable)UnoRuntime.queryInterface( XLoadable.class, databaseDoc ); + loadDoc.initNew(); + assureEquals( "wrong URL after initializing the document", "", databaseDoc.getURL() ); + impl_checkDocumentInitState( databaseDoc, true ); + + // same as above - initializing the document a second time must fail + verifyExpectedException( databaseDoc, XLoadable.class, "initNew", new Object[0], + DoubleInitializationException.class ); + verifyExpectedException( databaseDoc, XLoadable.class, "load", new Object[] { new PropertyValue[0] }, + DoubleInitializationException.class ); + } + + // -------------------------------------------------------------------------------------------------------- + private PropertyValue[] impl_getDefaultLoadArgs() + { + return new PropertyValue[] { + new PropertyValue( "PickListEntry", 0, false, PropertyState.DIRECT_VALUE ) + }; + } + + // -------------------------------------------------------------------------------------------------------- + private PropertyValue[] impl_getMacroExecLoadArgs() + { + return new PropertyValue[] { + new PropertyValue( "PickListEntry", 0, false, PropertyState.DIRECT_VALUE ), + new PropertyValue( "MacroExecutionMode", 0, com.sun.star.document.MacroExecMode.USE_CONFIG, PropertyState.DIRECT_VALUE ), + new PropertyValue( "InteractionHandler", 0, new MacroExecutionApprove(( getORB() )), PropertyState.DIRECT_VALUE ) + }; + } + + // -------------------------------------------------------------------------------------------------------- + private int impl_setMacroSecurityLevel( int _level ) throws Exception + { + XMultiServiceFactory configProvider = (XMultiServiceFactory)UnoRuntime.queryInterface( XMultiServiceFactory.class, + getORB().createInstance( "com.sun.star.configuration.ConfigurationProvider" ) ); + + PropertyValue[] args = new PropertyValue[] { + new PropertyValue( "nodepath", 0, "/org.openoffice.Office.Common/Security/Scripting", PropertyState.DIRECT_VALUE ) + }; + + XPropertySet securitySettings = (XPropertySet)UnoRuntime.queryInterface( XPropertySet.class, + configProvider.createInstanceWithArguments( "com.sun.star.configuration.ConfigurationUpdateAccess", args ) ); + int oldValue = ((Integer)securitySettings.getPropertyValue( "MacroSecurityLevel" )).intValue(); + securitySettings.setPropertyValue( "MacroSecurityLevel", new Integer( _level ) ); + + XChangesBatch committer = (XChangesBatch)UnoRuntime.queryInterface( XChangesBatch.class, + securitySettings ); + committer.commitChanges(); + + return oldValue; + } + + // -------------------------------------------------------------------------------------------------------- + public void testDocumentEvents() throws Exception, IOException + { + // create an empty document + XModel databaseDoc = impl_createEmptyEmbeddedHSQLDocument(); + + // create Basic library/module therein + XEmbeddedScripts embeddedScripts = (XEmbeddedScripts) UnoRuntime.queryInterface( XEmbeddedScripts.class, + databaseDoc ); + XStorageBasedLibraryContainer basicLibs = embeddedScripts.getBasicLibraries(); + XNameContainer newLib = basicLibs.createLibrary( "EventHandlers" ); + String eventHandlerCode = + "Option Explicit\n" + + "\n" + + "Sub OnLoad\n" + + " Dim oCallback as Object\n" + + " oCallback = createUnoService( \"" + getCallbackComponentServiceName() + "\" )\n" + + "\n" + + " ' as long as the Document is not passed to the Basic callbacks, we need to create\n" + + " ' one ourself\n" + + " Dim oEvent as new com.sun.star.document.DocumentEvent\n" + + " oEvent.EventName = \"OnLoad\"\n" + + " oEvent.Source = ThisComponent\n" + + "\n" + + " oCallback.documentEventOccured( oEvent )\n" + + "End Sub\n"; + newLib.insertByName( "all", eventHandlerCode ); + + // bind the macro to the OnLoad event + String macroURI = "vnd.sun.star.script:EventHandlers.all.OnLoad?language=Basic&location=document"; + XEventsSupplier eventsSupplier = (XEventsSupplier)UnoRuntime.queryInterface( XEventsSupplier.class, + databaseDoc ); + eventsSupplier.getEvents().replaceByName( "OnLoad", new PropertyValue[] { + new PropertyValue( "EventType", 0, "Script", PropertyState.DIRECT_VALUE ), + new PropertyValue( "Script", 0, macroURI, PropertyState.DIRECT_VALUE ) + } ); + + // store the document, and close it + String documentURL = databaseDoc.getURL(); + documentURL = impl_correctFileURL( documentURL ); + XStorable storeDoc = (XStorable) UnoRuntime.queryInterface( XStorable.class, + databaseDoc ); + storeDoc.store(); + impl_closeDocument( databaseDoc ); + + // ensure the macro security configuration is "ask the user for document macro execution" + int oldSecurityLevel = impl_setMacroSecurityLevel( 1 ); + + // load it, again + XComponentLoader loader = (XComponentLoader)UnoRuntime.queryInterface( XComponentLoader.class, + getORB().createInstance( "com.sun.star.frame.Desktop" ) ); + + m_loadDocState = STATE_LOADING_DOC; + // expected order of states is: + // STATE_LOADING_DOC - initialized here + // STATE_MACRO_EXEC_APPROVED - done in our interaction handler, which auto-approves the execution of macros + // STATE_ON_LOAD_RECEIVED - done in our callback for the document events + // + // In particular, it is important that the interaction handler (which plays the role of the user confirmation + // here) is called before the OnLoad notification is received - since the latter happens from within + // a Basic macro which is bound to the OnLoad event of the document. + + String context = "OnLoad"; + impl_startObservingEvents( context ); + databaseDoc = (XModel)UnoRuntime.queryInterface( XModel.class, + loader.loadComponentFromURL( documentURL, "_blank", 0, impl_getMacroExecLoadArgs() ) ); + impl_stopObservingEvents( m_documentEvents, new String[] { "OnLoad" }, context ); + + assureEquals( "our provided interaction handler was not called", STATE_ON_LOAD_RECEIVED, m_loadDocState ); + + // restore macro security level + impl_setMacroSecurityLevel( oldSecurityLevel ); + + // close the document + impl_closeDocument( databaseDoc ); + } + + // -------------------------------------------------------------------------------------------------------- + public void testGlobalEvents() throws Exception, IOException + { + XModel databaseDoc = impl_createEmptyEmbeddedHSQLDocument(); + XStorable storeDoc = (XStorable) UnoRuntime.queryInterface( XStorable.class, + databaseDoc ); + + String oldURL = null, newURL = null, context = null; + + // XStorable.store + oldURL = databaseDoc.getURL(); + context = "store"; + impl_startObservingEvents( context ); + storeDoc.store(); + assureEquals( "store is not expected to change the document URL", databaseDoc.getURL(), oldURL ); + impl_stopObservingEvents( m_globalEvents, new String[] { "OnSave", "OnSaveDone" }, context ); + + // XStorable.storeToURL + context = "storeToURL"; + impl_startObservingEvents( context ); + storeDoc.storeToURL( createTempFileURL(), new PropertyValue[0] ); + assureEquals( "storetoURL is not expected to change the document URL", databaseDoc.getURL(), oldURL ); + impl_stopObservingEvents( m_globalEvents, new String[] { "OnSaveTo", "OnSaveToDone" }, context ); + + // XStorable.storeAsURL + newURL = createTempFileURL(); + context = "storeAsURL"; + impl_startObservingEvents( context ); + storeDoc.storeAsURL( newURL, new PropertyValue[0] ); + assureEquals( "storeAsURL is expected to change the document URL", databaseDoc.getURL(), newURL ); + impl_stopObservingEvents( m_globalEvents, new String[] { "OnSaveAs", "OnSaveAsDone" }, context ); + + // XModifiable.setModified + XModifiable modifyDoc = (XModifiable) UnoRuntime.queryInterface( XModifiable.class, + databaseDoc ); + context = "setModified"; + impl_startObservingEvents( context ); + modifyDoc.setModified( true ); + assureEquals( "setModified didn't work", modifyDoc.isModified(), true ); + impl_stopObservingEvents( m_globalEvents, new String[] { "OnModifyChanged" }, context ); + + // XStorable.store, with implicit reset of the "Modified" flag + context = "store (2)"; + impl_startObservingEvents( context ); + storeDoc.store(); + assureEquals( "'store' should implicitly reset the modified flag", modifyDoc.isModified(), false ); + impl_stopObservingEvents( m_globalEvents, new String[] { "OnSave", "OnSaveDone", "OnModifyChanged" }, context ); + + // XComponentLoader.loadComponentFromURL + newURL = impl_copyTempFile( databaseDoc.getURL() ); + XComponentLoader loader = (XComponentLoader)UnoRuntime.queryInterface( XComponentLoader.class, + getORB().createInstance( "com.sun.star.frame.Desktop" ) ); + context = "loadComponentFromURL"; + impl_startObservingEvents( context ); + databaseDoc = (XModel) UnoRuntime.queryInterface( XModel.class, + loader.loadComponentFromURL( newURL, "_blank", 0, impl_getDefaultLoadArgs() ) ); + impl_stopObservingEvents( m_globalEvents, + new String[] { "OnLoadFinished", "OnViewCreated", "OnFocus", "OnLoad" }, context ); + + // closing a document by API + XCloseable closeDoc = (XCloseable) UnoRuntime.queryInterface( XCloseable.class, + databaseDoc ); + context = "close (API)"; + impl_startObservingEvents( context ); + closeDoc.close( true ); + impl_stopObservingEvents( m_globalEvents, + new String[] { "OnPrepareUnload", "OnViewClosed", "OnUnload" }, context ); + + // closing a document via UI + context = "close (UI)"; + impl_startObservingEvents( "prepare for '" + context + "'" ); + databaseDoc = (XModel)UnoRuntime.queryInterface( XModel.class, + loader.loadComponentFromURL( newURL, "_blank", 0, impl_getDefaultLoadArgs() ) ); + impl_waitForEvent( m_globalEvents, "OnLoad", 5000 ); + // wait for all events to arrive - OnLoad should be the last one + + XDispatchProvider dispatchProvider = (XDispatchProvider) UnoRuntime.queryInterface( XDispatchProvider.class, + databaseDoc.getCurrentController().getFrame() ); + URL url = impl_getURL( ".uno:CloseDoc" ); + XDispatch dispatcher = dispatchProvider.queryDispatch( url, "", 0 ); + impl_startObservingEvents( context ); + dispatcher.dispatch( url, new PropertyValue[0] ); + impl_stopObservingEvents( m_globalEvents, + new String[] { "OnPrepareViewClosing", "OnViewClosed", "OnPrepareUnload", "OnUnload" }, context ); + + // creating a new document + databaseDoc = impl_createDocument(); + XLoadable loadDoc = (XLoadable) UnoRuntime.queryInterface( XLoadable.class, + databaseDoc ); + context = "initNew"; + impl_startObservingEvents( context ); + loadDoc.initNew(); + impl_stopObservingEvents( m_globalEvents, new String[] { "OnCreate" }, context ); + + impl_startObservingEvents( context + " (cleanup)" ); + impl_closeDocument( databaseDoc ); + impl_waitForEvent( m_globalEvents, "OnUnload", 5000 ); + + // focus changes + context = "activation"; + // for this, load a database document ... + impl_startObservingEvents( "prepare for '" + context + "'" ); + databaseDoc = (XModel)UnoRuntime.queryInterface( XModel.class, + loader.loadComponentFromURL( newURL, "_blank", 0, impl_getDefaultLoadArgs() ) ); + impl_waitForEvent( m_globalEvents, "OnLoad", 5000 ); + // ... and another document ... + String otherURL = impl_copyTempFile( databaseDoc.getURL() ); + XModel otherDoc = (XModel)UnoRuntime.queryInterface( XModel.class, + loader.loadComponentFromURL( otherURL, "_blank", 0, impl_getDefaultLoadArgs() ) ); + impl_raise( otherDoc ); + + // ... and switch between the two + impl_startObservingEvents( context ); + impl_raise( databaseDoc ); + impl_stopObservingEvents( m_globalEvents, new String[] { "OnUnfocus", "OnFocus" }, context ); + + // cleanup + impl_closeDocument( databaseDoc ); + impl_closeDocument( otherDoc ); + } + + // -------------------------------------------------------------------------------------------------------- + private URL impl_getURL( String _completeURL ) throws Exception + { + URL[] url = { new URL() }; + url[0].Complete = _completeURL; + XURLTransformer urlTransformer = (XURLTransformer) UnoRuntime.queryInterface( XURLTransformer.class, + getORB().createInstance( "com.sun.star.util.URLTransformer" ) ); + urlTransformer.parseStrict( url ); + return url[0]; + } + + // -------------------------------------------------------------------------------------------------------- + private void impl_raise( XModel _document ) + { + XFrame frame = _document.getCurrentController().getFrame(); + XTopWindow topWindow = (XTopWindow) UnoRuntime.queryInterface( XTopWindow.class, + frame.getContainerWindow() ); + topWindow.toFront(); + } + + // -------------------------------------------------------------------------------------------------------- + private void impl_startObservingEvents( String _context ) + { + log.println( " " + _context ); + synchronized ( m_documentEvents ) + { + m_documentEvents.clear(); + } + synchronized ( m_globalEvents ) + { + m_globalEvents.clear(); + } + } + + // -------------------------------------------------------------------------------------------------------- + private void impl_stopObservingEvents( Vector _actualEvents, String[] _expectedEvents, String _context ) + { + synchronized ( _actualEvents ) + { + int actualEventCount = _actualEvents.size(); + while ( actualEventCount < _expectedEvents.length ) + { + // well, it's possible not all events already arrived, yet - finally, some of them + // are notified asynchronously + // So, wait a few seconds. + try + { + _actualEvents.wait( 5000 ); + } + catch ( InterruptedException ex ) { } + + if ( actualEventCount == _actualEvents.size() ) + // the above wait was left because of the timeout, *not* because an event + // arrived. Okay, we won't wait any longer, this is a failure. + break; + actualEventCount = _actualEvents.size(); + } + + assureEquals( "wrong event count for '" + _context + "'", + _expectedEvents.length, _actualEvents.size() ); + + for ( int i=0; i<_expectedEvents.length; ++i ) + { + assureEquals( "wrong event at positon " + ( i + 1 ) + " for '" + _context + "'", + _expectedEvents[i], _actualEvents.get(i) ); + } + } + } + + // -------------------------------------------------------------------------------------------------------- + void impl_waitForEvent( Vector _eventQueue, String _expectedEvent, int _maxMilliseconds ) + { + synchronized ( _eventQueue ) + { + int waitedMilliseconds = 0; + + while ( waitedMilliseconds < _maxMilliseconds ) + { + for ( int i=0; i<_eventQueue.size(); ++i ) + { + if ( _expectedEvent.equals( _eventQueue.get(i) ) ) + // found the event in the queue + return; + } + + // wait a little, perhaps the event will still arrive + try + { + _eventQueue.wait( 500 ); + waitedMilliseconds += 500; + } + catch ( InterruptedException e ) { } + } + } + + failed( "expected event '" + _expectedEvent + "' did not arrive after " + _maxMilliseconds + " milliseconds" ); + } + + // -------------------------------------------------------------------------------------------------------- + void onDocumentEvent( DocumentEvent _Event ) + { + if ( _Event.EventName.equals( "OnTitleChanged" ) ) + // OnTitleChanged events are notified too often. This is known, and accepted. + // (the deeper reason is that it's diffult to determine, in the DatabaseDocument implementatin, + // when the title actually changed. In particular, when we do a saveAsURL, and then ask for a + // title *before* the TitleHelper got the document's OnSaveAsDone event, then the wrong (old) + // title is obtained. + return; + + if ( ( _Event.EventName.equals( "OnLoad" ) ) + && ( m_loadDocState != STATE_NOT_STARTED ) + ) + { + assureEquals( "OnLoad event must come *after* invocation of the interaction handler / user!", + m_loadDocState, STATE_MACRO_EXEC_APPROVED ); + m_loadDocState = STATE_ON_LOAD_RECEIVED; + } + + synchronized ( m_documentEvents ) + { + m_documentEvents.add( _Event.EventName ); + m_documentEvents.notifyAll(); + } + + log.println( " document event: " + _Event.EventName ); + } + + // -------------------------------------------------------------------------------------------------------- + public void documentEventOccured( DocumentEvent _Event ) + { + if ( _Event.EventName.equals( "OnTitleChanged" ) ) + // ignore. See onDocumentEvent for a justification + return; + + synchronized ( m_globalEvents ) + { + m_globalEvents.add( _Event.EventName ); + m_globalEvents.notifyAll(); + } + + log.println( " global event: " + _Event.EventName ); + } + + // -------------------------------------------------------------------------------------------------------- + public void disposing( EventObject _Event ) + { + // not interested in + } +} diff --git a/dbaccess/qa/complex/dbaccess/Parser.java b/dbaccess/qa/complex/dbaccess/Parser.java index e68e1305cd34..b765bc2657c7 100644 --- a/dbaccess/qa/complex/dbaccess/Parser.java +++ b/dbaccess/qa/complex/dbaccess/Parser.java @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: Parser.java,v $ - * $Revision: 1.2 $ + * $Revision: 1.1.6.2 $ * * This file is part of OpenOffice.org. * diff --git a/dbaccess/qa/complex/dbaccess/QueryInQuery.java b/dbaccess/qa/complex/dbaccess/QueryInQuery.java index c9d3e02a0b80..b06d57d05c59 100644 --- a/dbaccess/qa/complex/dbaccess/QueryInQuery.java +++ b/dbaccess/qa/complex/dbaccess/QueryInQuery.java @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: QueryInQuery.java,v $ - * $Revision: 1.7 $ + * $Revision: 1.6.2.1 $ * * This file is part of OpenOffice.org. * diff --git a/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java b/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java index 6471dc377ad4..c73ce6496c88 100755 --- a/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java +++ b/dbaccess/qa/complex/dbaccess/SingleSelectQueryComposer.java @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: SingleSelectQueryComposer.java,v $ - * $Revision: 1.9 $ + * $Revision: 1.8.14.1 $ * * This file is part of OpenOffice.org. * diff --git a/dbaccess/qa/complex/dbaccess/Storable.java b/dbaccess/qa/complex/dbaccess/Storable.java deleted file mode 100644 index 37c99c5304c5..000000000000 --- a/dbaccess/qa/complex/dbaccess/Storable.java +++ /dev/null @@ -1,106 +0,0 @@ -/************************************************************************* - * - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * Copyright 2008 by Sun Microsystems, Inc. - * - * OpenOffice.org - a multi-platform office productivity suite - * - * $RCSfile: Storable.java,v $ - * $Revision: 1.5 $ - * - * This file is part of OpenOffice.org. - * - * OpenOffice.org is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License version 3 - * only, as published by the Free Software Foundation. - * - * OpenOffice.org is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License version 3 for more details - * (a copy is included in the LICENSE file that accompanied this code). - * - * You should have received a copy of the GNU Lesser General Public License - * version 3 along with OpenOffice.org. If not, see - * <http://www.openoffice.org/license.html> - * for a copy of the LGPLv3 License. - * - ************************************************************************/ -package complex.dbaccess; - -import com.sun.star.lang.XMultiServiceFactory; -import com.sun.star.uno.UnoRuntime; -import com.sun.star.frame.XStorable; -import com.sun.star.frame.FrameSearchFlag; -import com.sun.star.beans.PropertyValue; -import com.sun.star.lang.XComponent; -import com.sun.star.frame.XComponentLoader; -import com.sun.star.util.XCloseable; -import connectivity.tools.*; - -public class Storable extends complexlib.ComplexTestCase { - - HsqlDatabase m_database; - - // -------------------------------------------------------------------------------------------------------- - public String[] getTestMethodNames() { - return new String[] - { - "testStorable" - }; - } - - // -------------------------------------------------------------------------------------------------------- - public String getTestObjectName() { - return "Storable"; - } - - // -------------------------------------------------------------------------------------------------------- - private void createTestCase() - { - try - { - if ( m_database == null ) - { - CRMDatabase database = new CRMDatabase( getFactory() ); - m_database = database.getDatabase(); - } - } - catch( Exception e ) - { - System.err.println( "could not create the test case, error message:\n" + e.getMessage() ); - e.printStackTrace( System.err ); - assure( "failed to created the test case", false ); - } - } - - // -------------------------------------------------------------------------------------------------------- - private XMultiServiceFactory getFactory() - { - return (XMultiServiceFactory)param.getMSF(); - } - - // -------------------------------------------------------------------------------------------------------- - public void testStorable() - { - createTestCase(); - - try - { - Object object = getFactory().createInstance("com.sun.star.frame.Desktop"); - XComponentLoader xComponentLoader = (XComponentLoader)UnoRuntime.queryInterface(XComponentLoader.class, object); - XComponent xComponent = xComponentLoader.loadComponentFromURL(m_database.getDocumentURL(), "_blank",FrameSearchFlag.ALL, new PropertyValue[0]); - m_database.close(); - XStorable storable = (XStorable)UnoRuntime.queryInterface(XStorable.class,xComponent); - storable.store(); - XCloseable close = (XCloseable)UnoRuntime.queryInterface(XCloseable.class,xComponent); - close.close(true); - } - catch ( AssureException e ) { throw e; } - catch ( Exception e ) - { - assure( "caught an unexpected exception: " + e.getMessage(), false ); - } - } -} diff --git a/dbaccess/qa/complex/dbaccess/TestCase.java b/dbaccess/qa/complex/dbaccess/TestCase.java new file mode 100644 index 000000000000..65774e108247 --- /dev/null +++ b/dbaccess/qa/complex/dbaccess/TestCase.java @@ -0,0 +1,128 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2008 by Sun Microsystems, Inc. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: TestCase.java,v $ + * $Revision: 1.1.2.1 $ + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ +package complex.dbaccess; + +import com.sun.star.beans.XPropertySet; +import com.sun.star.lang.XMultiServiceFactory; +import com.sun.star.uno.UnoRuntime; +import com.sun.star.uno.XComponentContext; +import java.io.File; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public abstract class TestCase extends complexlib.ComplexTestCase +{ + // -------------------------------------------------------------------------------------------------------- + protected final XMultiServiceFactory getORB() + { + return (XMultiServiceFactory)param.getMSF(); + } + + // -------------------------------------------------------------------------------------------------------- + protected final XComponentContext getComponentContext() + { + XComponentContext context = null; + try + { + XPropertySet orbProps = (XPropertySet) UnoRuntime.queryInterface( XPropertySet.class, getORB() ); + context = (XComponentContext)UnoRuntime.queryInterface( XComponentContext.class, + orbProps.getPropertyValue( "DefaultContext" ) ); + } + catch ( Exception ex ) + { + failed( "could not retrieve the ComponentContext" ); + } + return context; + } + + // -------------------------------------------------------------------------------------------------------- + public void before() + { + } + + // -------------------------------------------------------------------------------------------------------- + public void after() + { + } + + // -------------------------------------------------------------------------------------------------------- + /** returns the URL of a temporary file which can be used during the test. + * + * The file will be deleted when the process exits + * @return the URL of a temporary file + */ + protected final String createTempFileURL() throws IOException + { + File documentFile = java.io.File.createTempFile( getTestObjectName(), ".odb" ); + documentFile.deleteOnExit(); + return documentFile.getAbsoluteFile().toURL().toString(); + } + + // -------------------------------------------------------------------------------------------------------- + protected void verifyExpectedException( Object _object, Class _unoInterfaceClass, String _methodName, Object[] _methodArgs, + Class _expectedExceptionClass ) + { + verifyExpectedException( UnoRuntime.queryInterface( _unoInterfaceClass, _object ), _methodName, + _methodArgs, _expectedExceptionClass ); + } + + // -------------------------------------------------------------------------------------------------------- + protected void verifyExpectedException( Object _object, String _methodName, Object[] _methodArgs, + Class _expectedExceptionClass ) + { + Class objectClass = _object.getClass(); + Class[] methodArgsClasses = new Class[ _methodArgs.length ]; + for ( int i=0; i<_methodArgs.length; ++i ) + methodArgsClasses[i] = _methodArgs[i].getClass(); + + boolean noExceptionAllowed = _expectedExceptionClass == null; + + boolean caughtExpected = noExceptionAllowed ? true : false; + try + { + Method method = objectClass.getMethod( _methodName, methodArgsClasses ); + method.invoke(_object, _methodArgs ); + } + catch ( InvocationTargetException e ) + { + caughtExpected = noExceptionAllowed + ? false + : ( e.getTargetException().getClass().equals( _expectedExceptionClass ) ); + } + catch( Exception e ) + { + caughtExpected = false; + } + assure( "did not catch the expected exception (" + + ( noExceptionAllowed ? "none" : _expectedExceptionClass.getName() ) + + ") while calling " + _object.getClass().getName() + "." + _methodName, caughtExpected ); + } +} diff --git a/dbaccess/qa/complex/dbaccess/dbaccess.sce b/dbaccess/qa/complex/dbaccess/dbaccess.sce index f5973808b8f4..3e0357af2727 100644 --- a/dbaccess/qa/complex/dbaccess/dbaccess.sce +++ b/dbaccess/qa/complex/dbaccess/dbaccess.sce @@ -3,6 +3,6 @@ -o complex.dbaccess.PropertyBag -o complex.dbaccess.Query -o complex.dbaccess.QueryInQuery --o complex.dbaccess.Storable +-o complex.dbaccess.DatabaseDocument -o complex.dbaccess.DataSource -o complex.dbaccess.Parser |