1a0428e9eSAndrew Rist#**************************************************************
2a0428e9eSAndrew Rist#
3a0428e9eSAndrew Rist#  Licensed to the Apache Software Foundation (ASF) under one
4a0428e9eSAndrew Rist#  or more contributor license agreements.  See the NOTICE file
5a0428e9eSAndrew Rist#  distributed with this work for additional information
6a0428e9eSAndrew Rist#  regarding copyright ownership.  The ASF licenses this file
7a0428e9eSAndrew Rist#  to you under the Apache License, Version 2.0 (the
8a0428e9eSAndrew Rist#  "License"); you may not use this file except in compliance
9a0428e9eSAndrew Rist#  with the License.  You may obtain a copy of the License at
10a0428e9eSAndrew Rist#
11a0428e9eSAndrew Rist#    http://www.apache.org/licenses/LICENSE-2.0
12a0428e9eSAndrew Rist#
13a0428e9eSAndrew Rist#  Unless required by applicable law or agreed to in writing,
14a0428e9eSAndrew Rist#  software distributed under the License is distributed on an
15a0428e9eSAndrew Rist#  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16a0428e9eSAndrew Rist#  KIND, either express or implied.  See the License for the
17a0428e9eSAndrew Rist#  specific language governing permissions and limitations
18a0428e9eSAndrew Rist#  under the License.
19a0428e9eSAndrew Rist#
20a0428e9eSAndrew Rist#**************************************************************
21cdf0e10cSrcweir
22cdf0e10cSrcweir#
23cdf0e10cSrcweir# Translated to python from "Bootstrap.java" by Kim Kulak
24cdf0e10cSrcweir#
25cdf0e10cSrcweir
26cdf0e10cSrcweirimport os
27cdf0e10cSrcweirimport random
28cdf0e10cSrcweirfrom sys import platform
29cdf0e10cSrcweirfrom time import sleep
30cdf0e10cSrcweir
31cdf0e10cSrcweirimport uno
32cdf0e10cSrcweirfrom com.sun.star.connection import NoConnectException
33cdf0e10cSrcweirfrom com.sun.star.uno import Exception as UnoException
34cdf0e10cSrcweir
35cdf0e10cSrcweir
36cdf0e10cSrcweirclass BootstrapException(UnoException):
37cdf0e10cSrcweir    pass
38cdf0e10cSrcweir
39cdf0e10cSrcweirdef bootstrap():
40cdf0e10cSrcweir    """Bootstrap OOo and PyUNO Runtime.
41cdf0e10cSrcweir    The soffice process is started opening a named pipe of random name, then the local context is used
4213cfd8dfSPedro Giffuni        to access the pipe. This function directly returns the remote component context, from whereon you can
4313cfd8dfSPedro Giffuni        get the ServiceManager by calling getServiceManager() on the returned object.
4413cfd8dfSPedro Giffuni        """
45cdf0e10cSrcweir    try:
4613cfd8dfSPedro Giffuni        # soffice script used on *ix, Mac; soffice.exe used on Windoof
47cdf0e10cSrcweir        if "UNO_PATH" in os.environ:
48cdf0e10cSrcweir            sOffice = os.environ["UNO_PATH"]
49cdf0e10cSrcweir        else:
50cdf0e10cSrcweir            sOffice = "" # lets hope for the best
51cdf0e10cSrcweir        sOffice = os.path.join(sOffice, "soffice")
5213cfd8dfSPedro Giffuni        if platform.startswith("win"):
53cdf0e10cSrcweir            sOffice += ".exe"
5413cfd8dfSPedro Giffuni
55cdf0e10cSrcweir        # Generate a random pipe name.
56cdf0e10cSrcweir        random.seed()
57cdf0e10cSrcweir        sPipeName = "uno" + str(random.random())[2:]
5813cfd8dfSPedro Giffuni
59cdf0e10cSrcweir        # Start the office proces, don't check for exit status since an exception is caught anyway if the office terminates unexpectedly.
6013cfd8dfSPedro Giffuni        cmdArray = (sOffice, "-nologo", "-nodefault", "".join(["-accept=pipe,name=", sPipeName, ";urp;"]))
61cdf0e10cSrcweir        os.spawnv(os.P_NOWAIT, sOffice, cmdArray)
6213cfd8dfSPedro Giffuni
63cdf0e10cSrcweir        # ---------
64cdf0e10cSrcweir
65cdf0e10cSrcweir        xLocalContext = uno.getComponentContext()
66cdf0e10cSrcweir        resolver = xLocalContext.ServiceManager.createInstanceWithContext(
6713cfd8dfSPedro Giffuni                        "com.sun.star.bridge.UnoUrlResolver", xLocalContext)
68cdf0e10cSrcweir        sConnect = "".join(["uno:pipe,name=", sPipeName, ";urp;StarOffice.ComponentContext"])
69cdf0e10cSrcweir
70cdf0e10cSrcweir        # Wait until an office is started, but loop only nLoop times (can we do this better???)
71cdf0e10cSrcweir        nLoop = 20
72cdf0e10cSrcweir        while True:
73cdf0e10cSrcweir            try:
74cdf0e10cSrcweir                xContext = resolver.resolve(sConnect)
75cdf0e10cSrcweir                break
76cdf0e10cSrcweir            except NoConnectException:
77cdf0e10cSrcweir                nLoop -= 1
78cdf0e10cSrcweir                if nLoop <= 0:
79cdf0e10cSrcweir                    raise BootstrapException("Cannot connect to soffice server.", None)
80cdf0e10cSrcweir                sleep(0.5)  # Sleep 1/2 second.
81cdf0e10cSrcweir
82cdf0e10cSrcweir    except BootstrapException:
8313cfd8dfSPedro Giffuni        raise
84*15745147SPedro Giffuni    except Exception as e:  # Any other exception
85cdf0e10cSrcweir        raise BootstrapException("Caught exception " + str(e), None)
86cdf0e10cSrcweir
87cdf0e10cSrcweir    return xContext
88