jafs-library-20020725
[openafs.git] / src / JAVA / classes / org / openafs / jafs / Process.java
1 /*
2  * @(#)Process.java     1.0 6/29/2001
3  *
4  * Copyright (c) 2001 International Business Machines Corp.
5  * All rights reserved.
6  *
7  * This software has been released under the terms of the IBM Public
8  * License.  For details, see the LICENSE file in the top-level source
9  * directory or online at http://www.openafs.org/dl/license10.html
10  * 
11  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
12  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
13  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
14  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
15  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
16  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
17  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
18  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
19  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
20  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22  */
23
24 package org.openafs.jafs;
25
26 import java.util.GregorianCalendar;
27 import java.util.Date;
28 import java.io.Serializable;
29
30 /**
31  * An abstract representation of an AFS process.  It holds information about 
32  * the server, such as what its state is.
33  * <BR><BR>
34  *
35  * Constructing an instance of a <code>Process</code> does not mean an actual 
36  * AFS process is created on a server -- usually a <code>Process</code>
37  * object is a representation of an already existing AFS process.  If, 
38  * however, the <code>Process</code> is constructed with the name of a 
39  * process that does not exist in the server represented by the provided 
40  * <code>Server</code>, a new process with that name can be
41  * created on that server by calling one of the {@link #createSimple(String)},
42  * {@link #createFS(String)}, or {@link #createCron(String,String)} methods. If
43  * such a process does already exist when one of these methods are called, 
44  * an exception will be thrown.<BR><BR>
45  *
46  * <!--Information on how member values are set-->
47  *
48  * <!--Example of how to use class-->
49  * The following is a simple example of how to construct and use a 
50  * <code>Process</code> object.  This example obtains the list of all
51  * <code>Process</code> objects on a particular server and prints out the
52  * name of each one along with its start time.<BR><BR>
53  *
54  * <PRE>
55  * import org.openafs.jafs.Cell;
56  * import org.openafs.jafs.AFSException;
57  * import org.openafs.jafs.Process;
58  * import org.openafs.jafs.Server;
59  * ...
60  * public class ...
61  * {
62  *   ...
63  *   private Cell cell;
64  *   private Server server;
65  *   ...
66  *   public static void main(String[] args) throws Exception
67  *   {
68  *     String username   = arg[0];
69  *     String password   = arg[1];
70  *     String cellName   = arg[2];
71  *     String serverName = arg[3];
72  * 
73  *     token = new Token(username, password, cellName);
74  *     cell   = new Cell(token);
75  *     server = new Server(serverName, cell);
76  * 
77  *     System.out.println("Processes in Server " + server.getName() + ":");
78  *     Process[] processes = server.getProcesss();
79  *     for (int i = 0; i < processes.length; i++) {
80  *       System.out.print("Process " + processes[i].getName());
81  *       System.out.print("was started: " + 
82  *                        processes[i].getStartTimeDate().getTime() + "\n");
83  *     }
84  *   }
85  *   ...
86  * }
87  * </PRE>
88  *
89  */
90 public class Process implements Serializable, Comparable
91 {
92   /**
93    * Any standard type of process except for fs (such as kaserver, 
94    * upclientbin, etc.)
95    */
96   public static final int SIMPLE_PROCESS = 0;
97   
98   /**
99    * Combination of File Server, Volume Server, and Salvager processes
100    */
101   public static final int FS_PROCESS = 1;
102   
103   /**
104    * A process that should be restarted at a specific time either daily 
105    * or weekly.
106    */
107   public static final int CRON_PROCESS = 2;
108
109   /**
110    * Process execution state stopped
111    */
112   public static final int STOPPED = 0;
113
114   /**
115    * Process execution state running
116    */
117   public static final int RUNNING = 1;
118
119   /**
120    * Process execution state stopping
121    */
122   public static final int STOPPING = 2;
123
124   /**
125    * Process execution state starting
126    */
127   public static final int STARTING = 3;
128
129   protected String name;
130   protected Server server;
131   protected int serverHandle;
132
133   protected int type;
134   protected int state;
135   protected int goal;
136
137   protected long startTime;
138   protected long numberStarts;
139   protected long exitTime;
140   protected long exitErrorTime;
141   protected long errorCode;
142   protected long errorSignal;
143
144   protected boolean stateOk;
145   protected boolean stateTooManyErrors;
146   protected boolean stateBadFileAccess;
147
148   protected GregorianCalendar startTimeDate;
149   protected GregorianCalendar exitTimeDate;
150   protected GregorianCalendar exitErrorTimeDate;
151
152   protected boolean cachedInfo;
153
154   /**
155    * Constructs a new <code>Process</code> object instance given the name 
156    * of the AFS process and the AFS server, represented by 
157    * <CODE>server</CODE>, to which it belongs.   This does not actually
158    * create a new AFS process, it just represents one.
159    * If <code>name</code> is not an actual AFS process, exceptions
160    * will be thrown during subsequent method invocations on this 
161    * object, unless one of the {@link #createSimple(String)},
162    * {@link #createFS(String)}, or {@link #createCron(String,String)} 
163    * methods are explicitly called to create it.
164    *
165    * @param name      the name of the server to represent 
166    * @param server    the server on which the process resides
167    * @exception AFSException      If an error occurs in the native code
168    */
169   public Process( String name, Server server ) throws AFSException
170   {
171     this.name = name;
172     this.server = server;
173     serverHandle = server.getBosHandle();
174         
175     startTimeDate = null;
176     exitTimeDate = null;
177     exitErrorTimeDate = null;
178
179     cachedInfo = false;
180   }
181
182   /**
183    * Constructs a new <CODE>Process</CODE> object instance given the name 
184    * of the AFS process and the AFS server, represented by 
185    * <CODE>server</CODE>, to which it belongs.  This does not actually
186    * create a new AFS process, it just represents one.
187    * If <code>name</code> is not an actual AFS process, exceptions
188    * will be thrown during subsequent method invocations on this 
189    * object, unless one of the {@link #createSimple(String)},
190    * {@link #createFS(String)}, or {@link #createCron(String,String)} 
191    * methods are explicitly called to create it.  Note that if he process
192    * doesn't exist and <code>preloadAllMembers</code> is true, an exception
193    * will be thrown.
194    *
195    * <P> This constructor is ideal for point-in-time representation and 
196    * transient applications. It ensures all data member values are set and 
197    * available without calling back to the filesystem at the first request 
198    * for them.  Use the {@link #refresh()} method to address any coherency 
199    * concerns.
200    *
201    * @param name               the name of the process to represent 
202    * @param server             the server to which the process belongs.
203    * @param preloadAllMembers  true will ensure all object members are 
204    *                           set upon construction; otherwise members will 
205    *                           be set upon access, which is the default 
206    *                           behavior.
207    * @exception AFSException      If an error occurs in the native code
208    * @see #refresh
209    */
210   public Process( String name, Server server, boolean preloadAllMembers ) 
211       throws AFSException
212   {
213     this(name, server);
214     if (preloadAllMembers) refresh(true);
215   }
216   
217   /**
218    * Creates a blank <code>Process</code> given the server to which the process
219    * belongs.  This blank object can then be passed into other methods to fill
220    * out its properties.
221    *
222    * @param server       the server to which the process belongs.
223    * @exception AFSException      If an error occurs in the native code
224    */
225   Process( Server server ) throws AFSException
226   {
227     this( null, server );
228   }
229
230   /*-------------------------------------------------------------------------*/
231
232   /**
233    * Refreshes the properties of this Process object instance with values 
234    * from the AFS process it represents.  All properties that have been 
235    * initialized and/or accessed will be renewed according to the values of 
236    * the AFS process this Process object instance represents.
237    *
238    * <P>Since in most environments administrative changes can be administered
239    * from an AFS command-line program or an alternate GUI application, this
240    * method provides a means to refresh the Java object representation and
241    * thereby ascertain any possible modifications that may have been made
242    * from such alternate administrative programs.  Using this method before
243    * an associated instance accessor will ensure the highest level of 
244    * representative accuracy, accommodating changes made external to the
245    * Java application space.  If administrative changes to the underlying AFS 
246    * system are only allowed via this API, then the use of this method is 
247    * unnecessary.
248    * 
249    * @exception AFSException  If an error occurs in the native code
250    */
251   public void refresh() throws AFSException
252   {
253     refresh(false);
254   }
255
256   /**
257    * Refreshes the properties of this Process object instance with values from
258    * the AFS process it represents.  If <CODE>all</CODE> is <CODE>true</CODE> 
259    * then <U>all</U> of the properties of this Process object instance will be
260    * set, or renewed, according to the values of the AFS process it represents,
261    * disregarding any previously set properties.
262    *
263    * <P> Thus, if <CODE>all</CODE> is <CODE>false</CODE> then properties that 
264    * are currently set will be refreshed and properties that are not set will 
265    * remain uninitialized. See {@link #refresh()} for more information.
266    *
267    * @param all   if true set or renew all object properties; otherwise renew 
268    *              all set properties
269    * @exception AFSException  If an error occurs in the native code
270    * @see #refresh()
271    */
272   protected void refresh(boolean all) throws AFSException
273   {
274     if (all || cachedInfo) refreshInfo();
275   }
276
277   /**
278    * Refreshes the information fields of this <code>Process</code> to reflect 
279    * the current state of the AFS process, such as the start time, the state,
280    * etc.
281    *
282    * @exception AFSException      If an error occurs in the native code
283    */
284   protected void refreshInfo() throws AFSException
285   {
286     getProcessInfo( server.getBosHandle(), name, this );
287     cachedInfo = true;
288     startTimeDate = null;
289     exitTimeDate = null;
290     exitErrorTimeDate = null;
291   }
292
293   /**
294    * Creates this process as a simple process on the server.
295    *
296    * @param executionPath   the path to the process's executable
297    * @exception AFSException      If an error occurs in the native code
298    */
299   public void createSimple( String executionPath ) throws AFSException
300   {
301     create( server.getBosHandle(), name, SIMPLE_PROCESS, executionPath, null, 
302             null );
303   }
304
305   /**
306    * Creates this process as a file server process on the server.
307    *
308    * @param executionPath   the path to the process's executable
309    * @exception AFSException      If an error occurs in the native code
310    */
311   public void createFS( String executionPath ) throws AFSException
312   {
313     create( server.getBosHandle(), name, FS_PROCESS, executionPath, null, 
314             null );
315   }
316
317   /**
318    * Creates this process as a cron process on the server.
319    *
320    * @param executionPath   the path to the process's executable
321    * @param cronTime   a String representing the time a cron process is 
322    *                   to be run.  Acceptable formats are:<ul>
323    *                   <li>for daily restarts: "23:10" or "11:10 pm"</li>
324    *                   <li>for weekly restarts: "sunday 11:10pm" or 
325    *                       "sun 11:10pm"</li>
326    *                   </ul>
327    * @exception AFSException      If an error occurs in the native code
328    */
329   public void createCron( String executionPath, String cronTime ) 
330       throws AFSException
331   {
332     create( server.getBosHandle(), name, CRON_PROCESS, executionPath, 
333             cronTime, null );
334   }
335
336   /**
337    * Removes this process from the bos server
338    *
339    * @exception AFSException      If an error occurs in the native code
340    */
341   public void delete() throws AFSException
342   {
343     delete( server.getBosHandle(), name );
344   }
345
346   /**
347    * Stops this process.
348    *
349    * @exception AFSException      If an error occurs in the native code
350    */
351   public void stop() throws AFSException
352   {
353     state = STOPPING;
354     goal = STOPPED;
355     stop( server.getBosHandle(), name );
356   }
357
358   /**
359    * Starts this process
360    *
361    * @exception AFSException      If an error occurs in the native code
362    */
363   public void start() throws AFSException
364   {
365     state = STARTING;
366     start( server.getBosHandle(), name );
367   }
368
369   /**
370    * Restarts this process
371    *
372    * @exception AFSException      If an error occurs in the native code
373    */
374   public void restart() throws AFSException
375   {
376     state = STARTING;
377     restart( server.getBosHandle(), name );
378   }
379
380   //////////////// accessors:  ////////////////////////
381
382   /**
383    * Returns the name of this process.
384    *
385    * @return the name of this process
386    */
387   public String getName()
388   {
389     return name;
390   }
391
392   /**
393    * Returns the server hosting this process.
394    *
395    * @return this process' server
396    */
397   public Server getServer()
398   {
399     return server;
400   }
401
402   /**
403    * Returns the process type.  Possible values are:<ul>
404    *      <li>{@link #SIMPLE_PROCESS}</li>
405    *      <li>{@link #FS_PROCESS}</li>
406    *      <li>{@link #CRON_PROCESS}</li></ul>
407    *
408    * @return the process type
409    * @exception AFSException      If an error occurs in the native code
410    */
411   public int getType() throws AFSException
412   {
413     if (!cachedInfo) refreshInfo();
414     return type;
415   }
416
417   /**
418    * Returns the process goal.  Possible values are:<ul>
419    *      <li>{@link #STOPPED}</li>
420    *      <li>{@link #RUNNING}</li>
421    *      <li>{@link #STARTING}</li>
422    *      <li>{@link #STOPPING}</li></ul>
423    * After this method is called once, it saves the value 
424    * and returns that value on subsequent calls, 
425    * until the {@link #refresh()} method is called and a more current 
426    * value is obtained.
427    *
428    * @return the process goal
429    * @exception AFSException      If an error occurs in the native code
430    */
431   public int getGoal() throws AFSException
432   {
433     if (!cachedInfo) refreshInfo();
434     return goal;
435   }
436
437   /**
438    * Returns the process execution state.  Possible values are:<ul>
439    *      <li>{@link #STOPPED}</li>
440    *      <li>{@link #RUNNING}</li>
441    *      <li>{@link #STARTING}</li>
442    *      <li>{@link #STOPPING}</li></ul>
443    * After this method is called once, it saves the value 
444    * and returns that value on subsequent calls, 
445    * until the {@link #refresh()} method is called and a more current 
446    * value is obtained.
447    *
448    * @return the process execution state
449    * @exception AFSException      If an error occurs in the native code
450    */
451   public int getState() throws AFSException
452   {
453     if (!cachedInfo) refreshInfo();
454     return state;
455   }
456
457   /**
458    * Returns the most recent start time of this process.  A 
459    * <code>null</code> value 
460    * indicates no start time.
461    * After this method is called once, it saves the value 
462    * and returns that value on subsequent calls, 
463    * until the {@link #refresh()} method is called and a more current 
464    * value is obtained.
465    *
466    * @return the start time
467    * @exception AFSException      If an error occurs in the native code
468    */
469   public long getStartTime() throws AFSException
470   {
471     if (!cachedInfo) refreshInfo();
472     return startTime;
473   }
474
475   /**
476    * Returns the most recent start time of this process.  A <code>null</code> 
477    * value indicates no start time.
478    * After this method is called once, it saves the value 
479    * and returns that value on subsequent calls, 
480    * until the {@link #refresh()} method is called and a more current 
481    * value is obtained.
482    *
483    * @return the start time
484    * @exception AFSException      If an error occurs in the native code
485    */
486   public GregorianCalendar getStartTimeDate() throws AFSException
487   {
488     if (!cachedInfo) {
489         refreshInfo();
490     }
491     if( startTimeDate == null && startTime != 0 ) {
492         // make it into a date . . .
493         startTimeDate = new GregorianCalendar();
494         long longTime = startTime * 1000;
495         Date d = new Date( longTime );
496         startTimeDate.setTime( d );
497     }
498     return startTimeDate;
499   }
500
501   /**
502    * Returns the number of starts of the process.
503    * After this method is called once, it saves the value 
504    * and returns that value on subsequent calls, 
505    * until the {@link #refresh()} method is called and a more current 
506    * value is obtained.
507    *
508    * @return the number of starts
509    * @exception AFSException      If an error occurs in the native code
510    */
511   public long getNumberOfStarts() throws AFSException
512   {
513     if (!cachedInfo) refreshInfo();
514     return numberStarts;
515   }
516
517   /**
518    * Returns the most recent exit time of this process.  A <code>null</code> 
519    * value indicates no exit time.
520    * After this method is called once, it saves the value 
521    * and returns that value on subsequent calls, 
522    * until the {@link #refresh()} method is called and a more current 
523    * value is obtained.
524    *
525    * @return the exit time
526    * @exception AFSException      If an error occurs in the native code
527    */
528   public long getExitTime() throws AFSException
529   {
530     if (!cachedInfo) refreshInfo();
531     return exitTime;
532   }
533
534   /**
535    * Returns the most recent exit time of this process.  A <code>null</code> 
536    * value indicates no exit time
537    * After this method is called once, it saves the value 
538    * and returns that value on subsequent calls, 
539    * until the {@link #refresh()} method is called and a more current 
540    * value is obtained.
541    *
542    * @return the exit time
543    * @exception AFSException      If an error occurs in the native code
544    */
545   public GregorianCalendar getExitTimeDate() throws AFSException
546   {
547     if (!cachedInfo) refreshInfo();
548     if( exitTimeDate == null && exitTime != 0 ) {
549         // make it into a date . . .
550         exitTimeDate = new GregorianCalendar();
551         long longTime = exitTime*1000;
552         Date d = new Date( longTime );
553         exitTimeDate.setTime( d );
554     }
555     return exitTimeDate;
556   }
557
558   /**
559    * Returns the most recent time this process exited with an error.  A 
560    * <code>null</code> value indicates no exit w/ error time.
561    * After this method is called once, it saves the value 
562    * and returns that value on subsequent calls, 
563    * until the {@link #refresh()} method is called and a more current 
564    * value is obtained.
565    *
566    * @return the exit w/ error time
567    * @exception AFSException      If an error occurs in the native code
568    */
569   public long getExitErrorTime() throws AFSException
570   {
571     if (!cachedInfo) refreshInfo();
572     return exitErrorTime;
573   }
574
575   /**
576    * Returns the most recent time this process exited with an error.  A <
577    * code>null</code> value indicates no exit w/ error time.
578    * After this method is called once, it saves the value 
579    * and returns that value on subsequent calls, 
580    * until the {@link #refresh()} method is called and a more current 
581    * value is obtained.
582    *
583    * @return the exit w/ error time
584    * @exception AFSException      If an error occurs in the native code
585    */
586   public GregorianCalendar getExitErrorTimeDate() throws AFSException
587   {
588     if (!cachedInfo) refreshInfo();
589     if (exitErrorTimeDate == null && exitErrorTime != 0) {
590         // make it into a date . . .
591         exitErrorTimeDate = new GregorianCalendar();
592         long longTime = exitErrorTime*1000;
593         Date d = new Date( longTime );
594         exitErrorTimeDate.setTime( d );
595     }
596     return exitErrorTimeDate;
597   }
598
599   /**
600    * Returns the error code of the process.  A value of 0 indicates 
601    * no error code.
602    * After this method is called once, it saves the value 
603    * and returns that value on subsequent calls, 
604    * until the {@link #refresh()} method is called and a more current 
605    * value is obtained.
606    *
607    * @return the error code
608    * @exception AFSException      If an error occurs in the native code
609    */
610   public long getErrorCode() throws AFSException
611   {
612     if (!cachedInfo) refreshInfo();
613     return errorCode;
614   }
615
616   /**
617    * Returns the error signal of the process.  A value of 0 indicates no 
618    * error signal.
619    * After this method is called once, it saves the value 
620    * and returns that value on subsequent calls, 
621    * until the {@link #refresh()} method is called and a more current 
622    * value is obtained.
623    *
624    * @return the error signal
625    * @exception AFSException      If an error occurs in the native code
626    */
627   public long getErrorSignal() throws AFSException
628   {
629     if (!cachedInfo) refreshInfo();
630     return errorSignal;
631   }
632
633   /**
634    * Returns whether or not the state of the process is ok.  A value of 
635    * <code>false</code> indicates there has been a core dump.
636    * After this method is called once, it saves the value 
637    * and returns that value on subsequent calls, 
638    * until the {@link #refresh()} method is called and a more current 
639    * value is obtained.
640    *
641    * @return whether or not the state is ok
642    * @exception AFSException      If an error occurs in the native code
643    */
644   public boolean getStateOk() throws AFSException
645   {
646     if (!cachedInfo) refreshInfo();
647     return stateOk;
648   }
649
650   /**
651    * Returns whether or not the state of the process indicates too many errors.
652    * After this method is called once, it saves the value 
653    * and returns that value on subsequent calls, 
654    * until the {@link #refresh()} method is called and a more current 
655    * value is obtained.
656    *
657    * @return whether or not the state indicates too many errors
658    * @exception AFSException      If an error occurs in the native code
659    */
660   public boolean getStateTooManyErrors() throws AFSException
661   {
662     if (!cachedInfo) refreshInfo();
663     return stateTooManyErrors;
664   }
665
666   /**
667    * Returns whether or not the state of the process indicates bad file access.
668    * After this method is called once, it saves the value 
669    * and returns that value on subsequent calls, 
670    * until the {@link #refresh()} method is called and a more current 
671    * value is obtained.
672    *
673    * @return whether or not the state indicates bad file access
674    * @exception AFSException      If an error occurs in the native code
675    */
676   public boolean getStateBadFileAccess() throws AFSException
677   {
678     if (!cachedInfo) refreshInfo();
679     return stateBadFileAccess;
680   }
681
682   /////////////// custom information methods ////////////////////
683
684   /**
685    * Returns a <code>String</code> representation of this <code>Process</code>.
686    * Contains the information fields.
687    *
688    * @return a <code>String</code> representation of the <code>Process</code>
689    */
690   protected String getInfo()
691   {
692     String r;
693     try {
694         
695         r = "Process: " + name + "\n";
696         
697         r += "\ttype: ";
698         switch( getType() ) {
699         case SIMPLE_PROCESS:
700           r += "simple";
701           break;
702         case FS_PROCESS:
703           r += "fs";
704           break;
705         case CRON_PROCESS:
706           r += "cron";
707           break;
708         default:
709           r += "other - " + getType();
710         }
711         r += "\n";
712
713         r += "\tstate: ";
714         switch( getState() ) {
715         case STOPPED:
716           r += "stopped";
717           break;
718         case RUNNING:
719           r += "running";
720           break;
721         case STOPPING:
722           r += "stopping";
723           break;
724         case STARTING:
725           r += "starting";
726           break;
727         default:
728           r += "other - " + getState();
729         }
730         r += "\n";
731
732         r += "\tgoal: ";
733         switch( getGoal() ) {
734         case STOPPED:
735           r += "stopped";
736           break;
737         case RUNNING:
738           r += "running";
739           break;
740         case STOPPING:
741           r += "stopping";
742           break;
743         case STARTING:
744           r += "starting";
745           break;
746         default:
747           r += "other - " + getGoal();
748         }
749         r += "\n";
750
751         r += "\tstartTime: ";
752         if( getStartTime() == 0) {
753           r += "0";
754         } else {
755           r += getStartTimeDate().getTime(); 
756         }
757       r += "\n";
758
759         r += "\tnumberStarts: " + getNumberOfStarts() + "\n";
760
761         r += "\texitTime: ";
762         if( getExitTime() == 0 ) {
763           r += "0";
764         } else {
765           r += getExitTimeDate().getTime(); 
766         }
767       r += "\n";
768
769         r += "\texitErrorTime: ";
770         if( getExitErrorTimeDate() == null ) {
771           r += "0";
772         } else {
773           r += getExitErrorTimeDate().getTime(); 
774         }
775       r += "\n";
776
777         r += "\terrorCode: " + getErrorCode() + "\n";
778         r += "\terrorSignal: " + getErrorSignal() + "\n";
779         r += "\tstateOk: " + getStateOk() + "\n";
780         r += "\tstateTooManyErrors: " + getStateTooManyErrors() + "\n";
781         r += "\tstateBadFileAccess: " + getStateBadFileAccess() + "\n";
782
783     } catch( Exception e ) {
784         return e.toString();
785     }
786     return r;
787   }
788
789   /////////////// custom override methods ////////////////////
790
791   /**
792    * Compares two Process objects respective to their names and does not
793    * factor any other attribute.    Alphabetic case is significant in 
794    * comparing names.
795    *
796    * @param     process    The Process object to be compared to this Process 
797    *                       instance
798    * 
799    * @return    Zero if the argument is equal to this Process' name, a
800    *            value less than zero if this Process' name is
801    *            lexicographically less than the argument, or a value greater
802    *            than zero if this Process' name is lexicographically
803    *            greater than the argument
804    */
805   public int compareTo(Process process)
806   {
807     return this.getName().compareTo(process.getName());
808   }
809
810   /**
811    * Comparable interface method.
812    *
813    * @see #compareTo(Process)
814    */
815   public int compareTo(Object obj)
816   {
817     return compareTo((Process)obj);
818   }
819
820   /**
821    * Tests whether two <code>Process</code> objects are equal, based on their 
822    * names and hosting server.
823    *
824    * @param otherProcess   the Process to test
825    * @return whether the specifed Process is the same as this Process
826    */
827   public boolean equals( Process otherProcess )
828   {
829     return ( name.equals(otherProcess.getName()) ) &&
830            ( this.getServer().equals(otherProcess.getServer()) );
831   }
832
833   /**
834    * Returns the name of this <CODE>Process</CODE>
835    *
836    * @return the name of this <CODE>Process</CODE>
837    */
838   public String toString()
839   {
840     return getName();
841   }
842
843   /////////////// native methods ////////////////////
844
845   /**
846    * Fills in the information fields of the provided <code>Process</code>.
847    *
848    * @param cellHandle    the handle of the cell to which the process belongs
849    * @see Cell#getCellHandle
850    * @param processName     the instance name of the process  for which to get
851    *                        the information
852    * @param theProcess     the {@link Process Process} object in which to fill 
853    *                       in the information
854    * @exception AFSException   If an error occurs in the native code
855    */
856   protected static native void getProcessInfo( int cellHandle, 
857                                                String processName, 
858                                                Process theProcess ) 
859         throws AFSException;
860
861   /**
862    * Creates a processes on a server.
863    *
864    * @param serverHandle  the bos handle of the server to which the key will 
865    *                      belong
866    * @see Server#getBosServerHandle
867    * @param processName  the instance name to give the process.  See AFS 
868    *                     documentation for a standard list of instance names
869    * @param processType  the type of process this will be. 
870    *                     Acceptable values are:<ul>
871    *                     <li>{@link #SIMPLE_PROCESS}</li>
872    *                     <li>{@link #FS_PROCESS}</li>
873    *                     <li>{@link #CRON_PROCESS}</li></ul>
874    * @param executionPath  the execution path process to create
875    * @param cronTime   a String representing the time a cron process is to 
876    *                   be run.  Acceptable formats are:<ul>
877    *                   <li>for daily restarts: "23:10" or "11:10 pm"</li>
878    *                   <li>for weekly restarts: "sunday 11:10pm" or 
879    *                       "sun 11:10pm"</li>
880    *                   </ul>
881    *                   Can be <code>null</code> for non-cron processes.
882    * @param notifier   the execution path to a notifier program that should 
883    *                   be called when the process terminates.  Can be 
884    *                   <code>null</code>
885    * @exception AFSException  If an error occurs in the native code
886    */
887   protected static native void create( int serverHandle, String processName, 
888                                        int processType, String executionPath, 
889                                        String cronTime, String notifier )
890     throws AFSException;
891
892   /**
893    * Removes a process from a server.
894    *
895    * @param serverHandle  the bos handle of the server to which the process 
896    *                      belongs
897    * @see Server#getBosServerHandle
898    * @param processName   the name of the process to remove
899    * @exception AFSException  If an error occurs in the native code
900    */
901   protected static native void delete( int serverHandle, String processName )
902     throws AFSException;
903
904   /**
905    * Start this process.
906    *
907    * @param serverHandle  the bos handle of the server to which the process 
908    *                      belongs
909    * @see Server#getBosServerHandle
910    * @param processName   the name of the process to start
911    * @exception AFSException  If an error occurs in the native code
912    */
913   protected static native void start( int serverHandle, String processName )
914     throws AFSException;
915
916   /**
917    * Retart this process.
918    *
919    * @param serverHandle  the bos handle of the server to which the process 
920    *                      belongs
921    * @see Server#getBosServerHandle
922    * @param processName   the name of the process to restart
923    * @exception AFSException  If an error occurs in the native code
924    */
925   protected static native void restart( int serverHandle, String processName )
926     throws AFSException;
927
928   /**
929    * Stop this process.
930    *
931    * @param serverHandle  the bos handle of the server to which the process 
932    *                      belongs
933    * @see Server#getBosServerHandle
934    * @param processName   the name of the process to stop
935    * @exception AFSException  If an error occurs in the native code
936    */
937   protected static native void stop( int serverHandle, String processName )
938     throws AFSException;
939
940   /**
941    * Reclaims all memory being saved by the process portion of the native 
942    * library. This method should be called when no more <code>Process</code> 
943    * objects are expected to be used.
944    */
945   protected static native void reclaimProcessMemory();
946 }
947
948
949
950
951
952
953