KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > mmbase > module > builders > vwms > Vwm


1 /*
2
3 This software is OSI Certified Open Source Software.
4 OSI Certified is a certification mark of the Open Source Initiative.
5
6 The license (Mozilla version 1.0) can be read at the MMBase site.
7 See http://www.MMBase.org/license
8
9 */

10 package org.mmbase.module.builders.vwms;
11
12 import java.util.*;
13 import java.util.Properties JavaDoc;
14 import java.io.*;
15
16 import org.mmbase.util.logging.*;
17 import org.mmbase.module.core.*;
18 import org.mmbase.module.builders.*;
19
20 /**
21  * Virtual Web Master base object.
22  * Most VWM's inherit fromt his base class.
23  * The Vwm contains routines for performing tasks at certain intervals.
24  * The interval is determined from the maintime value in the Vwms builder (Maintenance time in seconds),
25  * Each interval, the vwm invokes the ProbeCall() method.
26  * VWMs perform periodic maintenance by overrideing the probeCall method (the default doesn't do anything).
27  * A VWM is also called a 'Bot'.
28  *
29  * @application VWMs
30  * @author Daniel Ockeloen
31  * @author Pierre van Rooden (javadocs)
32  * @version $Id: Vwm.java,v 1.16 2004/10/08 10:57:57 pierre Exp $
33  */

