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