KickJava   Java API By Example, From Geeks To Geeks.

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


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
14 import org.mmbase.module.core.*;
15 import org.mmbase.util.*;
16 import org.mmbase.util.Queue;
17 import org.mmbase.util.logging.*;
18 import org.mmbase.module.builders.*;
19 import org.mmbase.module.gui.html.*;
20
21 /**
22  * A VWM that manages the files by scheduling them to be send to one or more mirror sites.
23  * Requests for scheduling is done in the netfile builder.
24  * This VWM handles those netfile requests whose service is 'pages'. Available subservices are 'main' and 'mirror'.
25  * Requests for file copy are checked periodically.
26  * This results in one or more requests for a 'mirror' service,
27  * which then result in a file copy request, which is handled in a separate thread.
28  * This VWM also has methods for recalculating pages and handling page changes (which in turn result in
29  * a request for file copy.)
30  * Entry point for these requests are the FileChange methods from the {@link VwmServiceInterface}.
31  *
32  * @author Daniel Ockeloen
33  * @author Pierre van Rooden (javadocs)
34  * @version $Id: PageMaster.java,v 1.17 2005/11/23 15:45:13 pierre Exp $
35  */

36
37 public class PageMaster extends Vwm implements MMBaseObserver,VwmServiceInterface {
38
39     private static final Logger log = Logging.getLoggerInstance(PageMaster.class);
40
41     // field used to skip first probeCall (why???)
42
boolean first=true;
43
44     Object JavaDoc syncobj=new Object JavaDoc(); // used in commented code
45

46     /**
47     * Queue containing the file-copy tasks that need to be performed by {@link #filecopier}
48     */

49     Queue files2copy=new Queue(128);
50     /**
51      * Thread that handles the actual file transfers.
52      */

53     FileCopier filecopier=new FileCopier(files2copy);
54     /**
55      * Cache for mirror servers
56      */

57     Vector mirrornodes;
58
59     //Hashtable properties; (unused)
60

61     /**
62      * Constructor for the PageMaster VWM.
63      */

64     public PageMaster() {
65         log.debug("ready for action");
66     }
67
68     /**
69      * Performs general periodic maintenance.
70      * This routine handles alle open pages/main and pages/mirror file service requests.
71      * These requests are obtained from the netfiles builder.
72      * For each file that should be serviced, the filechange method is called.
73      * This routine handles a maximum of 10 page/main, and 50 page/mirror service
74      * calls each time it is called.
75      * The first time this method is call, nothing happens (?)
76      *
77      * @return <code>true</code> if maintenance was performed, <code>false</code> otherwise
78      */

79     public boolean probeCall() {
80         if (first) {
81             // skip first time this method is called
82
first=false;
83         } else {
84             // handle up to 10 pages/main fileservice requests
85
try {
86                 Netfiles bul=(Netfiles)Vwms.getMMBase().getMMObject("netfiles");
87                 //Enumeration e=bul.search("WHERE service='pages' AND subservice='main' AND status="+Netfiles.STATUS_REQUEST+" ORDER BY number DESC");
88
Enumeration e=bul.search("service=='pages'+subservice=='main'+status="+Netfiles.STATUS_REQUEST);
89                 int i=0;
90                 while (e.hasMoreElements() && i<10) {
91                     MMObjectNode node=(MMObjectNode)e.nextElement();
92                     fileChange(""+node.getIntValue("number"),"c");
93                     i++;
94                 }
95             } catch(Exception JavaDoc e) {
96                 log.error(Logging.stackTrace(e));
97             }
98             // handle up to 50 pages/mirror fileservice requests
99
try {
100                 Netfiles bul=(Netfiles)Vwms.getMMBase().getMMObject("netfiles");
101                 Enumeration e=bul.search("service=='pages'+subservice=='mirror'+status="+Netfiles.STATUS_REQUEST);
102                 //Enumeration e=bul.search("WHERE service='pages' AND subservice='mirror' AND status="+Netfiles.STATUS_REQUEST+" ORDER BY number DESC");
103
int i=0;
104                 while (e.hasMoreElements() && i<50) {
105                     MMObjectNode node=(MMObjectNode)e.nextElement();
106                     fileChange(""+node.getIntValue("number"),"c");
107                     i++;
108                 }
109             } catch(Exception JavaDoc e) {
110                 log.error(Logging.stackTrace(e));
111             }
112         }
113         return true;
114     }
115
116     /**
117      * Called when a remote node is changed.
118      * @param machine Name of the machine that changed the node.
119      * @param number Number of the changed node as a <code>String</code>
120      * @param builder type of the changed node
121      * @param ctype command type, 'c'=changed, 'd'=deleted', 'r'=relations changed, 'n'=new
122      * @return <code>true</code>
123      */

124     public boolean nodeRemoteChanged(String JavaDoc machine,String JavaDoc number,String JavaDoc builder,String JavaDoc ctype) {
125         return nodeChanged(machine,number,builder,ctype);
126     }
127
128     /**
129      * Called when a local node is changed.
130      * @param machine Name of the machine that changed the node.
131      * @param number Number of the changed node as a <code>String</code>
132      * @param builder type of the changed node
133      * @param ctype command type, 'c'=changed, 'd'=deleted', 'r'=relations changed, 'n'=new
134      * @return <code>true</code>
135      */

136     public boolean nodeLocalChanged(String JavaDoc machine,String JavaDoc number,String JavaDoc builder,String JavaDoc ctype) {
137         return nodeChanged(machine,number,builder,ctype);
138     }
139
140     /**
141      * Called when a local or remote node is changed.
142      * Does not take any action.
143      * @param machine Name of the machine that changed the node.
144      * @param number Number of the changed node as a <code>String</code>
145      * @param builder type of the changed node
146      * @param ctype command type, 'c'=changed, 'd'=deleted', 'r'=relations changed, 'n'=new
147      * @return <code>true</code>
148      */

149     public boolean nodeChanged(String JavaDoc machine,String JavaDoc number,String JavaDoc builder, String JavaDoc ctype) {
150         // log.debug("sees that : "+number+" has changed type="+ctype);
151
return true;
152     }
153
154     /**
155      * Schedules a service-request on a file.
156      * Only "pages/main" services are handled.
157      * The service-request is later handled through the {@link #probeCall} method.
158      * @param service the service to be performed
159      * @param subservice the subservice to be performed
160      * @param filename the filename to service
161      * @return <code>true</code> if maintenance was performed, <code>false</code> otherwise
162      */

163     public boolean fileChange(String JavaDoc service,String JavaDoc subservice,String JavaDoc filename) {
164         log.debug("frontend change -> "+filename);
165         log.service("s="+service+" sub="+subservice+"file="+filename);
166         // jump to correct subhandles based on the subservice
167
if (subservice.equals("main")) {
168             handleMainCheck(service,subservice,filename);
169         }
170         return true;
171     }
172
173     /**
174      * Handles a service-request on a file, registered in the netfiles builder.
175      * Depending on the subservice requested, this routine calls {@link #handleMirror}
176      * or {@link #handleMain}.
177      * @param number Number of the node in the netfiles buidler than contain service request information.
178      * @param ctype the type of change on that node ("c" : node was changed)
179      * @return <code>true</code>
180      */

181     public boolean fileChange(String JavaDoc number, String JavaDoc ctype) {
182         // log.debug("fileChange="+number+" "+ctype);
183
// first get the change node so we can see what is the matter with it.
184
Netfiles bul=(Netfiles)Vwms.getMMBase().getMMObject("netfiles");
185         MMObjectNode filenode=bul.getNode(number);
186         if (filenode!=null) {
187             // obtain all the basic info on the file.
188
String JavaDoc service=filenode.getStringValue("service");
189             String JavaDoc subservice=filenode.getStringValue("subservice");
190             int status=filenode.getIntValue("status");
191
192             // jump to correct subhandles based on the subservice
193
if (subservice.equals("main")) {
194                 return handleMain(filenode,status,ctype);
195             } else if (subservice.equals("mirror")) {
196                 return handleMirror(filenode,status,ctype);
197             }
198         }
199         return true;
200     }
201
202     /**
203      * Handles a pages/mirror service request.
204      * Places a page in the file2copy queue, so it will be sent to a mirror
205      * site by the FileCopier.
206      * @param node the filenet node that contains the service request
207      * @param status the current status of the node
208      * @param ctype the type of change on that node ("c" : node was changed)
209      * @return <code>true</code>
210      */

211     public boolean handleMirror(MMObjectNode filenode,int status,String JavaDoc ctype) {
212         switch(status) {
213             case Netfiles.STATUS_REQUEST: // Request
214
// register the node as being On Its Way
215
filenode.setValue("status",Netfiles.STATUS_ON_ITS_WAY);
216                 filenode.commit();
217                 String JavaDoc filename=filenode.getStringValue("filename");
218                 String JavaDoc dstserver=filenode.getStringValue("mmserver");
219                 // recover the correct source/dest properties for this mirror
220
//
221
// why does it say "demoserver" ??
222
//
223
String JavaDoc sshpath=getProperty("demoserver","sshpath");
224                 log.debug("sshpath="+sshpath);
225                 String JavaDoc srcpath=getProperty("demoserver","path");
226                 log.debug("srcpath="+srcpath);
227                 String JavaDoc dstuser=getProperty(dstserver,"user");
228                 log.debug("dstuser="+dstuser);
229                 String JavaDoc dsthost=getProperty(dstserver,"host");
230                 log.debug("dsthost="+dsthost);
231                 String JavaDoc dstpath=getProperty(dstserver,"path");
232                 log.debug("dstpath="+dstpath);
233
234 /* this code can be dropped as it is handled in FileCopier
235
236         SCPcopy scpcopy=new SCPcopy(sshpath,dstuser,dsthost,dstpath);
237
238         synchronized(syncobj) {
239             scpcopy.copy(srcpath,filename);
240         }
241 */

242                 // create a new file2copy object and add it to the queue,
243
// so the FileCopier thread will handle it.
244
files2copy.append(new aFile2Copy(dstuser,dsthost,dstpath,srcpath,filename,sshpath));
245
246                 // register the node as being Done
247
filenode.setValue("status",Netfiles.STATUS_DONE);
248                 filenode.commit();
249                 break;
250             case Netfiles.STATUS_ON_ITS_WAY: // On its way
251
break;
252             case Netfiles.STATUS_DONE: // Done
253
break;
254         }
255         return true;
256     }
257
258     /**
259      * Handles a pages/main service request.
260      * The events handled are:<br />
261      * - requests for handling: schedules requests to mirror this page using {@link #doMainRequest}<br />
262      * - changed: page is scheduled to be recalculated<br />
263      * - recaculate" page is recaclcutated and scheduled to be handled<br />
264      *
265      * @param node the netfiles node that contains the service request
266      * @param status the current status of the node
267      * @param ctype the type of change on that node ("c" : node was changed)
268      * @return <code>true</code>
269      */

270     public boolean handleMain(MMObjectNode filenode,int status,String JavaDoc ctype) {
271         switch(status) {
272             case Netfiles.STATUS_REQUEST: // Request
273
// register the node as being On Its Way
274
filenode.setValue("status",Netfiles.STATUS_ON_ITS_WAY);
275                 filenode.commit();
276                 // do stuff
277
doMainRequest(filenode);
278                 // register the node as being Done
279
filenode.setValue("status",Netfiles.STATUS_DONE);
280                 filenode.commit();
281                 break;
282             case Netfiles.STATUS_ON_ITS_WAY: // On Its Way
283
break;
284             case Netfiles.STATUS_DONE: // Done
285
break;
286             case Netfiles.STATUS_CHANGED: // Dirty (?)
287
filenode.setValue("status",Netfiles.STATUS_CALC_PAGE);
288                 filenode.commit();
289                 break;
290             case Netfiles.STATUS_CALC_PAGE: // Recalculate Page
291
String JavaDoc filename=filenode.getStringValue("filename");
292                 calcPage(filename);
293                 filenode.setValue("status",Netfiles.STATUS_REQUEST);
294                 filenode.commit();
295                 break;
296         }
297         return true;
298     }
299
300     /**
301      * Handles a main subservice on a page.
302      * The page is scheduled to be sent to all appropriate mirrorsites for this service,
303      * by setting the request status in the associated mirror nodes.
304      * If no mirror nodes are associated with this page, nothing happens.
305      * @param filenode the netfiles node with the original (main) request
306      */

307     public boolean doMainRequest(MMObjectNode filenode) {
308         // so this file has changed probably, check if the file is ready on
309
// disk and set the mirrors to request.
310
String JavaDoc filename = filenode.getStringValue("filename");
311
312         // find and change all the mirror nodes so they get resend
313
Netfiles bul=(Netfiles)Vwms.getMMBase().getMMObject("netfiles");
314         Enumeration e=bul.search("WHERE filename='"+filename+"' AND service='pages' AND subservice='mirror'");
315         while (e.hasMoreElements()) {
316             MMObjectNode mirrornode=(MMObjectNode)e.nextElement();
317             mirrornode.setValue("status",Netfiles.STATUS_REQUEST);
318             mirrornode.commit();
319         }
320         return true;
321     }
322
323     /**
324      * Schedules a netfile object to be send to its mirror sites.
325      * The routine searches the appropriate netfile node, and sets its status to 'request'.
326      * If a node does not exits, a new node is created. In the latter case, the system also creates mirrornodes
327      * for each mirrorsite associated with this service.
328      * @param service the service to be performed
329      * @param subservice the subservice to be performed
330      * @param filename the filename to service
331      */

332     public void handleMainCheck(String JavaDoc service,String JavaDoc subservice,String JavaDoc filename) {
333         log.debug("Reached handleMainCheck");
334         Netfiles bul=(Netfiles)Vwms.getMMBase().getMMObject("netfiles");
335         Enumeration e=bul.search("WHERE filename='"+filename+"' AND service='"+service+"' AND subservice='"+subservice+"'");
336         if (e.hasMoreElements()) {
337             MMObjectNode mainnode=(MMObjectNode)e.nextElement();
338             mainnode.setValue("status",Netfiles.STATUS_REQUEST);
339             mainnode.commit();
340         } else {
341             MMObjectNode mainnode=bul.getNewNode("system");
342             mainnode.setValue("filename",filename);
343             mainnode.setValue("mmserver",Vwms.getMMBase().getMachineName());
344             mainnode.setValue("service",service);
345             mainnode.setValue("subservice",subservice);
346             mainnode.setValue("status",Netfiles.STATUS_REQUEST);
347             mainnode.setValue("filesize",-1);
348             bul.insert("system",mainnode);
349
350             Enumeration f=getMirrorNodes(service).elements();
351             while (f.hasMoreElements()) {
352                 MMObjectNode n2=(MMObjectNode)f.nextElement();
353                 // hack hack also have to create mirror nodes !
354
mainnode=bul.getNewNode("system");
355                 mainnode.setValue("filename",filename);
356                 mainnode.setValue("mmserver",n2.getStringValue("name"));
357                 mainnode.setValue("service",service);
358                 mainnode.setValue("subservice","mirror");
359                 mainnode.setValue("status",Netfiles.STATUS_DONE);
360                 mainnode.setValue("filesize",-1);
361                 bul.insert("system",mainnode);
362             }
363         }
364     }
365
366     /**
367      * Retrieves a named property of a server.
368      * @param machine name of the server
369      * @param key name of the property to retrieve
370      * @return the property value
371      */

372     public String JavaDoc getProperty(String JavaDoc machine,String JavaDoc key) {
373         MMServers mmservers=(MMServers)Vwms.getMMBase().getMMObject("mmservers");
374         return mmservers.getMMServerProperty(machine,key);
375     }
376
377
378     /**
379      * Recalculate a page.
380      * Invokes the SCAN parser (which will re-cache the page through the scancache module)
381      * Only works for SCAN.
382      * @param the url of the page to cache
383      */

384     public void calcPage(String JavaDoc url) {
385         scanparser m=(scanparser)Vwms.getMMBase().getModule("SCANPARSER");
386         url=url.substring(0,url.length()-5);
387         url=url.replace(':','?');
388         log.debug("getPage="+url);
389         if (m!=null) {
390             scanpage sp=new scanpage();
391             m.calcPage(url,sp,0);
392         }
393     }
394
395     /**
396      * Retrieves a list of Mirror Servers.
397      * This is done by obtaining a fileserver node and retrieving associated mmserver nodes.
398      * This method should be renamed and moved to the netfilesrv builder.
399      * @param service preseumably the service to query for. Unused.
400      * @return a <code>Vector</code> containing mmserver nodes that act as mirror server for this service
401      */

402     public Vector getMirrorNodes(String JavaDoc service) {
403         if (mirrornodes!=null) return mirrornodes;
404         NetFileSrv bul=(NetFileSrv)Vwms.getMMBase().getMMObject("netfilesrv");
405         if (bul!=null) {
406             Enumeration e=bul.search("service=='pages'+subservice=='mirror'");
407             if (e.hasMoreElements()) {
408                 MMObjectNode n1=(MMObjectNode)e.nextElement();
409                 mirrornodes=n1.getRelatedNodes("mmservers");
410                 if (mirrornodes!=null) return mirrornodes;
411             }
412         }
413         mirrornodes=new Vector();
414         return mirrornodes;
415     }
416 }
417
Popular Tags