bump product version to 6.4.0.3
[LibreOffice.git] / jurt / com / sun / star / comp / servicemanager / ServiceManager.java
blob574983f1e238eddff1d10b19f095381e1e29949a
1 /* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 package com.sun.star.comp.servicemanager;
22 import java.util.ArrayList;
23 import java.util.Collections;
25 import com.sun.star.container.XContentEnumerationAccess;
26 import com.sun.star.container.XEnumeration;
27 import com.sun.star.container.XSet;
28 import com.sun.star.lang.XComponent;
29 import com.sun.star.lang.XEventListener;
30 import com.sun.star.lang.XMultiComponentFactory;
31 import com.sun.star.lang.XMultiServiceFactory;
32 import com.sun.star.lang.XServiceInfo;
33 import com.sun.star.lang.XSingleComponentFactory;
34 import com.sun.star.lang.XSingleServiceFactory;
35 import com.sun.star.uno.UnoRuntime;
36 import com.sun.star.uno.XComponentContext;
38 /**
39 * The <code>ServiceManager</code> class is an implementation of the
40 * <code>ServiceManager</code>the central class needed for implementing or using
41 * UNO components in Java.
43 * <p>The Methods <code>queryInterface</code> and <code>isSame</code> delegate
44 * calls to the implementing objects and are used instead of casts and identity
45 * comparisons.</p>
47 * @see com.sun.star.lang.XMultiServiceFactory
48 * @see com.sun.star.container.XSet
49 * @see com.sun.star.container.XContentEnumerationAccess
50 * @see com.sun.star.lang.XComponent
51 * @see com.sun.star.lang.XServiceInfo
52 * @since UDK1.0
54 public class ServiceManager implements XMultiServiceFactory,
55 XMultiComponentFactory,
56 XSet,
57 XContentEnumerationAccess,
58 XComponent,
59 XServiceInfo
61 private static final boolean DEBUG = false;
63 private static final void DEBUG (String dbg) {
64 if (DEBUG) System.err.println( dbg );
67 private static com.sun.star.uno.Type UNO_TYPE = null;
69 static String[] supportedServiceNames = {
70 "com.sun.star.lang.MultiServiceFactory",
71 "com.sun.star.lang.ServiceManager"
74 ArrayList<XEventListener> eventListener;
75 java.util.HashMap<String, Object> factoriesByImplNames;
76 java.util.HashMap<String, ArrayList<Object>> factoriesByServiceNames; // keys:
78 private com.sun.star.uno.XComponentContext m_xDefaultContext;
80 /**
81 * Creates a new instance of the <code>ServiceManager</code>.
83 public ServiceManager() {
84 eventListener = new ArrayList<XEventListener>();
85 factoriesByImplNames = new java.util.HashMap<String, Object>();
86 factoriesByServiceNames = new java.util.HashMap<String, ArrayList<Object>>();
87 m_xDefaultContext = null;
90 public void setDefaultContext(XComponentContext context) {
91 m_xDefaultContext = context;
94 /**
95 * Creates a new instance of a specified service.
97 * <p>Therefore the associated factory of the service is looked up and used
98 * to instantiate a new component. </p>
100 * @param serviceSpecifier indicates the service or component name.
101 * @return newly created component.
103 * @see com.sun.star.lang.XMultiServiceFactory
105 public java.lang.Object createInstance( String serviceSpecifier )
106 throws com.sun.star.uno.Exception,
107 com.sun.star.uno.RuntimeException
109 return createInstanceWithContext( serviceSpecifier, m_xDefaultContext );
113 * Creates a new instance of a specified service with the given parameters.
115 * <p>Therefore the associated factory of the service is looked up and used
116 * to instantiate a new component.</p>
118 * @return newly created component.
119 * @param serviceSpecifier indicates the service or component name.
120 * @see com.sun.star.lang.XMultiServiceFactory
122 public java.lang.Object createInstanceWithArguments(
123 String serviceSpecifier, Object[] args )
124 throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException
126 if (DEBUG) {
127 System.err.println("createInstanceWithArguments:" );
129 for (Object arg : args) {
130 System.err.print(" " + arg);
133 System.err.println();
136 return createInstanceWithArgumentsAndContext( serviceSpecifier, args, m_xDefaultContext );
140 * Look up the factory for a given service or implementation name.
142 * <p>First the requested service name is search in the list of available
143 * services. If it can not be found the name is looked up in the implementation
144 * list.</p>
146 * @param serviceName indicates the service or implementation name.
147 * @return the factory of the service / implementation.
149 * @see com.sun.star.lang.XMultiServiceFactory
151 private Object queryServiceFactory(String serviceName)
152 throws com.sun.star.uno.Exception,
153 com.sun.star.uno.RuntimeException
155 DEBUG("queryServiceFactory for name " + serviceName );
156 Object factory = null;
158 if ( factoriesByServiceNames.containsKey( serviceName ) ) {
159 ArrayList<Object> availableFact = factoriesByServiceNames.get( serviceName );
161 DEBUG("");
162 DEBUG("available factories for " + serviceName +" "+ availableFact);
163 DEBUG("");
165 if ( !availableFact.isEmpty() )
166 factory = availableFact.get(availableFact.size()-1);
168 } else // not found in list of services - now try the implementations
169 factory = factoriesByImplNames.get( serviceName ); // return null if none is available
171 if (DEBUG) {
172 if (factory == null) System.err.println("service not registered");
173 else
174 System.err.println("service found:" + factory + " " + UnoRuntime.queryInterface(XSingleServiceFactory.class, factory));
177 if (factory == null)
178 throw new com.sun.star.uno.Exception("Query for service factory for " + serviceName + " failed.");
180 return factory;
184 * Supplies a list of all available services names.
186 * @return list of Strings of all service names.
187 * @see com.sun.star.container.XContentEnumerationAccess
189 public String[] getAvailableServiceNames()
190 throws com.sun.star.uno.RuntimeException
192 try{
193 return factoriesByServiceNames.keySet().toArray(
194 new String[ factoriesByServiceNames.size() ] );
195 } catch(Exception ex) {
196 throw new com.sun.star.uno.RuntimeException(ex);
200 // XMultiComponentFactory implementation
202 /** Create a service instance with given context.
204 * @param rServiceSpecifier service name.
205 * @param xContext context.
206 * @return service instance.
208 public java.lang.Object createInstanceWithContext(
209 String rServiceSpecifier,
210 com.sun.star.uno.XComponentContext xContext )
211 throws com.sun.star.uno.Exception
213 Object fac = queryServiceFactory( rServiceSpecifier );
214 if (fac != null)
216 XSingleComponentFactory xCompFac = UnoRuntime.queryInterface(
217 XSingleComponentFactory.class, fac );
218 if (xCompFac != null)
220 return xCompFac.createInstanceWithContext( xContext );
222 else
224 XSingleServiceFactory xServiceFac = UnoRuntime.queryInterface(
225 XSingleServiceFactory.class, fac );
226 if (xServiceFac != null)
228 if (DEBUG)
229 System.err.println( "### ignoring context raising service \"" + rServiceSpecifier + "\"!" );
230 return xServiceFac.createInstance();
232 else
234 throw new com.sun.star.uno.Exception(
235 "retrieved service factory object for \"" + rServiceSpecifier +
236 "\" does not export XSingleComponentFactory nor XSingleServiceFactory!" );
240 return null;
243 * Create a service instance with given context and arguments.
245 * @param rServiceSpecifier service name.
246 * @param rArguments arguments.
247 * @param xContext context.
248 * @return service instance.
250 public java.lang.Object createInstanceWithArgumentsAndContext(
251 String rServiceSpecifier,
252 java.lang.Object[] rArguments,
253 com.sun.star.uno.XComponentContext xContext )
254 throws com.sun.star.uno.Exception
256 Object fac = queryServiceFactory( rServiceSpecifier );
257 if (fac != null)
259 XSingleComponentFactory xCompFac = UnoRuntime.queryInterface(
260 XSingleComponentFactory.class, fac );
261 if (xCompFac != null)
263 return xCompFac.createInstanceWithArgumentsAndContext( rArguments, xContext );
265 else
267 XSingleServiceFactory xServiceFac = UnoRuntime.queryInterface(
268 XSingleServiceFactory.class, fac );
269 if (xServiceFac != null)
271 if (DEBUG)
272 System.err.println( "### ignoring context raising service \"" + rServiceSpecifier + "\"!" );
273 return xServiceFac.createInstanceWithArguments( rArguments );
275 else
277 throw new com.sun.star.uno.Exception(
278 "retrieved service factory object for \"" + rServiceSpecifier +
279 "\" does not export XSingleComponentFactory nor XSingleServiceFactory!" );
283 return null;
287 * Removes all listeners from the <code>ServiceManager</code> and clears the
288 * list of the services.
290 * @see com.sun.star.lang.XComponent
292 public void dispose()
293 throws com.sun.star.uno.RuntimeException
295 if (eventListener != null) {
296 for (XEventListener listener : eventListener) {
297 listener.disposing(new com.sun.star.lang.EventObject(this));
299 eventListener.clear();
302 factoriesByServiceNames.clear();
303 factoriesByImplNames.clear();
307 * Adds a new <code>EventListener</code>.
309 * <p>The listener is notified when a service is added (removed) to (from)
310 * the <code>ServiceManager</code>.</p>
312 * <p>If the listener is already registered a
313 * <code>com.sun.star.uno.RuntimeException</code> will be thrown.</p>
315 * @param xListener the new listener which should been added.
316 * @see com.sun.star.lang.XComponent
318 public void addEventListener( XEventListener xListener )
319 throws com.sun.star.uno.RuntimeException
321 if (xListener == null)
322 throw new com.sun.star.uno.RuntimeException("Listener must not be null");
324 if ( eventListener.contains(xListener) )
325 throw new com.sun.star.uno.RuntimeException("Listener already registered.");
327 eventListener.add(xListener);
331 * Removes a <code>EventListener</code> from the <code>ServiceManager</code>.
333 * <p>If the listener is not registered a <code>com.sun.star.uno.RuntimeException</code>
334 * will be thrown.</p>
336 * @param xListener the new listener which should been removed.
337 * @see com.sun.star.lang.XComponent
339 public void removeEventListener( XEventListener xListener )
340 throws com.sun.star.uno.RuntimeException
342 if (xListener == null)
343 throw new com.sun.star.uno.RuntimeException("Listener must not be null");
345 if ( !eventListener.contains(xListener) )
346 throw new com.sun.star.uno.RuntimeException("Listener is not registered.");
348 eventListener.remove(xListener);
352 * Checks if a component is registered at the <code>ServiceManager</code>.
354 * <p>The given object argument must provide a <code>XServiceInfo</code>
355 * interface.</p>
357 * @param object object which provides a <code>XServiceInfo</code> interface.
358 * @return true if the component is registered otherwise false.
360 * @see com.sun.star.container.XSet
361 * @see com.sun.star.lang.XServiceInfo
363 public boolean has( Object object )
364 throws com.sun.star.uno.RuntimeException
366 if (object == null)
367 throw new com.sun.star.uno.RuntimeException("The parameter must not been null");
369 XServiceInfo xServiceInfo = UnoRuntime.queryInterface(XServiceInfo.class, object);
371 return xServiceInfo != null && UnoRuntime.areSame(factoriesByImplNames.get(xServiceInfo.getImplementationName()), object);
375 * Adds a <code>SingleServiceFactory</code> to the <code>ServiceManager</code>.
377 * @param object factory which should be added.
378 * @see com.sun.star.container.XSet
379 * @see com.sun.star.lang.XSingleServiceFactory
381 public void insert( Object object )
382 throws com.sun.star.lang.IllegalArgumentException,
383 com.sun.star.container.ElementExistException,
384 com.sun.star.uno.RuntimeException
386 if (object == null) throw new com.sun.star.lang.IllegalArgumentException();
388 XServiceInfo xServiceInfo =
389 UnoRuntime.queryInterface(XServiceInfo.class, object);
391 if (xServiceInfo == null)
392 throw new com.sun.star.lang.IllegalArgumentException(
393 "The given object does not implement the XServiceInfo interface."
396 if ( factoriesByImplNames.containsKey( xServiceInfo.getImplementationName() ) ) {
397 throw new com.sun.star.container.ElementExistException(
398 xServiceInfo.getImplementationName() + " already registered"
402 DEBUG("add factory " + object.toString() + " for " + xServiceInfo.getImplementationName());
403 factoriesByImplNames.put( xServiceInfo.getImplementationName(), object );
406 String[] serviceNames = xServiceInfo.getSupportedServiceNames();
407 ArrayList<Object> vec ;
409 for (String serviceName : serviceNames) {
410 if (!factoriesByServiceNames.containsKey(serviceName)) {
411 DEBUG("> no registered services found under " + serviceName + ": adding...");
412 factoriesByServiceNames.put(serviceName, new ArrayList<Object>());
414 vec = factoriesByServiceNames.get(serviceName);
415 if (vec.contains( object )) {
416 System.err.println("The implementation " + xServiceInfo.getImplementationName() +
417 " already registered for the service " + serviceName + " - ignoring!");
418 } else {
419 vec.add(object);
425 * Removes a <code>SingleServiceFactory</code> from the <code>ServiceManager</code>.
427 * @param object factory which should be removed.
428 * @see com.sun.star.container.XSet
429 * @see com.sun.star.lang.XSingleServiceFactory
431 public void remove( Object object )
432 throws com.sun.star.lang.IllegalArgumentException,
433 com.sun.star.container.NoSuchElementException,
434 com.sun.star.uno.RuntimeException
436 if (object == null)
437 throw new com.sun.star.lang.IllegalArgumentException(
438 "The given object must not be null."
441 XServiceInfo xServiceInfo =
442 UnoRuntime.queryInterface(XServiceInfo.class, object);
444 if (xServiceInfo == null)
445 throw new com.sun.star.lang.IllegalArgumentException(
446 "The given object does not implement the XServiceInfo interface."
449 XSingleServiceFactory xSingleServiceFactory =
450 UnoRuntime.queryInterface(XSingleServiceFactory.class, object);
452 if (xSingleServiceFactory == null)
453 throw new com.sun.star.lang.IllegalArgumentException(
454 "The given object does not implement the XSingleServiceFactory interface."
457 if ( factoriesByImplNames.remove( xServiceInfo.getImplementationName() ) == null )
458 throw new com.sun.star.container.NoSuchElementException(
459 xServiceInfo.getImplementationName() +
460 " is not registered as an implementation."
463 String[] serviceNames = xServiceInfo.getSupportedServiceNames();
465 for (String serviceName : serviceNames) {
466 if (factoriesByServiceNames.containsKey(serviceName)) {
467 ArrayList<Object> vec = factoriesByServiceNames.get(serviceName);
468 if (!vec.remove(object)) {
469 System.err.println("The implementation " + xServiceInfo.getImplementationName() +
470 " is not registered for the service " + serviceName + " - ignoring!");
472 // remove the vector if no implementations available for the service
473 if (vec.isEmpty()) {
474 factoriesByServiceNames.remove(serviceName);
481 * Provides an enumeration of all registered services.
483 * @return an enumeration of all available services.
484 * @see com.sun.star.container.XEnumerationAccess
486 public XEnumeration createEnumeration()
487 throws com.sun.star.uno.RuntimeException
489 return new ServiceEnumerationImpl( factoriesByImplNames.values().iterator() );
493 * Provides the UNO type of the <code>ServiceManager</code>
495 * @return the UNO type of the <code>ServiceManager</code>.
496 * @see com.sun.star.container.XElementAccess
497 * @see com.sun.star.uno.TypeClass
499 public com.sun.star.uno.Type getElementType()
500 throws com.sun.star.uno.RuntimeException
502 if ( UNO_TYPE == null )
503 UNO_TYPE = new com.sun.star.uno.Type(ServiceManager.class);
505 return UNO_TYPE;
509 * Checks if the any components are registered.
511 * @return true - if the list of the registered components is not empty - otherwise false.
512 * @see com.sun.star.container.XElementAccess
514 public boolean hasElements() {
515 return ! factoriesByImplNames.isEmpty();
519 * Provides an enumeration of all factories for a specified service.
521 * @param serviceName name of the requested service.
522 * @return an enumeration for service name.
523 * @see com.sun.star.container.XContentEnumerationAccess
525 public XEnumeration createContentEnumeration( String serviceName )
526 throws com.sun.star.uno.RuntimeException
528 XEnumeration enumer ;
530 ArrayList<Object> serviceList = factoriesByServiceNames.get(serviceName);
532 if (serviceList != null)
533 enumer = new ServiceEnumerationImpl( serviceList.iterator() );
534 else
535 enumer = new ServiceEnumerationImpl();
537 return enumer;
541 * Returns the implementation name of the <code>ServiceManager</code> component.
543 * @return the class name of the <code>ServiceManager</code>.
544 * @see com.sun.star.lang.XServiceInfo
546 public String getImplementationName()
547 throws com.sun.star.uno.RuntimeException
549 return getClass().getName();
553 * Checks if the <code>ServiceManager</code> supports a service.
555 * @param serviceName service name which should be checked.
556 * @return true if the service is supported - otherwise false.
558 * @see com.sun.star.lang.XServiceInfo
560 public boolean supportsService( String serviceName )
561 throws com.sun.star.uno.RuntimeException
563 for (String supportedServiceName : supportedServiceNames) {
564 if (supportedServiceName.equals(serviceName)) {
565 return true;
569 return getImplementationName().equals(serviceName);
573 * Supplies list of all supported services.
575 * @return a list of all supported service names.
576 * @see com.sun.star.lang.XServiceInfo
578 public String[] getSupportedServiceNames()
579 throws com.sun.star.uno.RuntimeException
581 return supportedServiceNames;
585 * The <code>ServiceEnumerationImpl</code> class provides an
586 * implementation of the @see com.sun.star.container.XEnumeration interface.
588 * <p>It is an inner wrapper for a java.util.Enumeration object.</p>
590 * @see com.sun.star.lang.XSingleServiceFactory
591 * @see com.sun.star.lang.XServiceInfo
592 * @since UDK1.0
594 static class ServiceEnumerationImpl implements XEnumeration {
595 java.util.Iterator<Object> enumeration = null;
598 * Constructs a new empty instance.
600 public ServiceEnumerationImpl() {
604 * Constructs a new instance with a given enumeration.
606 * @param enumer is the enumeration which should been wrapped.
607 * @see com.sun.star.container.XEnumeration
609 public ServiceEnumerationImpl(java.util.Enumeration<Object> enumer) {
610 enumeration = Collections.list(enumer).iterator();
614 * Constructs a new instance with a given enumeration.
616 * @param enumer is the enumeration which should been wrapped.
617 * @see com.sun.star.container.XEnumeration
619 public ServiceEnumerationImpl(java.util.Iterator<Object> enumer) {
620 enumeration = enumer;
624 * Checks if the enumeration contains more elements.
626 * @return true if more elements are available - otherwise false.
627 * @see com.sun.star.container.XEnumeration
629 public boolean hasMoreElements()
630 throws com.sun.star.uno.RuntimeException
632 return enumeration != null && enumeration.hasNext();
637 * Returns the next element of the enumeration.
639 * <p>If no further elements available a com.sun.star.container.NoSuchElementException
640 * exception will be thrown.</p>
642 * @return the next element.
643 * @see com.sun.star.container.XEnumeration
645 public Object nextElement()
646 throws com.sun.star.container.NoSuchElementException,
647 com.sun.star.lang.WrappedTargetException,
648 com.sun.star.uno.RuntimeException
650 if (enumeration == null)
651 throw new com.sun.star.container.NoSuchElementException();
653 try {
654 return enumeration.next();
655 } catch (java.util.NoSuchElementException e) {
656 throw new com.sun.star.container.NoSuchElementException(e, e.toString());
662 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */