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