office-gobmx/qadevOOo/runner/helper/OfficeProvider.java
Rüdiger Timm 5b671466a4 INTEGRATION: CWS qadev20 (1.14.4); FILE MERGED
2004/11/24 20:05:10 cn 1.14.4.2: #i37028# bugfix in debug output
2004/11/22 12:27:07 sg 1.14.4.1: #i37187#CHG: removed functions that were not jdk131 compatible
2004-12-10 16:00:11 +00:00

627 lines
No EOL
20 KiB
Java

/*************************************************************************
*
* $RCSfile: OfficeProvider.java,v $
*
* $Revision: 1.15 $
*
* last change:$Date: 2004-12-10 17:00:11 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
*
* - GNU Lesser General Public License Version 2.1
* - Sun Industry Standards Source License Version 1.1
*
* Sun Microsystems Inc., October, 2000
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2000 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
*
* This library 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 for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*
*
* Sun Industry Standards Source License Version 1.1
* =================================================
* The contents of this file are subject to the Sun Industry Standards
* Source License Version 1.1 (the "License"); You may not use this file
* except in compliance with the License. You may obtain a copy of the
* License at http://www.openoffice.org/license.html.
*
* Software provided under this License is provided on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
* WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
* MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
* See the License for the specific provisions governing your rights and
* obligations concerning the Software.
*
* The Initial Developer of the Original Code is: Sun Microsystems, Inc.
*
* Copyright: 2000 by Sun Microsystems, Inc.
*
* All Rights Reserved.
*
* Contributor(s): _______________________________________
*
*
************************************************************************/
package helper;
//import com.sun.star.bridge.UnoUrlResolver;
import com.sun.star.bridge.XUnoUrlResolver;
import com.sun.star.connection.XConnection;
import com.sun.star.connection.XConnector;
import com.sun.star.container.XEnumeration;
import com.sun.star.container.XEnumerationAccess;
import com.sun.star.frame.XDesktop;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiComponentFactory;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XComponentContext;
import com.sun.star.uno.XInterface;
import com.sun.star.uno.XNamingService;
import com.sun.star.util.XCloseable;
import com.sun.star.util.XStringSubstitution;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import lib.TestParameters;
import share.DescEntry;
import share.LogWriter;
import util.DynamicClassLoader;
import util.utils;
/**
* This class will connect the office and start it if possible
*
*/
public class OfficeProvider implements AppProvider {
protected static boolean debug = false;
/**
* Dispose the office.
* This method can only be used, if the office was connected in the first
* place: getManager() was called first.
*/
public boolean disposeManager(lib.TestParameters param) {
XMultiServiceFactory msf = (XMultiServiceFactory) param.getMSF();
if (msf == null) {
return true;
} else {
XDesktop desk = null;
try {
desk = (XDesktop) UnoRuntime.queryInterface(XDesktop.class,
msf.createInstance(
"com.sun.star.frame.Desktop"));
} catch (com.sun.star.uno.Exception ue) {
return false;
}
msf = null;
if (desk != null) {
desk.terminate();
return true;
} else {
return false;
}
}
}
/**
* Method to get the ServiceManager of an Office
*/
public Object getManager(lib.TestParameters param) {
String errorMessage = null;
boolean bAppExecutionHasWarning = false;
debug = param.getBool("DebugIsActive");
String additionalArgs = (String) param.get(
"AdditionalConnectionArguments");
if (additionalArgs == null) {
additionalArgs = ";";
} else {
additionalArgs = "," + additionalArgs + ";";
}
String cncstr = "uno:" + param.get("ConnectionString") + ";urp" +
additionalArgs + "StarOffice.ServiceManager";
if (debug) {
System.out.print("Connecting the Office with " + cncstr);
}
XMultiServiceFactory msf = connectOffice(cncstr);
if (msf == null) {
String exc = "";
Exception exConnectFailed = null;
boolean isExecutable = false;
boolean isAppKnown = ((cncstr.indexOf("host=localhost") > 0) || (cncstr.indexOf("pipe,name=")>0));
isAppKnown &= !((String) param.get("AppExecutionCommand")).equals("");
if (isAppKnown) {
if (debug) {
System.out.println(
"Local Connection trying to start the Office");
}
//ensure that a pending officewatcher gets finished before a new
//office is started
OfficeWatcher ow_old = (OfficeWatcher) param.get("Watcher");
if (ow_old != null) {
ow_old.finish = true;
}
String cmd = (String) param.get("AppExecutionCommand");
// validate the AppExecutionCommand, but try it out anyway.
// keep the error message for later.
errorMessage =
util.utils.validateAppExecutionCommand(cmd, (String)param.get("OperatingSystem"));
if (errorMessage.startsWith("Error")) {
System.out.println(errorMessage);
return null;
}
bAppExecutionHasWarning = !errorMessage.equals("OK");
DynamicClassLoader dcl = new DynamicClassLoader();
LogWriter log = (LogWriter) dcl.getInstance(
(String) param.get("LogWriter"));
//create empty entry
DescEntry Entry = new DescEntry();
Entry.entryName = "office";
Entry.longName = "office";
Entry.EntryType = "placebo";
Entry.isOptional = false;
Entry.isToTest = false;
Entry.SubEntryCount = 0;
Entry.hasErrorMsg = false;
Entry.State = "non possible";
Entry.UserDefinedParams = param;
log.initialize(Entry, debug);
ProcessHandler ph = new ProcessHandler(cmd, (PrintWriter) log);
isExecutable = ph.executeAsynchronously();
if (isExecutable) {
param.put("AppProvider", ph);
OfficeWatcher ow = new OfficeWatcher(param);
param.put("Watcher", ow);
ow.start();
ow.ping();
}
int k = 0;
while ((k < 21) && (msf == null)) {
try {
Thread.sleep(k * 1000);
msf = connect(cncstr);
} catch (com.sun.star.uno.Exception ue) {
exConnectFailed = ue;
exc = ue.getMessage();
} catch (java.lang.Exception je) {
exConnectFailed = je;
exc = je.getMessage();
}
k++;
}
if (msf == null) {
System.out.println("Exception while connecting.\n" + exConnectFailed);
if (exc != null)
System.out.println(exc);
if (bAppExecutionHasWarning)
System.out.println(errorMessage);
} else if (isExecutable) {
//copy the user layer to a safe place
try {
XStringSubstitution sts = createStringSubstitution(msf);
String userLayer = sts.getSubstituteVariableValue(
"$(user)");
userLayer = getDirSys(userLayer);
param.put("userLayer", userLayer);
//System.out.println("UserLayer: "+userLayer);
String copyLayer = System.getProperty("java.io.tmpdir") +
System.getProperty("file.separator") +
"user_backup" +
System.currentTimeMillis();
param.put("copyLayer", copyLayer);
//System.out.println("CopyLayer: "+copyLayer);
copyDirectory(new File(userLayer), new File(copyLayer));
} catch (com.sun.star.container.NoSuchElementException e) {
System.out.println("User Variable '$(user)' not defined.");
} catch (java.io.IOException e) {
System.out.println("Couldn't backup user layer");
e.printStackTrace();
}
}
} else {
System.out.println("Could not connect an Office" +
" and cannot start one.");
if (bAppExecutionHasWarning)
System.out.println(errorMessage);
}
}
return msf;
}
/**
* Connect an Office
*/
protected static XMultiServiceFactory connect(String connectStr)
throws com.sun.star.uno.Exception,
com.sun.star.uno.RuntimeException,
com.sun.star.connection.NoConnectException,
Exception {
// Get component context
XComponentContext xcomponentcontext = com.sun.star.comp.helper.Bootstrap.createInitialComponentContext(
null);
// initial serviceManager
XMultiComponentFactory xLocalServiceManager = xcomponentcontext.getServiceManager();
// create a connector, so that it can contact the office
// XUnoUrlResolver urlResolver = UnoUrlResolver.create(xcomponentcontext);
Object xUrlResolver = xLocalServiceManager.createInstanceWithContext(
"com.sun.star.bridge.UnoUrlResolver", xcomponentcontext);
XUnoUrlResolver urlResolver = (XUnoUrlResolver) UnoRuntime.queryInterface(
XUnoUrlResolver.class, xUrlResolver);
Object rInitialObject = urlResolver.resolve(connectStr);
XMultiServiceFactory xMSF = null;
if (rInitialObject != null) {
if (debug) {
System.out.println("resolved url");
}
xMSF = (XMultiServiceFactory) UnoRuntime.queryInterface(
XMultiServiceFactory.class, rInitialObject);
}
return xMSF;
}
/**
* Close an office.
* @param param The test parameters.
* @param closeIfPossible If true, close even if
* it was running before the test
*/
public boolean closeExistingOffice(lib.TestParameters param,
boolean closeIfPossible) {
debug = param.getBool("DebugIsActive");
XMultiServiceFactory msf = (XMultiServiceFactory) param.getMSF();
boolean alreadyConnected = (msf != null);
if (alreadyConnected) {
ProcessHandler ph = (ProcessHandler) param.get("AppProvider");
if (ph != null) {
disposeOffice(msf, param);
// dispose watcher in case it's still running.
//System.out.println("INFO: disposing the office and terminate the watcher process.");
OfficeWatcher ow = (OfficeWatcher) param.get("Watcher");
if ((ow != null) && ow.isAlive()) {
ow.finish = true;
}
return true;
} else {
if (closeIfPossible) {
return disposeOffice(msf, param);
}
}
} else {
String cncstr = "uno:" + param.get("ConnectionString") +
";urp;StarOffice.ServiceManager";
msf = connectOffice(cncstr);
if (closeIfPossible) {
return disposeOffice(msf, param);
}
}
return true;
}
private XMultiServiceFactory connectOffice(String cncstr) {
XMultiServiceFactory msf = null;
String exc = "";
if (debug) System.out.println("trying to connect to " + cncstr);
try {
msf = connect(cncstr);
} catch (com.sun.star.uno.Exception ue) {
exc = ue.getMessage();
} catch (java.lang.Exception je) {
exc = je.getMessage();
}
if (debug && exc != null && exc.length() != 0) {
if (exc == null) exc="";
System.out.println("Could not connect an Office. " + exc);
}
return msf;
}
private synchronized boolean disposeOffice(XMultiServiceFactory msf,
TestParameters param) {
XDesktop desk = null;
boolean result = true;
if (msf != null) {
try {
desk = (XDesktop) UnoRuntime.queryInterface(XDesktop.class,
msf.createInstance(
"com.sun.star.frame.Desktop"));
msf = null;
if (desk != null) {
boolean allClosed = closeAllWindows(desk);
if (!allClosed) {
if (debug) {
System.out.println(
"Couldn't close all office windows!");
}
}
if (debug) {
System.out.println("Trying to terminate the desktop");
}
desk.terminate();
if (debug) {
System.out.println("Desktop terminated");
}
try {
Thread.sleep(5000);
} catch (java.lang.InterruptedException e) {
}
}
} catch (com.sun.star.uno.Exception ue) {
result = false;
} catch (com.sun.star.lang.DisposedException ue) {
result = false;
}
}
ProcessHandler ph = (ProcessHandler) param.get("AppProvider");
if (ph != null) {
// dispose watcher in case it's still running.
OfficeWatcher ow = (OfficeWatcher) param.get("Watcher");
if ((ow != null) && ow.isAlive()) {
ow.finish = true;
}
ph.kill();
}
param.remove("AppProvider");
param.remove("ServiceFactory");
//copy user_backup into user layer
try {
String userLayer = (String) param.get("userLayer");
String copyLayer = (String) param.get("copyLayer");
if (userLayer != null && copyLayer != null) {
File copyFile = new File(copyLayer);
copyDirectory(copyFile, new File(userLayer));
deleteDir(copyFile);
}
else
System.out.println("Cannot copy layer: " + copyLayer + " back to user layer: " + userLayer);
} catch (java.io.IOException e) {
if (debug) {
System.out.println("Couldn't recover from backup");
e.printStackTrace();
}
}
return result;
}
protected boolean closeAllWindows(XDesktop desk) {
XEnumerationAccess compEnumAccess = desk.getComponents();
XEnumeration compEnum = compEnumAccess.createEnumeration();
boolean res = true;
try {
while (compEnum.hasMoreElements()) {
XCloseable closer = (XCloseable) UnoRuntime.queryInterface(
XCloseable.class,
compEnum.nextElement());
if (closer != null) {
closer.close(true);
}
}
} catch (com.sun.star.util.CloseVetoException cve) {
res = false;
} catch (com.sun.star.container.NoSuchElementException nsee) {
res = false;
} catch (com.sun.star.lang.WrappedTargetException wte) {
res = false;
}
return res;
}
// Copies src file to dst file.
// If the dst file does not exist, it is created
void copyFile(File src, File dst) throws IOException {
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dst);
// Transfer bytes from in to out
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
// Copies all files under srcDir to dstDir.
// If dstDir does not exist, it will be created.
public void copyDirectory(File srcDir, File dstDir)
throws IOException {
if (srcDir.getName().endsWith("temp")) {
if (debug) {
System.out.println("Ignoring: " + srcDir.getName());
}
return;
}
if (srcDir.isDirectory()) {
if (!dstDir.exists()) {
dstDir.mkdir();
}
String[] children = srcDir.list();
for (int i = 0; i < children.length; i++) {
copyDirectory(new File(srcDir, children[i]),
new File(dstDir, children[i]));
}
} else {
copyFile(srcDir, dstDir);
}
}
public static XStringSubstitution createStringSubstitution(XMultiServiceFactory xMSF) {
Object xPathSubst = null;
try {
xPathSubst = xMSF.createInstance(
"com.sun.star.util.PathSubstitution");
} catch (com.sun.star.uno.Exception e) {
e.printStackTrace();
}
if (xPathSubst != null) {
return (XStringSubstitution) UnoRuntime.queryInterface(
XStringSubstitution.class, xPathSubst);
} else {
return null;
}
}
/**
* converts directory without 'file:///' prefix.
* and System dependend file separator
*/
public static String getDirSys(String dir) {
String sysDir = "";
int idx = dir.indexOf("file://");
int idx2 = dir.indexOf("file:///");
// remove leading 'file://'
if (idx < 0) {
sysDir = dir;
} else {
sysDir = dir.substring("file://".length());
}
sysDir = utils.replaceAll13(sysDir, "%20", " ");
// append '/' if not there (e.g. linux)
if (sysDir.charAt(sysDir.length() - 1) != '/') {
sysDir += "/";
}
// remove leading '/' and replace others with '\' on windows machines
String sep = System.getProperty("file.separator");
if (sep.equalsIgnoreCase("\\")) {
if (!(idx2 < 0)) {
sysDir = sysDir.substring(1);
} else {
//network path
sysDir = "//"+sysDir;
}
sysDir = sysDir.replace('/', '\\');
}
return sysDir;
}
// Deletes all files and subdirectories under dir.
// Returns true if all deletions were successful.
// If a deletion fails, the method stops attempting to delete and returns false.
public static boolean deleteDir(File dir) {
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
}
// The directory is now empty so delete it
return dir.delete();
}
}