KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mx > modelmbean > XMBean


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.mx.modelmbean;
23
24 import java.net.MalformedURLException JavaDoc;
25 import java.net.URL JavaDoc;
26 import java.util.HashMap JavaDoc;
27 import java.util.Iterator JavaDoc;
28 import java.util.List JavaDoc;
29
30 import javax.management.Descriptor JavaDoc;
31 import javax.management.InstanceNotFoundException JavaDoc;
32 import javax.management.ListenerNotFoundException JavaDoc;
33 import javax.management.MBeanException JavaDoc;
34 import javax.management.MBeanInfo JavaDoc;
35 import javax.management.MBeanNotificationInfo JavaDoc;
36 import javax.management.MBeanServer JavaDoc;
37 import javax.management.NotCompliantMBeanException JavaDoc;
38 import javax.management.NotificationBroadcaster JavaDoc;
39 import javax.management.Notification JavaDoc;
40 import javax.management.NotificationFilter JavaDoc;
41 import javax.management.NotificationListener JavaDoc;
42 import javax.management.ObjectName JavaDoc;
43 import javax.management.RuntimeOperationsException JavaDoc;
44 import javax.management.StandardMBean JavaDoc;
45 import javax.management.modelmbean.InvalidTargetObjectTypeException JavaDoc;
46 import javax.management.modelmbean.ModelMBeanAttributeInfo JavaDoc;
47 import javax.management.modelmbean.ModelMBeanConstructorInfo JavaDoc;
48 import javax.management.modelmbean.ModelMBeanInfo JavaDoc;
49 import javax.management.modelmbean.ModelMBeanInfoSupport JavaDoc;
50 import javax.management.modelmbean.ModelMBeanNotificationInfo JavaDoc;
51 import javax.management.modelmbean.ModelMBeanOperationInfo JavaDoc;
52 import javax.xml.parsers.DocumentBuilder JavaDoc;
53 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
54 import javax.xml.parsers.ParserConfigurationException JavaDoc;
55
56 import org.jboss.mx.interceptor.StandardMBeanInfoInterceptor;
57 import org.jboss.mx.metadata.MBeanInfoConversion;
58 import org.jboss.mx.metadata.MetaDataBuilder;
59 import org.jboss.mx.metadata.StandardMetaData;
60 import org.jboss.mx.metadata.XMLMetaData;
61
62 /**
63  * XMBean implementation.
64  *
65  * @author <a HREF="mailto:juha@jboss.org">Juha Lindfors</a>.
66  * @author Matt Munz
67  * @author <a HREF="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
68  * @version $Revision: 37459 $
69  */

70 public class XMBean
71    extends ModelMBeanInvoker
72    implements XMBeanConstants, NotificationListener JavaDoc
73 {
74
75    // Constructors --------------------------------------------------
76

77    /**
78     * Default constructor for the XMBean Model MBean implementation. This
79     * creates an uninitialized Model MBean template.
80     */

81    public XMBean() throws MBeanException JavaDoc
82    {
83       try
84       {
85          setManagedResource(new Object JavaDoc(), OBJECT_REF);
86          setModelMBeanInfo(new ModelMBeanInfoSupport JavaDoc("XMBean", "Uninitialized XMBean", new ModelMBeanAttributeInfo JavaDoc[0],
87                  new ModelMBeanConstructorInfo JavaDoc[0], new ModelMBeanOperationInfo JavaDoc[0], new ModelMBeanNotificationInfo JavaDoc[0]));
88       }
89       catch (RuntimeException JavaDoc e)
90       {
91          throw new RuntimeOperationsException JavaDoc(e);
92       }
93       catch (Exception JavaDoc e)
94       {
95          throw new MBeanException JavaDoc(e);
96       }
97    }
98
99    /**
100     * Creates an XMBean Model MBean implementation with a predefined JMX
101     * metadata.
102     *
103     * @param info Model MBean metadata describing this MBean template
104     */

105    public XMBean(ModelMBeanInfo JavaDoc info) throws MBeanException JavaDoc
106    {
107       super(info);
108    }
109
110    /**
111     * Creates a XMBean instance with a given resource object and resource type. <p>
112     *
113     * This Model MBean implementation supports the following resource types: <br><pre>
114     *
115     * - {@link ModelMBeanConstants#OBJECT_REF OBJECT_REF}
116     * - {@link XMBeanConstants#STANDARD_INTERFACE STANDARD_INTERFACE}
117     * - {@link XMBeanConstants#DESCRIPTOR DESCRIPTOR}
118     * - Any valid URL string to a *.xml file.
119     *
120     * </pre>
121     *
122     * <tt><b>OBJECT_REF:</b></tt> resource object can be any Java object. The
123     * management interface must be set separately via
124     * {@link javax.management.modelmbean.ModelMBean#setModelMBeanInfo setModelMBeanInfo}
125     * method. <p>
126     *
127     * <tt><b>STANDARD_INTERFACE:</b></tt> the resource object is assumed to
128     * follow the Standard MBean naming conventions to expose its management
129     * interface, including implementing a <tt>xxxMBean</tt> interface. A
130     * corresponding Model MBean metadata is generated for the Model MBean
131     * representing this resource type. <p>
132     *
133     * <tt><b>DESCRIPTOR:</b></tt> the resource object is wrapped as a part of
134     * the {@link javax.management.Descriptor Descriptor} object passed to this
135     * Model MBean instance. The descriptor object must contain the mandatory
136     * fields {@link XMBeanConstants#RESOURCE_REFERENCE RESOURCE_REFERENCE} and
137     * {@link XMBeanConstants#RESOURCE_TYPE RESOURCE_TYPE} that identify the
138     * correct resource reference and type used for this Model MBean instance.
139     * The descriptor object may also contain additional fields, such as
140     * {@link XMBeanConstants#SAX_PARSER SAX_PARSER} and
141     * {@link XMBeanConstants#XML_VALIDATION XML_VALIDATION} that are passed as
142     * configuration properties for the metadata builder instances. Any
143     * additional descriptor fields that match the
144     * {@link XMBeanConstants#METADATA_DESCRIPTOR_PREFIX METADATA_DESCRIPTOR_PREFIX}
145     * naming pattern will be passed to the builder implementation via its
146     * {@link org.jboss.mx.metadata.MetaDataBuilder#setProperty setProperty}
147     * method. <p>
148     *
149     * <tt><b>URL String:</b></tt> if a resource type string contains an URL
150     * that ends with a *.xml file name the resource object is exposed via the
151     * XML management interface definition read from this URL. The XML parser
152     * implementation is picked based on the schema definition in the XML
153     * document.
154     *
155     * @param resource resource object or descriptor
156     * @param resourceType resource type string or URL to *.xml file
157     */

158    public XMBean(Object JavaDoc resource, String JavaDoc resourceType) throws MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
159    {
160       // TODO: document STANDARD_MBEAN
161

162       ModelMBeanInfo JavaDoc minfo = null;
163       try
164       {
165          HashMap JavaDoc properties = new HashMap JavaDoc();
166
167          if (resourceType.equals(DESCRIPTOR))
168          {
169             Descriptor JavaDoc d = (Descriptor JavaDoc)resource;
170
171             // get the actual resource type from the descriptor
172
resourceType = (String JavaDoc)d.getFieldValue(RESOURCE_TYPE);
173
174             // and the resource reference
175
resource = d.getFieldValue(RESOURCE_REFERENCE);
176
177             // extract builder configuration fields
178
String JavaDoc[] fields = d.getFieldNames();
179
180             for (int i = 0; i < fields.length; ++i)
181             {
182                // extract all the fields starting with the METADATA_DESCRIPTOR_PREFIX
183
// prefix to a property map that is passed to the builder implementations
184
if (fields[i].startsWith(METADATA_DESCRIPTOR_PREFIX))
185                   properties.put(fields[i], d.getFieldValue(fields[i]));
186             }
187          }
188
189          if (resourceType.equals(STANDARD_MBEAN) && resource instanceof StandardMBean JavaDoc)
190             setManagedResource(((StandardMBean JavaDoc)resource).getImplementation(), resourceType);
191          else
192             setManagedResource(resource, resourceType);
193
194          // automatically create management operations that the attributes
195
// can map to.
196
final boolean CREATE_ATTRIBUTE_OPERATION_MAPPING = true;
197
198          // the resource extends StandardMBean
199
if (resourceType.equals(STANDARD_MBEAN) &&
200              resource instanceof StandardMBean JavaDoc)
201          {
202             StandardMBean JavaDoc standardMBean = (StandardMBean JavaDoc) resource;
203             minfo = MBeanInfoConversion.toModelMBeanInfo(standardMBean.getMBeanInfo(),
204                CREATE_ATTRIBUTE_OPERATION_MAPPING);
205          }
206
207          // the resource implements a Standard MBean interface
208
else if ((resourceType.equals(STANDARD_INTERFACE)) ||
209              (resourceType.equals(STANDARD_MBEAN)))
210          {
211             dynamicResource = false;
212             
213             // create and configure the builder
214
MetaDataBuilder builder = new StandardMetaData(resource);
215
216             // pass the config keys to the builder instance
217
for (Iterator JavaDoc it = properties.keySet().iterator(); it.hasNext();)
218             {
219                String JavaDoc key = (String JavaDoc)it.next();
220                builder.setProperty(key, properties.get(key));
221             }
222
223             // build the metadata
224
MBeanInfo JavaDoc standardInfo = builder.build();
225
226             // StandardMetaData is used by the MBean server to introspect
227
// standard MBeans. We need to now turn that Standard metadata into
228
// ModelMBean metadata (including operation mapping for attributes)
229
minfo = MBeanInfoConversion.toModelMBeanInfo(standardInfo, CREATE_ATTRIBUTE_OPERATION_MAPPING);
230          }
231
232          // If the resource type string ends with an '.xml' extension attempt
233
// to create the metadata with the aggregated XML builder.
234
else if (resourceType.endsWith(".xml"))
235          {
236             // Create and configure the builder. XMLMetaData builder is an
237
// aggregate builder that picks the correct schema specific builder
238
// based on schema declaration at the beginning of the XML file.
239

240             MetaDataBuilder builder = new XMLMetaData(
241                   this.getClass().getName(), // MMBean implementation name
242
resource.getClass().getName(), // resource class name
243
resourceType
244             );
245
246             // pass the config keys to the builder instance
247
for (Iterator JavaDoc it = properties.keySet().iterator(); it.hasNext();)
248             {
249                String JavaDoc key = (String JavaDoc)it.next();
250                builder.setProperty(key, properties.get(key));
251             }
252
253             minfo = (ModelMBeanInfo JavaDoc) builder.build();
254          }
255          // Sotre the ModelMBeanInfo
256
this.setModelMBeanInfo(minfo);
257
258          // we must try to load this MBean (as the superclass does), even if only NullPersistence
259
// is used - MMM
260
load();
261       }
262       catch (InstanceNotFoundException JavaDoc e)
263       {
264          throw new MBeanException JavaDoc(e);
265       }
266       catch (InvalidTargetObjectTypeException JavaDoc e)
267       {
268          if (resourceType.endsWith(".xml"))
269             throw new MBeanException JavaDoc(e, "Malformed URL: " + resourceType);
270
271          throw new MBeanException JavaDoc(e, "Unsupported resource type: " + resourceType);
272       }
273       catch (MalformedURLException JavaDoc e)
274       {
275          throw new MBeanException JavaDoc(e, "Malformed URL: " + resourceType);
276       }
277    }
278
279
280    public XMBean(Object JavaDoc resource, URL JavaDoc interfaceURL) throws MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
281    {
282       this(resource, interfaceURL.toString());
283    }
284
285
286    public XMBean(Descriptor JavaDoc descriptor) throws MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
287    {
288       this(descriptor, DESCRIPTOR);
289    }
290
291    public XMBean(Object JavaDoc resource, org.w3c.dom.Element JavaDoc element, String JavaDoc version) throws MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
292    {
293       try
294       {
295          DocumentBuilder JavaDoc builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
296          org.w3c.dom.Document JavaDoc doc = builder.newDocument();
297          doc.appendChild(doc.importNode(element, true));
298
299          org.dom4j.io.DOMReader domReader = new org.dom4j.io.DOMReader();
300          org.dom4j.Document dom4jDoc = domReader.read(doc);
301          org.dom4j.Element dom4jElem = dom4jDoc.getRootElement();
302          dom4jElem.detach();
303          createXMBean(resource, dom4jElem, version);
304       }
305       catch (ParserConfigurationException JavaDoc e)
306       {
307          throw new MBeanException JavaDoc(e, "Could not convert w3c Element to dom4j Element.");
308       }
309
310    }
311
312    public XMBean(Object JavaDoc resource, org.dom4j.Element element, String JavaDoc version) throws MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
313    {
314       // this(resource, OBJECT_REF);
315
createXMBean(resource, element, version);
316
317    }
318
319    private void createXMBean(Object JavaDoc resource, org.dom4j.Element element, String JavaDoc version)
320          throws MBeanException JavaDoc, NotCompliantMBeanException JavaDoc
321    {
322       try
323       {
324          setManagedResource(resource, OBJECT_REF);
325          MetaDataBuilder builder = new XMLMetaData(
326             this.getClass().getName(), // MMBean implementation name
327
resource.getClass().getName(), // resource class name
328
element,
329             version
330             );
331
332          ModelMBeanInfo JavaDoc minfo = (ModelMBeanInfo JavaDoc) builder.build();
333          this.setModelMBeanInfo(minfo);
334       }
335       catch (InstanceNotFoundException JavaDoc e)
336       {
337          throw new MBeanException JavaDoc(e);
338       }
339       catch (InvalidTargetObjectTypeException JavaDoc e)
340       {
341          throw new MBeanException JavaDoc(e, "Unsupported resource type: " + resourceType);
342       }
343
344    }
345
346
347    // Public --------------------------------------------------------
348

349    public boolean isSupportedResourceType(Object JavaDoc resource, String JavaDoc resourceType)
350    {
351       if (resourceType == null)
352          return false;
353
354       if (resourceType.equalsIgnoreCase(OBJECT_REF))
355          return true;
356       if (resourceType.equalsIgnoreCase(STANDARD_INTERFACE))
357          return true;
358       if (resourceType.equalsIgnoreCase(STANDARD_MBEAN))
359          return true;
360       if (resourceType.equalsIgnoreCase(DESCRIPTOR))
361       {
362          if (resource == null || !(resource instanceof Descriptor JavaDoc))
363             return false;
364
365          Descriptor JavaDoc d = (Descriptor JavaDoc)resource;
366
367          if (d.getFieldValue(RESOURCE_REFERENCE) == null)
368             return false;
369
370          if (d.getFieldValue(RESOURCE_TYPE) == null)
371             return false;
372
373          return true;
374       }
375       if (resourceType.endsWith(".xml"))
376       {
377          try
378          {
379             new URL JavaDoc(resourceType);
380             return true;
381          }
382          catch (MalformedURLException JavaDoc e)
383          {
384             return false;
385          }
386       }
387
388       return false;
389    }
390
391
392    // ModelMBeanInvoker overrides -----------------------------------
393

394    protected void configureInterceptorStack(ModelMBeanInfo JavaDoc info,
395       MBeanServer JavaDoc server, ObjectName JavaDoc name)
396      throws Exception JavaDoc
397    {
398       // FIXME: do not require super calls
399

400       super.configureInterceptorStack(info, server, name);
401
402       if (resourceType.equals(STANDARD_MBEAN))
403       {
404          List JavaDoc interceptors = getMBeanInfoCtx.getInterceptors();
405          interceptors.add(0, new StandardMBeanInfoInterceptor());
406          getMBeanInfoCtx.setInterceptors(interceptors);
407       }
408    }
409
410    // NotificationBroadcaster overrides -----------------------------
411

412    // TODO: intercept these... (?) rather than do this overriding
413

414    public void addNotificationListener(NotificationListener JavaDoc listener,
415                                        NotificationFilter JavaDoc filter, Object JavaDoc handback)
416    {
417       // a standard mbean handles broadcasting itself (if a broadcaster)
418
if (resourceType.equals(STANDARD_MBEAN))
419       {
420          addNotificationListenerToResource(listener, filter, handback);
421       }
422       else
423       {
424          // for all other types register a listener for AVCs
425
// (including XMBeans wrapping POJOs or standard mbean impls)
426
super.addNotificationListener(listener, filter, handback);
427          
428          // in addition if the resource is a broadcaster update its subscription list
429
if (getResource() instanceof NotificationBroadcaster JavaDoc)
430             addNotificationListenerToResource(listener, filter, handback);
431       }
432    }
433
434    public void removeNotificationListener(NotificationListener JavaDoc listener)
435          throws ListenerNotFoundException JavaDoc
436    {
437       // a standard mbean handles broadcasting itself (if a broadcaster)
438
if (resourceType.equals(STANDARD_MBEAN))
439       {
440          removeNotificationListenerFromResource(listener);
441       }
442       else
443       {
444          // for all other types remove the listener for AVCs
445
// (including XMBeans wrapping POJOs or standard mbean impls)
446
super.removeNotificationListener(listener);
447          
448          // in addition if the resource is a broadcaster update its subscription list
449
if (getResource() instanceof NotificationBroadcaster JavaDoc)
450             removeNotificationListenerFromResource(listener);
451       }
452    }
453
454    public void removeNotificationListener(NotificationListener JavaDoc listener,
455                                           NotificationFilter JavaDoc filter,
456                                           Object JavaDoc handback)
457          throws ListenerNotFoundException JavaDoc
458    {
459       // a standard mbean handles broadcasting itself (if a broadcaster)
460
if (resourceType.equals(STANDARD_MBEAN))
461       {
462          removeNotificationListenerFromResource(listener, filter, handback);
463       }
464       else
465       {
466          // for all other types remove the listener for AVCs
467
// (including XMBeans wrapping POJOs or standard mbean impls)
468
super.removeNotificationListener(listener, filter, handback);
469          
470          // in addition if the resource is a broadcaster update its subscription list
471
if (getResource() instanceof NotificationBroadcaster JavaDoc)
472             removeNotificationListenerFromResource(listener, filter, handback);
473       }
474    }
475
476    public MBeanNotificationInfo JavaDoc[] getNotificationInfo()
477    {
478       if (resourceType.equals(STANDARD_MBEAN))
479          return getNotificationInfoFromResource();
480       else
481          return super.getNotificationInfo();
482    }
483
484    // NotificationListener overrides --------------------------------
485

486    /**
487     * Implements NotificationListener interface by simply forwarding
488     * any received Notification to the wrapped resource, if it
489     * implements the NotificationListener interface, too.
490     *
491     * This is needed to allow the wrapped resource to register for
492     * Notifications using the XMBean ObjectName, rather than its own
493     * "this" reference - dimitris
494     */

495    public void handleNotification(Notification JavaDoc notification, Object JavaDoc handback)
496    {
497       Object JavaDoc resource = getResource();
498       
499       if (resource instanceof NotificationListener JavaDoc)
500          ((NotificationListener JavaDoc)resource).handleNotification(notification, handback);
501    }
502
503 }
504
Popular Tags