1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.modeler;
19
20
21 import java.io.File;
22 import java.io.FileInputStream;
23 import java.io.InputStream;
24 import java.net.URL;
25 import java.util.ArrayList;
26 import java.util.Enumeration;
27 import java.util.HashMap;
28 import java.util.Hashtable;
29 import java.util.Iterator;
30 import java.util.List;
31 import java.util.Collections;
32 import java.util.Map;
33
34 import javax.management.DynamicMBean;
35 import javax.management.MBeanAttributeInfo;
36 import javax.management.MBeanInfo;
37 import javax.management.MBeanOperationInfo;
38 import javax.management.MBeanRegistration;
39 import javax.management.MBeanServer;
40 import javax.management.MBeanServerFactory;
41 import javax.management.MalformedObjectNameException;
42 import javax.management.ObjectName;
43 import javax.management.modelmbean.ModelMBean;
44
45 import org.apache.commons.logging.Log;
46 import org.apache.commons.logging.LogFactory;
47 import org.apache.commons.modeler.modules.ModelerSource;
48
49
50
51
52
53
54
55
56
57
58
59 /***
60 * Registry for modeler MBeans.
61 *
62 * This is the main entry point into modeler. It provides methods to create
63 * and manipulate model mbeans and simplify their use.
64 *
65 * Starting with version 1.1, this is no longer a singleton and the static
66 * methods are strongly deprecated. In a container environment we can expect
67 * different applications to use different registries.
68 *
69 * This class is itself an mbean.
70 *
71 * IMPORTANT: public methods not marked with @since x.x are experimental or
72 * internal. Should not be used.
73 *
74 * @author Craig R. McClanahan
75 * @author Costin Manolache
76 */
77 public class Registry implements RegistryMBean, MBeanRegistration {
78 /*** Experimental support for manifest-based discovery.
79 */
80 public static String MODELER_MANIFEST="/META-INF/mbeans-descriptors.xml";
81
82 /***
83 * The Log instance to which we will write our log messages.
84 */
85 private static Log log = LogFactory.getLog(Registry.class);
86
87
88
89 /*** Will be used to isolate different apps and enhance security
90 */
91 private static HashMap perLoaderRegistries=null;
92
93 /***
94 * The registry instance created by our factory method the first time
95 * it is called.
96 */
97 private static Registry registry = null;
98
99
100
101 /***
102 * The <code>MBeanServer</code> instance that we will use to register
103 * management beans.
104 */
105 private MBeanServer server = null;
106
107 /***
108 * The set of ManagedBean instances for the beans this registry
109 * knows about, keyed by name.
110 */
111 private final HashMap descriptors = new HashMap();
112
113 /*** List of managed byeans, keyed by class name
114 */
115 private final HashMap descriptorsByClass = new HashMap();
116
117
118 private final Map searchedPaths= Collections.synchronizedMap(new HashMap());
119
120 private Object guard;
121
122
123 private Hashtable idDomains=new Hashtable();
124 private Hashtable ids=new Hashtable();
125
126
127
128
129 /***
130 */
131 public Registry() {
132 super();
133 }
134
135
136
137
138 /***
139 * Factory method to create (if necessary) and return our
140 * <code>Registry</code> instance.
141 *
142 * Use this method to obtain a Registry - all other static methods
143 * are deprecated and shouldn't be used.
144 *
145 * The current version uses a static - future versions could use
146 * the thread class loader.
147 *
148 * @param key Support for application isolation. If null, the context class
149 * loader will be used ( if setUseContextClassLoader is called ) or the
150 * default registry is returned.
151 * @param guard Prevent access to the registry by untrusted components
152 *
153 * @since 1.1
154 */
155 public synchronized static Registry getRegistry(Object key, Object guard) {
156 Registry localRegistry;
157 if( perLoaderRegistries!=null ) {
158 if( key==null )
159 key=Thread.currentThread().getContextClassLoader();
160 if( key != null ) {
161 localRegistry=(Registry)perLoaderRegistries.get(key);
162 if( localRegistry == null ) {
163 localRegistry=new Registry();
164 localRegistry.guard=guard;
165 perLoaderRegistries.put( key, localRegistry );
166 return localRegistry;
167 }
168 if( localRegistry.guard != null &&
169 localRegistry.guard != guard ) {
170 return null;
171 }
172 return localRegistry;
173 }
174 }
175
176
177 if (registry == null) {
178 registry = new Registry();
179 }
180 if( registry.guard != null &&
181 registry.guard != guard ) {
182 return null;
183 }
184 return (registry);
185 }
186
187 /*** Allow containers to isolate apps. Can be called only once.
188 * It is highly recommended you call this method if using Registry in
189 * a container environment. The default is false for backward compatibility
190 *
191 * @param enable
192 * @since 1.1
193 */
194 public static void setUseContextClassLoader( boolean enable ) {
195 if( enable ) {
196 perLoaderRegistries=new HashMap();
197 }
198 }
199
200
201
202 /*** Set a guard object that will prevent access to this registry
203 * by unauthorized components
204 *
205 * @param guard
206 *
207 * @since 1.1
208 */
209 public void setGuard( Object guard ) {
210 if( this.guard!=null ) {
211 return;
212 }
213 this.guard=guard;
214 }
215
216 /*** Lifecycle method - clean up the registry metadata.
217 *
218 * @since 1.1
219 */
220 public void stop() {
221 synchronized(descriptors) {
222 descriptorsByClass.clear();
223 descriptors.clear();
224 searchedPaths.clear();
225 }
226 }
227
228 /***
229 * Load an extended mlet file. The source can be an URL, File or
230 * InputStream.
231 *
232 * All mbeans will be instantiated, registered and the attributes will be
233 * set. The result is a list of ObjectNames.
234 *
235 * @param source InputStream or URL of the file
236 * @param cl ClassLoader to be used to load the mbeans, or null to use the
237 * default JMX mechanism ( i.e. all registered loaders )
238 * @return List of ObjectName for the loaded mbeans
239 * @throws Exception
240 *
241 * @since 1.1
242 */
243 public List loadMBeans( Object source, ClassLoader cl )
244 throws Exception
245 {
246 return load("MbeansSource", source, null );
247 }
248
249
250 /*** Load descriptors. The source can be a File or URL or InputStream for the
251 * descriptors file. In the case of File and URL, if the extension is ".ser"
252 * a serialized version will be loaded.
253 *
254 * Also ( experimental for now ) a ClassLoader - in which case META-INF/ will
255 * be used.
256 *
257 * This method should be used to explicitely load metadata - but this is not
258 * required in most cases. The registerComponent() method will find metadata
259 * in the same pacakge.
260 *
261 * @param source
262 */
263 public void loadMetadata(Object source ) throws Exception {
264 if( source instanceof ClassLoader ) {
265 loadMetaInfDescriptors((ClassLoader)source);
266 } else {
267 loadDescriptors( null, source, null );
268 }
269
270 }
271
272 /*** Register a bean by creating a modeler mbean and adding it to the
273 * MBeanServer.
274 *
275 * If metadata is not loaded, we'll look up and read a file named
276 * "mbeans-descriptors.ser" or "mbeans-descriptors.xml" in the same package
277 * or parent.
278 *
279 * If the bean is an instance of DynamicMBean. it's metadata will be converted
280 * to a model mbean and we'll wrap it - so modeler services will be supported
281 *
282 * If the metadata is still not found, introspection will be used to extract
283 * it automatically.
284 *
285 * If an mbean is already registered under this name, it'll be first
286 * unregistered.
287 *
288 * If the component implements MBeanRegistration, the methods will be called.
289 * If the method has a method "setRegistry" that takes a RegistryMBean as
290 * parameter, it'll be called with the current registry.
291 *
292 *
293 * @param bean Object to be registered
294 * @param oname Name used for registration
295 * @param type The type of the mbean, as declared in mbeans-descriptors. If
296 * null, the name of the class will be used. This can be used as a hint or
297 * by subclasses.
298 *
299 * @since 1.1
300 */
301 public void registerComponent(Object bean, String oname, String type)
302 throws Exception
303 {
304 registerComponent(bean, new ObjectName(oname), type);
305 }
306
307 /*** Unregister a component. We'll first check if it is registered,
308 * and mask all errors. This is mostly a helper.
309 *
310 * @param oname
311 *
312 * @since 1.1
313 */
314 public void unregisterComponent( String oname ) {
315 try {
316 unregisterComponent(new ObjectName(oname));
317 } catch (MalformedObjectNameException e) {
318 log.info("Error creating object name " + e );
319 }
320 }
321
322
323 /*** Invoke a operation on a list of mbeans. Can be used to implement
324 * lifecycle operations.
325 *
326 * @param mbeans list of ObjectName on which we'll invoke the operations
327 * @param operation Name of the operation ( init, start, stop, etc)
328 * @param failFirst If false, exceptions will be ignored
329 * @throws Exception
330 * @since 1.1
331 */
332 public void invoke( List mbeans, String operation, boolean failFirst )
333 throws Exception
334 {
335 if( mbeans==null ) {
336 return;
337 }
338 Iterator itr=mbeans.iterator();
339 while(itr.hasNext()) {
340 Object current=itr.next();
341 ObjectName oN=null;
342 try {
343 if( current instanceof ObjectName) {
344 oN=(ObjectName)current;
345 }
346 if( current instanceof String ) {
347 oN=new ObjectName( (String)current );
348 }
349 if( oN==null ) {
350 continue;
351 }
352 if( getMethodInfo(oN, operation) == null) {
353 continue;
354 }
355 getMBeanServer().invoke(oN, operation,
356 new Object[] {}, new String[] {});
357
358 } catch( Exception t ) {
359 if( failFirst ) throw t;
360 log.info("Error initializing " + current + " " + t.toString());
361 }
362 }
363 }
364
365
366
367 /*** Return an int ID for faster access. Will be used for notifications
368 * and for other operations we want to optimize.
369 *
370 * @param domain Namespace
371 * @param name Type of the notification
372 * @return An unique id for the domain:name combination
373 * @since 1.1
374 */
375 public synchronized int getId( String domain, String name) {
376 if( domain==null) {
377 domain="";
378 }
379 Hashtable domainTable=(Hashtable)idDomains.get( domain );
380 if( domainTable == null ) {
381 domainTable=new Hashtable();
382 idDomains.put( domain, domainTable);
383 }
384 if( name==null ) {
385 name="";
386 }
387 Integer i=(Integer)domainTable.get(name);
388
389 if( i!= null ) {
390 return i.intValue();
391 }
392
393 int id[]=(int [])ids.get( domain );
394 if( id == null ) {
395 id=new int[1];
396 ids.put( domain, id);
397 }
398 int code=id[0]++;
399 domainTable.put( name, new Integer( code ));
400 return code;
401 }
402
403
404
405
406 /***
407 * Add a new bean metadata to the set of beans known to this registry.
408 * This is used by internal components.
409 *
410 * @param bean The managed bean to be added
411 * @since 1.0
412 */
413 public void addManagedBean(ManagedBean bean) {
414
415 synchronized(descriptors) {
416 descriptors.put(bean.getName(), bean);
417 if( bean.getType() != null ) {
418 descriptorsByClass.put( bean.getType(), bean );
419 }
420 }
421 }
422
423
424 /***
425 * Find and return the managed bean definition for the specified
426 * bean name, if any; otherwise return <code>null</code>.
427 *
428 * @param name Name of the managed bean to be returned. Since 1.1, both
429 * short names or the full name of the class can be used.
430 * @since 1.0
431 */
432 public ManagedBean findManagedBean(String name) {
433
434 synchronized(descriptors) {
435 ManagedBean mb=((ManagedBean) descriptors.get(name));
436 if( mb==null )
437 mb=(ManagedBean)descriptorsByClass.get(name);
438 return mb;
439 }
440 }
441
442 /***
443 * Return the set of bean names for all managed beans known to
444 * this registry.
445 *
446 * @since 1.0
447 */
448 public String[] findManagedBeans() {
449 synchronized(descriptors) {
450 return ((String[]) descriptors.keySet().toArray(new String[0]));
451 }
452 }
453
454
455 /***
456 * Return the set of bean names for all managed beans known to
457 * this registry that belong to the specified group.
458 *
459 * @param group Name of the group of interest, or <code>null</code>
460 * to select beans that do <em>not</em> belong to a group
461 * @since 1.0
462 */
463 public String[] findManagedBeans(String group) {
464
465 ArrayList results = new ArrayList();
466 synchronized (descriptors) {
467 for (Iterator items = descriptors.values().iterator(); items.hasNext(); ) {
468 ManagedBean item = (ManagedBean) items.next();
469 if (group == null) {
470 if (item.getGroup() == null) {
471 results.add(item.getName());
472 }
473 } else if (group.equals(item.getGroup())) {
474 results.add(item.getName());
475 }
476 }
477 }
478 String values[] = new String[results.size()];
479 return ((String[]) results.toArray(values));
480
481 }
482
483
484 /***
485 * Remove an existing bean from the set of beans known to this registry.
486 *
487 * @param bean The managed bean to be removed
488 * @since 1.0
489 */
490 public void removeManagedBean(ManagedBean bean) {
491
492 synchronized (descriptors) {
493 descriptors.remove(bean.getName());
494 descriptorsByClass.remove( bean.getType());
495 }
496 }
497
498
499
500 /***
501 * Factory method to create (if necessary) and return our
502 * <code>MBeanServer</code> instance.
503 *
504 * @since 1.0
505 * @deprecated Use the instance method
506 */
507 public static MBeanServer getServer() {
508 return Registry.getRegistry().getMBeanServer();
509 }
510
511 /***
512 * Set the <code>MBeanServer</code> to be utilized for our
513 * registered management beans.
514 *
515 * @param mbeanServer The new <code>MBeanServer</code> instance
516 * @since 1.0
517 * @deprecated Use the instance method
518 */
519 public static void setServer(MBeanServer mbeanServer) {
520 Registry.getRegistry().setMBeanServer(mbeanServer);
521 }
522
523 /***
524 * Load the registry from the XML input found in the specified input
525 * stream.
526 *
527 * @param stream InputStream containing the registry configuration
528 * information
529 *
530 * @exception Exception if any parsing or processing error occurs
531 * @deprecated use normal class method instead
532 * @since 1.0
533 */
534 public static void loadRegistry(InputStream stream) throws Exception {
535 Registry registry = getRegistry();
536 registry.loadMetadata(stream);
537 }
538
539 /*** Get a "singelton" registry, or one per thread if setUseContextLoader
540 * was called
541 *
542 * @deprecated Not enough info - use the method that takes CL and domain
543 * @since 1.0
544 */
545 public synchronized static Registry getRegistry() {
546 return getRegistry(null, null);
547 }
548
549
550
551 /*** Get the type of an attribute of the object, from the metadata.
552 *
553 * @param oname
554 * @param attName
555 * @return null if metadata about the attribute is not found
556 * @since 1.1
557 */
558 public String getType( ObjectName oname, String attName )
559 {
560 String type=null;
561 MBeanInfo info;
562 try {
563 info=server.getMBeanInfo(oname);
564 } catch (Exception e) {
565 log.info( "Can't find metadata for object" + oname );
566 return null;
567 }
568
569 MBeanAttributeInfo attInfo[]=info.getAttributes();
570 for( int i=0; i<attInfo.length; i++ ) {
571 if( attName.equals(attInfo[i].getName())) {
572 type=attInfo[i].getType();
573 return type;
574 }
575 }
576 return null;
577 }
578
579 /*** Find the operation info for a method
580 *
581 * @param oname
582 * @param opName
583 * @return the operation info for the specified operation
584 */
585 public MBeanOperationInfo getMethodInfo( ObjectName oname, String opName )
586 {
587 String type=null;
588 MBeanInfo info;
589 try {
590 info=server.getMBeanInfo(oname);
591 } catch (Exception e) {
592 log.info( "Can't find metadata " + oname );
593 return null;
594 }
595 MBeanOperationInfo attInfo[]=info.getOperations();
596 for( int i=0; i<attInfo.length; i++ ) {
597 if( opName.equals(attInfo[i].getName())) {
598 return attInfo[i];
599 }
600 }
601 return null;
602 }
603
604 /*** Unregister a component. This is just a helper that
605 * avoids exceptions by checking if the mbean is already registered
606 *
607 * @param oname
608 */
609 public void unregisterComponent( ObjectName oname ) {
610 try {
611 if( getMBeanServer().isRegistered(oname)) {
612 getMBeanServer().unregisterMBean(oname);
613 }
614 } catch( Throwable t ) {
615 log.error( "Error unregistering mbean ", t);
616 }
617 }
618
619 /***
620 * Factory method to create (if necessary) and return our
621 * <code>MBeanServer</code> instance.
622 *
623 */
624 public synchronized MBeanServer getMBeanServer() {
625 long t1=System.currentTimeMillis();
626
627 if (server == null) {
628 if( MBeanServerFactory.findMBeanServer(null).size() > 0 ) {
629 server=(MBeanServer)MBeanServerFactory.findMBeanServer(null).get(0);
630 if( log.isDebugEnabled() ) {
631 log.debug("Using existing MBeanServer " + (System.currentTimeMillis() - t1 ));
632 }
633 } else {
634 server=MBeanServerFactory.createMBeanServer();
635 if( log.isDebugEnabled() ) {
636 log.debug("Creating MBeanServer"+ (System.currentTimeMillis() - t1 ));
637 }
638 }
639 }
640 return (server);
641 }
642
643 /*** Find or load metadata.
644 */
645 public ManagedBean findManagedBean(Object bean, Class beanClass, String type)
646 throws Exception
647 {
648 if( bean!=null && beanClass==null ) {
649 beanClass=bean.getClass();
650 }
651
652 if( type==null ) {
653 type=beanClass.getName();
654 }
655
656
657 ManagedBean managed = findManagedBean(type);
658
659
660 if( managed==null ) {
661
662 if( log.isDebugEnabled() ) {
663 log.debug( "Looking for descriptor ");
664 }
665 findDescriptor( beanClass, type );
666
667 managed=findManagedBean(type);
668 }
669
670 if( bean instanceof DynamicMBean ) {
671 if( log.isDebugEnabled() ) {
672 log.debug( "Dynamic mbean support ");
673 }
674
675 loadDescriptors("MbeansDescriptorsDynamicMBeanSource",
676 bean, type);
677
678 managed=findManagedBean(type);
679 }
680
681
682 if( managed==null ) {
683 if( log.isDebugEnabled() ) {
684 log.debug( "Introspecting ");
685 }
686
687
688 loadDescriptors("MbeansDescriptorsIntrospectionSource",
689 beanClass, type);
690
691 managed=findManagedBean(type);
692 if( managed==null ) {
693 log.warn( "No metadata found for " + type );
694 return null;
695 }
696 managed.setName( type );
697 addManagedBean(managed);
698 }
699 return managed;
700 }
701
702
703 /*** EXPERIMENTAL Convert a string to object, based on type. Used by several
704 * components. We could provide some pluggability. It is here to keep
705 * things consistent and avoid duplication in other tasks
706 *
707 * @param type Fully qualified class name of the resulting value
708 * @param value String value to be converted
709 * @return Converted value
710 */
711 public Object convertValue(String type, String value)
712 {
713 Object objValue=value;
714
715 if( type==null || "java.lang.String".equals( type )) {
716
717 objValue=value;
718 } else if( "javax.management.ObjectName".equals( type ) ||
719 "ObjectName".equals( type )) {
720 try {
721 objValue=new ObjectName( value );
722 } catch (MalformedObjectNameException e) {
723 return null;
724 }
725 } else if( "java.lang.Integer".equals( type ) ||
726 "int".equals( type )) {
727 objValue=new Integer( value );
728 } else if("java.lang.Long".equals( type ) ||
729 "long".equals( type )) {
730 objValue = new Long( value );
731 } else if( "java.lang.Boolean".equals( type ) ||
732 "boolean".equals( type )) {
733 objValue=Boolean.valueOf( value );
734 }
735 return objValue;
736 }
737
738 /*** Experimental.
739 *
740 * @param sourceType
741 * @param source
742 * @param param
743 * @return List of descriptors
744 * @throws Exception
745 * @deprecated bad interface, mixing of metadata and mbeans
746 */
747 public List load( String sourceType, Object source, String param)
748 throws Exception
749 {
750 if( log.isTraceEnabled()) {
751 log.trace("load " + source );
752 }
753 String location=null;
754 String type=null;
755 Object inputsource=null;
756
757 if( source instanceof DynamicMBean ) {
758 sourceType="MbeansDescriptorsDynamicMBeanSource";
759 inputsource=source;
760 } else if( source instanceof URL ) {
761 URL url=(URL)source;
762 location=url.toString();
763 type=param;
764 inputsource=url.openStream();
765 if( sourceType == null ) {
766 sourceType = sourceTypeFromExt(location);
767 }
768 } else if( source instanceof File ) {
769 location=((File)source).getAbsolutePath();
770 inputsource=new FileInputStream((File)source);
771 type=param;
772 if( sourceType == null ) {
773 sourceType = sourceTypeFromExt(location);
774 }
775 } else if( source instanceof InputStream ) {
776 type=param;
777 inputsource=source;
778 } else if( source instanceof Class ) {
779 location=((Class)source).getName();
780 type=param;
781 inputsource=source;
782 if( sourceType== null ) {
783 sourceType="MbeansDescriptorsIntrospectionSource";
784 }
785 }
786
787 if( sourceType==null ) {
788 sourceType="MbeansDescriptorsDOMSource";
789 }
790 ModelerSource ds=getModelerSource(sourceType);
791 List mbeans=ds.loadDescriptors(this, location, type, inputsource);
792
793 return mbeans;
794 }
795
796 private String sourceTypeFromExt( String s ) {
797 if( s.endsWith( ".ser")) {
798 return "MbeansDescriptorsSerSource";
799 }
800 else if( s.endsWith(".xml")) {
801 return "MbeansDescriptorsDOMSource";
802 }
803 return null;
804 }
805
806 /*** Register a component
807 * XXX make it private
808 *
809 * @param bean
810 * @param oname
811 * @param type
812 * @throws Exception
813 */
814 public void registerComponent(Object bean, ObjectName oname, String type)
815 throws Exception
816 {
817 if( log.isDebugEnabled() ) {
818 log.debug( "Managed= "+ oname);
819 }
820
821 if( bean ==null ) {
822 log.error("Null component " + oname );
823 return;
824 }
825
826 try {
827 if( type==null ) {
828 type=bean.getClass().getName();
829 }
830
831 ManagedBean managed = findManagedBean(bean.getClass(), type);
832
833
834 ModelMBean mbean = managed.createMBean(bean);
835
836 if( getMBeanServer().isRegistered( oname )) {
837 if( log.isDebugEnabled()) {
838 log.debug("Unregistering existing component " + oname );
839 }
840 getMBeanServer().unregisterMBean( oname );
841 }
842
843 getMBeanServer().registerMBean( mbean, oname);
844 } catch( Exception ex) {
845 log.error("Error registering " + oname, ex );
846 throw ex;
847 }
848 }
849
850 /*** Lookup the component descriptor in the package and
851 * in the parent packages.
852 *
853 * @param packageName
854 */
855 public synchronized void loadDescriptors( String packageName, ClassLoader classLoader ) {
856 String res=packageName.replace( '.', '/');
857
858 if( log.isTraceEnabled() ) {
859 log.trace("Finding descriptor " + res );
860 }
861
862 if( searchedPaths.get( packageName ) != null ) {
863 return;
864 }
865 String descriptors=res + "/mbeans-descriptors.ser";
866
867 URL dURL=classLoader.getResource( descriptors );
868
869 if( dURL == null ) {
870 descriptors=res + "/mbeans-descriptors.xml";
871 dURL=classLoader.getResource( descriptors );
872 }
873 if( dURL == null ) {
874 return;
875 }
876
877 log.debug( "Found " + dURL);
878 searchedPaths.put( packageName, dURL );
879 try {
880 if( descriptors.endsWith(".xml" ))
881 loadDescriptors("MbeansDescriptorsDOMSource", dURL, null);
882 else
883 loadDescriptors("MbeansDescriptorsSerSource", dURL, null);
884 } catch(Exception ex ) {
885 log.error("Error loading " + dURL);
886 }
887 }
888
889 /*** Experimental. Will become private, some code may still use it
890 *
891 * @param sourceType
892 * @param source
893 * @param param
894 * @throws Exception
895 * @deprecated
896 */
897 public void loadDescriptors( String sourceType, Object source, String param)
898 throws Exception
899 {
900 List mbeans=load( sourceType, source, param );
901 if( mbeans == null) return;
902
903 Iterator itr=mbeans.iterator();
904 while( itr.hasNext() ) {
905 Object mb=itr.next();
906 if( mb instanceof ManagedBean) {
907 addManagedBean((ManagedBean)mb);
908 }
909 }
910 }
911
912 /*** Discover all META-INF/modeler.xml files in classpath and register
913 * the components
914 *
915 * @since EXPERIMENTAL
916 */
917 private void loadMetaInfDescriptors(ClassLoader cl) {
918 try {
919 Enumeration en=cl.getResources(MODELER_MANIFEST);
920 while( en.hasMoreElements() ) {
921 URL url=(URL)en.nextElement();
922 InputStream is=url.openStream();
923 if( log.isDebugEnabled()) log.debug("Loading " + url);
924 loadDescriptors("MBeansDescriptorDOMSource", is, null );
925 }
926 } catch( Exception ex ) {
927 ex.printStackTrace();
928 }
929 }
930
931 /*** Lookup the component descriptor in the package and
932 * in the parent packages.
933 *
934 * @param beanClass
935 * @param type
936 */
937 private void findDescriptor( Class beanClass, String type ) {
938 if( type==null ) {
939 type=beanClass.getName();
940 }
941 ClassLoader classLoader=null;
942 if( beanClass!=null ) {
943 classLoader=beanClass.getClassLoader();
944 }
945 if( classLoader==null ) {
946 classLoader=Thread.currentThread().getContextClassLoader();
947 }
948 if( classLoader==null ) {
949 classLoader=this.getClass().getClassLoader();
950 }
951
952 String pkg=type;
953 while( pkg.indexOf( ".") > 0 ) {
954 int lastComp=pkg.lastIndexOf( ".");
955 if( lastComp <= 0 ) return;
956 pkg=pkg.substring(0, lastComp);
957 if( searchedPaths.get( pkg ) != null ) {
958 return;
959 }
960 loadDescriptors(pkg, classLoader);
961 }
962 }
963
964 private ModelerSource getModelerSource( String type )
965 throws Exception
966 {
967 if( type==null ) type="MbeansDescriptorsDOMSource";
968 if( type.indexOf( ".") < 0 ) {
969 type="org.apache.commons.modeler.modules." + type;
970 }
971
972 Class c=Class.forName( type );
973 ModelerSource ds=(ModelerSource)c.newInstance();
974 return ds;
975 }
976
977
978
979
980 public ObjectName preRegister(MBeanServer server,
981 ObjectName name) throws Exception
982 {
983 this.server=server;
984 return name;
985 }
986
987 public void postRegister(Boolean registrationDone) {
988 }
989
990 public void preDeregister() throws Exception {
991 }
992
993 public void postDeregister() {
994 }
995
996
997
998
999
1000
1001
1002
1003 /*** Called by a registry or by the container to unload a loader
1004 * @param loader
1005 */
1006 public void unregisterRegistry(ClassLoader loader ) {
1007
1008 perLoaderRegistries.remove(loader);
1009 }
1010
1011 public ManagedBean findManagedBean(Class beanClass, String type)
1012 throws Exception
1013 {
1014 return findManagedBean(null, beanClass, type);
1015 }
1016
1017 /***
1018 * Set the <code>MBeanServer</code> to be utilized for our
1019 * registered management beans.
1020 *
1021 * @param server The new <code>MBeanServer</code> instance
1022 */
1023 public void setMBeanServer( MBeanServer server ) {
1024 this.server=server;
1025 }
1026
1027 public void resetMetadata() {
1028 stop();
1029 }
1030 /***
1031 * Load the registry from the XML input found in the specified input
1032 * stream.
1033 *
1034 * @param source Source to be used to load. Can be an InputStream or URL.
1035 *
1036 * @exception Exception if any parsing or processing error occurs
1037 */
1038 public void loadDescriptors( Object source )
1039 throws Exception
1040 {
1041 loadDescriptors("MbeansDescriptorsDOMSource", source, null );
1042 }
1043
1044 /*** @deprecated - may still be used in code using pre-1.1 builds
1045 */
1046 public void registerComponent(Object bean, String domain, String type,
1047 String name)
1048 throws Exception
1049 {
1050 StringBuffer sb=new StringBuffer();
1051 sb.append( domain ).append(":");
1052 sb.append( name );
1053 String nameStr=sb.toString();
1054 ObjectName oname=new ObjectName( nameStr );
1055 registerComponent(bean, oname, type );
1056 }
1057
1058
1059
1060
1061 public void unregisterComponent( String domain, String name ) {
1062 try {
1063 ObjectName oname=new ObjectName( domain + ":" + name );
1064
1065
1066 getMBeanServer().unregisterMBean( oname );
1067 } catch( Throwable t ) {
1068 log.error( "Error unregistering mbean ", t );
1069 }
1070 }
1071
1072 public List loadMBeans( Object source )
1073 throws Exception
1074 {
1075 return loadMBeans( source, null );
1076 }
1077
1078
1079 /***
1080 * Load the registry from a cached .ser file. This is typically 2-3 times
1081 * faster than parsing the XML.
1082 *
1083 * @param source Source to be used to load. Can be an InputStream or URL.
1084 *
1085 * @exception Exception if any parsing or processing error occurs
1086 * @deprecated Loaded automatically or using a File or Url ending in .ser
1087 */
1088 public void loadCachedDescriptors( Object source )
1089 throws Exception
1090 {
1091 loadDescriptors("MbeansDescriptorsSerSource", source, null );
1092 }
1093 }