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