diff --git a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapConnector.java b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapConnector.java index b0debb6..1908058 100644 --- a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapConnector.java +++ b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapConnector.java @@ -29,7 +29,7 @@ /** * A bootstrap connector which establishes a connection to an OOo server. - * + *

* Most of the source code in this class has been taken from the Java class * "Bootstrap.java" (Revision: 1.15) from the UDK projekt (Uno Software Develop- * ment Kit) from OpenOffice.org (http://udk.openoffice.org/). The source code @@ -37,7 +37,7 @@ * access at http://udk.openoffice.org/source/browse/udk/. The Java class * "Bootstrap.java" is there available at * http://udk.openoffice.org/source/browse/udk/javaunohelper/com/sun/star/comp/helper/Bootstrap.java?view=markup - * + *

* The idea to develop this BootstrapConnector comes from the blog "Getting * started with the OpenOffice.org API part III : starting OpenOffice.org with * jars not in the OOo install dir by Wouter van Reeven" @@ -48,54 +48,62 @@ */ public class BootstrapConnector { - /** The OOo server. */ + /** + * The OOo server. + */ private OOServer oooServer; - - /** The connection string which has ben used to establish the connection. */ + + /** + * The connection string which has ben used to establish the connection. + */ private String oooConnectionString; + protected int connectionTimeoutSec; + + protected static final int CONNECTION_RETRY_INTERVAL = 500; + /** * Constructs a bootstrap connector which connects to the specified * OOo server. - * - * @param oooServer The OOo server + * + * @param oooServer The OOo server */ - public BootstrapConnector(OOServer oooServer) { - + public BootstrapConnector(OOServer oooServer, int connectionTimeoutSec) { this.oooServer = oooServer; this.oooConnectionString = null; + this.connectionTimeoutSec = connectionTimeoutSec; } /** * Connects to an OOo server using the specified accept option and * connection string and returns a component context for using the * connection to the OOo server. - * + *

* The accept option and the connection string should match to get a * connection. OOo provides to different types of connections: * 1) The socket connection * 2) The named pipe connection - * + *

* To create a socket connection a host and port must be provided. * For example using the host "localhost" and the port "8100" the * accept option and connection string looks like this: * - accept option : -accept=socket,host=localhost,port=8100;urp; * - connection string: uno:socket,host=localhost,port=8100;urp;StarOffice.ComponentContext - * + *

* To create a named pipe a pipe name must be provided. For example using * the pipe name "oooPipe" the accept option and connection string looks * like this: * - accept option : -accept=pipe,name=oooPipe;urp; * - connection string: uno:pipe,name=oooPipe;urp;StarOffice.ComponentContext - * - * @param oooConnectionString The connection string - * @return The component context + * + * @param oooConnectionString The connection string + * @return The component context */ public XComponentContext connect(String oooConnectionString) throws BootstrapException { this.oooConnectionString = oooConnectionString; - XComponentContext xContext = null; + XComponentContext xContext; try { // get local context XComponentContext xLocalContext = getLocalContext(); @@ -104,24 +112,26 @@ public XComponentContext connect(String oooConnectionString) throws BootstrapExc // initial service manager XMultiComponentFactory xLocalServiceManager = xLocalContext.getServiceManager(); - if ( xLocalServiceManager == null ) + if (xLocalServiceManager == null) throw new BootstrapException("no initial service manager!"); // create a URL resolver XUnoUrlResolver xUrlResolver = UnoUrlResolver.create(xLocalContext); - // wait until office is started - for (int i = 0;; ++i) { + long connectionTimeoutMillis = connectionTimeoutSec * 1000; + // wait until office is started but no longer than connectionTimeoutMillis + long start = System.currentTimeMillis(); + for (; ; ) { try { xContext = getRemoteContext(xUrlResolver); break; - } catch ( NoConnectException ex ) { - // Wait 500 ms, then try to connect again, but do not wait - // longer than 5 sec total: - if (i == 10) { - throw new BootstrapException(ex); + } catch (NoConnectException ex) { + if (System.currentTimeMillis() - start < connectionTimeoutMillis) { + // Retry to connect after a short interval + Thread.sleep(CONNECTION_RETRY_INTERVAL); + } else { + throw new BootstrapException("Unable to connect to the OO process", ex); } - Thread.sleep(500); } } } catch (RuntimeException e) { @@ -135,9 +145,9 @@ public XComponentContext connect(String oooConnectionString) throws BootstrapExc /** * Disconnects from an OOo server using the connection string from the * previous connect. - * + *

* If there has been no previous connect, the disconnects does nothing. - * + *

* If there has been a previous connect, disconnect tries to terminate * the OOo server and kills the OOo server process the connect started. */ @@ -158,11 +168,11 @@ public void disconnect() { XComponentContext xRemoteContext = getRemoteContext(xUrlResolver); // get desktop to terminate office - Object desktop = xRemoteContext.getServiceManager().createInstanceWithContext("com.sun.star.frame.Desktop",xRemoteContext); + Object desktop = xRemoteContext.getServiceManager().createInstanceWithContext( + "com.sun.star.frame.Desktop", xRemoteContext); XDesktop xDesktop = (XDesktop) UnoRuntime.queryInterface(XDesktop.class, desktop); xDesktop.terminate(); - } - catch (Exception e) { + } catch (Exception e) { // Bad luck, unable to terminate office } @@ -172,8 +182,8 @@ public void disconnect() { /** * Create default local component context. - * - * @return The default local component context + * + * @return The default local component context */ protected XComponentContext getLocalContext() throws BootstrapException, Exception { @@ -186,10 +196,11 @@ protected XComponentContext getLocalContext() throws BootstrapException, Excepti /** * Try to connect to office. - * - * @return The remote component context + * + * @return The remote component context */ - protected XComponentContext getRemoteContext(XUnoUrlResolver xUrlResolver) throws BootstrapException, ConnectionSetupException, IllegalArgumentException, NoConnectException { + protected XComponentContext getRemoteContext(XUnoUrlResolver xUrlResolver) throws BootstrapException, + ConnectionSetupException, IllegalArgumentException, NoConnectException { Object context = xUrlResolver.resolve(oooConnectionString); XComponentContext xContext = (XComponentContext) UnoRuntime.queryInterface(XComponentContext.class, context); diff --git a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapSocketConnector.java b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapSocketConnector.java index 9b1eca7..c430a32 100644 --- a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapSocketConnector.java +++ b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/BootstrapSocketConnector.java @@ -29,8 +29,8 @@ public class BootstrapSocketConnector extends BootstrapConnector { * * @param oooServer The OOo server */ - public BootstrapSocketConnector(OOServer oooServer) { - super(oooServer); + public BootstrapSocketConnector(OOServer oooServer, int connectionTimeoutSec) { + super(oooServer, connectionTimeoutSec); } /** diff --git a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeConnection.java b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeConnection.java index 2e6c16f..c8899de 100644 --- a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeConnection.java +++ b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeConnection.java @@ -47,7 +47,7 @@ public OfficeConnection(String openOfficePath, Integer port, ProcessManager proc this.officeIntegration = officeIntegration; this.oooServer = new OOServer(openOfficePath, OOServer.getDefaultOOoOptions(), "localhost", port, officeIntegration.getTemporaryDirPath(), processManager); - this.bsc = new BootstrapSocketConnector(oooServer); + this.bsc = new BootstrapSocketConnector(oooServer, officeIntegration.getConnectionTimeoutSec()); this.openOfficePath = openOfficePath; } diff --git a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegration.java b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegration.java index d1696a1..6f8c2ec 100644 --- a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegration.java +++ b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegration.java @@ -35,6 +35,7 @@ public class OfficeIntegration implements OfficeIntegrationAPI { protected String temporaryDirPath; protected Integer[] openOfficePorts; protected Integer timeoutInSeconds = DEFAULT_TIMEOUT; + protected int connectionTimeoutSec = DEFAULT_CONNECTION_TIMEOUT; protected int countOfRetry = DEFAULT_RETRY_COUNT; protected int retryIntervalMs = DEFAULT_RETRY_INTERVAL; protected Boolean displayDeviceAvailable = false; @@ -78,6 +79,14 @@ public Integer getTimeoutInSeconds() { return timeoutInSeconds; } + public int getConnectionTimeoutSec() { + return connectionTimeoutSec; + } + + public void setConnectionTimeoutSec(int connectionTimeoutSec) { + this.connectionTimeoutSec = connectionTimeoutSec; + } + public Boolean isDisplayDeviceAvailable() { return displayDeviceAvailable; } diff --git a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegrationAPI.java b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegrationAPI.java index 2e9f296..9913fd7 100644 --- a/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegrationAPI.java +++ b/core/modules/core/src/com/haulmont/yarg/formatters/impl/doc/connector/OfficeIntegrationAPI.java @@ -21,6 +21,7 @@ public interface OfficeIntegrationAPI { int DEFAULT_RETRY_COUNT = 2; int DEFAULT_RETRY_INTERVAL = 1000; int DEFAULT_TIMEOUT = 60; + int DEFAULT_CONNECTION_TIMEOUT = 15; String getTemporaryDirPath();