KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ant > JMX


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.ant;
23
24 import java.beans.PropertyEditor JavaDoc;
25 import java.beans.PropertyEditorManager JavaDoc;
26 import java.util.ArrayList JavaDoc;
27 import java.util.List JavaDoc;
28 import java.util.Properties JavaDoc;
29 import javax.management.Attribute JavaDoc;
30 import javax.management.MBeanServerConnection JavaDoc;
31 import javax.management.ObjectName JavaDoc;
32 import javax.naming.Context JavaDoc;
33 import javax.naming.InitialContext JavaDoc;
34 import org.apache.tools.ant.BuildException;
35 import org.apache.tools.ant.Task;
36 import org.jboss.util.propertyeditor.PropertyEditors;
37
38 /**
39  * JMX.java. An ant plugin to call managed operations and set attributes
40  * on mbeans in a jboss jmx mbean server.
41  * To use this plugin with Ant, place the jbossjmx-ant.jar together with the
42  * jboss jars jboss-j2ee.jar and jboss-common-client.jar, and the sun jnet.jar in the
43  * ant/lib directory you wish to use.
44  *
45  * Here is an example from an ant build file.
46  *
47  * <target name="jmx">
48  * <taskdef name="jmx"
49  * classname="org.jboss.ant.JMX"/>
50  * <jmx adapterName="jmx:HP.home.home:rmi">
51  *
52  * <propertyEditor type="java.math.BigDecimal" editor="org.jboss.util.propertyeditor.BigDecimalEditor"/>
53  * <propertyEditor type="java.util.Date" editor="org.jboss.util.propertyeditor.DateEditor"/>
54  *
55  *
56  * <!-- define classes -->
57  * <invoke target="fgm.sysadmin:service=DefineClasses"
58  * operation="defineClasses">
59  * <parameter type="java.lang.String" arg="defineclasses.xml"/>
60  * </invoke>
61  * </jmx>
62  *
63  *
64  * Created: Tue Jun 11 20:17:44 2002
65  *
66  * @author <a HREF="mailto:d_jencks@users.sourceforge.net">David Jencks</a>
67  * @author <a HREF="mailto:dsnyder_lion@users.sourceforge.net">David Snyder</a>
68  * @version
69  */

