simplify writeBitmapObject
[LibreOffice.git] / ridljar / com / sun / star / comp / helper / Bootstrap.java
blob6b371f50324b000102c92d5d08cf5a596be0427d
1 // -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
3 /*
4 * This file is part of the LibreOffice project.
6 * This Source Code Form is subject to the terms of the Mozilla Public
7 * License, v. 2.0. If a copy of the MPL was not distributed with this
8 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
10 * This file incorporates work covered by the following license notice:
12 * Licensed to the Apache Software Foundation (ASF) under one or more
13 * contributor license agreements. See the NOTICE file distributed
14 * with this work for additional information regarding copyright
15 * ownership. The ASF licenses this file to you under the Apache
16 * License, Version 2.0 (the "License"); you may not use this file
17 * except in compliance with the License. You may obtain a copy of
18 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 package com.sun.star.comp.helper;
23 import com.sun.star.bridge.UnoUrlResolver;
24 import com.sun.star.bridge.XUnoUrlResolver;
25 import com.sun.star.comp.loader.JavaLoader;
26 import com.sun.star.comp.servicemanager.ServiceManager;
27 import com.sun.star.container.XSet;
28 import com.sun.star.lang.XInitialization;
29 import com.sun.star.lang.XMultiServiceFactory;
30 import com.sun.star.lang.XMultiComponentFactory;
31 import com.sun.star.lib.util.NativeLibraryLoader;
32 import com.sun.star.loader.XImplementationLoader;
33 import com.sun.star.uno.UnoRuntime;
34 import com.sun.star.uno.XComponentContext;
35 import com.sun.star.beans.XPropertySet;
37 import java.io.BufferedReader;
38 import java.io.File;
39 import java.io.InputStream;
40 import java.io.InputStreamReader;
41 import java.io.PrintStream;
42 import java.io.UnsupportedEncodingException;
43 import java.util.HashMap;
44 import java.util.Hashtable;
45 import java.util.Map;
46 import java.util.Random;
48 /** Bootstrap offers functionality to obtain a context or simply
49 a service manager.
50 The service manager can create a few basic services, whose implementations are:
51 <ul>
52 <li>com.sun.star.comp.loader.JavaLoader</li>
53 <li>com.sun.star.comp.urlresolver.UrlResolver</li>
54 <li>com.sun.star.comp.bridgefactory.BridgeFactory</li>
55 <li>com.sun.star.comp.connections.Connector</li>
56 <li>com.sun.star.comp.connections.Acceptor</li>
57 <li>com.sun.star.comp.servicemanager.ServiceManager</li>
58 </ul>
60 Other services can be inserted into the service manager by
61 using its XSet interface:
62 <pre>
63 XSet xSet = UnoRuntime.queryInterface( XSet.class, aMultiComponentFactory );
64 // insert the service manager
65 xSet.insert( aSingleComponentFactory );
66 </pre>
68 public class Bootstrap {
70 private static void insertBasicFactories(
71 XSet xSet, XImplementationLoader xImpLoader )
72 throws Exception
74 // insert the factory of the loader
75 xSet.insert( xImpLoader.activate(
76 "com.sun.star.comp.loader.JavaLoader", null, null, null ) );
78 // insert the factory of the URLResolver
79 xSet.insert( xImpLoader.activate(
80 "com.sun.star.comp.urlresolver.UrlResolver", null, null, null ) );
82 // insert the bridgefactory
83 xSet.insert( xImpLoader.activate(
84 "com.sun.star.comp.bridgefactory.BridgeFactory", null, null, null ) );
86 // insert the connector
87 xSet.insert( xImpLoader.activate(
88 "com.sun.star.comp.connections.Connector", null, null, null ) );
90 // insert the acceptor
91 xSet.insert( xImpLoader.activate(
92 "com.sun.star.comp.connections.Acceptor", null, null, null ) );
95 /**
96 * Returns an array of default commandline options to start bootstrapped
97 * instance of soffice with. You may use it in connection with bootstrap
98 * method for example like this:
99 * <pre>
100 * List list = Arrays.asList( Bootstrap.getDefaultOptions() );
101 * list.remove("--nologo");
102 * list.remove("--nodefault");
103 * list.add("--invisible");
105 * Bootstrap.bootstrap( list.toArray( new String[list.size()] );
106 * </pre>
108 * @return an array of default commandline options
109 * @see #bootstrap( String[] )
110 * @since LibreOffice 5.1
112 public static final String[] getDefaultOptions()
114 return new String[]
116 "--nologo",
117 "--nodefault",
118 "--norestore",
119 "--nolockcheck"
124 backwards compatibility stub.
125 @param context_entries the hash table contains mappings of entry names (type string) to
126 context entries (type class ComponentContextEntry).
127 @throws Exception if things go awry.
128 @return a new context.
130 public static XComponentContext createInitialComponentContext( Hashtable<String, Object> context_entries )
131 throws Exception
133 return createInitialComponentContext((Map<String, Object>) context_entries);
135 /** Bootstraps an initial component context with service manager and basic
136 jurt components inserted.
137 @param context_entries the hash table contains mappings of entry names (type string) to
138 context entries (type class ComponentContextEntry).
139 @throws Exception if things go awry.
140 @return a new context.
142 public static XComponentContext createInitialComponentContext( Map<String, Object> context_entries )
143 throws Exception
145 ServiceManager xSMgr = new ServiceManager();
147 XImplementationLoader xImpLoader = UnoRuntime.queryInterface(
148 XImplementationLoader.class, new JavaLoader() );
149 XInitialization xInit = UnoRuntime.queryInterface(
150 XInitialization.class, xImpLoader );
151 Object[] args = new Object [] { xSMgr };
152 xInit.initialize( args );
154 // initial component context
155 if (context_entries == null)
156 context_entries = new HashMap<String,Object>( 1 );
157 // add smgr
158 context_entries.put(
159 "/singletons/com.sun.star.lang.theServiceManager",
160 new ComponentContextEntry( null, xSMgr ) );
161 // ... xxx todo: add standard entries
162 XComponentContext xContext = new ComponentContext( context_entries, null );
164 xSMgr.setDefaultContext(xContext);
166 XSet xSet = UnoRuntime.queryInterface( XSet.class, xSMgr );
167 // insert basic jurt factories
168 insertBasicFactories( xSet, xImpLoader );
170 return xContext;
174 * Bootstraps a servicemanager with the jurt base components registered.
176 * See also UNOIDL <code>com.sun.star.lang.ServiceManager</code>.
178 * @throws Exception if things go awry.
179 * @return a freshly bootstrapped service manager
181 public static XMultiServiceFactory createSimpleServiceManager() throws Exception
183 return UnoRuntime.queryInterface(
184 XMultiServiceFactory.class, createInitialComponentContext( (Map<String, Object>) null ).getServiceManager() );
188 /** Bootstraps the initial component context from a native UNO installation.
190 @throws Exception if things go awry.
191 @return a freshly bootstrapped component context.
193 See also
194 <code>cppuhelper/defaultBootstrap_InitialComponentContext()</code>.
196 public static final XComponentContext defaultBootstrap_InitialComponentContext()
197 throws Exception
199 return defaultBootstrap_InitialComponentContext( (String) null, (Map<String,String>) null );
202 * Backwards compatibility stub.
204 * @param ini_file
205 * ini_file (may be null: uno.rc besides cppuhelper lib)
206 * @param bootstrap_parameters
207 * bootstrap parameters (maybe null)
209 * @throws Exception if things go awry.
210 * @return a freshly bootstrapped component context.
212 public static final XComponentContext defaultBootstrap_InitialComponentContext(
213 String ini_file, Hashtable<String,String> bootstrap_parameters )
214 throws Exception
216 return defaultBootstrap_InitialComponentContext(ini_file, (Map<String,String>) bootstrap_parameters);
219 /** Bootstraps the initial component context from a native UNO installation.
221 See also
222 <code>cppuhelper/defaultBootstrap_InitialComponentContext()</code>.
224 @param ini_file
225 ini_file (may be null: uno.rc besides cppuhelper lib)
226 @param bootstrap_parameters
227 bootstrap parameters (maybe null)
229 @throws Exception if things go awry.
230 @return a freshly bootstrapped component context.
232 public static final XComponentContext defaultBootstrap_InitialComponentContext(
233 String ini_file, Map<String,String> bootstrap_parameters )
234 throws Exception
236 // jni convenience: easier to iterate over array than calling Hashtable
237 String pairs [] = null;
238 if (null != bootstrap_parameters)
240 pairs = new String [ 2 * bootstrap_parameters.size() ];
241 int n = 0;
242 for (Map.Entry<String, String> bootstrap_parameter : bootstrap_parameters.entrySet()) {
243 pairs[ n++ ] = bootstrap_parameter.getKey();
244 pairs[ n++ ] = bootstrap_parameter.getValue();
248 if (! m_loaded_juh)
250 if ("The Android Project".equals(System.getProperty("java.vendor")))
252 // Find out if we are configured with DISABLE_DYNLOADING or
253 // not. Try to load the lo-bootstrap shared library which
254 // won't exist in the DISABLE_DYNLOADING case. (And which will
255 // be already loaded otherwise, so nothing unexpected happens
256 // that case.) Yeah, this would be simpler if I just could be
257 // bothered to keep a separate branch for DISABLE_DYNLOADING
258 // on Android, merging in master periodically, until I know
259 // for sure whether it is what I want, or not.
261 boolean disable_dynloading = false;
262 try {
263 System.loadLibrary( "lo-bootstrap" );
264 } catch ( UnsatisfiedLinkError e ) {
265 disable_dynloading = true;
268 if (!disable_dynloading)
270 NativeLibraryLoader.loadLibrary( Bootstrap.class.getClassLoader(), "juh" );
273 else
275 NativeLibraryLoader.loadLibrary( Bootstrap.class.getClassLoader(), "juh" );
277 m_loaded_juh = true;
279 return UnoRuntime.queryInterface(
280 XComponentContext.class,
281 cppuhelper_bootstrap(
282 ini_file, pairs, Bootstrap.class.getClassLoader() ) );
285 private static boolean m_loaded_juh = false;
286 private static native Object cppuhelper_bootstrap(
287 String ini_file, String bootstrap_parameters [], ClassLoader loader )
288 throws Exception;
291 * Bootstraps the component context from a UNO installation.
293 * @throws BootstrapException if things go awry.
295 * @return a bootstrapped component context.
297 * @since UDK 3.1.0
299 public static final XComponentContext bootstrap()
300 throws BootstrapException {
302 String[] defaultArgArray = getDefaultOptions();
303 return bootstrap( defaultArgArray );
307 * Bootstraps the component context from a UNO installation.
309 * @param argArray
310 * an array of strings - commandline options to start instance of
311 * soffice with
312 * @see #getDefaultOptions()
314 * @throws BootstrapException if things go awry.
316 * @return a bootstrapped component context.
318 * @since LibreOffice 5.1
320 public static final XComponentContext bootstrap( String[] argArray )
321 throws BootstrapException {
323 XComponentContext xContext = null;
325 try {
326 // create default local component context
327 XComponentContext xLocalContext =
328 createInitialComponentContext( (Map<String, Object>) null );
329 if ( xLocalContext == null )
330 throw new BootstrapException( "no local component context!" );
332 // find office executable relative to this class's class loader
333 String sOffice =
334 System.getProperty( "os.name" ).startsWith( "Windows" ) ?
335 "soffice.exe" : "soffice";
336 File fOffice = NativeLibraryLoader.getResource(
337 Bootstrap.class.getClassLoader(), sOffice );
338 if ( fOffice == null )
339 throw new BootstrapException( "no office executable found!" );
341 // create random pipe name
342 String sPipeName = "uno" +
343 Long.toString(randomPipeName.nextLong() & 0x7fffffffffffffffL);
345 // create call with arguments
346 String[] cmdArray = new String[ argArray.length + 2 ];
347 cmdArray[0] = fOffice.getPath();
348 cmdArray[1] = ( "--accept=pipe,name=" + sPipeName + ";urp;" );
350 System.arraycopy( argArray, 0, cmdArray, 2, argArray.length );
352 // start office process
353 Process p = Runtime.getRuntime().exec( cmdArray );
354 pipe( p.getInputStream(), System.out, "CO> " );
355 pipe( p.getErrorStream(), System.err, "CE> " );
357 // initial service manager
358 XMultiComponentFactory xLocalServiceManager =
359 xLocalContext.getServiceManager();
360 if ( xLocalServiceManager == null )
361 throw new BootstrapException( "no initial service manager!" );
363 // create a URL resolver
364 XUnoUrlResolver xUrlResolver =
365 UnoUrlResolver.create( xLocalContext );
367 // connection string
368 String sConnect = "uno:pipe,name=" + sPipeName +
369 ";urp;StarOffice.ComponentContext";
371 // wait until office is started
372 for (int i = 0;; ++i) {
373 try {
374 // try to connect to office
375 Object context = xUrlResolver.resolve( sConnect );
376 xContext = UnoRuntime.queryInterface(
377 XComponentContext.class, context);
378 if ( xContext == null )
379 throw new BootstrapException( "no component context!" );
380 break;
381 } catch ( com.sun.star.connection.NoConnectException ex ) {
382 // Wait 500 ms, then try to connect again, but do not wait
383 // longer than 5 min (= 600 * 500 ms) total:
384 if (i == 600) {
385 throw new BootstrapException(ex);
387 Thread.sleep( 500 );
390 } catch ( BootstrapException e ) {
391 throw e;
392 } catch ( java.lang.RuntimeException e ) {
393 throw e;
394 } catch ( java.lang.Exception e ) {
395 throw new BootstrapException( e );
398 return xContext;
402 * Bootstraps the component context from a websocket location.
404 * @param url
405 * the ws:// or wss:// url of the websocket server
407 * @throws BootstrapException if things go awry.
409 * @return a bootstrapped component context.
411 * @since LibreOffice 24.2
413 public static final XComponentContext bootstrapWebsocketConnection( String url )
414 throws BootstrapException {
416 XComponentContext xContext = null;
418 try {
419 // create default local component context
420 XComponentContext xLocalContext =
421 createInitialComponentContext( (Map<String, Object>) null );
422 if ( xLocalContext == null )
423 throw new BootstrapException( "no local component context!" );
425 // initial service manager
426 XMultiComponentFactory xLocalServiceManager =
427 xLocalContext.getServiceManager();
428 if ( xLocalServiceManager == null )
429 throw new BootstrapException( "no initial service manager!" );
431 // create a URL resolver
432 XUnoUrlResolver xUrlResolver =
433 UnoUrlResolver.create( xLocalContext );
435 // connection string
436 String sConnect = "uno:websocket"
437 + ",url=" + url
438 + ";urp;StarOffice.ComponentContext";
440 try {
441 // try to connect to office
442 Object xOfficeServiceManager = xUrlResolver.resolve(sConnect);
444 xContext = UnoRuntime.queryInterface(XComponentContext.class, xOfficeServiceManager);
446 if ( xContext == null )
447 throw new BootstrapException( "no component context!" );
448 } catch ( com.sun.star.connection.NoConnectException ex ) {
449 throw new BootstrapException(ex);
451 } catch ( BootstrapException e ) {
452 throw e;
453 } catch ( java.lang.RuntimeException e ) {
454 throw e;
455 } catch ( java.lang.Exception e ) {
456 throw new BootstrapException( e );
459 return xContext;
463 private static final Random randomPipeName = new Random();
465 private static void pipe(
466 final InputStream in, final PrintStream out, final String prefix ) {
468 new Thread( "Pipe: " + prefix) {
469 @Override
470 public void run() {
471 try {
472 BufferedReader r = new BufferedReader(
473 new InputStreamReader(in, "UTF-8") );
475 for ( ; ; ) {
476 String s = r.readLine();
477 if ( s == null ) {
478 break;
480 out.println( prefix + s );
482 } catch ( UnsupportedEncodingException e ) {
483 e.printStackTrace( System.err );
484 } catch ( java.io.IOException e ) {
485 e.printStackTrace( System.err );
488 }.start();
492 // vim:set shiftwidth=4 softtabstop=4 expandtab: