KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > mx4j > tools > jython > JythonRunner


1 /*
2  * Copyright (C) The MX4J Contributors.
3  * All rights reserved.
4  *
5  * This software is distributed under the terms of the MX4J License version 1.0.
6  * See the terms of the MX4J License in the documentation provided with this software.
7  */

8
9 package mx4j.tools.jython;
10
11 import java.io.BufferedReader JavaDoc;
12 import java.io.IOException JavaDoc;
13 import java.io.InputStream JavaDoc;
14 import java.io.InputStreamReader JavaDoc;
15 import java.net.URL JavaDoc;
16 import javax.management.InstanceNotFoundException JavaDoc;
17 import javax.management.ListenerNotFoundException JavaDoc;
18 import javax.management.MBeanRegistration JavaDoc;
19 import javax.management.MBeanServer JavaDoc;
20 import javax.management.Notification JavaDoc;
21 import javax.management.NotificationFilter JavaDoc;
22 import javax.management.NotificationListener JavaDoc;
23 import javax.management.ObjectName JavaDoc;
24
25 import mx4j.log.Log;
26 import mx4j.log.Logger;
27 import org.python.core.Py;
28 import org.python.core.PyCode;
29 import org.python.core.PySystemState;
30 import org.python.util.PythonInterpreter;
31
32 /**
33  * This MBean enables you to run scripts written in jython. Scripts can be run
34  * using the managed operation runScript or by listening notifcations from
35  * another MBean. To us it you need to install jython 2.1 or higher from
36  * <a HREF="http://www.jython.org">here&lt/a&gt
37  * <p/>
38  * If you want to use a jython library remember to add the jython jar to the
39  * classpath in the right location or modify the python.path address
40  * <p/>
41  * The scripts have always the &quot;server&quot; embedded variable which points
42  * to the current server. It also automatically import some JMX modules as:
43  * <p/>
44  * <ul>
45  * <li>from javax.management import *
46  * <li>from javax.management.loading import *
47  * </ul>
48  *
49  * @version $Revision: 1.9 $
50  */

51 public class JythonRunner implements JythonRunnerMBean, NotificationListener JavaDoc, MBeanRegistration JavaDoc
52 {
53    private MBeanServer JavaDoc server = null;
54
55    private ObjectName JavaDoc targetMBeanName, objectName;
56
57    private String JavaDoc notificationName;
58
59    private boolean useText = true;
60
61    private boolean useCache = false;
62
63    private String JavaDoc scriptText;
64
65    private URL JavaDoc scriptFile;
66
67    private PyCode cache = null;
68
69    private static PythonInterpreter interpreter;
70
71    public void handleNotification(Notification JavaDoc notification, Object JavaDoc handback)
72    {
73       if (notificationName != null && !notification.getType().equals(notificationName)) return;
74
75       Logger logger = getLogger();
76       if (logger.isEnabledFor(Logger.DEBUG)) logger.debug("Notification " + notification + " hit, sending message");
77       runScript();
78    }
79
80    private Logger getLogger()
81    {
82       return Log.getLogger(getClass().getName());
83    }
84
85    /**
86     * Executes a given script. If useText is true the text passed will be run as a script
87     * otherwise the script will be loaded from the URL an executed
88     */

89    public void runScript()
90    {
91       PythonInterpreter interp = getPythonInterpreter();
92       interp.set("server", server);
93       String JavaDoc script = null;
94       if (useText)
95       {
96          script = scriptText;
97       }
98       else
99       {
100          try
101          {
102             script = loadStream(scriptFile.openStream());
103          }
104          catch (IOException JavaDoc e)
105          {
106             Logger log = getLogger();
107             log.error("Exception during url opening", e);
108          }
109       }
110       interp.exec(script);
111    }
112
113    public static PythonInterpreter getPythonInterpreter()
114    {
115       if (interpreter == null)
116       {
117          interpreter = new PythonInterpreter();
118          PySystemState sys = Py.getSystemState();
119          sys.add_package("javax.management");
120          sys.add_package("javax.management.loading");
121          sys.add_package("javax.management.modelmbean");
122          sys.add_package("javax.management.monitor");
123          sys.add_package("javax.management.openmbean");
124          sys.add_package("javax.management.remote");
125          sys.add_package("javax.management.remote.rmi");
126          sys.add_package("javax.management.relation");
127          sys.add_package("javax.management.timer");
128          try
129          {
130             String JavaDoc script = loadStream(JythonRunner.class.getClassLoader().getResourceAsStream("mx4j/tools/jython/jmxUtils.py"));
131             interpreter.exec(script);
132          }
133          catch (IOException JavaDoc e)
134          {
135             e.printStackTrace();
136          }
137       }
138       return interpreter;
139    }
140
141    protected static String JavaDoc loadStream(InputStream JavaDoc in) throws IOException JavaDoc
142    {
143       BufferedReader JavaDoc reader = new BufferedReader JavaDoc(new InputStreamReader JavaDoc(in));
144       String JavaDoc line = null;
145       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc();
146       while ((line = reader.readLine()) != null)
147       {
148          buffer.append(line);
149          buffer.append("\n");
150       }
151       return buffer.toString();
152    }
153
154    /**
155     * Gets the specific notification type being listened
156     */

157    public String JavaDoc getNotificationType()
158    {
159       return notificationName;
160    }
161
162    /**
163     * Sets the notification being listed. If null any notification will trigger
164     * the execution of the script. Otherwise only notifications matching notificationName
165     * will trigger it
166     */

167    public void setNotificationType(String JavaDoc notificationName)
168    {
169       this.notificationName = notificationName;
170    }
171
172    /**
173     * Sets the object being observed by this MBean. The MBean will register
174     * itself as a listener of targetMBeanName
175     */

176    public void setObservedObject(ObjectName JavaDoc targetMBeanName)
177    {
178       this.targetMBeanName = targetMBeanName;
179       registerListener();
180    }
181
182    /**
183     * Gets the object being observed by this MBean
184     */

185    public ObjectName JavaDoc getObservedObject()
186    {
187       return targetMBeanName;
188    }
189
190    /**
191     * Indicates wether to use the script given in the ScripText variable or
192     * the one given in the script File.
193     */

194    public boolean getUseText()
195    {
196       return this.useText;
197    }
198
199    /**
200     * Sets the content of the script. If you want to use a file, use ScriptFile
201     * instead.
202     */

203    public void setScript(String JavaDoc text)
204    {
205       this.scriptText = text;
206       this.useText = true;
207    }
208
209    /**
210     * Returns the script as text.
211     */

212    public String JavaDoc getScript()
213    {
214       return this.scriptText;
215    }
216
217    /**
218     * Returns the URL pointing to the script source
219     */

220    public URL JavaDoc getScriptURL()
221    {
222       return scriptFile;
223    }
224
225    /**
226     * Sets the script source as URL. If the cache script variable is true
227     * the file will be loaded only once, otherwise everytime the script is
228     * executed
229     */

230    public void setScriptURL(URL JavaDoc file)
231    {
232       this.scriptFile = file;
233       this.useText = false;
234    }
235
236    /**
237     * Returns whether the script should be kept in the cache. If true, no further
238     * attempts to read the script will be done afterwards. By default is false
239     */

240    public boolean getCacheScript()
241    {
242       return useCache;
243    }
244
245    /**
246     * Sets whether the script should be kept in the cache. If true, no further
247     * attempts to read the script will be done afterwards. By default is false
248     */

249    public void setCacheScript(boolean useCache)
250    {
251       this.useCache = useCache;
252    }
253
254    /**
255     * Gathers some basic data
256     */

257    public ObjectName JavaDoc preRegister(MBeanServer JavaDoc server, ObjectName JavaDoc name)
258            throws java.lang.Exception JavaDoc
259    {
260       this.server = server;
261       this.objectName = name;
262       return name;
263    }
264
265
266    public void postRegister(Boolean JavaDoc registrationDone)
267    {
268    }
269
270
271    public void preDeregister() throws java.lang.Exception JavaDoc
272    {
273       unregisterListener();
274    }
275
276
277    public void postDeregister()
278    {
279    }
280
281    protected void registerListener()
282    {
283       try
284       {
285          if (targetMBeanName != null && server.isInstanceOf(targetMBeanName, "javax.management.NotificationBroadcaster"))
286          {
287             server.addNotificationListener(targetMBeanName, this, new MessageFilter(), null);
288          }
289       }
290       catch (InstanceNotFoundException JavaDoc e)
291       {
292          Logger log = getLogger();
293          log.error("Exception during notification registration", e);
294       }
295    }
296
297    protected void unregisterListener()
298    {
299       try
300       {
301          if (targetMBeanName != null && server.isInstanceOf(targetMBeanName, "javax.management.NotificationBroadcaster"))
302          {
303             server.removeNotificationListener(targetMBeanName, this);
304          }
305       }
306       catch (InstanceNotFoundException JavaDoc e)
307       {
308          Logger log = getLogger();
309          log.error("Exception during notification unregistration", e);
310       }
311       catch (ListenerNotFoundException JavaDoc e)
312       {
313       }
314    }
315
316    private class MessageFilter implements NotificationFilter JavaDoc
317    {
318       public boolean isNotificationEnabled(Notification JavaDoc notification)
319       {
320          return notificationName == null || (notification.getType() != null && notification.getType().equals(notificationName));
321       }
322    }
323 }
324
Popular Tags