70 public class JMX extends Task
71 {
72    private String JavaDoc serverURL;
73
74    private String JavaDoc adapterName = "jmx/invoker/RMIAdaptor";
75
76    private List JavaDoc ops = new ArrayList JavaDoc();
77
78    private List JavaDoc editors = new ArrayList JavaDoc();
79
80    /**
81     * Creates a new <code>JMX</code> instance.
82     * Provides a default adapterName for the current server, so you only need to set it to
83     * talk to a remote server.
84     *
85     * @exception Exception if an error occurs
86     */

87    public JMX() throws Exception JavaDoc
88    {
89    }
90
91    /**
92     * Use the <code>setServerURL</code> method to set the URL of the server
93     * you wish to connect to.
94     *
95     * @param serverURL a <code>String</code> value
96     */

97    public void setServerURL(String JavaDoc serverURL)
98    {
99       this.serverURL = serverURL;
100    }
101
102    /**
103     * Use the <code>setAdapterName</code> method to set the name the
104     * adapter mbean is bound under in jndi.
105     *
106     * @param adapterName a <code>String</code> value
107     */

108    public void setAdapterName(String JavaDoc adapterName)
109    {
110       this.adapterName = adapterName;
111    }
112
113    /**
114     * Use the <code>addInvoke</code> method to add an <invoke> operation.
115     * Include as attributes the target ObjectName and operation name.
116     * Include as sub-elements parameters: see addParameter in the Invoke class.
117     *
118     * @param invoke an <code>Invoke</code> value
119     */

120    public void addInvoke(Invoke invoke)
121    {
122       ops.add(invoke);
123    }
124
125    /**
126     * Use the <code>addSetAttribute</code> method to add a set-attribute
127     * operation. Include as attributes the target ObjectName and the
128     * the attribute name. Include the value as a nested value tag
129     * following the parameter syntax.
130     *
131     * @param setter a <code>Setter</code> value
132     */

133    public void addSetAttribute(Setter setter)
134    {
135       ops.add(setter);
136    }
137
138    /**
139     * Use the <code>addGetAttribute</code> method to add a get-attribute
140     * operation. Include as attributes the target ObjectName, the
141     * the attribute name, and a property name to hold the result of the
142     * get-attribute operation.
143     *
144     * @param getter a <code>Getter</code> value
145     */

146    public void addGetAttribute(Getter getter)
147    {
148        ops.add(getter);
149    }
150
151    /**
152     * Use the <code>addPropertyEditor</code> method to make a PropertyEditor
153     * available for values. Include attributes for the type and editor fully
154     * qualified class name.
155     *
156     * @param peh a <code>PropertyEditorHolder</code> value
157     */

158    public void addPropertyEditor(PropertyEditorHolder peh)
159    {
160       editors.add(peh);
161    }
162
163    /**
164     * The <code>execute</code> method is called by ant to execute the task.
165     *
166     * @exception BuildException if an error occurs
167     */

168    public void execute() throws BuildException
169    {
170       final ClassLoader JavaDoc origCL = Thread.currentThread().getContextClassLoader();
171       try
172       {
173          Thread.currentThread().setContextClassLoader(getClass().getClassLoader());
174          try
175          {
176             for (int i = 0; i < editors.size(); i++)
177             {
178                ((PropertyEditorHolder)editors.get(i)).execute();
179             } // end of for ()
180

181    
182          }
183          catch (Exception JavaDoc e)
184          {
185             e.printStackTrace();
186             throw new BuildException("Could not register property editors: " + e);
187          } // end of try-catch
188

189          try
190          {
191             Properties JavaDoc props = new Properties JavaDoc();
192             props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
193             props.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
194    
195             if (serverURL == null || "".equals(serverURL))
196             {
197                props.put(Context.PROVIDER_URL, "jnp://localhost:1099");
198             }
199             else
200             {
201                props.put(Context.PROVIDER_URL, serverURL);
202             }
203             InitialContext JavaDoc ctx = new InitialContext JavaDoc(props);;
204    
205             // if adapter is null, the use the default
206
if (adapterName == null) {
207                adapterName = "jmx/rmi/RMIAdaptor";//org.jboss.jmx.adaptor.rmi.RMIAdaptorService.DEFAULT_JNDI_NAME;
208
}
209    
210             Object JavaDoc obj = ctx.lookup(adapterName);
211             ctx.close();
212    
213             if (!(obj instanceof MBeanServerConnection JavaDoc)) {
214                throw new ClassCastException JavaDoc
215                   ("Object not of type: MBeanServerConnection, but: " +
216                    (obj == null ? "not found" : obj.getClass().getName()));
217             }
218    
219             MBeanServerConnection JavaDoc server = (MBeanServerConnection JavaDoc) obj;
220
221             for (int i = 0; i < ops.size(); i++)
222             {
223                Operation op = (Operation)ops.get(i);
224                op.execute(server, this);
225             } // end of for ()
226

227    
228          }
229          catch (Exception JavaDoc e)
230          {
231             e.printStackTrace();
232             throw new BuildException("problem: " + e);
233          } // end of try-catch
234
}
235       finally
236       {
237          Thread.currentThread().setContextClassLoader(origCL);
238       }
239
240    }
241
242    /**
243     * The interface <code>Operation</code> provides a common interface
244     * for the sub-tasks..
245     *
246     */

247    public static interface Operation
248    {
249       void execute(MBeanServerConnection JavaDoc server, Task parent) throws Exception JavaDoc;
250    }
251
252    /**
253     * The class <code>Invoke</code> specifies the invocation of a
254     * managed operation.
255     *
256     */

257    public static class Invoke
258       implements Operation
259    {
260       private ObjectName JavaDoc target;
261       private String JavaDoc property;
262
263       private String JavaDoc operation;
264
265       private List JavaDoc params = new ArrayList JavaDoc();
266
267       /**
268        * The <code>setProperty</code> method sets the name of the property
269        * that will contain the result of the operation.
270        *
271        * @param property a <code>String</code> value
272        */

273       public void setProperty(String JavaDoc property)
274       {
275           this.property = property;
276       }
277
278       /**
279        * The <code>setTarget</code> method sets the ObjectName
280        * of the target mbean.
281        *
282        * @param target an <code>ObjectName</code> value
283        */

284       public void setTarget(ObjectName JavaDoc target)
285       {
286          this.target = target;
287       }
288
289       /**
290        * The <code>setOperation</code> method specifies the operation to
291        * be performed.
292        *
293        * @param operation a <code>String</code> value
294        */

295       public void setOperation(String JavaDoc operation)
296       {
297          this.operation = operation;
298       }
299
300       /**
301        * The <code>addParameter</code> method adds a parameter for
302        * the operation. You must specify type and value.
303        *
304        * @param param a <code>Param</code> value
305        */

306       public void addParameter(Param param)
307       {
308          params.add(param);
309       }
310
311       public void execute(MBeanServerConnection JavaDoc server, Task parent) throws Exception JavaDoc
312       {
313          int paramCount = params.size();
314          Object JavaDoc[] args = new Object JavaDoc[paramCount];
315          String JavaDoc[] types = new String JavaDoc[paramCount];
316          int pos = 0;
317          for (int i = 0; i < params.size(); i++)
318          {
319             Param p = (Param)params.get(i);
320             args[pos] = p.getValue();
321             types[pos] = p.getType();
322             pos++;
323          } // end of for ()
324
Object JavaDoc result = server.invoke(target, operation, args, types);
325          if( (property != null) && (result != null) )
326          {
327              parent.getProject().setProperty(property,result.toString());
328          }
329       }
330    }
331
332    /**
333     * The class <code>Setter</code> specifies setting an attribute
334     * value on an mbean.
335     *
336     */

337    public static class Setter
338       implements Operation
339    {
340       private ObjectName JavaDoc target;
341
342       private String JavaDoc attribute;
343
344       private Param value;
345
346       /**
347        * The <code>setTarget</code> method sets the ObjectName
348        * of the target mbean.
349        *
350        * @param target an <code>ObjectName</code> value
351        */

352       public void setTarget(ObjectName JavaDoc target)
353       {
354          this.target = target;
355       }
356
357       /**
358        * The <code>setAttribute</code> method specifies the attribute to be set.
359        *
360        * @param attribute a <code>String</code> value
361        */

362       public void setAttribute(String JavaDoc attribute)
363       {
364          this.attribute = attribute;
365       }
366
367       /**
368        * The <code>setValue</code> method specifies the value to be used.
369        * The type is used to convert the value to the correct type.
370        *
371        * @param value a <code>Param</code> value
372        */

373       public void setValue(Param value)
374       {
375          this.value = value;
376       }
377
378       public void execute(MBeanServerConnection JavaDoc server, Task parent) throws Exception JavaDoc
379       {
380          Attribute JavaDoc att = new Attribute JavaDoc(attribute, value.getValue());
381          server.setAttribute(target, att);
382       }
383    }
384
385    /**
386     * The class <code>Getter</code> specifies getting an attribute
387     * value of an mbean.
388     *
389     */

390    public static class Getter
391            implements Operation
392    {
393        private ObjectName JavaDoc target;
394
395        private String JavaDoc attribute;
396
397        private String JavaDoc property;
398
399        /**
400         * The <code>setTarget</code> method sets the ObjectName
401         * of the target mbean.
402         *
403         * @param target an <code>ObjectName</code> value
404         */

405        public void setTarget(ObjectName JavaDoc target)
406        {
407            this.target = target;
408        }
409
410        /**
411         * The <code>setAttribute</code> method specifies the attribute to be
412         * retrieved.
413         *
414         * @param attribute a <code>String</code> value
415         */

416        public void setAttribute(String JavaDoc attribute)
417        {
418            this.attribute = attribute;
419        }
420
421        /**
422         * The <code>setProperty</code> method specifies the name of the property
423         * to be set with the attribute value.
424         *
425         * @param property a <code>String</code> value
426         */

427        public void setProperty(String JavaDoc property)
428        {
429            this.property = property;
430        }
431
432        public void execute(MBeanServerConnection JavaDoc server, Task parent) throws Exception JavaDoc
433        {
434            Object JavaDoc result = server.getAttribute(target,attribute);
435            if( (property != null) && (result != null) )
436            {
437                parent.getProject().setProperty(property,result.toString());
438            }
439        }
440    }
441
442    /**
443     * The class <code>Param</code> is used to represent a object by
444     * means of a string representation of its value and its type.
445     *
446     */

447    public static class Param
448    {
449       private String JavaDoc arg;
450       private String JavaDoc type;
451
452       /**
453        * The <code>setArg</code> method sets the string representation
454        * of the parameters value.
455        *
456        * @param arg a <code>String</code> value
457        */

458       public void setArg(String JavaDoc arg)
459       {
460          this.arg = arg;
461       }
462
463       public String JavaDoc getArg()
464       {
465          return arg;
466       }
467
468       /**
469        * The <code>setType</code> method sets the fully qualified class
470        * name of the type represented by the param object.
471        *
472        * @param type a <code>String</code> value
473        */

474       public void setType(String JavaDoc type)
475       {
476          this.type = type;
477       }
478
479       public String JavaDoc getType()
480       {
481          return type;
482       }
483
484       /**
485        * The <code>getValue</code> method uses PropertyEditors to convert
486        * the string representation of the value to an object, which it returns.
487        * The PropertyEditor to use is determined by the type specified.
488        *
489        * @return an <code>Object</code> value
490        * @exception Exception if an error occurs
491        */

492       public Object JavaDoc getValue() throws Exception JavaDoc
493       {
494          PropertyEditor JavaDoc editor = PropertyEditors.getEditor(type);
495          editor.setAsText(arg);
496          return editor.getValue();
497       }
498    }
499
500    /**
501     * The class <code>PropertyEditorHolder</code> allows you to add a
502     * PropertyEditor to the default set.
503     *
504     */

505    public static class PropertyEditorHolder
506    {
507       private String JavaDoc type;
508       private String JavaDoc editor;
509
510       /**
511        * The <code>setType</code> method specifies the return type from the
512        * property editor.
513        *
514        * @param type a <code>String</code> value
515        */

516       public void setType(final String JavaDoc type)
517       {
518          this.type = type;
519       }
520
521       public String JavaDoc getType()
522       {
523          return type;
524       }
525
526       private Class JavaDoc getTypeClass() throws ClassNotFoundException JavaDoc
527       {
528          //with a little luck, one of these will work with Ant's classloaders
529
try
530          {
531             return Class.forName(type);
532          }
533          catch (ClassNotFoundException JavaDoc e)
534          {
535          } // end of try-catch
536
try
537          {
538             return getClass().getClassLoader().loadClass(type);
539          }
540          catch (ClassNotFoundException JavaDoc e)
541          {
542          } // end of try-catch
543
return Thread.currentThread().getContextClassLoader().loadClass(type);
544       }
545
546       /**
547        * The <code>setEditor</code> method specifies the fully qualified
548        * class name of the PropertyEditor for the type specified in the type field.
549        *
550        * @param editor a <code>String</code> value
551        */

552       public void setEditor(final String JavaDoc editor)
553       {
554          this.editor = editor;
555       }
556
557       public String JavaDoc getEditor()
558       {
559          return editor;
560       }
561
562       private Class JavaDoc getEditorClass() throws ClassNotFoundException JavaDoc
563       {
564          //with a little luck, one of these will work with Ant's classloaders
565
try
566          {
567             return Class.forName(editor);
568          }
569          catch (ClassNotFoundException JavaDoc e)
570          {
571          } // end of try-catch
572
try
573          {
574             return getClass().getClassLoader().loadClass(editor);
575          }
576          catch (ClassNotFoundException JavaDoc e)
577          {
578          } // end of try-catch
579
return Thread.currentThread().getContextClassLoader().loadClass(editor);
580       }
581
582       public void execute() throws ClassNotFoundException JavaDoc
583       {
584          PropertyEditorManager.registerEditor(getTypeClass(), getEditorClass());
585       }
586    }
587    
588 }// JMX
589
Popular Tags