1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski package basicrunner; 24*b1cdbd2cSJim Jagielski 25*b1cdbd2cSJim Jagielski 26*b1cdbd2cSJim Jagielski import com.sun.star.beans.PropertyValue; 27*b1cdbd2cSJim Jagielski import com.sun.star.beans.XPropertySet; 28*b1cdbd2cSJim Jagielski import com.sun.star.connection.ConnectionSetupException; 29*b1cdbd2cSJim Jagielski import com.sun.star.container.ContainerEvent; 30*b1cdbd2cSJim Jagielski import com.sun.star.container.XContainer; 31*b1cdbd2cSJim Jagielski import com.sun.star.container.XContainerListener; 32*b1cdbd2cSJim Jagielski import com.sun.star.container.XNameContainer; 33*b1cdbd2cSJim Jagielski import com.sun.star.frame.XComponentLoader; 34*b1cdbd2cSJim Jagielski import com.sun.star.frame.XDesktop; 35*b1cdbd2cSJim Jagielski import com.sun.star.lang.WrappedTargetException; 36*b1cdbd2cSJim Jagielski import com.sun.star.lang.XComponent; 37*b1cdbd2cSJim Jagielski import com.sun.star.lang.XMultiServiceFactory; 38*b1cdbd2cSJim Jagielski import com.sun.star.lang.XServiceInfo; 39*b1cdbd2cSJim Jagielski import com.sun.star.lang.XSingleServiceFactory; 40*b1cdbd2cSJim Jagielski import com.sun.star.lang.XTypeProvider; 41*b1cdbd2cSJim Jagielski import com.sun.star.uno.Type; 42*b1cdbd2cSJim Jagielski import com.sun.star.uno.UnoRuntime; 43*b1cdbd2cSJim Jagielski import com.sun.star.util.XChangesBatch; 44*b1cdbd2cSJim Jagielski import java.util.Hashtable; 45*b1cdbd2cSJim Jagielski import lib.TestParameters; 46*b1cdbd2cSJim Jagielski 47*b1cdbd2cSJim Jagielski import share.LogWriter; 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski 50*b1cdbd2cSJim Jagielski /** 51*b1cdbd2cSJim Jagielski * This class is a java-part of BASIC-java interaction "driver" 52*b1cdbd2cSJim Jagielski * It is used to call Star-Basic's function from java using 53*b1cdbd2cSJim Jagielski * basic's part of "driver" where listeners are implemented. 54*b1cdbd2cSJim Jagielski * The instance of the BasicHandler should be added to the MSF that will be 55*b1cdbd2cSJim Jagielski * used for loading BASIC's part of "driver".<br> 56*b1cdbd2cSJim Jagielski * After opening basic's document it creates an instance of the 57*b1cdbd2cSJim Jagielski * HandlerContainer using BasicHandler. HandlerContainer is a UNO 58*b1cdbd2cSJim Jagielski * XContainer and XNameContainer. 59*b1cdbd2cSJim Jagielski * Only one instance of BasicHandler can be used at the moment. 60*b1cdbd2cSJim Jagielski * @see com.sun.star.lang.XServiceInfo 61*b1cdbd2cSJim Jagielski * @see com.sun.star.lang.XSingleServiceFactory 62*b1cdbd2cSJim Jagielski */ 63*b1cdbd2cSJim Jagielski public class BasicHandler implements XServiceInfo, XSingleServiceFactory { 64*b1cdbd2cSJim Jagielski /** 65*b1cdbd2cSJim Jagielski * serviceName is the name of service that can be created in BASIC. 66*b1cdbd2cSJim Jagielski */ 67*b1cdbd2cSJim Jagielski static final String serviceName = 68*b1cdbd2cSJim Jagielski "com.sun.star.jsuite.basicrunner.BasicHandler"; 69*b1cdbd2cSJim Jagielski 70*b1cdbd2cSJim Jagielski /** 71*b1cdbd2cSJim Jagielski * <code>container</code> is a SHARED variable (between BASIC and Java). 72*b1cdbd2cSJim Jagielski * It is used for interacting. 73*b1cdbd2cSJim Jagielski */ 74*b1cdbd2cSJim Jagielski static private HandlerContainer container = null; 75*b1cdbd2cSJim Jagielski 76*b1cdbd2cSJim Jagielski /** 77*b1cdbd2cSJim Jagielski * Contains a writer to log an information about the interface testing, to 78*b1cdbd2cSJim Jagielski * allows for tests to access it. 79*b1cdbd2cSJim Jagielski */ 80*b1cdbd2cSJim Jagielski static private LogWriter log; 81*b1cdbd2cSJim Jagielski 82*b1cdbd2cSJim Jagielski /** 83*b1cdbd2cSJim Jagielski * <code>oHandlerDoc</code> is a referrence to BASIC's document. 84*b1cdbd2cSJim Jagielski */ 85*b1cdbd2cSJim Jagielski static private XComponent oHandlerDoc = null; 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski /** 88*b1cdbd2cSJim Jagielski * <code>xMSF</code> is a MultiServiceFactory currently used by 89*b1cdbd2cSJim Jagielski * BasicHandler. 90*b1cdbd2cSJim Jagielski */ 91*b1cdbd2cSJim Jagielski static private XMultiServiceFactory xMSF = null; 92*b1cdbd2cSJim Jagielski 93*b1cdbd2cSJim Jagielski /** 94*b1cdbd2cSJim Jagielski * Interface being tested now. 95*b1cdbd2cSJim Jagielski */ 96*b1cdbd2cSJim Jagielski static private BasicIfcTest TestedInterface = null; 97*b1cdbd2cSJim Jagielski 98*b1cdbd2cSJim Jagielski /** 99*b1cdbd2cSJim Jagielski * Ab enhanced scheme of timeouts can be used with BASIC tests. 100*b1cdbd2cSJim Jagielski * A small timeout can be used zo wait for changes in the test status. 101*b1cdbd2cSJim Jagielski * <code>respFlag</code> is set to <code>true</code> when a BASIC test 102*b1cdbd2cSJim Jagielski * writes any log information. 103*b1cdbd2cSJim Jagielski */ 104*b1cdbd2cSJim Jagielski static private boolean respFlag = false; 105*b1cdbd2cSJim Jagielski 106*b1cdbd2cSJim Jagielski /** 107*b1cdbd2cSJim Jagielski * <code>iBasicTimeout</code> is the amount of milliseconds that 108*b1cdbd2cSJim Jagielski * the BasicHandler will wait for a response from tests 109*b1cdbd2cSJim Jagielski * (finish to execute a method or add log information) 110*b1cdbd2cSJim Jagielski * before it decides that SOffice is dead. 111*b1cdbd2cSJim Jagielski */ 112*b1cdbd2cSJim Jagielski static private int iBasicTimeout = 10000; 113*b1cdbd2cSJim Jagielski 114*b1cdbd2cSJim Jagielski 115*b1cdbd2cSJim Jagielski 116*b1cdbd2cSJim Jagielski /** 117*b1cdbd2cSJim Jagielski * Creates an instance of a HandlerContainer. This instance is used from 118*b1cdbd2cSJim Jagielski * BASIC. 119*b1cdbd2cSJim Jagielski * @param tParam The test parameters. 120*b1cdbd2cSJim Jagielski */ BasicHandler(TestParameters tParam)121*b1cdbd2cSJim Jagielski public BasicHandler(TestParameters tParam) { 122*b1cdbd2cSJim Jagielski if (tParam.get("soapi.test.basic.debugFile") != null) { 123*b1cdbd2cSJim Jagielski iBasicTimeout = 0; // Debug mode. 124*b1cdbd2cSJim Jagielski } 125*b1cdbd2cSJim Jagielski container = new HandlerContainer(this); 126*b1cdbd2cSJim Jagielski } 127*b1cdbd2cSJim Jagielski 128*b1cdbd2cSJim Jagielski /** 129*b1cdbd2cSJim Jagielski * Set the tested interface and a log writer. 130*b1cdbd2cSJim Jagielski * @param ifc The test of an interface 131*b1cdbd2cSJim Jagielski * @param log A log writer. 132*b1cdbd2cSJim Jagielski */ setTestedInterface(BasicIfcTest ifc, LogWriter log)133*b1cdbd2cSJim Jagielski public void setTestedInterface(BasicIfcTest ifc, LogWriter log) { 134*b1cdbd2cSJim Jagielski this.log = log; 135*b1cdbd2cSJim Jagielski TestedInterface = ifc; 136*b1cdbd2cSJim Jagielski } 137*b1cdbd2cSJim Jagielski 138*b1cdbd2cSJim Jagielski /** 139*b1cdbd2cSJim Jagielski * Is called when BASIC signals that it has performed the test of a method. 140*b1cdbd2cSJim Jagielski * @param methodName The name of the method. 141*b1cdbd2cSJim Jagielski * @bResult The result of the test. 142*b1cdbd2cSJim Jagielski */ methodTested(String methodName, boolean bResult)143*b1cdbd2cSJim Jagielski synchronized void methodTested(String methodName, boolean bResult) { 144*b1cdbd2cSJim Jagielski respFlag = true; 145*b1cdbd2cSJim Jagielski TestedInterface.methodTested(methodName, bResult); 146*b1cdbd2cSJim Jagielski notify() ; 147*b1cdbd2cSJim Jagielski } 148*b1cdbd2cSJim Jagielski 149*b1cdbd2cSJim Jagielski /** 150*b1cdbd2cSJim Jagielski * Is called when BASIC sends a signal to write some log information. 151*b1cdbd2cSJim Jagielski * @param info The string to write. 152*b1cdbd2cSJim Jagielski */ Log(String info)153*b1cdbd2cSJim Jagielski synchronized public void Log(String info) { 154*b1cdbd2cSJim Jagielski respFlag = true; 155*b1cdbd2cSJim Jagielski log.println(info); 156*b1cdbd2cSJim Jagielski notify() ; 157*b1cdbd2cSJim Jagielski } 158*b1cdbd2cSJim Jagielski 159*b1cdbd2cSJim Jagielski /** 160*b1cdbd2cSJim Jagielski * Is called by BasicIfcTest to find out if this BasicHandler uses the 161*b1cdbd2cSJim Jagielski * correct MultiServiceFactory. 162*b1cdbd2cSJim Jagielski * @param xMSF The MultiServiceFactory 163*b1cdbd2cSJim Jagielski * @see com.sun.star.lang.XMultiServiceFactory 164*b1cdbd2cSJim Jagielski * @return True, if xMSF is equal to the MultiServiceFactory of this class. 165*b1cdbd2cSJim Jagielski */ isUptodate(XMultiServiceFactory xMSF)166*b1cdbd2cSJim Jagielski public boolean isUptodate(XMultiServiceFactory xMSF) { 167*b1cdbd2cSJim Jagielski return xMSF.equals(this.xMSF); 168*b1cdbd2cSJim Jagielski } 169*b1cdbd2cSJim Jagielski 170*b1cdbd2cSJim Jagielski 171*b1cdbd2cSJim Jagielski /** 172*b1cdbd2cSJim Jagielski * Establishes a connection between BASIC and Java. 173*b1cdbd2cSJim Jagielski * If required, hte BASIC part of the "driver" is loaded. 174*b1cdbd2cSJim Jagielski * @param sBasicBridgeURL The URL of the basic bridge document 175*b1cdbd2cSJim Jagielski * (BasicBridge.sxw) 176*b1cdbd2cSJim Jagielski * @param tParam The test parameters. 177*b1cdbd2cSJim Jagielski * @param xMSF The MultiServiceFactory 178*b1cdbd2cSJim Jagielski * @param log The log writer. 179*b1cdbd2cSJim Jagielski * @see com.sun.star.lang.XMultiServiceFactory 180*b1cdbd2cSJim Jagielski * @throws ConnectionSetupException Exception is thrown, if no connection could be made. 181*b1cdbd2cSJim Jagielski */ Connect(String sBasicBridgeURL, TestParameters tParam, XMultiServiceFactory xMSF, LogWriter log)182*b1cdbd2cSJim Jagielski public synchronized void Connect(String sBasicBridgeURL, 183*b1cdbd2cSJim Jagielski TestParameters tParam, XMultiServiceFactory xMSF, 184*b1cdbd2cSJim Jagielski LogWriter log) throws ConnectionSetupException { 185*b1cdbd2cSJim Jagielski this.log = log; 186*b1cdbd2cSJim Jagielski try { 187*b1cdbd2cSJim Jagielski this.xMSF = xMSF; 188*b1cdbd2cSJim Jagielski Object oInterface = xMSF.createInstance( 189*b1cdbd2cSJim Jagielski "com.sun.star.frame.Desktop"); 190*b1cdbd2cSJim Jagielski XDesktop oDesktop = (XDesktop) UnoRuntime.queryInterface( 191*b1cdbd2cSJim Jagielski XDesktop.class, oInterface); 192*b1cdbd2cSJim Jagielski XComponentLoader oCLoader = (XComponentLoader) 193*b1cdbd2cSJim Jagielski UnoRuntime.queryInterface( 194*b1cdbd2cSJim Jagielski XComponentLoader.class, oDesktop); 195*b1cdbd2cSJim Jagielski 196*b1cdbd2cSJim Jagielski // load BasicBridge with MarcoEceutionMode = Always-no warn 197*b1cdbd2cSJim Jagielski //PropertyValue[] DocArgs = null; 198*b1cdbd2cSJim Jagielski PropertyValue[] DocArgs = new PropertyValue[1]; 199*b1cdbd2cSJim Jagielski PropertyValue DocArg = new PropertyValue(); 200*b1cdbd2cSJim Jagielski DocArg.Name = "MacroExecutionMode"; 201*b1cdbd2cSJim Jagielski DocArg.Value = new Short( 202*b1cdbd2cSJim Jagielski com.sun.star.document.MacroExecMode.ALWAYS_EXECUTE_NO_WARN); 203*b1cdbd2cSJim Jagielski DocArgs[0] = DocArg; 204*b1cdbd2cSJim Jagielski 205*b1cdbd2cSJim Jagielski // configure Office to allow to execute macos 206*b1cdbd2cSJim Jagielski PropertyValue [] ProvArgs = new PropertyValue [1]; 207*b1cdbd2cSJim Jagielski PropertyValue Arg = new PropertyValue(); 208*b1cdbd2cSJim Jagielski Arg.Name = "nodepath"; 209*b1cdbd2cSJim Jagielski Arg.Value = "/org.openoffice.Office.Common/Security"; 210*b1cdbd2cSJim Jagielski ProvArgs[0] = Arg; 211*b1cdbd2cSJim Jagielski 212*b1cdbd2cSJim Jagielski Object oProvider = xMSF.createInstance( 213*b1cdbd2cSJim Jagielski "com.sun.star.configuration.ConfigurationProvider"); 214*b1cdbd2cSJim Jagielski 215*b1cdbd2cSJim Jagielski XMultiServiceFactory oProviderMSF = (XMultiServiceFactory) 216*b1cdbd2cSJim Jagielski UnoRuntime.queryInterface( 217*b1cdbd2cSJim Jagielski XMultiServiceFactory.class, oProvider); 218*b1cdbd2cSJim Jagielski 219*b1cdbd2cSJim Jagielski Object oSecure = oProviderMSF.createInstanceWithArguments( 220*b1cdbd2cSJim Jagielski "com.sun.star.configuration.ConfigurationUpdateAccess", 221*b1cdbd2cSJim Jagielski ProvArgs); 222*b1cdbd2cSJim Jagielski 223*b1cdbd2cSJim Jagielski XPropertySet oSecureProps = (XPropertySet) 224*b1cdbd2cSJim Jagielski UnoRuntime.queryInterface(XPropertySet.class, oSecure); 225*b1cdbd2cSJim Jagielski 226*b1cdbd2cSJim Jagielski Object oScripting = oSecureProps.getPropertyValue("Scripting"); 227*b1cdbd2cSJim Jagielski XPropertySet oScriptingSettings = (XPropertySet) 228*b1cdbd2cSJim Jagielski UnoRuntime.queryInterface(XPropertySet.class, oScripting); 229*b1cdbd2cSJim Jagielski 230*b1cdbd2cSJim Jagielski oScriptingSettings.setPropertyValue("Warning", Boolean.FALSE); 231*b1cdbd2cSJim Jagielski oScriptingSettings.setPropertyValue("OfficeBasic", new Integer(2)); 232*b1cdbd2cSJim Jagielski 233*b1cdbd2cSJim Jagielski XChangesBatch oSecureChange = (XChangesBatch) 234*b1cdbd2cSJim Jagielski UnoRuntime.queryInterface(XChangesBatch.class, oSecure); 235*b1cdbd2cSJim Jagielski oSecureChange.commitChanges(); 236*b1cdbd2cSJim Jagielski 237*b1cdbd2cSJim Jagielski // As we want to have some information about a debugFile 238*b1cdbd2cSJim Jagielski // BEFORE connection is established 239*b1cdbd2cSJim Jagielski // we pass the information about it in frame name. 240*b1cdbd2cSJim Jagielski String sFrameName = (String)tParam.get( 241*b1cdbd2cSJim Jagielski "soapi.test.basic.debugFile"); 242*b1cdbd2cSJim Jagielski if (sFrameName == null) sFrameName = "BasicRunner"; 243*b1cdbd2cSJim Jagielski 244*b1cdbd2cSJim Jagielski oHandlerDoc = oCLoader.loadComponentFromURL(sBasicBridgeURL, 245*b1cdbd2cSJim Jagielski sFrameName, 40, DocArgs); 246*b1cdbd2cSJim Jagielski 247*b1cdbd2cSJim Jagielski do { 248*b1cdbd2cSJim Jagielski respFlag = false ; 249*b1cdbd2cSJim Jagielski wait(10000); // waiting for basic response for 10 seconds. 250*b1cdbd2cSJim Jagielski } while (respFlag && !container.hasByName("BASIC_Done")) ; 251*b1cdbd2cSJim Jagielski 252*b1cdbd2cSJim Jagielski if (!container.hasByName("BASIC_Done")) { 253*b1cdbd2cSJim Jagielski throw new ConnectionSetupException("Connection timed out."); 254*b1cdbd2cSJim Jagielski } 255*b1cdbd2cSJim Jagielski } catch (Exception e) { 256*b1cdbd2cSJim Jagielski System.out.println("Exception: " + e.toString()); 257*b1cdbd2cSJim Jagielski throw new ConnectionSetupException(); 258*b1cdbd2cSJim Jagielski } 259*b1cdbd2cSJim Jagielski 260*b1cdbd2cSJim Jagielski log.println("Java-BASIC connection established!"); 261*b1cdbd2cSJim Jagielski } 262*b1cdbd2cSJim Jagielski 263*b1cdbd2cSJim Jagielski /** 264*b1cdbd2cSJim Jagielski * Overloads perform(Strin fName, Object params) for convenience. 265*b1cdbd2cSJim Jagielski * @return A proprty value as result. 266*b1cdbd2cSJim Jagielski * 267*b1cdbd2cSJim Jagielski public synchronized PropertyValue perform(String fName) 268*b1cdbd2cSJim Jagielski throws BasicException { 269*b1cdbd2cSJim Jagielski return perform(fName, ""); 270*b1cdbd2cSJim Jagielski } 271*b1cdbd2cSJim Jagielski */ 272*b1cdbd2cSJim Jagielski /** 273*b1cdbd2cSJim Jagielski * Perform a test of a method. 274*b1cdbd2cSJim Jagielski * @param fName The name of the method to test. 275*b1cdbd2cSJim Jagielski * @param params The test parameters. 276*b1cdbd2cSJim Jagielski * @return A proprty value as result of the test. 277*b1cdbd2cSJim Jagielski * @throws BasicException The method could not be executed. 278*b1cdbd2cSJim Jagielski */ perform(String fName, Object params)279*b1cdbd2cSJim Jagielski public synchronized PropertyValue perform(String fName, Object params) 280*b1cdbd2cSJim Jagielski throws BasicException { 281*b1cdbd2cSJim Jagielski try { 282*b1cdbd2cSJim Jagielski container.callBasicFunction(fName, params); 283*b1cdbd2cSJim Jagielski 284*b1cdbd2cSJim Jagielski do { 285*b1cdbd2cSJim Jagielski respFlag = false; 286*b1cdbd2cSJim Jagielski // waiting for basic response for iBasicTimeout milliseconds. 287*b1cdbd2cSJim Jagielski wait(iBasicTimeout); 288*b1cdbd2cSJim Jagielski } while(respFlag && !container.hasByName("BASIC_Done")); 289*b1cdbd2cSJim Jagielski 290*b1cdbd2cSJim Jagielski } catch (InterruptedException e) { 291*b1cdbd2cSJim Jagielski System.out.println("The operation " + fName + " was interrupted."); 292*b1cdbd2cSJim Jagielski } catch (com.sun.star.lang.DisposedException de) { 293*b1cdbd2cSJim Jagielski System.out.println("## Office is disposed"); 294*b1cdbd2cSJim Jagielski } 295*b1cdbd2cSJim Jagielski 296*b1cdbd2cSJim Jagielski if (!container.hasByName("BASIC_Done")) { 297*b1cdbd2cSJim Jagielski System.out.println("Operation timed out."); 298*b1cdbd2cSJim Jagielski throw new BasicException( 299*b1cdbd2cSJim Jagielski "Operation timed out."); 300*b1cdbd2cSJim Jagielski } 301*b1cdbd2cSJim Jagielski 302*b1cdbd2cSJim Jagielski Object res = container.getByName("BASIC_Done") ; 303*b1cdbd2cSJim Jagielski container.removeByName("BASIC_Done"); 304*b1cdbd2cSJim Jagielski 305*b1cdbd2cSJim Jagielski if (!(res instanceof PropertyValue)) { 306*b1cdbd2cSJim Jagielski if (res == null) { 307*b1cdbd2cSJim Jagielski System.out.println( 308*b1cdbd2cSJim Jagielski "BasicBridge returns null"); 309*b1cdbd2cSJim Jagielski throw new BasicException( 310*b1cdbd2cSJim Jagielski "BasicBridge returns null"); 311*b1cdbd2cSJim Jagielski } else { 312*b1cdbd2cSJim Jagielski System.out.println( 313*b1cdbd2cSJim Jagielski "BasicBridge returns wrong type: " + res.getClass()); 314*b1cdbd2cSJim Jagielski throw new BasicException( 315*b1cdbd2cSJim Jagielski "BasicBridge returns wrong type: " + res.getClass()); 316*b1cdbd2cSJim Jagielski } 317*b1cdbd2cSJim Jagielski } 318*b1cdbd2cSJim Jagielski 319*b1cdbd2cSJim Jagielski PropertyValue result = (PropertyValue) res ; 320*b1cdbd2cSJim Jagielski 321*b1cdbd2cSJim Jagielski if ((result.Value instanceof String) && (((String)result.Value)).startsWith("Exception")) { 322*b1cdbd2cSJim Jagielski throw new BasicException((String)result.Value); 323*b1cdbd2cSJim Jagielski } 324*b1cdbd2cSJim Jagielski 325*b1cdbd2cSJim Jagielski return result; 326*b1cdbd2cSJim Jagielski } 327*b1cdbd2cSJim Jagielski 328*b1cdbd2cSJim Jagielski /** 329*b1cdbd2cSJim Jagielski * Returns true, if name is a supported service of this class. 330*b1cdbd2cSJim Jagielski * @param name The service name. 331*b1cdbd2cSJim Jagielski * @return True, if the service is supported. 332*b1cdbd2cSJim Jagielski */ supportsService(String name)333*b1cdbd2cSJim Jagielski public boolean supportsService(String name) { 334*b1cdbd2cSJim Jagielski return serviceName.equals(name); 335*b1cdbd2cSJim Jagielski } 336*b1cdbd2cSJim Jagielski 337*b1cdbd2cSJim Jagielski /** 338*b1cdbd2cSJim Jagielski * Return all supported service names. 339*b1cdbd2cSJim Jagielski * @return All supported services. 340*b1cdbd2cSJim Jagielski */ getSupportedServiceNames()341*b1cdbd2cSJim Jagielski public String[] getSupportedServiceNames() { 342*b1cdbd2cSJim Jagielski return new String[] {serviceName}; 343*b1cdbd2cSJim Jagielski } 344*b1cdbd2cSJim Jagielski 345*b1cdbd2cSJim Jagielski /** 346*b1cdbd2cSJim Jagielski * Get the implementation name. 347*b1cdbd2cSJim Jagielski * @return Implementation name. 348*b1cdbd2cSJim Jagielski */ getImplementationName()349*b1cdbd2cSJim Jagielski public String getImplementationName() { 350*b1cdbd2cSJim Jagielski return getClass().getName(); 351*b1cdbd2cSJim Jagielski } 352*b1cdbd2cSJim Jagielski 353*b1cdbd2cSJim Jagielski /** 354*b1cdbd2cSJim Jagielski * Create an instance of HandlerContainer. 355*b1cdbd2cSJim Jagielski * Arguments are not supported here, so they will be ignored. 356*b1cdbd2cSJim Jagielski * @param args The arguments. 357*b1cdbd2cSJim Jagielski * @return The instance. 358*b1cdbd2cSJim Jagielski */ createInstanceWithArguments(Object[] args)359*b1cdbd2cSJim Jagielski public Object createInstanceWithArguments(Object[] args) { 360*b1cdbd2cSJim Jagielski return container; 361*b1cdbd2cSJim Jagielski } 362*b1cdbd2cSJim Jagielski 363*b1cdbd2cSJim Jagielski /** 364*b1cdbd2cSJim Jagielski * Create an instance of HandlerContainer. 365*b1cdbd2cSJim Jagielski * @return The instance. 366*b1cdbd2cSJim Jagielski */ createInstance()367*b1cdbd2cSJim Jagielski public Object createInstance() { 368*b1cdbd2cSJim Jagielski return createInstanceWithArguments(null); 369*b1cdbd2cSJim Jagielski } 370*b1cdbd2cSJim Jagielski 371*b1cdbd2cSJim Jagielski /** 372*b1cdbd2cSJim Jagielski * Dispose the BASIC document. 373*b1cdbd2cSJim Jagielski */ dispose()374*b1cdbd2cSJim Jagielski public synchronized void dispose() { 375*b1cdbd2cSJim Jagielski try { 376*b1cdbd2cSJim Jagielski if (oHandlerDoc != null) { 377*b1cdbd2cSJim Jagielski //oHandlerDoc.dispose(); 378*b1cdbd2cSJim Jagielski util.DesktopTools.closeDoc(oHandlerDoc); 379*b1cdbd2cSJim Jagielski wait(1000); 380*b1cdbd2cSJim Jagielski } 381*b1cdbd2cSJim Jagielski } catch (Exception e) { 382*b1cdbd2cSJim Jagielski System.out.println("Exception: " + e.toString()); 383*b1cdbd2cSJim Jagielski } 384*b1cdbd2cSJim Jagielski } 385*b1cdbd2cSJim Jagielski } 386*b1cdbd2cSJim Jagielski 387*b1cdbd2cSJim Jagielski 388*b1cdbd2cSJim Jagielski /** 389*b1cdbd2cSJim Jagielski * This class handles the communication between Java and BASIC. 390*b1cdbd2cSJim Jagielski * @see com.sun.star.container.XContainer 391*b1cdbd2cSJim Jagielski * @see com.sun.star.container.XNameContainer 392*b1cdbd2cSJim Jagielski * @see com.sun.star.lang.XTypeProvider 393*b1cdbd2cSJim Jagielski */ 394*b1cdbd2cSJim Jagielski class HandlerContainer implements XContainer, XNameContainer, XTypeProvider{ 395*b1cdbd2cSJim Jagielski 396*b1cdbd2cSJim Jagielski /** Container for parameters. 397*b1cdbd2cSJim Jagielski **/ 398*b1cdbd2cSJim Jagielski Hashtable container = new Hashtable(20); 399*b1cdbd2cSJim Jagielski /** 400*b1cdbd2cSJim Jagielski * An array of listeners for container events. 401*b1cdbd2cSJim Jagielski * @see com.sun.star.container.XContainerListener 402*b1cdbd2cSJim Jagielski */ 403*b1cdbd2cSJim Jagielski static XContainerListener[] listener = null; 404*b1cdbd2cSJim Jagielski 405*b1cdbd2cSJim Jagielski /** The BasicHandler belonging to this handler. **/ 406*b1cdbd2cSJim Jagielski BasicHandler parent = null; 407*b1cdbd2cSJim Jagielski 408*b1cdbd2cSJim Jagielski /** 409*b1cdbd2cSJim Jagielski * Constructor with the parent BasicHandler. 410*b1cdbd2cSJim Jagielski * @param par The BasicHandler. 411*b1cdbd2cSJim Jagielski */ HandlerContainer(BasicHandler par)412*b1cdbd2cSJim Jagielski public HandlerContainer(BasicHandler par) { 413*b1cdbd2cSJim Jagielski parent = par; 414*b1cdbd2cSJim Jagielski } 415*b1cdbd2cSJim Jagielski 416*b1cdbd2cSJim Jagielski /** 417*b1cdbd2cSJim Jagielski * Call a BASIC function, meaning a test method. 418*b1cdbd2cSJim Jagielski * @param fName The method name. 419*b1cdbd2cSJim Jagielski * @param args Arguments for the method. 420*b1cdbd2cSJim Jagielski */ callBasicFunction(String fName, Object args)421*b1cdbd2cSJim Jagielski public void callBasicFunction(String fName, Object args) { 422*b1cdbd2cSJim Jagielski // BASIC's listener should be called ONLY in this case. 423*b1cdbd2cSJim Jagielski if (container.containsKey(fName)) { 424*b1cdbd2cSJim Jagielski container.remove(fName); 425*b1cdbd2cSJim Jagielski } 426*b1cdbd2cSJim Jagielski container.put(fName, args); 427*b1cdbd2cSJim Jagielski if (listener != null) { 428*b1cdbd2cSJim Jagielski ContainerEvent event = new ContainerEvent(); 429*b1cdbd2cSJim Jagielski event.Element = fName; 430*b1cdbd2cSJim Jagielski for (int i=0; i<listener.length; i++){ 431*b1cdbd2cSJim Jagielski if (listener[i] != null) { 432*b1cdbd2cSJim Jagielski listener[i].elementInserted(event); 433*b1cdbd2cSJim Jagielski } 434*b1cdbd2cSJim Jagielski } 435*b1cdbd2cSJim Jagielski } 436*b1cdbd2cSJim Jagielski } 437*b1cdbd2cSJim Jagielski 438*b1cdbd2cSJim Jagielski /** 439*b1cdbd2cSJim Jagielski * Insert an object into the container. 440*b1cdbd2cSJim Jagielski * @param name The key for the object. 441*b1cdbd2cSJim Jagielski * @param object The object to insert. 442*b1cdbd2cSJim Jagielski * @throws IllegalArgumentException Throws this exception when trying to insert null. 443*b1cdbd2cSJim Jagielski */ insertByName(String name, Object object)444*b1cdbd2cSJim Jagielski public void insertByName(String name, Object object) throws com.sun.star.lang.IllegalArgumentException, com.sun.star.container.ElementExistException, com.sun.star.lang.WrappedTargetException { 445*b1cdbd2cSJim Jagielski 446*b1cdbd2cSJim Jagielski // BASIC and Java can insert into the container. 447*b1cdbd2cSJim Jagielski if (container.containsKey(name)) { 448*b1cdbd2cSJim Jagielski container.remove(name); 449*b1cdbd2cSJim Jagielski } 450*b1cdbd2cSJim Jagielski container.put(name, object); 451*b1cdbd2cSJim Jagielski 452*b1cdbd2cSJim Jagielski PropertyValue result = null ; 453*b1cdbd2cSJim Jagielski 454*b1cdbd2cSJim Jagielski if (object instanceof PropertyValue) { 455*b1cdbd2cSJim Jagielski result = (PropertyValue)object; 456*b1cdbd2cSJim Jagielski if (name.equals("BASIC_Done")) { 457*b1cdbd2cSJim Jagielski synchronized (parent) { 458*b1cdbd2cSJim Jagielski parent.notify(); 459*b1cdbd2cSJim Jagielski } 460*b1cdbd2cSJim Jagielski } else if (name.equals("BASIC_MethodTested")) { 461*b1cdbd2cSJim Jagielski parent.methodTested(result.Name, 462*b1cdbd2cSJim Jagielski ((Boolean)result.Value).booleanValue()); 463*b1cdbd2cSJim Jagielski } 464*b1cdbd2cSJim Jagielski } else if (name.equals("BASIC_Log")) { 465*b1cdbd2cSJim Jagielski parent.Log(object.toString()); 466*b1cdbd2cSJim Jagielski } 467*b1cdbd2cSJim Jagielski } 468*b1cdbd2cSJim Jagielski 469*b1cdbd2cSJim Jagielski /** 470*b1cdbd2cSJim Jagielski * Remove the object with this name from the container. 471*b1cdbd2cSJim Jagielski * @param name The key. 472*b1cdbd2cSJim Jagielski */ removeByName(String name)473*b1cdbd2cSJim Jagielski public void removeByName(String name) { 474*b1cdbd2cSJim Jagielski container.remove(name) ; 475*b1cdbd2cSJim Jagielski } 476*b1cdbd2cSJim Jagielski 477*b1cdbd2cSJim Jagielski /** 478*b1cdbd2cSJim Jagielski * Unsupported method. 479*b1cdbd2cSJim Jagielski * @param name The name of the key. 480*b1cdbd2cSJim Jagielski * @param value The value. 481*b1cdbd2cSJim Jagielski * @throws WrappedTargetException Throws this exception when called falsely. 482*b1cdbd2cSJim Jagielski */ replaceByName(String name, Object value)483*b1cdbd2cSJim Jagielski public void replaceByName(String name, Object value) 484*b1cdbd2cSJim Jagielski throws WrappedTargetException { 485*b1cdbd2cSJim Jagielski throw new WrappedTargetException("Unsupported"); 486*b1cdbd2cSJim Jagielski } 487*b1cdbd2cSJim Jagielski 488*b1cdbd2cSJim Jagielski /** 489*b1cdbd2cSJim Jagielski * Has a value for this key. 490*b1cdbd2cSJim Jagielski * @param name The name of a key. 491*b1cdbd2cSJim Jagielski * @return True, if name exists as key in the container. 492*b1cdbd2cSJim Jagielski */ hasByName(String name)493*b1cdbd2cSJim Jagielski public boolean hasByName(String name) { 494*b1cdbd2cSJim Jagielski return container.containsKey(name); 495*b1cdbd2cSJim Jagielski } 496*b1cdbd2cSJim Jagielski 497*b1cdbd2cSJim Jagielski /** 498*b1cdbd2cSJim Jagielski * Get an object by its key. 499*b1cdbd2cSJim Jagielski * @param name The name of the key. 500*b1cdbd2cSJim Jagielski * @return The object of this key. 501*b1cdbd2cSJim Jagielski */ getByName(String name)502*b1cdbd2cSJim Jagielski public Object getByName(String name) { 503*b1cdbd2cSJim Jagielski return container.get(name); 504*b1cdbd2cSJim Jagielski } 505*b1cdbd2cSJim Jagielski 506*b1cdbd2cSJim Jagielski /** 507*b1cdbd2cSJim Jagielski * Get all key names. 508*b1cdbd2cSJim Jagielski * @return All names of keys. 509*b1cdbd2cSJim Jagielski */ getElementNames()510*b1cdbd2cSJim Jagielski public String[] getElementNames() { 511*b1cdbd2cSJim Jagielski String[] res = new String[container.size()]; 512*b1cdbd2cSJim Jagielski return (String[])container.keySet().toArray(res); 513*b1cdbd2cSJim Jagielski } 514*b1cdbd2cSJim Jagielski 515*b1cdbd2cSJim Jagielski /** 516*b1cdbd2cSJim Jagielski * Is the xcontainer empty? 517*b1cdbd2cSJim Jagielski * @return True, if the container has elements. 518*b1cdbd2cSJim Jagielski */ hasElements()519*b1cdbd2cSJim Jagielski public boolean hasElements() { 520*b1cdbd2cSJim Jagielski return !container.isEmpty(); 521*b1cdbd2cSJim Jagielski } 522*b1cdbd2cSJim Jagielski 523*b1cdbd2cSJim Jagielski /** 524*b1cdbd2cSJim Jagielski * Get the type of this class. 525*b1cdbd2cSJim Jagielski * @return The type of this class. 526*b1cdbd2cSJim Jagielski */ getElementType()527*b1cdbd2cSJim Jagielski public Type getElementType() { 528*b1cdbd2cSJim Jagielski try { 529*b1cdbd2cSJim Jagielski return new Type(String.class); 530*b1cdbd2cSJim Jagielski } catch (Exception e) { 531*b1cdbd2cSJim Jagielski return null; 532*b1cdbd2cSJim Jagielski } 533*b1cdbd2cSJim Jagielski } 534*b1cdbd2cSJim Jagielski 535*b1cdbd2cSJim Jagielski /** 536*b1cdbd2cSJim Jagielski * Get the implementation id of this class. 537*b1cdbd2cSJim Jagielski * @return A unique id for this class 538*b1cdbd2cSJim Jagielski * @see com.sun.star.lang.XTypeProvider 539*b1cdbd2cSJim Jagielski */ getImplementationId()540*b1cdbd2cSJim Jagielski public byte[] getImplementationId() { 541*b1cdbd2cSJim Jagielski return toString().getBytes(); 542*b1cdbd2cSJim Jagielski } 543*b1cdbd2cSJim Jagielski 544*b1cdbd2cSJim Jagielski /** 545*b1cdbd2cSJim Jagielski * Get all types of this class. 546*b1cdbd2cSJim Jagielski * @return All implemented UNO types. 547*b1cdbd2cSJim Jagielski */ getTypes()548*b1cdbd2cSJim Jagielski public Type[] getTypes() { 549*b1cdbd2cSJim Jagielski Class interfaces[] = getClass().getInterfaces(); 550*b1cdbd2cSJim Jagielski Type types[] = new Type[interfaces.length]; 551*b1cdbd2cSJim Jagielski for(int i = 0; i < interfaces.length; ++ i) { 552*b1cdbd2cSJim Jagielski types[i] = new Type(interfaces[i]); 553*b1cdbd2cSJim Jagielski } 554*b1cdbd2cSJim Jagielski return types; 555*b1cdbd2cSJim Jagielski } 556*b1cdbd2cSJim Jagielski 557*b1cdbd2cSJim Jagielski /** 558*b1cdbd2cSJim Jagielski * Add a listener 559*b1cdbd2cSJim Jagielski * @param xListener The listener. 560*b1cdbd2cSJim Jagielski */ addContainerListener(XContainerListener xListener)561*b1cdbd2cSJim Jagielski public void addContainerListener(XContainerListener xListener){ 562*b1cdbd2cSJim Jagielski int length = 0; 563*b1cdbd2cSJim Jagielski if (listener != null) 564*b1cdbd2cSJim Jagielski length = listener.length; 565*b1cdbd2cSJim Jagielski 566*b1cdbd2cSJim Jagielski XContainerListener[] mListener = 567*b1cdbd2cSJim Jagielski new XContainerListener[length+1]; 568*b1cdbd2cSJim Jagielski for (int i=0; i<length-1; i++) { 569*b1cdbd2cSJim Jagielski mListener[i] = listener[i]; 570*b1cdbd2cSJim Jagielski // listener already added 571*b1cdbd2cSJim Jagielski if (((Object)xListener).equals(listener[i])) 572*b1cdbd2cSJim Jagielski return; 573*b1cdbd2cSJim Jagielski } 574*b1cdbd2cSJim Jagielski mListener[length] = xListener; 575*b1cdbd2cSJim Jagielski listener = mListener; 576*b1cdbd2cSJim Jagielski } 577*b1cdbd2cSJim Jagielski 578*b1cdbd2cSJim Jagielski /** 579*b1cdbd2cSJim Jagielski * Remove a listener 580*b1cdbd2cSJim Jagielski * @param xListener The listener. 581*b1cdbd2cSJim Jagielski */ removeContainerListener(XContainerListener xListener)582*b1cdbd2cSJim Jagielski public void removeContainerListener(XContainerListener xListener){ 583*b1cdbd2cSJim Jagielski if (listener != null && listener.length != 0) { 584*b1cdbd2cSJim Jagielski int length = listener.length; 585*b1cdbd2cSJim Jagielski XContainerListener[] mListener = 586*b1cdbd2cSJim Jagielski new XContainerListener[length-1]; 587*b1cdbd2cSJim Jagielski boolean found = false; 588*b1cdbd2cSJim Jagielski int j=0; 589*b1cdbd2cSJim Jagielski for (int i=0; i<length-1; i++) { 590*b1cdbd2cSJim Jagielski if (!((Object)xListener).equals(listener[j])) { 591*b1cdbd2cSJim Jagielski mListener[i] = listener[j]; 592*b1cdbd2cSJim Jagielski } 593*b1cdbd2cSJim Jagielski else { 594*b1cdbd2cSJim Jagielski j++; 595*b1cdbd2cSJim Jagielski found = true; 596*b1cdbd2cSJim Jagielski } 597*b1cdbd2cSJim Jagielski j++; 598*b1cdbd2cSJim Jagielski } 599*b1cdbd2cSJim Jagielski if (!found) { 600*b1cdbd2cSJim Jagielski if (((Object)xListener).equals(listener[length-1])) 601*b1cdbd2cSJim Jagielski listener = mListener; 602*b1cdbd2cSJim Jagielski } 603*b1cdbd2cSJim Jagielski else 604*b1cdbd2cSJim Jagielski listener = mListener; 605*b1cdbd2cSJim Jagielski 606*b1cdbd2cSJim Jagielski } 607*b1cdbd2cSJim Jagielski } 608*b1cdbd2cSJim Jagielski } 609