34
35 public class Vwm implements VwmInterface, VwmProbeInterface, Runnable JavaDoc {
36
37     // Logger class
38
private static Logger log = Logging.getLoggerInstance(Vwm.class);
39
40     // temporary debug method... has to change later on!
41
protected void debug(String JavaDoc msg) {
42         log.debug(msg);
43     }
44
45     /**
46     * Scheduler of tasks depending on VWMtask nodes associated with this Vwm.
47     */

48     protected VwmProbe probe;
49
50     /**
51     * Sleep time in seconds.
52     * This is the interval in which the VWM performs it's maintenance probes.
53     */

54     protected int sleeptime;
55
56     /**
57     * The creation node of this VWM.
58     * Used to retrieve the maintenance time and to maintain VWM state information.
59     */

60     protected MMObjectNode wvmnode;
61
62     /**
63     * Name of the VWM.
64     * Retrieved from the node from the VWMs builder, but can also be set manually by the VWM's overriding class.
65     */

66     protected String JavaDoc name = "Unknown";
67
68     /**
69     * The VWMs builder that holds the VWM's node.
70     * The same as the <code>parent</code> attribute of the vwm node (but a bit easier in use).
71     * @see #getVwmNode
72     */

73     protected Vwms Vwms;
74
75     /**
76     * Thread in which the VWM runs.
77     * This field can be used to stop the VWM.
78     * Setting kicker to null (either from outside the thread or within) will cause the VWM
79     * to terminate it's {@link #run} method.
80     */

81     Thread JavaDoc kicker = null;
82
83     /**
84     * What clients are using this VWM.
85     * Each client implements the {@link VwmCallBackInterface}, and can be invoked when important changes occur.
86     */

87     Vector clients = new Vector();
88
89     /**
90     * Initialize the Vwm.
91     * Called by the Vwms builder that starts the VWM.
92     * Sets a few fields, creates a new probe instance, and starts a new thread.
93     * @param vwmnode
94     * @param Vwms The VWMs builder. It is not really necessary as this is the same as the <code>parent</code> attribute of <code>vwmnode</code>.
95     */

96     public void init(MMObjectNode vwmnode, Vwms Vwms) {
97         this.wvmnode = vwmnode;
98         this.name = vwmnode.getStringValue("name");
99         this.sleeptime = wvmnode.getIntValue("maintime");
100         this.Vwms = Vwms;
101         /* or :
102             this.Vwms = (Vwms)vwmnode.parent;
103         */

104         probe = new VwmProbe(this);
105         this.start();
106     }
107
108     /**
109      * Starts the thread for the Vwm.
110      */

111     public void start() {
112         /* Start up the main thread */
113         if (kicker == null) {
114             kicker = new Thread JavaDoc(this, "Vwm : " + name);
115             kicker.setDaemon(true);
116             kicker.start();
117         }
118     }
119
120     /**
121      * Stops the Vwm's thread.
122      * Sets the kicker field to null, which causes the run method to terminate.
123      */

124     public void stop() {
125         /* Stop thread */
126         kicker.interrupt();
127         kicker = null;
128     }
129
130     /**
131      * VWM maintenance scheduler.
132      * Calls the {@link #probeCall} method, after which the thread sleeps for a number of seconds as set in {@link #sleeptime}.
133      */

134     public void run() {
135         while (kicker != null) {
136             try {
137                 probeCall();
138             } catch (Exception JavaDoc e) {
139                 log.error("Vwm : Got a Exception in my probeCall : " + e.getMessage());
140                 log.error(Logging.stackTrace(e));
141             }
142             try {
143                 Thread.sleep(sleeptime * 1000);
144             } catch (InterruptedException JavaDoc e) {
145                 //interrupted so exit
146
return;
147             }
148         }
149     }
150
151     /**
152     * Add a client to the listen queue of the wvm.
153     * @param client The client-object to add
154     * @return <code>true</code> if the client was added, <code>false</code> if it already existed in the queue.
155     */

156     public boolean addClient(VwmCallBackInterface client) {
157         if (clients.contains(client)) {
158             log.warn("Vwm : " + name + " allready has the client : " + client + ".");
159             return false;
160         } else {
161             clients.addElement(client);
162             return true;
163         }
164     }
165
166     /**
167     * Release a client from the listen queue of the wvm.
168     * @param client The client-object to release
169     * @return <code>true</code> if the client was released, <code>false</code> if it did not exist in the queue.
170     */

171     public boolean releaseClient(VwmCallBackInterface client) {
172         if (clients.contains(client)) {
173             clients.removeElement(client);
174             return true;
175         } else {
176             log.warn("Vwm : " + name + " got a release call from : " + client + " but have no idea who he is.");
177             return false;
178         }
179     }
180
181     /**
182     * Performs periodic maintenance.
183     * This method is called by the VWM's own {@link #run} method.
184     * Since this does not actually do anything, perhaps this method should be abstract.
185     * @return <code>true</code> if maintenance was performed, <code>false</code> otherwise
186     */

187     public boolean probeCall() {
188         log.info("Vwm probe call : " + name);
189         return false;
190     }
191
192     /**
193     * Adds a new task to the list of taks to perform.
194     * Passes the task to the VWM's probe, which handles the of tasks.
195     * @param node the node describing the task (from the Vwmtasks builder)
196     * @return <code>true</code> is the task was succesfully added.
197     */

198     public boolean putTask(MMObjectNode node) {
199         return probe.putTask(node);
200     }
201
202     /**
203     * Returns the name of the VWM.
204     */

205     public String JavaDoc getName() {
206         return name;
207     }
208
209     /**
210     * Performs maintenance based on a Vwmtasknode.
211     * This method is called by the {@link #probe} object assoviated with the VWM.
212     * the default method sets a status field to indicate an error, and sends an error email.
213     * Perhaps this method should be abstract.
214     * @param node The Vwmtask node that describes the task to be performed.
215     * @return <code>true</code> if maintenance was performed, <code>false</code> if it failed
216     */

217     public boolean performTask(MMObjectNode node) {
218         log.error("Vwm : performTask not implemented in : " + name);
219         node.setValue("status", Vwmtasks.STATUS_ERROR);
220         node.commit();
221
222         Vwms.sendMail(name, "performTask not implemented", "");
223         return false;
224     }
225
226     /**
227     * Signals that the task node is claimed.
228     * Sets the status of the task to 'claimed', as well as the machinename that is claiming the task.
229     * Setting a task to 'claimed' prevents it from being scheduled for performance by the Vwmtask builder.
230     * @param node The VwmTask node that describes the task
231     * @return <code>true</code> if teh task's state was cahnged, <code>false</code> if it fails.
232     */

233     protected boolean claim(MMObjectNode node) {
234         node.setValue("status", Vwmtasks.STATUS_CLAIMED);
235         node.setValue("claimedcpu", Vwms.getMachineName());
236         return node.commit();
237     }
238
239     /**
240     * Signals that the task should be performed again (possibly after an initial failure).
241     * Sets the status of the task to 'request'.
242     * Setting a task to 'request' allows it to be scheduled for performance by the Vwmtask builder.
243     * @param node The VwmTask node that describes the task
244     * @return <code>true</code> if teh task's state was cahnged, <code>false</code> if it fails.
245     */

246     protected boolean rollback(MMObjectNode node) {
247         node.setValue("status", Vwmtasks.STATUS_REQUEST);
248         return node.commit();
249     }
250
251     /**
252     * Signals that the task to be performed failed.
253     * Sets the status of the task to 'error'.
254     * Setting a task to 'error' prevents it from being scheduled for performance by the Vwmtask builder.
255     * @param node The VwmTask node that describes the task
256     * @return <code>true</code> if the task's state was cahnged, <code>false</code> if it fails.
257     */

258     protected boolean failed(MMObjectNode node) {
259         node.setValue("status", Vwmtasks.STATUS_ERROR);
260         return node.commit();
261     }
262
263     /**
264     * Signals that the task to be performed was successful and has finished.
265     * Sets the status of the task to 'done'.
266     * Setting a task to 'done' prevents it from being scheduled for performance by the Vwmtask builder.
267     * @param node The VwmTask node that describes the task
268     * @return <code>true</code> if teh task's state was cahnged, <code>false</code> if it fails.
269     */

270     protected boolean performed(MMObjectNode node) {
271         node.setValue("status", Vwmtasks.STATUS_DONE);
272         return node.commit();
273     }
274
275     /**
276     * Converts a string of properties to a Hashtable.
277     * Used to parse the 'data' field of a VwmTask node.
278     * The property format is a string with a property on each line in the format: name = value
279     * Very generic, should probably be moved to the MMObjectNode class (as in getPropertiesValue(fieldname) ).
280     * @param props the properties string
281     * @return a <code>hashtable</code> with the property name=value pairs.
282     */

283     protected Hashtable parseProperties(String JavaDoc props) {
284         //assume properties are in default encoding
285
//it might also be possible to props.getBytes("utf-8");
286
byte[] bytes = props.getBytes();
287         Properties JavaDoc p = new Properties JavaDoc();
288         try {
289             p.load(new ByteArrayInputStream(bytes));
290         } catch (IOException e) {
291             log.error("failed to load the String ["+props +"] into the properties object due to IOException (this might be an encoding problem) stacktrace" + Logging.stackTrace(e));
292         }
293         return p;
294     }
295
296     /**
297     * Retrieves the creation node of this VWM.
298     */

299     public MMObjectNode getVwmNode() {
300         return wvmnode;
301     }
302
303     /**
304     * Called when a local node is changed.
305     * @param machine Name of the machine that changed the node.
306     * @param number Number of the changed node as a <code>String</code>
307     * @param builder type of the changed node
308     * @param ctype command type, 'c'=changed, 'd'=deleted', 'r'=relations changed, 'n'=new
309     * @return <code>true</code> if maintenance was performed, <code>false</code> (the default) otherwise
310     */

311     public boolean nodeRemoteChanged(String JavaDoc machine, String JavaDoc number, String JavaDoc builder, String JavaDoc ctype) {
312         return false;
313     }
314
315     /**
316     * Called when a remote node is changed.
317     * @param machine Name of the machine that changed the node.
318     * @param number Number of the changed node as a <code>String</code>
319     * @param builder type of the changed node
320     * @param ctype command type, 'c'=changed, 'd'=deleted', 'r'=relations changed, 'n'=new
321     * @return <code>true</code> if maintenance was performed, <code>false</code> (the default) otherwise
322     */

323     public boolean nodeLocalChanged(String JavaDoc machine, String JavaDoc number, String JavaDoc builder, String JavaDoc ctype) {
324         return false;
325     }
326 }
327
Popular Tags