1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 package com.sun.star.comp.servicemanager;
25 
26 import com.sun.star.uno.UnoRuntime;
27 import com.sun.star.uno.XComponentContext;
28 
29 import com.sun.star.container.XSet;
30 import com.sun.star.container.XContentEnumerationAccess;
31 import com.sun.star.container.XEnumeration;
32 
33 import com.sun.star.lang.XComponent;
34 import com.sun.star.lang.XEventListener;
35 import com.sun.star.lang.XInitialization;
36 import com.sun.star.lang.XMultiServiceFactory;
37 import com.sun.star.lang.XServiceInfo;
38 import com.sun.star.lang.XSingleServiceFactory;
39 import com.sun.star.lang.XSingleComponentFactory;
40 import com.sun.star.lang.XMultiComponentFactory;
41 
42 import com.sun.star.registry.XRegistryKey;
43 import com.sun.star.registry.XSimpleRegistry;
44 
45 import com.sun.star.loader.XImplementationLoader;
46 
47 import java.lang.reflect.InvocationTargetException;
48 
49 /**
50  * The <code>ServiceManager</code> class is an implmentation of the <code>ServiceManager</code>the central class needed for
51  * implementing or using UNO components in Java.
52  * <p>
53  * The Methods <code>queryInterface</code> and <code>isSame</code> delegate
54  * calls to the implementing objects and are used instead of casts
55  * and identity comparisons.
56  * <p>
57  * @version 	$Revision: 1.10 $ $ $Date: 2008-04-11 11:11:46 $
58  * @author 	    Markus Herzog
59  * @see         com.sun.star.lang.XMultiServiceFactory
60  * @see         com.sun.star.container.XSet
61  * @see         com.sun.star.container.XContentEnumerationAccess
62  * @see         com.sun.star.lang.XComponent
63  * @see         com.sun.star.lang.XServiceInfo
64  * @see         com.sun.star.lang.XInitialization
65  * @since       UDK1.0
66  */
67 public class ServiceManager implements XMultiServiceFactory,
68                                        XMultiComponentFactory,
69                                        XSet,
70                                        XContentEnumerationAccess,
71                                        XComponent,
72                                        XServiceInfo,
73 									   XInitialization
74 {
75     private static final boolean DEBUG = false;
76 
DEBUG(String dbg)77     private static final void DEBUG (String dbg) {
78         if (DEBUG) System.err.println( dbg );
79     }
80 
81 	private static com.sun.star.uno.Type UNO_TYPE = null;
82 
83     XImplementationLoader loader = null;
84 
85     static String[] supportedServiceNames = {
86 	        "com.sun.star.lang.MultiServiceFactory",
87 	        "com.sun.star.lang.ServiceManager"
88 	};
89 
90     java.util.Vector    eventListener;
91     java.util.Hashtable factoriesByImplNames;
92     java.util.Hashtable factoriesByServiceNames;  // keys:
93 
94     private com.sun.star.uno.XComponentContext m_xDefaultContext;
95 
96 	/**
97 	 * Creates a new instance of the <code>ServiceManager</code>.
98 	 */
ServiceManager()99     public ServiceManager() {
100         eventListener           = new java.util.Vector();
101         factoriesByImplNames    = new java.util.Hashtable();
102         factoriesByServiceNames = new java.util.Hashtable();
103         m_xDefaultContext = null;
104     }
105 	/**
106 	 * Creates a new instance of the <code>ServiceManager</code>.
107 	 */
ServiceManager( XComponentContext xContext )108     public ServiceManager( XComponentContext xContext ) {
109         eventListener           = new java.util.Vector();
110         factoriesByImplNames    = new java.util.Hashtable();
111         factoriesByServiceNames = new java.util.Hashtable();
112         m_xDefaultContext = xContext;
113     }
114 
115 	/**
116 	 * Returns the service factory for the <code>ServiceManager</code>. If the given implementation name
117 	 * does not equal to the <code>ServiceManagers</code> class name null will be returned.
118 	 * <p>
119 	 * @return     the factory for the <code>ServiceManager</code>.
120 	 * @param      implName		the implementation name of the of the service.
121 	 *                          Must be equal to <code>com.sun.star.comp.servicemanager.ServicManager</code>
122 	 * @param	   multiFactory	refernce of the <code>MultiServiceFactory</code>. This parameter will be ignored.
123 	 * @param	   regKey		the root key of the registry. This parameter will be ignored.
124 	 */
getServiceFactory( String implName, XMultiServiceFactory multiFactory, XRegistryKey regKey)125   	public static XSingleServiceFactory getServiceFactory( String implName,
126 	                                                       XMultiServiceFactory multiFactory,
127 	                                                       XRegistryKey regKey)
128 	{
129 	    if ( implName.equals(ServiceManager.class.getName()) )
130 	        return new ServiceManagerFactory();
131 
132 	    return null;
133 	}
134 
135 
136     /**
137      * Supplies a Java component loader. The loader component must be enlisted at the <code>ServiceManager</code> before.
138      * <p>
139      * @return		a new instance of the Java component loader
140      * @see			com.sun.star.loader.Java
141      */
getLoader()142 	private XImplementationLoader getLoader()
143 				throws 	com.sun.star.uno.Exception,
144                   		com.sun.star.uno.RuntimeException
145     {
146         Object[] param = { this };
147         DEBUG("make loader");
148         Object loaderObj = createInstanceWithArgumentsAndContext(
149             "com.sun.star.loader.Java", param, m_xDefaultContext );
150 
151         if (loaderObj == null)
152         	throw new com.sun.star.uno.Exception("Can get an instance of com.sun.star.loader.Java");
153 
154         return UnoRuntime.queryInterface( XImplementationLoader.class, loaderObj );
155     }
156 
157     /**
158      * Registers a list of components given by their class names.
159      * <p>
160      * @param 	newImpls	list of the components that should be registered, given by their class names.
161      *						If any exception occured during the registration, the process will be canceled.
162      * @see 	com.sun.star.container.XSet
163      */
xaddFactories( String[] newImpls )164     private void xaddFactories( String[] newImpls )
165     				throws com.sun.star.uno.Exception
166     {
167     	for (int i=0; i<newImpls.length; i++) {
168             DEBUG ("try to add " + newImpls[i] );
169             Object newFactory = null;
170 
171             try {
172             	if (loader == null)
173             		loader = getLoader();
174 
175             	newFactory = loader.activate( newImpls[i], null, null, null );
176             }
177 			catch (com.sun.star.uno.Exception e) {
178 
179 //****************************** BEGIN DEPRECATED ******************************************
180 
181 	            try {
182 	                // try to get the class of the implementation
183 	                Class clazz = Class.forName( newImpls[i] );
184 
185 	                Class[] methodClassParam = { String.class, XMultiServiceFactory.class, XRegistryKey.class };
186 	                java.lang.reflect.Method getFactoryMeth  ;
187 	                try {
188 	                	getFactoryMeth = clazz.getMethod("__getServiceFactory", methodClassParam);
189 	            	}
190 	            	catch (NoSuchMethodException noSuchMethodEx) {
191 	            		getFactoryMeth = null;
192 	            	}
193 	            	catch (SecurityException securityExc) {
194 	            		getFactoryMeth = null;
195 	            	}
196 
197 					if (getFactoryMeth == null)
198 	                	getFactoryMeth = clazz.getMethod("getServiceFactory", methodClassParam);
199 
200 	            	Object[] methodParams = { newImpls[i], this, null };
201 	            	newFactory = getFactoryMeth.invoke( clazz, methodParams );
202 	            }
203 	            catch (NoSuchMethodException ex) {}
204 	        	catch (SecurityException ex) {}
205 				catch (ClassNotFoundException ex) {}
206 				catch (IllegalAccessException ex) {}
207 				catch (IllegalArgumentException ex) {}
208 				catch (InvocationTargetException ex) {}
209 
210 //****************************** END DEPRECATED ******************************************
211 			}
212 
213         	if ( newFactory == null )
214         		throw new com.sun.star.loader.CannotActivateFactoryException("Can not get factory for " +  newImpls[i]);
215 
216         	insert( newFactory );
217         } // end of for ...
218     }
219 
220     /**
221      * The method is used to add components to the <code>ServiceManager</code>. The first argument indicates a <code>SimpleRegistry</code>.
222      * The components which should be added will be searched under the <i>Implementations</i> key in the registry.
223      * <p>
224      * @param 	args	the first argument ( args[0] ) specifices the SimpleRegistry object
225      * @see		com.sun.star.lang.XInitialization
226      * @see		com.sun.star.lang.RegistryServiceManager
227      * @see		com.sun.star.lang.XSimpleRegistry
228      */
initialize( Object args[] )229 	public void initialize( Object args[] )
230 				throws 	com.sun.star.uno.Exception,
231 						com.sun.star.uno.RuntimeException {
232 		XSimpleRegistry xSimpleRegistry  ;
233 		try {
234 			xSimpleRegistry = (XSimpleRegistry) args[0];
235             if (xSimpleRegistry != null)
236             {
237                 XRegistryKey rootkey = xSimpleRegistry.getRootKey();
238 
239                 XRegistryKey implkey_xRegistryKey = rootkey.openKey("Implementations");
240                 if(implkey_xRegistryKey != null) {
241                     XRegistryKey xRegistryKeys[] = implkey_xRegistryKey.openKeys();
242 
243                     for(int i = 0; i < xRegistryKeys.length; ++ i) {
244                         xaddFactories(new String[]{xRegistryKeys[i].getStringValue()});
245                     }
246                 }
247             }
248 
249             if (args.length > 1)
250             {
251                 m_xDefaultContext = (XComponentContext)args[ 1 ];
252             }
253 		}
254 		catch (ArrayIndexOutOfBoundsException e)
255         {
256 			throw new com.sun.star.lang.IllegalArgumentException("Argument must not be null.");
257 		}
258 	}
259 
260 	/**
261 	 * Creates a new instance of a specified service. Therefor the associated factory of the service is
262 	 * looked up and used to instanciate a new component.
263 	 * <p>
264 	 * @return	newly created component
265 	 * @param	serviceSpecifier 	indicates the service or component name
266 	 * @see		com.sun.star.lang.XMultiServiceFactory
267 	 */
createInstance( String serviceSpecifier )268     public java.lang.Object createInstance( String serviceSpecifier )
269             throws com.sun.star.uno.Exception,
270                    com.sun.star.uno.RuntimeException
271     {
272         return createInstanceWithContext( serviceSpecifier, m_xDefaultContext );
273 	}
274 
275 	/**
276 	 * Creates a new instance of a specified service with the given parameters.
277 	 * Therefor the associated factory of the service is  looked up and used to instanciate a new component.
278 	 * <p>
279 	 * @return	newly created component
280 	 * @param	serviceSpecifier 	indicates the service or component name
281 	 * @see		com.sun.star.lang.XMultiServiceFactory
282 	 */
createInstanceWithArguments( String serviceSpecifier, Object[] args )283     public java.lang.Object createInstanceWithArguments(
284         String serviceSpecifier, Object[] args )
285         throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException
286     {
287 	    if (DEBUG) {
288 	        System.err.println("createInstanceWithArguments:" );
289 
290 	        for (int i=0; i<args.length; i++)
291 	            System.err.print(" "+ args[i]);
292 
293 	        System.err.println();
294 	    }
295 
296 	    return createInstanceWithArgumentsAndContext( serviceSpecifier, args, m_xDefaultContext );
297 	}
298 
299 	/**
300 	 * Look up the factory for a given service or implementation name.
301 	 * First the requested service name is search in the list of avaible services. If it can not be found
302 	 * the name is looked up in the the implementation list.
303 	 * <p>
304 	 * @return	the factory of the service / implementation
305 	 * @param	serviceSpecifier 	indicates the service or implementation name
306 	 * @see		com.sun.star.lang.XMultiServiceFactory
307 	 */
queryServiceFactory(String serviceName)308 	private Object queryServiceFactory(String serviceName)
309 	        throws com.sun.star.uno.Exception,
310                    com.sun.star.uno.RuntimeException
311 	{
312 	    DEBUG("queryServiceFactory for name " + serviceName );
313 	    Object factory = null;
314 
315 		if ( factoriesByServiceNames.containsKey( serviceName ) ) {
316 		    java.util.Vector aviableFact = (java.util.Vector) factoriesByServiceNames.get( serviceName );
317 
318 		    DEBUG("");
319 		    DEBUG("aviable factories for " + serviceName +" "+ aviableFact);
320 		    DEBUG("");
321 
322 		    if ( !aviableFact.isEmpty() )
323 		        factory = aviableFact.lastElement();
324 
325 		} else // not found in list of services - now try the implementations
326 	        factory = factoriesByImplNames.get( serviceName ); // return null if none is aviable
327 
328 	    if (DEBUG) {
329             if (factory == null) System.err.println("service not registered");
330             else
331                 System.err.println("service found:" + factory + " " + UnoRuntime.queryInterface(XSingleServiceFactory.class, factory));
332         }
333 
334         if (factory == null)
335         	throw new com.sun.star.uno.Exception("Query for service factory for " + serviceName + " failed.");
336 
337         return factory;
338 	}
339 
340 	/**
341 	 * Supplies a list of all avialable services names.
342 	 * <p>
343 	 * @return 	list of Strings of all service names
344 	 * @see 	com.sun.star.container.XContentEnumerationAccess
345 	 */
getAvailableServiceNames()346     public String[] getAvailableServiceNames()
347             throws com.sun.star.uno.RuntimeException
348     {
349         int i = 0;
350         String[] availableServiceNames = new String[factoriesByServiceNames.size()];
351 
352         java.util.Enumeration keys = factoriesByServiceNames.keys();
353 
354         while (keys.hasMoreElements())
355             availableServiceNames[i++] = (String) keys.nextElement();
356 
357 		return availableServiceNames;
358 	}
359 
360     // XMultiComponentFactory implementation
361 
362     /** Create a service instance with given context.
363 
364         @param rServiceSpecifier service name
365         @param xContext context
366         @return service instance
367     */
createInstanceWithContext( String rServiceSpecifier, com.sun.star.uno.XComponentContext xContext )368     public java.lang.Object createInstanceWithContext(
369         String rServiceSpecifier,
370         com.sun.star.uno.XComponentContext xContext )
371         throws com.sun.star.uno.Exception
372     {
373 	    Object fac = queryServiceFactory( rServiceSpecifier );
374         if (fac != null)
375         {
376             XSingleComponentFactory xCompFac = UnoRuntime.queryInterface(
377                 XSingleComponentFactory.class, fac );
378             if (xCompFac != null)
379             {
380                 return xCompFac.createInstanceWithContext( xContext );
381             }
382             else
383             {
384                 XSingleServiceFactory xServiceFac = UnoRuntime.queryInterface(
385                     XSingleServiceFactory.class, fac );
386                 if (xServiceFac != null)
387                 {
388                     if (DEBUG)
389                         System.err.println( "### ignoring context raising service \"" + rServiceSpecifier + "\"!" );
390                     return xServiceFac.createInstance();
391                 }
392                 else
393                 {
394                     throw new com.sun.star.uno.Exception(
395                         "retrieved service factory object for \"" + rServiceSpecifier +
396                         "\" does not export XSingleComponentFactory nor XSingleServiceFactory!" );
397                 }
398             }
399         }
400         return null;
401     }
402     /** Create a service instance with given context and arguments.
403 
404         @param rServiceSpecifier service name
405         @param rArguments arguments
406         @param xContext context
407         @return service instance
408     */
createInstanceWithArgumentsAndContext( String rServiceSpecifier, java.lang.Object[] rArguments, com.sun.star.uno.XComponentContext xContext )409     public java.lang.Object createInstanceWithArgumentsAndContext(
410         String rServiceSpecifier,
411         java.lang.Object[] rArguments,
412         com.sun.star.uno.XComponentContext xContext )
413         throws com.sun.star.uno.Exception
414     {
415 	    Object fac = queryServiceFactory( rServiceSpecifier );
416         if (fac != null)
417         {
418             XSingleComponentFactory xCompFac = UnoRuntime.queryInterface(
419                 XSingleComponentFactory.class, fac );
420             if (xCompFac != null)
421             {
422                 return xCompFac.createInstanceWithArgumentsAndContext( rArguments, xContext );
423             }
424             else
425             {
426                 XSingleServiceFactory xServiceFac = UnoRuntime.queryInterface(
427                     XSingleServiceFactory.class, fac );
428                 if (xServiceFac != null)
429                 {
430                     if (DEBUG)
431                         System.err.println( "### ignoring context raising service \"" + rServiceSpecifier + "\"!" );
432                     return xServiceFac.createInstanceWithArguments( rArguments );
433                 }
434                 else
435                 {
436                     throw new com.sun.star.uno.Exception(
437                         "retrieved service factory object for \"" + rServiceSpecifier +
438                         "\" does not export XSingleComponentFactory nor XSingleServiceFactory!" );
439                 }
440             }
441         }
442         return null;
443     }
444 //      public String[] getAvailableServiceNames();
445 
446 	/**
447 	 * Removes all listeners from the <code>ServiceManager</code> and clears the list of the services.
448 	 * <p>
449 	 * @see	com.sun.star.lang.XComponent
450 	 */
dispose()451     public void dispose()
452         throws com.sun.star.uno.RuntimeException
453     {
454         if (eventListener != null) {
455             java.util.Enumeration enumer = eventListener.elements();
456 
457             while (enumer.hasMoreElements()) {
458                 XEventListener listener = (XEventListener) enumer.nextElement();
459                 listener.disposing(new com.sun.star.lang.EventObject(this));
460             }
461             eventListener.removeAllElements();
462         }
463 
464         factoriesByServiceNames.clear();
465         factoriesByImplNames.clear();
466 	}
467 
468 	/**
469 	 * Adds a new <code>EventListener</code>. The listener is notified when a
470 	 * service is added (removed) to (from) the <code>ServiceManager</code>.
471 	 * If the listener is already registred a
472 	 * <code>com.sun.star.uno.RuntimeException</code> will be thrown.
473 	 * <p>
474 	 * @param 	xListener	the new listener which should been added.
475 	 * @see		com.sun.star.lang.XComponent
476 	 */
addEventListener( XEventListener xListener )477     public void addEventListener( XEventListener xListener )
478             throws com.sun.star.uno.RuntimeException
479     {
480         if (xListener == null)
481         	throw new com.sun.star.uno.RuntimeException("Listener must not be null");
482 
483   		if ( eventListener.contains(xListener) )
484   			throw new com.sun.star.uno.RuntimeException("Listener already registred.");
485 
486        	eventListener.addElement(xListener);
487 	}
488 
489 	/**
490 	 * Removes a <code>EventListener</code> from the <code>ServiceManager</code>.
491 	 * If the listener is not registered a <code>com.sun.star.uno.RuntimeException</code>
492 	 * will be thrown.
493 	 * <p>
494 	 * @param 	xListener	the new listener which should been removed.
495 	 * @see	com.sun.star.lang.XComponent
496 	 */
removeEventListener( XEventListener xListener )497     public void removeEventListener( XEventListener xListener )
498             throws com.sun.star.uno.RuntimeException
499     {
500         if (xListener == null)
501         	throw new com.sun.star.uno.RuntimeException("Listener must not be null");
502 
503   		if ( !eventListener.contains(xListener) )
504   			throw new com.sun.star.uno.RuntimeException("Listener is not registered.");
505 
506         eventListener.removeElement(xListener);
507 	}
508 
509 	/**
510 	 * Checks if a component is registered at the <code>ServiceManager</code>. The given object argument must
511 	 * provide a <code>XServiceInfo</code> interface.
512 	 * <p>
513 	 * @return 	true if the component is registred otherwise false.
514 	 * @param	object object which provides a <code>XServiceInfo</code> interface.
515 	 * @see		com.sun.star.container.XSet
516 	 * @see		com.sun.star.lang.XServiceInfo
517 	 */
has( Object object )518     public boolean has( Object object )
519         throws com.sun.star.uno.RuntimeException
520     {
521             if (object == null)
522             	throw new com.sun.star.uno.RuntimeException("The parameter must not been null");
523 
524             XServiceInfo xServiceInfo = UnoRuntime.queryInterface(XServiceInfo.class, object);
525 
526         return xServiceInfo != null && UnoRuntime.areSame(factoriesByImplNames.get(xServiceInfo.getImplementationName()), object);
527 
528 		}
529 
530     /**
531      * Adds a <code>SingleServiceFactory</code> to the <code>ServiceManager</code>.
532      * <p>
533      * @param	object	factory which should be added.
534      * @see com.sun.star.container.XSet
535      * @see	com.sun.star.lang.XSingleServiceFactory
536      */
insert( Object object )537     public void insert( Object object )
538         throws com.sun.star.lang.IllegalArgumentException,
539                com.sun.star.container.ElementExistException,
540                com.sun.star.uno.RuntimeException
541     {
542         if (object == null) throw new com.sun.star.lang.IllegalArgumentException();
543 
544         XServiceInfo xServiceInfo =
545                 UnoRuntime.queryInterface(XServiceInfo.class, object);
546 
547         if (xServiceInfo == null)
548             throw new com.sun.star.lang.IllegalArgumentException(
549                 "The given object does not implement the XServiceInfo interface."
550             );
551 
552         if ( factoriesByImplNames.containsKey( xServiceInfo.getImplementationName() ) ) {
553             throw new com.sun.star.container.ElementExistException(
554                 xServiceInfo.getImplementationName() + " already registred"
555             );
556         }
557 
558         DEBUG("add factory " + object.toString() + " for " + xServiceInfo.getImplementationName());
559         factoriesByImplNames.put( xServiceInfo.getImplementationName(), object );
560 
561 
562         String[] serviceNames = xServiceInfo.getSupportedServiceNames();
563         java.util.Vector vec  ;
564 
565         for (int i=0; i<serviceNames.length; i++) {
566             if ( !factoriesByServiceNames.containsKey( serviceNames[i] ) ) {
567             	DEBUG("> no registered services found under " + serviceNames[i] + ": adding..." );
568                 factoriesByServiceNames.put(serviceNames[i], new java.util.Vector());
569             }
570 
571             vec = (java.util.Vector) factoriesByServiceNames.get( serviceNames[i] );
572 
573             if ( vec.contains( object ) )
574                 System.err.println("The implementation " + xServiceInfo.getImplementationName() +
575                     " already registered for the service " + serviceNames[i] + " - ignoring!");
576             else
577                 vec.addElement(object);
578         }
579 	}
580 
581     /**
582      * Removes a <code>SingleServiceFactory</code> from the <code>ServiceManager</code>.
583      * <p>
584      * @param	object	factory which should be removed.
585      * @see com.sun.star.container.XSet
586      * @see	com.sun.star.lang.XSingleServiceFactory
587      */
remove( Object object )588     public void remove( Object object )
589         throws com.sun.star.lang.IllegalArgumentException,
590                com.sun.star.container.NoSuchElementException,
591                com.sun.star.uno.RuntimeException
592     {
593         if (object == null)
594             throw new com.sun.star.lang.IllegalArgumentException(
595                     "The given object must not be null."
596             );
597 
598         XServiceInfo xServiceInfo =
599             UnoRuntime.queryInterface(XServiceInfo.class, object);
600 
601         if (xServiceInfo == null)
602             throw new com.sun.star.lang.IllegalArgumentException(
603                     "The given object does not implement the XServiceInfo interface."
604             );
605 
606         XSingleServiceFactory xSingleServiceFactory =
607             UnoRuntime.queryInterface(XSingleServiceFactory.class, object);
608 
609         if (xSingleServiceFactory == null)
610             throw new com.sun.star.lang.IllegalArgumentException(
611                     "The given object does not implement the XSingleServiceFactory interface."
612             );
613 
614         if ( factoriesByImplNames.remove( xServiceInfo.getImplementationName() ) == null )
615             throw new com.sun.star.container.NoSuchElementException(
616                     xServiceInfo.getImplementationName() +
617                     " is not registered as an implementation."
618             );
619 
620         String[] serviceNames = xServiceInfo.getSupportedServiceNames();
621 
622         for ( int i=0; i<serviceNames.length; i++ ) {
623             if ( factoriesByServiceNames.containsKey( serviceNames[i] ) ) {
624                 java.util.Vector vec = (java.util.Vector) factoriesByServiceNames.get(serviceNames[i]);
625 
626                 if ( !vec.removeElement(object) )
627                     System.err.println("The implementation " + xServiceInfo.getImplementationName() +
628                         " is not registered for the service " + serviceNames[i] + " - ignoring!");
629 
630                 if ( vec.isEmpty() ) // remove the vector if no implementations aviable for the service
631                     factoriesByServiceNames.remove( serviceNames[i] );
632             }
633         }
634 	}
635 
636     /**
637      * Provides an enumeration of all registred services.
638      * <p>
639      * @return 	an enumeration of all avialable services.
640      * @see 	com.sun.star.conatiner.XEnumerationAccess
641      */
createEnumeration()642     public XEnumeration createEnumeration()
643             throws com.sun.star.uno.RuntimeException
644     {
645         return new ServiceEnumerationImpl( factoriesByImplNames.elements() );
646 	}
647 
648 	/**
649 	 * Provides the UNO type of the <code>ServiceManager</code>
650 	 * <p>
651 	 * @return 	the UNO type of the <code>ServiceManager</code>.
652 	 * @see 	com.sun.star.container.XElementAccess
653 	 * @see		com.sun.star.uno.TypeClass
654 	 */
getElementType()655     public com.sun.star.uno.Type getElementType()
656             throws com.sun.star.uno.RuntimeException
657     {
658     	if ( UNO_TYPE == null )
659 			UNO_TYPE = new com.sun.star.uno.Type(ServiceManager.class);
660 
661 		return UNO_TYPE;
662 	}
663 
664 	/**
665      * Checks if the any componets are registered.
666 	 * <p>
667 	 * @return	true - if the list of the registred components is not empty - otherwise false.
668 	 * @see		com.sun.star.container.XElementAccess
669 	 */
hasElements()670     public boolean hasElements() {
671 		return ! factoriesByImplNames.isEmpty();
672 	}
673 
674 	/**
675 	 * Provides an enumeration of of all factorys for a specified service.
676 	 * <p>
677 	 * @return	an enumeration for service name.
678 	 * @param	serviceName		name of the requested service
679 	 * @see 	com.sun.star.container.XContentEnumerationAccess
680 	 */
createContentEnumeration( String serviceName )681     public XEnumeration createContentEnumeration( String serviceName )
682                 throws com.sun.star.uno.RuntimeException
683     {
684         XEnumeration enumer  ;
685 
686         java.util.Vector serviceList = (java.util.Vector) factoriesByServiceNames.get(serviceName);
687 
688         if (serviceList != null)
689             enumer = new ServiceEnumerationImpl( serviceList.elements() );
690         else
691             enumer = new ServiceEnumerationImpl();
692 
693         return enumer;
694 	}
695 
696 	/**
697 	 * Returns the implementation name of the <code>ServiceManager</code> component.
698 	 * <p>
699 	 * @return	the class name of the <code>ServiceManager</code>.
700 	 * @see		com.sun.star.lang.XServiceInfo
701 	 */
getImplementationName()702     public String getImplementationName()
703             throws com.sun.star.uno.RuntimeException
704     {
705 		return getClass().getName();
706 	}
707 
708 	/**
709 	 * Checks if the <code>ServiceManager</code> supports a service.
710 	 * <p>
711 	 * @return	true if the service is supported - otherwise false.
712 	 * @param	serviceName	service name which should be checked.
713 	 * @see		com.sun.star.lang.XServiceInfo
714 	 */
supportsService( String serviceName )715     public boolean supportsService( String serviceName )
716             throws com.sun.star.uno.RuntimeException
717     {
718         for (int i=0; i<supportedServiceNames.length; i++)
719             if (supportedServiceNames[i].equals( serviceName )) return true;
720 
721         return getImplementationName().equals(serviceName);
722 
723         }
724 
725 	/**
726 	 * Supplies list of all supported services.
727 	 * <p>
728 	 * @return	a list of all supported service names.
729 	 * @see		com.sun.star.lang.XServiceInfo
730 	 */
getSupportedServiceNames()731 	public String[] getSupportedServiceNames()
732 	        throws com.sun.star.uno.RuntimeException
733 	{
734 	    return supportedServiceNames;
735 	}
736 
737 	/**
738 	 * The <code>ServiceEnumerationImpl</code> class provides an
739 	 * implementation of the @see com.sun.star.container.XEnumeration interface.
740 	 * It is a inner wrapper for a java.util.Enumeration object.
741 	 * <p>
742 	 * @version 	$Revision: 1.10 $ $ $Date: 2008-04-11 11:11:46 $
743 	 * @author 	    Markus Herzog
744 	 * @see         com.sun.star.lang.XSingleServiceFactory
745 	 * @see         com.sun.star.lang.XServiceInfo
746 	 * @since       UDK1.0
747 	 */
748 	class ServiceEnumerationImpl implements XEnumeration {
749 	    java.util.Enumeration enumeration = null;
750 
751 		/**
752 		 * Constructs a new empty instance.
753 		 */
ServiceEnumerationImpl()754         public ServiceEnumerationImpl() {
755         }
756 
757 		/**
758 		 * Constructs a new instance with a given enumeration.
759 		 * <p>
760 		 * @param	enumer	is the enumeration which should been wrapped.
761 		 * @see		com.sun.star.container.XEnumeration
762 		 */
ServiceEnumerationImpl(java.util.Enumeration enumer)763         public ServiceEnumerationImpl(java.util.Enumeration enumer) {
764             enumeration = enumer;
765         }
766 
767 		/**
768 		 * Checks if the enumeration contains more elements.
769 		 * <p>
770 		 * @return	true if more elements are available - otherwise false.
771 		 * @see		com.sun.star.container.XEnumeration
772 		 */
hasMoreElements()773         public boolean hasMoreElements()
774                 throws com.sun.star.uno.RuntimeException
775         {
776             return enumeration != null && enumeration.hasMoreElements();
777 
778             }
779 
780 		/**
781 		 * Returns the next element of the enumeration. If no further elements
782 		 * available a com.sun.star.container.NoSuchElementException exception will be thrown.
783 		 * <p>
784 		 * @return	the next element.
785 		 * @see		com.sun.star.container.XEnumeration
786 		 */
nextElement()787         public Object nextElement()
788                 throws com.sun.star.container.NoSuchElementException,
789                        com.sun.star.lang.WrappedTargetException,
790                        com.sun.star.uno.RuntimeException
791         {
792             if (enumeration == null)
793                 throw new com.sun.star.container.NoSuchElementException();
794 
795             try {
796                 return enumeration.nextElement();
797             } catch (java.util.NoSuchElementException e) {
798                 com.sun.star.container.NoSuchElementException ex =
799                         new com.sun.star.container.NoSuchElementException();
800                 ex.fillInStackTrace();
801 
802                 throw ex;
803             }
804         }
805     }
806 }
807 /**
808  * The <code>ServiceManagerFactory</code> is the factory class for the
809  * <code>ServiceManager</code>. As all factories it implments the
810  * com.sun.star.lang.XSingleServiceFactory and the com.sun.star.lang.XServiceInfo
811  * interfaces.
812  * <p>
813  * @version 	$Revision: 1.10 $ $ $Date: 2008-04-11 11:11:46 $
814  * @author 	    Markus Herzog
815  * @see         com.sun.star.lang.XSingleServiceFactory
816  * @see         com.sun.star.lang.XServiceInfo
817  * @since       UDK1.0
818 */
819 class ServiceManagerFactory implements 	XServiceInfo, XSingleComponentFactory, XSingleServiceFactory
820 {
821 	/**
822 	 * Creates a new instance of the <code>ServiceManagerFactory</code>.
823 	 */
ServiceManagerFactory()824     public ServiceManagerFactory() {
825     }
826 
827 	/**
828 	 * Supplies the implementation name of the <code>ServiceManager</code>.
829 	 * <p>
830 	 * @return		<code>ServiceManager</code> class name.
831  	 * @see         com.sun.star.lang.XServiceInfo
832 	 */
getImplementationName()833     public String getImplementationName()
834             throws com.sun.star.uno.RuntimeException
835     {
836         return ServiceManager.class.getName();
837     }
838 
839 	/**
840 	 * Checks wether or not a service is supported.
841 	 * <p>
842 	 * @return 		true - if the service is supported, otherwise false.
843 	 * @param		serviceName		the name of the service that should be checked.
844  	 * @see         com.sun.star.lang.XServiceInfo
845 	 */
supportsService( String serviceName )846     public boolean supportsService( String serviceName )
847             throws com.sun.star.uno.RuntimeException
848     {
849         for ( int i=0; i<ServiceManager.supportedServiceNames.length; i++ )
850             if ( ServiceManager.supportedServiceNames[i].equals(serviceName) ) return true;
851 
852         return getImplementationName().equals(serviceName);
853 
854         }
855 
856 	/**
857 	 * Returns all service names which are supported by <code>ServiceManager</code>.
858 	 * <p>
859 	 * @return		a list aof all supported service names.
860  	 * @see         com.sun.star.lang.XServiceInfo
861 	 */
getSupportedServiceNames()862     public String[] getSupportedServiceNames()
863             throws com.sun.star.uno.RuntimeException
864     {
865         return ServiceManager.supportedServiceNames;
866     }
867 
868 	/**
869 	 * Creates a new instance of the <code>ServiceManager</code>.
870 	 * <p>
871 	 * @return		newly created <code>ServiceManager</code> object.
872  	 * @see         com.sun.star.lang.XSingleServiceFactory
873 	 */
createInstance()874     public java.lang.Object createInstance()
875             throws com.sun.star.uno.Exception,
876                    com.sun.star.uno.RuntimeException
877     {
878         return new ServiceManager();
879     }
880 
881 	/**
882 	 * Creates a new instance of the <code>ServiceManager</code> with arguments.
883 	 * At this time it always throws a com.sun.star.lang.NoSuchMethodException
884 	 * because there is no the <code>ServiceManager</code> has no constructor with
885 	 * arguments.
886 	 * <p>
887 	 * @return		null - allways throws an exception
888 	 * @param		aArguments arguments for new instance.
889  	 * @see         com.sun.star.lang.XSingleServiceFactory
890 	 */
createInstanceWithArguments( java.lang.Object[] aArguments )891     public java.lang.Object createInstanceWithArguments( java.lang.Object[] aArguments )
892             throws com.sun.star.uno.Exception,
893                    com.sun.star.uno.RuntimeException
894     {
895         throw new com.sun.star.lang.NoSuchMethodException("Constructor with arguments is not supported.");
896     }
897 
898     // XSingleComponentFactory impl
899     //______________________________________________________________________________________________
createInstanceWithContext( XComponentContext xContext )900     public Object createInstanceWithContext( XComponentContext xContext )
901         throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException
902     {
903         return new ServiceManager( xContext );
904     }
905     //______________________________________________________________________________________________
createInstanceWithArgumentsAndContext( Object aArguments [], XComponentContext xContext )906     public Object createInstanceWithArgumentsAndContext(
907         Object aArguments [], XComponentContext xContext )
908         throws com.sun.star.uno.Exception, com.sun.star.uno.RuntimeException
909     {
910         throw new com.sun.star.lang.NoSuchMethodException(
911             "ServiceManagerFactory.createInstanceWithArgumentsAndContext() not impl!" );
912     }
913 }
914 
915 
916