1*76b6b121SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*76b6b121SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*76b6b121SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*76b6b121SAndrew Rist * distributed with this work for additional information 6*76b6b121SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*76b6b121SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*76b6b121SAndrew Rist * "License"); you may not use this file except in compliance 9*76b6b121SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 11*76b6b121SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 13*76b6b121SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*76b6b121SAndrew Rist * software distributed under the License is distributed on an 15*76b6b121SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*76b6b121SAndrew Rist * KIND, either express or implied. See the License for the 17*76b6b121SAndrew Rist * specific language governing permissions and limitations 18*76b6b121SAndrew Rist * under the License. 19cdf0e10cSrcweir * 20*76b6b121SAndrew Rist *************************************************************/ 21*76b6b121SAndrew Rist 22*76b6b121SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir package complex.framework.recovery; 25cdf0e10cSrcweir 26cdf0e10cSrcweir import com.sun.star.awt.XDialog; 27cdf0e10cSrcweir import com.sun.star.awt.XExtendedToolkit; 28cdf0e10cSrcweir import com.sun.star.awt.XWindow; 29cdf0e10cSrcweir import com.sun.star.beans.NamedValue; 30cdf0e10cSrcweir import com.sun.star.frame.XController; 31cdf0e10cSrcweir import com.sun.star.frame.XDesktop; 32cdf0e10cSrcweir import com.sun.star.frame.XDispatch; 33cdf0e10cSrcweir import com.sun.star.frame.XDispatchProvider; 34cdf0e10cSrcweir import com.sun.star.frame.XModel; 35cdf0e10cSrcweir import com.sun.star.lang.XComponent; 36cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory; 37cdf0e10cSrcweir import com.sun.star.ucb.XSimpleFileAccess; 38cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 39cdf0e10cSrcweir import com.sun.star.uno.XInterface; 40cdf0e10cSrcweir import com.sun.star.util.URL; 41cdf0e10cSrcweir import com.sun.star.util.XURLTransformer; 42cdf0e10cSrcweir import helper.FileTools; 43cdf0e10cSrcweir import helper.OfficeProvider; 44cdf0e10cSrcweir import helper.UnoProvider; 45cdf0e10cSrcweir import java.io.File; 46cdf0e10cSrcweir import java.io.PrintWriter; 47cdf0e10cSrcweir import java.util.HashMap; 48cdf0e10cSrcweir import lib.TestParameters; 49cdf0e10cSrcweir import share.LogWriter; 50cdf0e10cSrcweir import util.PropertyName; 51cdf0e10cSrcweir import util.UITools; 52cdf0e10cSrcweir import util.utils; 53cdf0e10cSrcweir 54cdf0e10cSrcweir /** 55cdf0e10cSrcweir * this class supports the <CODE>RecoverTest</CODE>. You will find here some helper 56cdf0e10cSrcweir * functions. 57cdf0e10cSrcweir */ 58cdf0e10cSrcweir public class RecoveryTools { 59cdf0e10cSrcweir 60cdf0e10cSrcweir private final TestParameters param; 61cdf0e10cSrcweir private final LogWriter log; 62cdf0e10cSrcweir 63cdf0e10cSrcweir /** 64cdf0e10cSrcweir * Creates new OfficeWatcher 65cdf0e10cSrcweir * @param param the test parameter 66cdf0e10cSrcweir * @param log a log writer 67cdf0e10cSrcweir */ RecoveryTools(TestParameters param, LogWriter log)68cdf0e10cSrcweir public RecoveryTools(TestParameters param, LogWriter log) { 69cdf0e10cSrcweir this.param = param; 70cdf0e10cSrcweir this.log = log; 71cdf0e10cSrcweir 72cdf0e10cSrcweir } 73cdf0e10cSrcweir 74cdf0e10cSrcweir /** 75cdf0e10cSrcweir * get the active dialog from the top of the desktop 76cdf0e10cSrcweir * @param xToolKit xToolKit the <CODE> XExtendedToolkit</CODE> to get the dialog from the top of the desktop. 77cdf0e10cSrcweir * @return a <CODE>XDialog</CODE> interface of the dialog 78cdf0e10cSrcweir */ getActiveDialog( XMultiServiceFactory xMSF)79cdf0e10cSrcweir public XDialog getActiveDialog( XMultiServiceFactory xMSF){ 80cdf0e10cSrcweir XWindow xWin = getActiveWindow(xMSF); 81cdf0e10cSrcweir return (XDialog) UnoRuntime.queryInterface(XDialog.class, xWin); 82cdf0e10cSrcweir } 83cdf0e10cSrcweir getActiveWindow( XMultiServiceFactory xMSF)84cdf0e10cSrcweir public XWindow getActiveWindow( XMultiServiceFactory xMSF){ 85cdf0e10cSrcweir XInterface xToolKit = null; 86cdf0e10cSrcweir try { 87cdf0e10cSrcweir xToolKit = (XInterface) xMSF.createInstance("com.sun.star.awt.Toolkit") ; 88cdf0e10cSrcweir } catch (com.sun.star.uno.Exception e) { 89cdf0e10cSrcweir return null; 90cdf0e10cSrcweir } 91cdf0e10cSrcweir 92cdf0e10cSrcweir XExtendedToolkit tk = (XExtendedToolkit) 93cdf0e10cSrcweir UnoRuntime.queryInterface(XExtendedToolkit.class, xToolKit); 94cdf0e10cSrcweir Object atw = tk.getActiveTopWindow(); 95cdf0e10cSrcweir return (XWindow) UnoRuntime.queryInterface(XWindow.class, atw); 96cdf0e10cSrcweir } 97cdf0e10cSrcweir 98cdf0e10cSrcweir /** 99cdf0e10cSrcweir * After a crash the office start with a recovery diaolg. It could be that the office 100cdf0e10cSrcweir * is connectable but not all services to get the dialog a loaded. This function 101cdf0e10cSrcweir * tries to get the dialog until the <CODE>OfficeWatcher</CODE> kills the office. 102cdf0e10cSrcweir * @param xToolKit the <CODE> XExtendedToolkit</CODE> to get the dialog from the top of the desktop. 103cdf0e10cSrcweir * @return a <CODE>XDialog</CODE> interface of the dialog 104cdf0e10cSrcweir */ getActiveDialogAfterStartup(XMultiServiceFactory xMSF)105cdf0e10cSrcweir public XDialog getActiveDialogAfterStartup(XMultiServiceFactory xMSF){ 106cdf0e10cSrcweir // while the office starts it takes some time to get the dialog. 107cdf0e10cSrcweir 108cdf0e10cSrcweir // the dialog is accessible AFTER the office has recoverd all documents. 109cdf0e10cSrcweir // This could consumes more time then the TimeOut allow. 110cdf0e10cSrcweir int counter = 0; 111cdf0e10cSrcweir int multi = 5; 112cdf0e10cSrcweir int pause = param.getInt(PropertyName.SHORT_WAIT)*10; 113cdf0e10cSrcweir int timeOut = param.getInt(PropertyName.THREAD_TIME_OUT)*5; 114cdf0e10cSrcweir int maximum = (timeOut / pause) * multi; 115cdf0e10cSrcweir 116cdf0e10cSrcweir XDialog oDialog = getActiveDialog(xMSF); 117cdf0e10cSrcweir 118cdf0e10cSrcweir while (oDialog == null && (counter < maximum)){ 119cdf0e10cSrcweir log.println("waiting until the office has recoverd... remaining " + (timeOut * multi - pause * counter)/1000 + " seconds"); 120cdf0e10cSrcweir pause(pause); 121cdf0e10cSrcweir oDialog = getActiveDialog(xMSF); 122cdf0e10cSrcweir counter ++; 123cdf0e10cSrcweir } 124cdf0e10cSrcweir return oDialog; 125cdf0e10cSrcweir } 126cdf0e10cSrcweir 127cdf0e10cSrcweir /** 128cdf0e10cSrcweir * halt the thread for some time 129cdf0e10cSrcweir */ pause()130cdf0e10cSrcweir public void pause(){ 131cdf0e10cSrcweir pause(param.getInt(PropertyName.SHORT_WAIT)); 132cdf0e10cSrcweir } 133cdf0e10cSrcweir 134cdf0e10cSrcweir /** 135cdf0e10cSrcweir * halt the thread for some time 136cdf0e10cSrcweir */ pause(int sleepTime)137cdf0e10cSrcweir public void pause(int sleepTime){ 138cdf0e10cSrcweir sleep(sleepTime); 139cdf0e10cSrcweir } 140cdf0e10cSrcweir sleep(long millis)141cdf0e10cSrcweir private void sleep(long millis){ 142cdf0e10cSrcweir try{ 143cdf0e10cSrcweir Thread.sleep(millis); 144cdf0e10cSrcweir }catch (java.lang.InterruptedException e){} 145cdf0e10cSrcweir } 146cdf0e10cSrcweir 147cdf0e10cSrcweir /** 148cdf0e10cSrcweir * remove the content of the user backup folder and removes the Recovery.xcu. This 149cdf0e10cSrcweir * was done from the Office via XSimpleFileAccess 150cdf0e10cSrcweir * @throws com.sun.star.io.IOException the exception was thrown if something goes wrong. 151cdf0e10cSrcweir */ cleanRecoveryData()152cdf0e10cSrcweir public void cleanRecoveryData() 153cdf0e10cSrcweir throws com.sun.star.io.IOException 154cdf0e10cSrcweir { 155cdf0e10cSrcweir try{ 156cdf0e10cSrcweir HashMap recFiles = getRecoveryFiles(); 157cdf0e10cSrcweir 158cdf0e10cSrcweir String recoveryFolder = (String) recFiles.get("recoveryFolder"); 159cdf0e10cSrcweir String recoveryXCU = (String) recFiles.get("recoveryXCU"); 160cdf0e10cSrcweir 161cdf0e10cSrcweir log.println("try to remove content of '" + recoveryFolder + "'"); 162cdf0e10cSrcweir 163cdf0e10cSrcweir File rf = new File(recoveryFolder); 164cdf0e10cSrcweir 165cdf0e10cSrcweir boolean success = FileTools.cleanDir(rf); 166cdf0e10cSrcweir log.println("removed " + recoveryFolder + ": " + success); 167cdf0e10cSrcweir 168cdf0e10cSrcweir log.println("try to remove '" + recoveryXCU + "'"); 169cdf0e10cSrcweir 170cdf0e10cSrcweir File xcu = new File(recoveryXCU); 171cdf0e10cSrcweir if (xcu.isFile()){ 172cdf0e10cSrcweir success = xcu.delete(); 173cdf0e10cSrcweir log.println("removed " + recoveryXCU + " : " + success); 174cdf0e10cSrcweir } 175cdf0e10cSrcweir 176cdf0e10cSrcweir } catch (Exception e){ 177cdf0e10cSrcweir throw new com.sun.star.io.IOException("could not remove old recovery data: " + e.toString()); 178cdf0e10cSrcweir } 179cdf0e10cSrcweir } 180cdf0e10cSrcweir getRecoveryFiles()181cdf0e10cSrcweir public HashMap getRecoveryFiles() 182cdf0e10cSrcweir throws com.sun.star.io.IOException 183cdf0e10cSrcweir { 184cdf0e10cSrcweir try{ 185cdf0e10cSrcweir log.println("try to get UnoProvider..."); 186cdf0e10cSrcweir UnoProvider unoProv = new UnoProvider(); 187cdf0e10cSrcweir XMultiServiceFactory xMSF = (XMultiServiceFactory) unoProv.getManager(param); 188cdf0e10cSrcweir 189cdf0e10cSrcweir String userPath = utils.expandMacro(xMSF, "${$ORIGIN/bootstraprc:UserInstallation}"); 190cdf0e10cSrcweir System.out.println("userPath:'" + userPath + "'"); 191cdf0e10cSrcweir 192cdf0e10cSrcweir if (userPath.equals(""))userPath = utils.expandMacro(xMSF, "${$ORIGIN/bootstrap.ini:UserInstallation}"); 193cdf0e10cSrcweir System.out.println("userPath:'" + userPath + "'"); 194cdf0e10cSrcweir 195cdf0e10cSrcweir if (userPath.equals("")) throw new com.sun.star.io.IOException("could not get user path at bootstraping"); 196cdf0e10cSrcweir 197cdf0e10cSrcweir String recoveryFolder = utils.getSystemURL(userPath + "/user/backup"); 198cdf0e10cSrcweir 199cdf0e10cSrcweir String recoveryXCU = utils.getSystemURL(userPath + "/user/registry/data/org/openoffice/Office/Recovery.xcu"); 200cdf0e10cSrcweir 201cdf0e10cSrcweir HashMap recFiles = new HashMap(); 202cdf0e10cSrcweir 203cdf0e10cSrcweir recFiles.put("recoveryFolder", recoveryFolder); 204cdf0e10cSrcweir recFiles.put("recoveryXCU", recoveryXCU); 205cdf0e10cSrcweir return recFiles; 206cdf0e10cSrcweir 207cdf0e10cSrcweir } catch (Exception e){ 208cdf0e10cSrcweir throw new com.sun.star.io.IOException("could not get recovery folder: " + e.toString()); 209cdf0e10cSrcweir } 210cdf0e10cSrcweir 211cdf0e10cSrcweir } 212cdf0e10cSrcweir /** 213cdf0e10cSrcweir * This function close the office while calling terminate on the desktop. If 214cdf0e10cSrcweir * this failed, the <CODE>ProcessHandler</CODE> kills the process. 215cdf0e10cSrcweir * @param xMSF the <CODE>XMultiServiceFactory</CODE> 216cdf0e10cSrcweir * @return <CODE>TRUE</CODE> if no exception was thrown, otherwise <CODE>FALSE</CODE> 217cdf0e10cSrcweir */ closeOffice(XMultiServiceFactory xMSF)218cdf0e10cSrcweir public boolean closeOffice(XMultiServiceFactory xMSF) { 219cdf0e10cSrcweir try { 220cdf0e10cSrcweir XDesktop desk = (XDesktop) UnoRuntime.queryInterface( 221cdf0e10cSrcweir XDesktop.class, xMSF.createInstance( 222cdf0e10cSrcweir "com.sun.star.frame.Desktop")); 223cdf0e10cSrcweir xMSF = null; 224cdf0e10cSrcweir 225cdf0e10cSrcweir desk.terminate(); 226cdf0e10cSrcweir log.println("Waiting until ProcessHandler loose the office..."); 227cdf0e10cSrcweir 228cdf0e10cSrcweir } 229cdf0e10cSrcweir catch (java.lang.Exception e) { 230cdf0e10cSrcweir e.printStackTrace(); 231cdf0e10cSrcweir return false; 232cdf0e10cSrcweir } 233cdf0e10cSrcweir waitForClosedOffice(); 234cdf0e10cSrcweir return true; 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir /** 238cdf0e10cSrcweir * This function waits until the office is closed. If the closing time reach 239cdf0e10cSrcweir * the value of parameter <CODE>THREAD_TIME_OUT</CODE> the office was killed. 240cdf0e10cSrcweir */ waitForClosedOffice()241cdf0e10cSrcweir public void waitForClosedOffice(){ 242cdf0e10cSrcweir // check for the office process 243cdf0e10cSrcweir helper.ProcessHandler ph = (helper.ProcessHandler) param.get("AppProvider"); 244cdf0e10cSrcweir 245cdf0e10cSrcweir int timeOut = param.getInt(PropertyName.THREAD_TIME_OUT)*5; 246cdf0e10cSrcweir int pause = param.getInt(PropertyName.SHORT_WAIT)*20; 247cdf0e10cSrcweir int multi = 0; 248cdf0e10cSrcweir while ((ph != null) && (ph.getExitCode()<0) && (pause*multi < timeOut)) { 249cdf0e10cSrcweir log.println("waiting until the office is closed... remaining " + (timeOut - pause * multi)/1000 + " seconds"); 250cdf0e10cSrcweir pause(pause); 251cdf0e10cSrcweir multi ++; 252cdf0e10cSrcweir } 253cdf0e10cSrcweir 254cdf0e10cSrcweir // be shure that office is closed 255cdf0e10cSrcweir if (ph != null) ph.kill(); 256cdf0e10cSrcweir } 257cdf0e10cSrcweir killOffice()258cdf0e10cSrcweir public void killOffice(){ 259cdf0e10cSrcweir helper.ProcessHandler ph = (helper.ProcessHandler) param.get("AppProvider"); 260cdf0e10cSrcweir ph.kill(); 261cdf0e10cSrcweir } 262cdf0e10cSrcweir 263cdf0e10cSrcweir /** 264cdf0e10cSrcweir * The office must be started WITH restore and crashreporter functionality. 265cdf0e10cSrcweir * Therefore the parmater '<CODE>-norestore</CODE>' and '<CODE>-nocrashreport</CODE>' 266cdf0e10cSrcweir * was removed from the <CODE>AppExecutionCommand</CODE> parameter 267cdf0e10cSrcweir */ removeParametersFromAppExecutionCommand()268cdf0e10cSrcweir public void removeParametersFromAppExecutionCommand(){ 269cdf0e10cSrcweir 270cdf0e10cSrcweir //remove some params to start office 271cdf0e10cSrcweir String office = (String) param.get("AppExecutionCommand"); 272cdf0e10cSrcweir String[] params = {"-norestore", "-nocrashreport"}; 273cdf0e10cSrcweir 274cdf0e10cSrcweir for (int i = 0; i < params.length; i++){ 275cdf0e10cSrcweir int index = office.indexOf(params[i]); 276cdf0e10cSrcweir int length = params[i].length(); 277cdf0e10cSrcweir if (index != -1){ 278cdf0e10cSrcweir office = office.substring(0, index) + office.substring(index + length); 279cdf0e10cSrcweir log.println("removed '" + params[i] + "' from AppExecutionCommand: " + office); 280cdf0e10cSrcweir } 281cdf0e10cSrcweir } 282cdf0e10cSrcweir param.put("AppExecutionCommand", office); 283cdf0e10cSrcweir log.println("connect: " + (String) param.get("AppExecutionCommand")); 284cdf0e10cSrcweir 285cdf0e10cSrcweir } 286cdf0e10cSrcweir 287cdf0e10cSrcweir /** 288cdf0e10cSrcweir * This function uses accessibility to handle modal dialogs like the 289cdf0e10cSrcweir * "Are you sure" dialog. 290cdf0e10cSrcweir * It cklick the named button given in parameter <CODE>buttonName</CODE> 291cdf0e10cSrcweir * @param buttonName the name of the button wich should be chlicked 292cdf0e10cSrcweir */ handleModalDialog(XMultiServiceFactory xMSF, String buttonName)293cdf0e10cSrcweir public void handleModalDialog(XMultiServiceFactory xMSF, String buttonName) 294cdf0e10cSrcweir throws com.sun.star.accessibility.IllegalAccessibleComponentStateException 295cdf0e10cSrcweir { 296cdf0e10cSrcweir 297cdf0e10cSrcweir log.println("try to get modal Dialog..."); 298cdf0e10cSrcweir 299cdf0e10cSrcweir pause(); 300cdf0e10cSrcweir 301cdf0e10cSrcweir XWindow oDialog = getActiveWindow(xMSF); 302cdf0e10cSrcweir 303cdf0e10cSrcweir if (oDialog == null) throw new com.sun.star.accessibility.IllegalAccessibleComponentStateException("could not get modal Dialog"); 304cdf0e10cSrcweir 305cdf0e10cSrcweir 306cdf0e10cSrcweir UITools oUITools = new UITools(xMSF, oDialog); 307cdf0e10cSrcweir oUITools.printAccessibleTree((PrintWriter) log, param.getBool(PropertyName.DEBUG_IS_ACTIVE)); 308cdf0e10cSrcweir 309cdf0e10cSrcweir try{ 310cdf0e10cSrcweir log.println("click ' " + buttonName + "' button.."); 311cdf0e10cSrcweir oUITools.clickButton(buttonName); 312cdf0e10cSrcweir } catch ( java.lang.Exception e){ 313cdf0e10cSrcweir throw new com.sun.star.accessibility.IllegalAccessibleComponentStateException("Could not klick '"+buttonName +"' at modal dialog: " + e.toString()); 314cdf0e10cSrcweir } 315cdf0e10cSrcweir pause(); 316cdf0e10cSrcweir } 317cdf0e10cSrcweir clickThreadButton(XMultiServiceFactory xMSF, XWindow xWindow, String buttonName)318cdf0e10cSrcweir public void clickThreadButton(XMultiServiceFactory xMSF, XWindow xWindow, String buttonName) 319cdf0e10cSrcweir throws com.sun.star.accessibility.IllegalAccessibleComponentStateException 320cdf0e10cSrcweir { 321cdf0e10cSrcweir KlickButtonThread kbt = new KlickButtonThread(xMSF, xWindow, buttonName); 322cdf0e10cSrcweir kbt.start(); 323cdf0e10cSrcweir pause(param.getInt(PropertyName.SHORT_WAIT) * 10); 324cdf0e10cSrcweir } 325cdf0e10cSrcweir copyRecoveryData(boolean backup)326cdf0e10cSrcweir public void copyRecoveryData(boolean backup) 327cdf0e10cSrcweir throws com.sun.star.io.IOException, java.io.IOException 328cdf0e10cSrcweir { 329cdf0e10cSrcweir HashMap recFiles = null; 330cdf0e10cSrcweir 331cdf0e10cSrcweir try{ 332cdf0e10cSrcweir recFiles = getRecoveryFiles(); 333cdf0e10cSrcweir } catch ( com.sun.star.io.IOException e){ 334cdf0e10cSrcweir throw new com.sun.star.io.IOException("Could not get recovery files: " + e.toString()); 335cdf0e10cSrcweir } 336cdf0e10cSrcweir 337cdf0e10cSrcweir try{ 338cdf0e10cSrcweir String recoveryFolder = (String) recFiles.get("recoveryFolder"); 339cdf0e10cSrcweir String recoveryXCU = (String) recFiles.get("recoveryXCU"); 340cdf0e10cSrcweir 341cdf0e10cSrcweir File recFolder = new File(recoveryFolder); 342cdf0e10cSrcweir File recFolderBackup = new File(recoveryFolder+".recoveryTest"); 343cdf0e10cSrcweir 344cdf0e10cSrcweir File recXCU = new File(recoveryXCU); 345cdf0e10cSrcweir File recXCUBackup = new File(recoveryXCU + ".recoveryTest"); 346cdf0e10cSrcweir 347cdf0e10cSrcweir if (backup){ 348cdf0e10cSrcweir FileTools.copyDirectory(recFolder, recFolderBackup); 349cdf0e10cSrcweir FileTools.copyFile(recXCU, recXCUBackup); 350cdf0e10cSrcweir } else { 351cdf0e10cSrcweir FileTools.copyDirectory(recFolderBackup, recFolder); 352cdf0e10cSrcweir FileTools.copyFile(recXCUBackup, recXCU); 353cdf0e10cSrcweir 354cdf0e10cSrcweir } 355cdf0e10cSrcweir } catch (java.io.IOException e){ 356cdf0e10cSrcweir throw new java.io.IOException("Could not copy recovery files: " + e.toString()); 357cdf0e10cSrcweir } 358cdf0e10cSrcweir } 359cdf0e10cSrcweir 360cdf0e10cSrcweir 361cdf0e10cSrcweir } 362