KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > management > config > AMXConfigImplBase


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23 package com.sun.enterprise.management.config;
24
25 import java.util.Set JavaDoc;
26 import java.util.HashSet JavaDoc;
27 import java.util.Map JavaDoc;
28
29 import java.lang.reflect.Method JavaDoc;
30 import java.lang.reflect.Constructor JavaDoc;
31 import java.lang.reflect.InvocationTargetException JavaDoc;
32
33 import javax.management.ObjectName JavaDoc;
34 import javax.management.MBeanInfo JavaDoc;
35 import javax.management.MBeanNotificationInfo JavaDoc;
36 import javax.management.Attribute JavaDoc;
37 import javax.management.AttributeList JavaDoc;
38 import javax.management.AttributeNotFoundException JavaDoc;
39 import javax.management.AttributeChangeNotification JavaDoc;
40 import javax.management.MBeanException JavaDoc;
41 import javax.management.ReflectionException JavaDoc;
42 import javax.management.InstanceNotFoundException JavaDoc;
43
44 import com.sun.appserv.management.util.misc.ClassUtil;
45 import com.sun.appserv.management.util.misc.CollectionUtil;
46 import com.sun.appserv.management.util.misc.GSetUtil;
47 import com.sun.appserv.management.util.misc.ThrowableMapper;
48 import com.sun.appserv.management.util.misc.StringUtil;
49 import com.sun.appserv.management.util.misc.ExceptionUtil;
50 import com.sun.appserv.management.util.jmx.JMXUtil;
51
52 import com.sun.appserv.management.config.PropertiesAccess;
53 import com.sun.appserv.management.config.AMXConfig;
54 import com.sun.appserv.management.config.RefConfig;
55 import com.sun.appserv.management.config.ResourceConfig;
56 import com.sun.appserv.management.config.ModuleConfig;
57 import com.sun.appserv.management.config.RefConfigReferent;
58 import com.sun.appserv.management.config.ResourceRefConfig;
59 import com.sun.appserv.management.config.ResourceRefConfigReferent;
60 import com.sun.appserv.management.config.DeployedItemRefConfigReferent;
61 import com.sun.appserv.management.config.ClusterRefConfigReferent;
62 import com.sun.appserv.management.config.ServerRefConfigReferent;
63 import com.sun.appserv.management.config.Description;
64 import com.sun.appserv.management.config.Enabled;
65 import com.sun.appserv.management.config.ObjectType;
66
67 import com.sun.appserv.management.config.DeployedItemRefConfigCR;
68 import com.sun.appserv.management.config.ServerRefConfigCR;
69 import com.sun.appserv.management.config.ClusterRefConfigCR;
70 import com.sun.appserv.management.config.ResourceRefConfigCR;
71 import com.sun.appserv.management.config.SystemPropertiesAccess;
72
73 import com.sun.appserv.management.base.XTypesMapper;
74 import com.sun.appserv.management.base.XTypes;
75 import com.sun.appserv.management.base.AMX;
76 import com.sun.appserv.management.base.AMXDebug;
77 import com.sun.appserv.management.base.Container;
78 import com.sun.appserv.management.base.Util;
79
80 import com.sun.appserv.management.helper.RefHelper;
81
82 import com.sun.enterprise.management.support.AMXImplBase;
83 import com.sun.enterprise.management.support.Delegate;
84 import com.sun.enterprise.management.support.DelegateBase;
85 import com.sun.enterprise.management.support.AMXAttributeNameMapper;
86
87 import com.sun.enterprise.management.config.ConfigFactory;
88 import com.sun.enterprise.management.support.oldconfig.OldProperties;
89 import com.sun.enterprise.management.support.oldconfig.OldSystemProperties;
90
91 /**
92     Base class from which all AMX Config MBeans should derive (but not "must").
93     <p>
94  */

