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