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