95 public class AMXConfigImplBase extends AMXImplBase
96     implements AMXConfig
97 {
98         protected
99     AMXConfigImplBase( Delegate delegate )
100     {
101         super( delegate );
102     }
103     
104         protected boolean
105     supportsProperties()
106     {
107         return PropertiesAccess.class.isAssignableFrom( getInterface() );
108     }
109     
110         protected boolean
111     supportsSystemProperties()
112     {
113         return SystemPropertiesAccess.class.isAssignableFrom( getInterface() );
114     }
115     
116     /**
117         Verify that the AMX support for system properties is the same
118         as its Delegate.
119      */

120         protected final void
121     checkPropertiesAccessSupport()
122     {
123         if ( getDelegate() != null)
124         {
125             final boolean delegateHasProperties = delegateSupportsProperties();
126             
127             if ( delegateHasProperties != supportsProperties() )
128             {
129                 final String JavaDoc msg = getJ2EEType() + ": " +
130                     "delegateSupportsProperties=" + delegateHasProperties +
131                     ", but supportsProperties=" + supportsProperties();
132                 // implementation error
133
logWarning( msg );
134                 throw new Error JavaDoc( msg );
135             }
136         }
137         else if ( supportsProperties() )
138         {
139             final String JavaDoc msg = getJ2EEType() + ": " +
140                 "AMX interface supports properties, but has no delegate";
141             logSevere( msg );
142             throw new Error JavaDoc( msg );
143         }
144     }
145     
146         private boolean
147     delegateSupportsSystemProperties()
148     {
149         boolean supports = true;
150         final OldSystemProperties old = getOldSystemProperties();
151         try
152         {
153             final AttributeList JavaDoc props = old.getSystemProperties();
154             supports = true;
155         }
156         catch( Exception JavaDoc e )
157         {
158             supports = false;
159         }
160         return supports;
161     }
162     
163         private boolean
164     delegateSupportsProperties()
165     {
166         boolean supports = true;
167         final OldProperties old = getOldProperties();
168         try
169         {
170           final AttributeList JavaDoc props = old.getProperties();
171           supports = true;
172         }
173         catch( Exception JavaDoc e )
174         {
175             supports = false;
176         }
177         return supports;
178     }
179     
180     /**
181         Verify that the AMX support for properties is the same
182         as its Delegate.
183      */

184         protected final void
185     checkSystemPropertiesAccessSupport()
186     {
187         if ( getDelegate() != null)
188         {
189             final boolean delegateSupports = delegateSupportsSystemProperties();
190             
191             if ( delegateSupports != supportsSystemProperties() )
192             {
193                 final String JavaDoc msg = getJ2EEType() + ": " +
194                     "delegateSupportsSystemProperties=" + delegateSupports +
195                     ", but supportsSystemProperties=" + supportsSystemProperties();
196                 // implementation error
197
logWarning( msg );
198                 throw new Error JavaDoc( msg );
199             }
200         }
201         else if ( supportsSystemProperties() )
202         {
203             final String JavaDoc msg = getJ2EEType() + ": " +
204                 "AMX interface supports system properties, but has no delegate";
205             logSevere( msg );
206             throw new Error JavaDoc( msg );
207         }
208     }
209     
210         protected final void
211     checkInterfaceSupport(
212         final Class JavaDoc<?> theInterface,
213         final String JavaDoc attributeToCheck )
214     {
215         if ( getDelegate() != null)
216         {
217             final boolean delegateSupports =
218                 getDelegate().supportsAttribute( attributeToCheck );
219             
220             final boolean supported = theInterface.isAssignableFrom( getInterface() );
221             
222             if ( delegateSupports != supported )
223             {
224                 final String JavaDoc msg = "ERROR: " + getJ2EEType() + ": " +
225                     "AMX interface does not match Delegate capabilities for " +
226                     "interface " + theInterface.getName() + ", " +
227                     "delegate support = " + delegateSupports +
228                     ", AMX support = " + supported;
229                 logSevere( msg );
230                 throw new Error JavaDoc( msg );
231             }
232         }
233     }
234
235     
236         protected final Set JavaDoc<String JavaDoc>
237     getSuperfluousMethods()
238     {
239         final Set JavaDoc<String JavaDoc> items = super.getSuperfluousMethods();
240         
241         final Method JavaDoc[] methods = this.getClass().getMethods();
242         for( final Method JavaDoc m : methods )
243         {
244             final String JavaDoc name = m.getName();
245             
246             if ( isConfigFactoryGetter( name ) ||
247                     isRemoveConfig( name ) ||
248                     isCreateConfig( name ) )
249             {
250                 if ( m.getParameterTypes().length <= 1 )
251                 {
252                     items.add( name );
253                 }
254             }
255         }
256         
257         return items;
258     }
259     
260         protected final void
261     implCheck()
262     {
263         super.implCheck();
264         
265         // not sure how to implement these checks in offline mode
266
if ( ! com.sun.enterprise.management.support.BootUtil.getInstance().getOffline() )
267         {
268             checkPropertiesAccessSupport();
269             checkSystemPropertiesAccessSupport();
270         }
271         
272         checkInterfaceSupport( Description.class, "Description" );
273         checkInterfaceSupport( ObjectType.class, "ObjectType" );
274         checkInterfaceSupport( Enabled.class, "Enabled" );
275     }
276     
277         private static void
278     validatePropertyName( final String JavaDoc propertyName )
279     {
280         if ( propertyName == null ||
281             propertyName.length() == 0 )
282         {
283             throw new IllegalArgumentException JavaDoc( "Illegal property name: " +
284                 StringUtil.quote( propertyName ) );
285         }
286     }
287     
288         protected OldSystemProperties
289     getOldSystemProperties()
290     {
291         if ( ! haveDelegate() )
292         {
293             final String JavaDoc msg = "system properties not supported (no delegate) by " +
294                                     quote( getObjectName() );
295             
296             throw new IllegalArgumentException JavaDoc( msg );
297         }
298         
299         return( new OldSystemPropertiesImpl( getDelegate() ) );
300     }
301     
302         public Map JavaDoc<String JavaDoc,String JavaDoc>
303     getSystemProperties( )
304     {
305         final AttributeList JavaDoc props = getOldSystemProperties().getSystemProperties();
306         
307         final Map JavaDoc<String JavaDoc,String JavaDoc> result = JMXUtil.attributeListToStringMap( props );
308         
309         return result;
310     }
311     
312         public String JavaDoc[]
313     getSystemPropertyNames( )
314     {
315         final Set JavaDoc<String JavaDoc> names = getSystemProperties().keySet();
316         
317         return( GSetUtil.toStringArray( names ) );
318     }
319     
320         public String JavaDoc
321     getSystemPropertyValue( String JavaDoc propertyName )
322     {
323         return( getOldSystemProperties().getSystemPropertyValue( propertyName ) );
324     }
325     
326         public final void
327     setSystemPropertyValue(
328         final String JavaDoc propertyName,
329         final String JavaDoc propertyValue )
330     {
331         validatePropertyName( propertyName );
332         
333         if ( propertyValue == null )
334         {
335             throw new IllegalArgumentException JavaDoc( "" + null );
336         }
337
338         final Attribute JavaDoc attr = new Attribute JavaDoc( propertyName, propertyValue );
339         
340         getOldSystemProperties().setSystemProperty( attr );
341     }
342     
343         public final boolean
344     existsSystemProperty( String JavaDoc propertyName )
345     {
346         validatePropertyName( propertyName );
347         
348         return( GSetUtil.newSet( getSystemPropertyNames() ).contains( propertyName ) );
349     }
350     
351         public final void
352     removeSystemProperty( String JavaDoc propertyName )
353     {
354         validatePropertyName( propertyName );
355         
356         getOldSystemProperties().setSystemProperty( new Attribute JavaDoc( propertyName, null ) );
357     }
358     
359         public final void
360     createSystemProperty( String JavaDoc propertyName, String JavaDoc propertyValue )
361     {
362         setSystemPropertyValue( propertyName, propertyValue );
363     }
364     
365     
366     
367     
368     /**
369         Get the old mbean's properties API.
370      */

371         protected OldProperties
372     getOldProperties()
373     {
374         if ( ! haveDelegate() )
375         {
376             final String JavaDoc msg = "properties not supported (no delegate) by " +
377                                     quote( getObjectName() );
378             
379             throw new IllegalArgumentException JavaDoc( msg );
380         }
381         
382         return( new OldPropertiesImpl( getDelegate() ) );
383     }
384     
385         public Map JavaDoc<String JavaDoc,String JavaDoc>
386     getProperties( )
387     {
388         final AttributeList JavaDoc props = getOldProperties().getProperties();
389         
390         return JMXUtil.attributeListToStringMap( props );
391     }
392     
393     
394         public String JavaDoc[]
395     getPropertyNames( )
396     {
397         final Set JavaDoc<String JavaDoc> names = getProperties().keySet();
398         
399         return( GSetUtil.toStringArray( names ) );
400     }
401     
402         public String JavaDoc
403     getPropertyValue( String JavaDoc propertyName )
404     {
405         return( getOldProperties().getPropertyValue( propertyName ) );
406     }
407     
408         public final void
409     setPropertyValue(
410         final String JavaDoc propertyName,
411         final String JavaDoc propertyValue )
412     {
413         validatePropertyName( propertyName );
414         
415         if ( propertyValue == null )
416         {
417             throw new IllegalArgumentException JavaDoc( "null" );
418         }
419
420         final Attribute JavaDoc attr = new Attribute JavaDoc( propertyName, propertyValue );
421         
422         getOldProperties().setProperty( attr );
423     }
424     
425         public final boolean
426     existsProperty( String JavaDoc propertyName )
427     {
428         validatePropertyName( propertyName );
429         
430         return( GSetUtil.newSet( getPropertyNames() ).contains( propertyName ) );
431     }
432     
433         public final void
434     removeProperty( String JavaDoc propertyName )
435     {
436         validatePropertyName( propertyName );
437         
438         getOldProperties().setProperty( new Attribute JavaDoc( propertyName, null ) );
439     }
440     
441         public final void
442     createProperty( String JavaDoc propertyName, String JavaDoc propertyValue )
443     {
444         validatePropertyName( propertyName );
445         
446         setPropertyValue( propertyName, propertyValue );
447     }
448     
449         public final String JavaDoc
450     getGroup()
451     {
452         return( AMX.GROUP_CONFIGURATION );
453     }
454     
455     
456         public MBeanNotificationInfo JavaDoc[]
457     getNotificationInfo()
458     {
459         final MBeanNotificationInfo JavaDoc[] superInfos = super.getNotificationInfo();
460         
461         // create a NotificationInfo for AttributeChangeNotification
462
final String JavaDoc description = "";
463         final String JavaDoc[] notifTypes = new String JavaDoc[] { AttributeChangeNotification.ATTRIBUTE_CHANGE };
464         final MBeanNotificationInfo JavaDoc attributeChange = new MBeanNotificationInfo JavaDoc(
465                 notifTypes,
466                 AttributeChangeNotification JavaDoc.class.getName(),
467                 description );
468     
469         final MBeanNotificationInfo JavaDoc[] selfInfos =
470             new MBeanNotificationInfo JavaDoc[] { attributeChange };
471
472         final MBeanNotificationInfo JavaDoc[] allInfos =
473             JMXUtil.mergeMBeanNotificationInfos( superInfos, selfInfos );
474             
475         return allInfos;
476     }
477     
478         private String JavaDoc
479     getSimpleInterfaceName( final AMX amx )
480     {
481         final String JavaDoc fullInterfaceName = Util.getExtra( amx ).getInterfaceName();
482         final String JavaDoc interfaceName = ClassUtil.stripPackageName( fullInterfaceName );
483         
484         return interfaceName;
485     }
486     
487     
488     /**
489         Do anything necessary prior to removing an AMXConfig.
490         <p>
491         We have the situation where some of the com.sun.appserv MBeans
492         behave by auto-creating references, even in EE, but not auto-removing,
493         though in PE they are always auto-removed. So the algorithm varies
494         by both release (PE vs EE) and by MBean. This is hopeless.
495         <p>
496         So first we attempt remove all references to the AMXCOnfig (if any).
497         This will fail in PE, and may or may not fail in EE; we just ignore
498         it so long as there is only one failure.
499      */

500         protected void
501     preRemove( final ObjectName JavaDoc objectName )
502     {
503         final AMXConfig amxConfig = getProxy( objectName, AMXConfig.class );
504         
505         if ( amxConfig instanceof RefConfigReferent )
506         {
507             debug( "*** Removing all references to ", objectName );
508             
509             final Set JavaDoc<RefConfig> failures =
510                 RefHelper.removeAllRefsTo( (RefConfigReferent)amxConfig, true );
511             if( failures.size() != 0 )
512             {
513                 debug( "FAILURE removing references to " + objectName + ": " +
514                     CollectionUtil.toString( Util.toObjectNames( failures ) ) );
515             }
516         }
517         else
518         {
519             debug( "*** not a RefConfigReferent: ", objectName );
520         }
521     }
522     
523     /**
524         Make sure the item exists, then call preRemove( ObjectName ).
525      */

526         protected ObjectName JavaDoc
527     preRemove(
528         final Map JavaDoc<String JavaDoc,ObjectName JavaDoc> items,
529         final String JavaDoc name )
530     {
531         if ( name == null )
532         {
533             throw new IllegalArgumentException JavaDoc( "null name" );
534         }
535
536         final ObjectName JavaDoc objectName = items.get( name );
537         if ( objectName == null )
538         {
539             throw new IllegalArgumentException JavaDoc( "Item not found: " + name );
540         }
541         
542         preRemove( objectName );
543         
544         return objectName;
545     }
546   
547     
548     /**
549         Remove the config by finding its ConfigFactory.
550         The caller must have already called preRemove().
551         @return true for success.
552      */

553         protected final boolean
554     removeConfigWithFactory( final ObjectName JavaDoc objectName )
555     {
556         ConfigFactory factory = null;
557         
558         boolean attempted = false;
559         try
560         {
561             final AMXConfig amxConfig = getProxy( objectName, AMXConfig.class );
562             final String JavaDoc interfaceName = getSimpleInterfaceName( amxConfig );
563             debug( "removeConfigWithFactory: " + objectName );
564             
565             factory = createConfigFactory( interfaceName );
566         }
567         catch( Exception JavaDoc e )
568         {
569             debug( ExceptionUtil.toString( e ) );
570         }
571         
572         if ( factory != null )
573         {
574             attempted = true;
575                 
576             // some factories have remove(), because they remove a singleton
577
// instance, and some have remove( ObjectName )
578
try
579             {
580                 final Method JavaDoc m = factory.getClass().getMethod( "remove", (Class JavaDoc[])null );
581                 if ( m != null )
582                 {
583                     m.invoke( factory, (Object JavaDoc[])null );
584                 }
585             }
586             catch( NoSuchMethodException JavaDoc e )
587             {
588                 factory.remove( objectName );
589             }
590             catch( Exception JavaDoc e )
591             {
592                 throw new RuntimeException JavaDoc( e );
593             }
594         }
595         
596         return attempted;
597     }
598     
599     
600     static private final String JavaDoc CREATE = "create";
601     static private final String JavaDoc CREATE_PREFIX = CREATE;
602     static private final String JavaDoc REMOVE_PREFIX = "remove";
603     static private final String JavaDoc CONFIG_SUFFIX = "Config";
604     static private final String JavaDoc FACTORY_SUFFIX = "Factory";
605     
606     static private final Class JavaDoc[] STRING_SIG = new Class JavaDoc[] { String JavaDoc.class };
607     
608     /**
609         Remove the config, if possible, by finding a method of the
610         appropriate name. Usually, removeConfigWithFactory()
611         should have been used instead.
612         <p>
613         The caller must have already called preRemove().
614         <p>
615         A RuntimeException is thrown if an appropriate method cannot
616         be found.
617      */

618         protected final void
619     removeConfigWithMethod( final ObjectName JavaDoc objectName )
620     {
621         final AMXConfig amxConfig = getProxy( objectName, AMXConfig.class );
622         final String JavaDoc interfaceName = getSimpleInterfaceName( amxConfig );
623         if ( ! interfaceName.endsWith( CONFIG_SUFFIX ) )
624         {
625             throw new IllegalArgumentException JavaDoc(
626                 "Interface doesn't end in " + CONFIG_SUFFIX + ": " + interfaceName );
627         }
628             
629         // do it generically by constructing the expected method name,
630
// and then calling it.
631
final String JavaDoc operationName = REMOVE_PREFIX + interfaceName;
632         debug( "removing config generically by calling ", operationName, "()" );
633         try
634         {
635             final Method JavaDoc m =
636                 this.getClass().getDeclaredMethod( operationName, STRING_SIG);
637             
638             m.invoke( this, amxConfig.getName() );
639         }
640         catch( Exception JavaDoc e )
641         {
642             throw new RuntimeException JavaDoc( e );
643         }
644      }
645     
646     
647     /**
648         Generic removal of any config contained by this config.
649      */

650         public final void
651     removeConfig( final String JavaDoc j2eeType, final String JavaDoc name )
652     {
653         if ( name == null )
654         {
655             throw new IllegalArgumentException JavaDoc();
656         }
657
658         final Map JavaDoc<String JavaDoc,ObjectName JavaDoc> items = getContaineeObjectNameMap( j2eeType );
659         final ObjectName JavaDoc objectName = preRemove( items, name );
660         
661         if ( ! removeConfigWithFactory( objectName ) )
662         {
663             debug( "removeConfigWithFactory failed, using removeConfigWithMethod" );
664             removeConfigWithMethod( objectName );
665         }
666     }
667     
668     /**
669         Generic removal of RefConfig.
670      */

671         protected void
672     removeRefConfig( final String JavaDoc j2eeType, final String JavaDoc name )
673     {
674         removeConfig( j2eeType, name );
675     }
676     
677     
678         private boolean
679     isRemoveConfig( final String JavaDoc operationName)
680     {
681         return operationName.startsWith( REMOVE_PREFIX ) &&
682             operationName.endsWith( CONFIG_SUFFIX );
683     }
684     
685         private boolean
686     isRemoveConfig(
687         String JavaDoc operationName,
688         Object JavaDoc[] args,
689         String JavaDoc[] types )
690     {
691         final int numArgs = args == null ? 0 : args.length;
692         
693         boolean isRemove = numArgs <= 1 && isRemoveConfig( operationName );
694         if ( isRemove && numArgs == 1 )
695         {
696             isRemove = types[0].equals( String JavaDoc.class.getName() );
697         }
698         return isRemove;
699     }
700    
701         private boolean
702     isCreateConfig( final String JavaDoc operationName)
703     {
704         return operationName.startsWith( CREATE_PREFIX ) &&
705             operationName.endsWith( CONFIG_SUFFIX );
706     }
707     
708         private boolean
709     isConfigFactoryGetter(
710         String JavaDoc operationName,
711         Object JavaDoc[] args,
712         String JavaDoc[] types )
713     {
714         final int numArgs = args == null ? 0 : args.length;
715         
716         return numArgs == 0 && isConfigFactoryGetter( operationName );
717     }
718     
719         private boolean
720     isConfigFactoryGetter( final String JavaDoc operationName )
721     {
722         return operationName.startsWith( GET_PREFIX ) &&
723                 operationName.endsWith( FACTORY_SUFFIX ) &&
724                 (! operationName.equals( "getProxyFactory" ) );
725     }
726     
727         protected ObjectName JavaDoc
728    createConfig(
729         final String JavaDoc simpleInterfaceName,
730         final Object JavaDoc[] args,
731         String JavaDoc[] types)
732         throws NoSuchMethodException JavaDoc, IllegalAccessException JavaDoc,
733         InvocationTargetException JavaDoc, ClassNotFoundException JavaDoc, InstantiationException JavaDoc
734    {
735         ObjectName JavaDoc result = null;
736     
737         final Class JavaDoc[] sig = ClassUtil.signatureFromClassnames( types );
738             
739         final ConfigFactory factory = createConfigFactory( simpleInterfaceName );
740         if ( factory == null )
741         {
742             // look for the appropriate method
743
final String JavaDoc createMethodName = CREATE + simpleInterfaceName;
744             final Method JavaDoc m = this.getClass().getMethod( createMethodName, sig);
745             if ( m == null )
746             {
747                 throw new RuntimeException JavaDoc( "Can't find ConfigFactory for " + simpleInterfaceName );
748             }
749         }
750         else
751         {
752             final Method JavaDoc createMethod =
753                 factory.getClass().getDeclaredMethod( CREATE, sig);
754             if ( createMethod != null )
755             {
756                 result = (ObjectName JavaDoc)createMethod.invoke( factory, args );
757             }
758             else
759             {
760                 final String JavaDoc msg = "Can't find method " + CREATE +
761                     " in factory " + factory.getClass().getName();
762                 
763                 throw new NoSuchMethodException JavaDoc( msg );
764             }
765         }
766         
767         return result;
768    }
769    
770     
771     private static final Set JavaDoc<String JavaDoc> CR_PREFIXES =
772         GSetUtil.newUnmodifiableStringSet(
773             "create", "remove"
774         );
775         
776   
777      /**
778         Return the simple (no package) classname associated
779         with certain operations:
780         <ul>
781         <li>removeAbcConfig => AbcConfig</li>
782         <li>createAbcConfig => AbcConfig</li>
783         <li>getAbcConfig => AbcConfig</li>
784         </ul>
785     */

786         protected String JavaDoc
787     operationNameToSimpleClassname( final String JavaDoc operationName )
788     {
789         return StringUtil.findAndStripPrefix( CR_PREFIXES, operationName );
790     }
791     
792         protected String JavaDoc
793     operationNameToJ2EEType( final String JavaDoc operationName )
794     {
795         String JavaDoc j2eeType = null;
796         
797         if ( isRemoveConfig( operationName ) ||
798               isCreateConfig( operationName ) )
799         {
800             j2eeType = XTypes.PREFIX + operationNameToSimpleClassname( operationName );
801         }
802         else
803         {
804             j2eeType = super.operationNameToJ2EEType( operationName );
805         }
806         return j2eeType;
807     }
808     
809     
810    /**
811         Remove config for a singleton Containee.
812     */

813       protected void
814    removeConfig( final String JavaDoc operationName)
815    {
816         final String JavaDoc j2eeType = operationNameToJ2EEType( operationName );
817         final ObjectName JavaDoc objectName = getContaineeObjectName( j2eeType );
818         if ( objectName == null )
819         {
820             throw new RuntimeException JavaDoc( new InstanceNotFoundException JavaDoc( j2eeType ) );
821         }
822         preRemove( objectName );
823         
824         final String JavaDoc simpleInterfaceName =
825             operationName.substring( REMOVE_PREFIX.length(), operationName.length());
826             
827         createConfigFactory( simpleInterfaceName ).remove( objectName );
828    }
829    
830    /**
831         Remove config for a named Containee.
832     */

833       protected void
834    removeConfig(
835         final String JavaDoc operationName,
836         final Object JavaDoc[] args,
837         String JavaDoc[] types)
838         throws InvocationTargetException JavaDoc
839    {
840         final String JavaDoc name = (String JavaDoc)args[ 0 ];
841         final String JavaDoc simpleInterfaceName =
842             operationName.substring( REMOVE_PREFIX.length(), operationName.length());
843             
844         final Set JavaDoc<? extends AMX> containees = getFactoryContainer().getContaineeSet();
845         ObjectName JavaDoc objectName = null;
846         for( final AMX containee : containees )
847         {
848             if ( containee.getName().equals( name ) )
849             {
850                 debug( "removeConfig: found name match: " + Util.getObjectName( containee ) );
851                 if ( getSimpleInterfaceName( containee ).equals( simpleInterfaceName ) )
852                 {
853                     objectName = Util.getObjectName( containee );
854                     break;
855                 }
856                 debug( getSimpleInterfaceName( containee ), " != ", simpleInterfaceName );
857             }
858         }
859         
860         if ( objectName != null )
861         {
862             final AMX amx = getProxy( objectName, AMX.class);
863                 
864             removeConfig( amx.getJ2EEType(), amx.getName() );
865         }
866         else
867         {
868             throw new IllegalArgumentException JavaDoc( "Not found: " + name );
869         }
870    }
871    
872         protected String JavaDoc
873    getFactoryPackage()
874    {
875         // same package as the MBean implementation
876
return this.getClass().getPackage().getName();
877    }
878    
879    /**
880         Create a ConfigFactory or return null if couldn't be created.
881     */

882         protected ConfigFactory
883    createConfigFactory( final String JavaDoc simpleClassname )
884    {
885         ConfigFactory factory = null;
886         
887         try
888         {
889             final String JavaDoc classname = getFactoryPackage() + "." +
890                                             simpleClassname + FACTORY_SUFFIX;
891             
892             final Class JavaDoc factoryClass = ClassUtil.getClassFromName( classname );
893             final Constructor JavaDoc constructor = factoryClass.getConstructor( FACTORY_CONSTRUCTOR_SIG );
894             
895             if ( constructor != null )
896             {
897                 factory = (ConfigFactory)constructor.newInstance( new Object JavaDoc[] { this } );
898             }
899             else
900             {
901                 throw new RuntimeException JavaDoc( "No ConfigFactory found for " + classname );
902             }
903         }
904         catch( Exception JavaDoc e )
905         {
906             debug( ExceptionUtil.toString( e ) );
907             throw new RuntimeException JavaDoc( e );
908         }
909         return factory;
910    }
911    
912    
913     private static final Class JavaDoc[] FACTORY_CONSTRUCTOR_SIG = new Class JavaDoc[]
914     {
915         ConfigFactoryCallback.class,
916     };
917     
918     /**
919         Automatically figure out get<abc>Factory(),
920         create<Abc>Config(), remove<Abc>Config().
921         
922      */

923         protected Object JavaDoc
924     invokeManually(
925         String JavaDoc operationName,
926         Object JavaDoc[] args,
927         String JavaDoc[] types )
928         throws MBeanException JavaDoc, ReflectionException JavaDoc, NoSuchMethodException JavaDoc, AttributeNotFoundException JavaDoc
929     {
930         final int numArgs = args == null ? 0 : args.length;
931         
932         Object JavaDoc result = null;
933         
934         debugMethod( operationName, args );
935         
936         if ( isConfigFactoryGetter( operationName, args, types ) &&
937              ConfigFactoryCallback.class.isAssignableFrom( this.getClass() ) )
938         {
939             debug( "looking for factory denoted by " + operationName );
940             result = createConfigFactory( operationName );
941             if ( result == null )
942             {
943                 debug( "FAILED TO FIND factory denoted by " + operationName );
944                 result = super.invokeManually( operationName, args, types );
945             }
946         }
947         else if ( isRemoveConfig( operationName, args, types ) )
948         {
949             try
950             {
951                 if ( numArgs == 0 )
952                 {
953                     // a single, possibly unnamed containee
954
removeConfig( operationName );
955                 }
956                 else
957                 {
958                     removeConfig( operationName, args, types );
959                 }
960             }
961             catch( InvocationTargetException JavaDoc e )
962             {
963                 throw new MBeanException JavaDoc( e );
964             }
965         }
966         else if ( isCreateConfig( operationName ) )
967         {
968             // name will be of the form create<XXX>Config
969
final String JavaDoc simpleInterfaceName =
970                 operationName.substring( CREATE_PREFIX.length(), operationName.length() );
971                 
972             try
973             {
974                 result = createConfig( simpleInterfaceName, args, types);
975             }
976             catch( Exception JavaDoc e )
977             {
978                 throw new MBeanException JavaDoc( e );
979             }
980         }
981         else
982         {
983             result = super.invokeManually( operationName, args, types );
984         }
985         return result;
986     }
987     
988     
989     /**
990         Get the name of the config in which this MBean lives.
991         
992         @return config name, or null if not in a config
993      */

994         public String JavaDoc
995     getConfigName()
996     {
997         return( (String JavaDoc)getKeyProperty( XTypes.CONFIG_CONFIG ) );
998     }
999     
1000        public void
1001    sendConfigCreatedNotification( final ObjectName JavaDoc configObjectName )
1002    {
1003        sendNotification( AMXConfig.CONFIG_CREATED_NOTIFICATION_TYPE,
1004            AMXConfig.CONFIG_REMOVED_NOTIFICATION_TYPE,
1005            AMXConfig.CONFIG_OBJECT_NAME_KEY, configObjectName );
1006    }
1007    
1008        public void
1009    sendConfigRemovedNotification( final ObjectName JavaDoc configObjectName )
1010    {
1011        sendNotification( AMXConfig.CONFIG_REMOVED_NOTIFICATION_TYPE,
1012            AMXConfig.CONFIG_REMOVED_NOTIFICATION_TYPE,
1013            AMXConfig.CONFIG_OBJECT_NAME_KEY, configObjectName );
1014    }
1015}
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
Popular Tags