1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir package com.sun.star.comp.helper; 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir import com.sun.star.bridge.UnoUrlResolver; 31*cdf0e10cSrcweir import com.sun.star.bridge.XUnoUrlResolver; 32*cdf0e10cSrcweir import com.sun.star.comp.loader.JavaLoader; 33*cdf0e10cSrcweir import com.sun.star.container.XSet; 34*cdf0e10cSrcweir import com.sun.star.lang.XInitialization; 35*cdf0e10cSrcweir import com.sun.star.lang.XMultiServiceFactory; 36*cdf0e10cSrcweir import com.sun.star.lang.XMultiComponentFactory; 37*cdf0e10cSrcweir import com.sun.star.lang.XSingleComponentFactory; 38*cdf0e10cSrcweir import com.sun.star.lib.util.NativeLibraryLoader; 39*cdf0e10cSrcweir import com.sun.star.loader.XImplementationLoader; 40*cdf0e10cSrcweir import com.sun.star.uno.UnoRuntime; 41*cdf0e10cSrcweir import com.sun.star.uno.XComponentContext; 42*cdf0e10cSrcweir 43*cdf0e10cSrcweir import java.io.BufferedReader; 44*cdf0e10cSrcweir import java.io.File; 45*cdf0e10cSrcweir import java.io.InputStream; 46*cdf0e10cSrcweir import java.io.InputStreamReader; 47*cdf0e10cSrcweir import java.io.PrintStream; 48*cdf0e10cSrcweir import java.util.Enumeration; 49*cdf0e10cSrcweir import java.util.Hashtable; 50*cdf0e10cSrcweir import java.util.Random; 51*cdf0e10cSrcweir 52*cdf0e10cSrcweir /** Bootstrap offers functionality to obtain a context or simply 53*cdf0e10cSrcweir a service manager. 54*cdf0e10cSrcweir The service manager can create a few basic services, whose implementations are: 55*cdf0e10cSrcweir <ul> 56*cdf0e10cSrcweir <li>com.sun.star.comp.loader.JavaLoader</li> 57*cdf0e10cSrcweir <li>com.sun.star.comp.urlresolver.UrlResolver</li> 58*cdf0e10cSrcweir <li>com.sun.star.comp.bridgefactory.BridgeFactory</li> 59*cdf0e10cSrcweir <li>com.sun.star.comp.connections.Connector</li> 60*cdf0e10cSrcweir <li>com.sun.star.comp.connections.Acceptor</li> 61*cdf0e10cSrcweir <li>com.sun.star.comp.servicemanager.ServiceManager</li> 62*cdf0e10cSrcweir </ul> 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir Other services can be inserted into the service manager by 65*cdf0e10cSrcweir using its XSet interface: 66*cdf0e10cSrcweir <pre> 67*cdf0e10cSrcweir XSet xSet = UnoRuntime.queryInterface( XSet.class, aMultiComponentFactory ); 68*cdf0e10cSrcweir // insert the service manager 69*cdf0e10cSrcweir xSet.insert( aSingleComponentFactory ); 70*cdf0e10cSrcweir </pre> 71*cdf0e10cSrcweir */ 72*cdf0e10cSrcweir public class Bootstrap { 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir private static void insertBasicFactories( 75*cdf0e10cSrcweir XSet xSet, XImplementationLoader xImpLoader ) 76*cdf0e10cSrcweir throws Exception 77*cdf0e10cSrcweir { 78*cdf0e10cSrcweir // insert the factory of the loader 79*cdf0e10cSrcweir xSet.insert( xImpLoader.activate( 80*cdf0e10cSrcweir "com.sun.star.comp.loader.JavaLoader", null, null, null ) ); 81*cdf0e10cSrcweir 82*cdf0e10cSrcweir // insert the factory of the URLResolver 83*cdf0e10cSrcweir xSet.insert( xImpLoader.activate( 84*cdf0e10cSrcweir "com.sun.star.comp.urlresolver.UrlResolver", null, null, null ) ); 85*cdf0e10cSrcweir 86*cdf0e10cSrcweir // insert the bridgefactory 87*cdf0e10cSrcweir xSet.insert( xImpLoader.activate( 88*cdf0e10cSrcweir "com.sun.star.comp.bridgefactory.BridgeFactory", null, null, null ) ); 89*cdf0e10cSrcweir 90*cdf0e10cSrcweir // insert the connector 91*cdf0e10cSrcweir xSet.insert( xImpLoader.activate( 92*cdf0e10cSrcweir "com.sun.star.comp.connections.Connector", null, null, null ) ); 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir // insert the acceptor 95*cdf0e10cSrcweir xSet.insert( xImpLoader.activate( 96*cdf0e10cSrcweir "com.sun.star.comp.connections.Acceptor", null, null, null ) ); 97*cdf0e10cSrcweir } 98*cdf0e10cSrcweir 99*cdf0e10cSrcweir /** Bootstraps an initial component context with service manager and basic 100*cdf0e10cSrcweir jurt components inserted. 101*cdf0e10cSrcweir @param context_entries the hash table contains mappings of entry names (type string) to 102*cdf0e10cSrcweir context entries (type class ComponentContextEntry). 103*cdf0e10cSrcweir @return a new context. 104*cdf0e10cSrcweir */ 105*cdf0e10cSrcweir static public XComponentContext createInitialComponentContext( Hashtable context_entries ) 106*cdf0e10cSrcweir throws Exception 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir XImplementationLoader xImpLoader = UnoRuntime.queryInterface( 109*cdf0e10cSrcweir XImplementationLoader.class, new JavaLoader() ); 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir // Get the factory of the ServiceManager 112*cdf0e10cSrcweir XSingleComponentFactory smgr_fac = UnoRuntime.queryInterface( 113*cdf0e10cSrcweir XSingleComponentFactory.class, xImpLoader.activate( 114*cdf0e10cSrcweir "com.sun.star.comp.servicemanager.ServiceManager", null, null, null ) ); 115*cdf0e10cSrcweir 116*cdf0e10cSrcweir // Create an instance of the ServiceManager 117*cdf0e10cSrcweir XMultiComponentFactory xSMgr = UnoRuntime.queryInterface( 118*cdf0e10cSrcweir XMultiComponentFactory.class, smgr_fac.createInstanceWithContext( null ) ); 119*cdf0e10cSrcweir 120*cdf0e10cSrcweir // post init loader 121*cdf0e10cSrcweir XInitialization xInit = UnoRuntime.queryInterface( 122*cdf0e10cSrcweir XInitialization.class, xImpLoader ); 123*cdf0e10cSrcweir Object[] args = new Object [] { xSMgr }; 124*cdf0e10cSrcweir xInit.initialize( args ); 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir // initial component context 127*cdf0e10cSrcweir if (context_entries == null) 128*cdf0e10cSrcweir context_entries = new Hashtable( 1 ); 129*cdf0e10cSrcweir // add smgr 130*cdf0e10cSrcweir context_entries.put( 131*cdf0e10cSrcweir "/singletons/com.sun.star.lang.theServiceManager", 132*cdf0e10cSrcweir new ComponentContextEntry( null, xSMgr ) ); 133*cdf0e10cSrcweir // ... xxx todo: add standard entries 134*cdf0e10cSrcweir XComponentContext xContext = new ComponentContext( context_entries, null ); 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir // post init smgr 137*cdf0e10cSrcweir xInit = UnoRuntime.queryInterface( 138*cdf0e10cSrcweir XInitialization.class, xSMgr ); 139*cdf0e10cSrcweir args = new Object [] { null, xContext }; // no registry, default context 140*cdf0e10cSrcweir xInit.initialize( args ); 141*cdf0e10cSrcweir 142*cdf0e10cSrcweir XSet xSet = UnoRuntime.queryInterface( XSet.class, xSMgr ); 143*cdf0e10cSrcweir // insert the service manager 144*cdf0e10cSrcweir xSet.insert( smgr_fac ); 145*cdf0e10cSrcweir // and basic jurt factories 146*cdf0e10cSrcweir insertBasicFactories( xSet, xImpLoader ); 147*cdf0e10cSrcweir 148*cdf0e10cSrcweir return xContext; 149*cdf0e10cSrcweir } 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir /** 152*cdf0e10cSrcweir * Bootstraps a servicemanager with the jurt base components registered. 153*cdf0e10cSrcweir * <p> 154*cdf0e10cSrcweir * @return a freshly boostrapped service manager 155*cdf0e10cSrcweir * @see com.sun.star.lang.ServiceManager 156*cdf0e10cSrcweir */ 157*cdf0e10cSrcweir static public XMultiServiceFactory createSimpleServiceManager() throws Exception 158*cdf0e10cSrcweir { 159*cdf0e10cSrcweir return UnoRuntime.queryInterface( 160*cdf0e10cSrcweir XMultiServiceFactory.class, createInitialComponentContext( null ).getServiceManager() ); 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir /** Bootstraps the initial component context from a native UNO installation. 165*cdf0e10cSrcweir 166*cdf0e10cSrcweir @see cppuhelper/defaultBootstrap_InitialComponentContext() 167*cdf0e10cSrcweir */ 168*cdf0e10cSrcweir static public final XComponentContext defaultBootstrap_InitialComponentContext() 169*cdf0e10cSrcweir throws Exception 170*cdf0e10cSrcweir { 171*cdf0e10cSrcweir return defaultBootstrap_InitialComponentContext( null, null ); 172*cdf0e10cSrcweir } 173*cdf0e10cSrcweir /** Bootstraps the initial component context from a native UNO installation. 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir @param ini_file 176*cdf0e10cSrcweir ini_file (may be null: uno.rc besides cppuhelper lib) 177*cdf0e10cSrcweir @param bootstrap_parameters 178*cdf0e10cSrcweir bootstrap parameters (maybe null) 179*cdf0e10cSrcweir 180*cdf0e10cSrcweir @see cppuhelper/defaultBootstrap_InitialComponentContext() 181*cdf0e10cSrcweir */ 182*cdf0e10cSrcweir static public final XComponentContext defaultBootstrap_InitialComponentContext( 183*cdf0e10cSrcweir String ini_file, Hashtable bootstrap_parameters ) 184*cdf0e10cSrcweir throws Exception 185*cdf0e10cSrcweir { 186*cdf0e10cSrcweir // jni convenience: easier to iterate over array than calling Hashtable 187*cdf0e10cSrcweir String pairs [] = null; 188*cdf0e10cSrcweir if (null != bootstrap_parameters) 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir pairs = new String [ 2 * bootstrap_parameters.size() ]; 191*cdf0e10cSrcweir Enumeration keys = bootstrap_parameters.keys(); 192*cdf0e10cSrcweir int n = 0; 193*cdf0e10cSrcweir while (keys.hasMoreElements()) 194*cdf0e10cSrcweir { 195*cdf0e10cSrcweir String name = (String)keys.nextElement(); 196*cdf0e10cSrcweir pairs[ n++ ] = name; 197*cdf0e10cSrcweir pairs[ n++ ] = (String)bootstrap_parameters.get( name ); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir } 200*cdf0e10cSrcweir 201*cdf0e10cSrcweir if (! m_loaded_juh) 202*cdf0e10cSrcweir { 203*cdf0e10cSrcweir NativeLibraryLoader.loadLibrary( Bootstrap.class.getClassLoader(), "juh" ); 204*cdf0e10cSrcweir m_loaded_juh = true; 205*cdf0e10cSrcweir } 206*cdf0e10cSrcweir return UnoRuntime.queryInterface( 207*cdf0e10cSrcweir XComponentContext.class, 208*cdf0e10cSrcweir cppuhelper_bootstrap( 209*cdf0e10cSrcweir ini_file, pairs, Bootstrap.class.getClassLoader() ) ); 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir 212*cdf0e10cSrcweir static private boolean m_loaded_juh = false; 213*cdf0e10cSrcweir static private native Object cppuhelper_bootstrap( 214*cdf0e10cSrcweir String ini_file, String bootstrap_parameters [], ClassLoader loader ) 215*cdf0e10cSrcweir throws Exception; 216*cdf0e10cSrcweir 217*cdf0e10cSrcweir /** 218*cdf0e10cSrcweir * Bootstraps the component context from a UNO installation. 219*cdf0e10cSrcweir * 220*cdf0e10cSrcweir * @return a bootstrapped component context. 221*cdf0e10cSrcweir * 222*cdf0e10cSrcweir * @since UDK 3.1.0 223*cdf0e10cSrcweir */ 224*cdf0e10cSrcweir public static final XComponentContext bootstrap() 225*cdf0e10cSrcweir throws BootstrapException { 226*cdf0e10cSrcweir 227*cdf0e10cSrcweir XComponentContext xContext = null; 228*cdf0e10cSrcweir 229*cdf0e10cSrcweir try { 230*cdf0e10cSrcweir // create default local component context 231*cdf0e10cSrcweir XComponentContext xLocalContext = 232*cdf0e10cSrcweir createInitialComponentContext( null ); 233*cdf0e10cSrcweir if ( xLocalContext == null ) 234*cdf0e10cSrcweir throw new BootstrapException( "no local component context!" ); 235*cdf0e10cSrcweir 236*cdf0e10cSrcweir // find office executable relative to this class's class loader 237*cdf0e10cSrcweir String sOffice = 238*cdf0e10cSrcweir System.getProperty( "os.name" ).startsWith( "Windows" ) ? 239*cdf0e10cSrcweir "soffice.exe" : "soffice"; 240*cdf0e10cSrcweir File fOffice = NativeLibraryLoader.getResource( 241*cdf0e10cSrcweir Bootstrap.class.getClassLoader(), sOffice ); 242*cdf0e10cSrcweir if ( fOffice == null ) 243*cdf0e10cSrcweir throw new BootstrapException( "no office executable found!" ); 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir // create random pipe name 246*cdf0e10cSrcweir String sPipeName = "uno" + 247*cdf0e10cSrcweir Long.toString( (new Random()).nextLong() & 0x7fffffffffffffffL ); 248*cdf0e10cSrcweir 249*cdf0e10cSrcweir // create call with arguments 250*cdf0e10cSrcweir String[] cmdArray = new String[7]; 251*cdf0e10cSrcweir cmdArray[0] = fOffice.getPath(); 252*cdf0e10cSrcweir cmdArray[1] = "-nologo"; 253*cdf0e10cSrcweir cmdArray[2] = "-nodefault"; 254*cdf0e10cSrcweir cmdArray[3] = "-norestore"; 255*cdf0e10cSrcweir cmdArray[4] = "-nocrashreport"; 256*cdf0e10cSrcweir cmdArray[5] = "-nolockcheck"; 257*cdf0e10cSrcweir cmdArray[6] = "-accept=pipe,name=" + sPipeName + ";urp;"; 258*cdf0e10cSrcweir 259*cdf0e10cSrcweir // start office process 260*cdf0e10cSrcweir Process p = Runtime.getRuntime().exec( cmdArray ); 261*cdf0e10cSrcweir pipe( p.getInputStream(), System.out, "CO> " ); 262*cdf0e10cSrcweir pipe( p.getErrorStream(), System.err, "CE> " ); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir // initial service manager 265*cdf0e10cSrcweir XMultiComponentFactory xLocalServiceManager = 266*cdf0e10cSrcweir xLocalContext.getServiceManager(); 267*cdf0e10cSrcweir if ( xLocalServiceManager == null ) 268*cdf0e10cSrcweir throw new BootstrapException( "no initial service manager!" ); 269*cdf0e10cSrcweir 270*cdf0e10cSrcweir // create a URL resolver 271*cdf0e10cSrcweir XUnoUrlResolver xUrlResolver = 272*cdf0e10cSrcweir UnoUrlResolver.create( xLocalContext ); 273*cdf0e10cSrcweir 274*cdf0e10cSrcweir // connection string 275*cdf0e10cSrcweir String sConnect = "uno:pipe,name=" + sPipeName + 276*cdf0e10cSrcweir ";urp;StarOffice.ComponentContext"; 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir // wait until office is started 279*cdf0e10cSrcweir for (int i = 0;; ++i) { 280*cdf0e10cSrcweir try { 281*cdf0e10cSrcweir // try to connect to office 282*cdf0e10cSrcweir Object context = xUrlResolver.resolve( sConnect ); 283*cdf0e10cSrcweir xContext = UnoRuntime.queryInterface( 284*cdf0e10cSrcweir XComponentContext.class, context); 285*cdf0e10cSrcweir if ( xContext == null ) 286*cdf0e10cSrcweir throw new BootstrapException( "no component context!" ); 287*cdf0e10cSrcweir break; 288*cdf0e10cSrcweir } catch ( com.sun.star.connection.NoConnectException ex ) { 289*cdf0e10cSrcweir // Wait 500 ms, then try to connect again, but do not wait 290*cdf0e10cSrcweir // longer than 5 min (= 600 * 500 ms) total: 291*cdf0e10cSrcweir if (i == 600) { 292*cdf0e10cSrcweir throw new BootstrapException(ex.toString()); 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir Thread.currentThread().sleep( 500 ); 295*cdf0e10cSrcweir } 296*cdf0e10cSrcweir } 297*cdf0e10cSrcweir } catch ( BootstrapException e ) { 298*cdf0e10cSrcweir throw e; 299*cdf0e10cSrcweir } catch ( java.lang.RuntimeException e ) { 300*cdf0e10cSrcweir throw e; 301*cdf0e10cSrcweir } catch ( java.lang.Exception e ) { 302*cdf0e10cSrcweir throw new BootstrapException( e ); 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir return xContext; 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir 308*cdf0e10cSrcweir private static void pipe( 309*cdf0e10cSrcweir final InputStream in, final PrintStream out, final String prefix ) { 310*cdf0e10cSrcweir 311*cdf0e10cSrcweir new Thread( "Pipe: " + prefix) { 312*cdf0e10cSrcweir public void run() { 313*cdf0e10cSrcweir BufferedReader r = new BufferedReader( 314*cdf0e10cSrcweir new InputStreamReader( in ) ); 315*cdf0e10cSrcweir try { 316*cdf0e10cSrcweir for ( ; ; ) { 317*cdf0e10cSrcweir String s = r.readLine(); 318*cdf0e10cSrcweir if ( s == null ) { 319*cdf0e10cSrcweir break; 320*cdf0e10cSrcweir } 321*cdf0e10cSrcweir out.println( prefix + s ); 322*cdf0e10cSrcweir } 323*cdf0e10cSrcweir } catch ( java.io.IOException e ) { 324*cdf0e10cSrcweir e.printStackTrace( System.err ); 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir } 327*cdf0e10cSrcweir }.start(); 328*cdf0e10cSrcweir } 329*cdf0e10cSrcweir } 330