KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > antlr > works > scm > p4 > P4


1 /*
2
3 [The "BSD licence"]
4 Copyright (c) 2005 Jean Bovet
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 3. The name of the author may not be used to endorse or promote products
17 derived from this software without specific prior written permission.
18
19 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 */

31
32
33 package org.antlr.works.scm.p4;
34
35 import org.antlr.works.prefs.AWPrefs;
36 import org.antlr.works.scm.SCM;
37 import org.antlr.works.scm.SCMDelegate;
38 import org.antlr.works.utils.Console;
39
40 import javax.swing.*;
41 import java.io.*;
42 import java.util.ArrayList JavaDoc;
43 import java.util.Iterator JavaDoc;
44 import java.util.List JavaDoc;
45
46 public class P4 implements SCM {
47
48     protected static final int CMD_EDIT = 1;
49     protected static final int CMD_ADD = 2;
50     protected static final int CMD_REVERT = 3;
51     protected static final int CMD_DELETE = 4;
52     protected static final int CMD_SUBMIT = 5;
53     protected static final int CMD_SYNC = 6;
54     protected static final int CMD_FSTAT = 7;
55
56     protected SCMDelegate delegate = null;
57     protected String JavaDoc fileStatus = null;
58
59     protected P4Scheduler scheduler = new P4Scheduler();
60     protected P4CommandCompletion lastCompletion = null;
61
62     protected Console console;
63
64     private final Object JavaDoc lock = new Object JavaDoc();
65
66     public P4(SCMDelegate delegate, Console console) {
67         this.delegate = delegate;
68         this.console = console;
69     }
70
71     public synchronized void queryFileStatus(String JavaDoc file) {
72         runCommand(new P4Command(CMD_FSTAT, new String JavaDoc[] { "fstat", file }, null));
73     }
74
75     public synchronized void editFile(String JavaDoc file) {
76         scheduleCommand(new P4Command(CMD_EDIT, new String JavaDoc[] { "edit", file }, null));
77         queryFileStatus(file);
78     }
79
80     public synchronized void addFile(String JavaDoc file) {
81         scheduleCommand(new P4Command(CMD_ADD, new String JavaDoc[] { "add", file }, null));
82         queryFileStatus(file);
83     }
84
85     public synchronized void deleteFile(String JavaDoc file) {
86         scheduleCommand(new P4Command(CMD_DELETE, new String JavaDoc[] { "delete", file }, null));
87         queryFileStatus(file);
88     }
89
90     public synchronized void revertFile(String JavaDoc file) {
91         scheduleCommand(new P4Command(CMD_REVERT, new String JavaDoc[] { "revert", file }, null));
92         queryFileStatus(file);
93     }
94
95     public synchronized void submitFile(String JavaDoc file, String JavaDoc description, boolean remainOpen) {
96         scheduleCommand(new P4Command(CMD_FSTAT, new String JavaDoc[] { "fstat", file }, null));
97         scheduleCommand(new P4CommandSubmit(file, description, remainOpen));
98         queryFileStatus(file);
99     }
100
101     public synchronized void sync() {
102         runCommand(new P4Command(CMD_SYNC, new String JavaDoc[] { "sync" }, null));
103     }
104
105     public synchronized boolean isFileWritable() {
106         if(fileStatus == null)
107             return true;
108         else
109             return fileStatus.equals("edit");
110     }
111
112     public synchronized String JavaDoc getFileStatus() {
113         return fileStatus;
114     }
115
116     public synchronized boolean hasErrors() {
117         if(lastCompletion == null)
118             return false;
119         else
120             return lastCompletion.hasErrors();
121     }
122
123     public synchronized String JavaDoc getErrorsDescription() {
124         if(lastCompletion == null)
125             return "";
126         else
127             return lastCompletion.errorsDescription();
128     }
129
130     public void resetErrors() {
131         lastCompletion = null;
132     }
133
134     protected void runCommand(P4Command command) {
135         scheduleCommand(command);
136         scheduleLaunch();
137     }
138
139     protected void scheduleCommand(P4Command command) {
140         scheduler.scheduleCommand(command);
141     }
142
143     protected synchronized void scheduleLaunch() {
144         if(!scheduler.isRunning())
145             scheduler.start();
146     }
147
148     protected class P4Scheduler implements Runnable JavaDoc, P4CommandCompletionDelegate {
149
150         protected List JavaDoc<P4Command> scheduledCommands = new ArrayList JavaDoc<P4Command>();
151         protected P4Command runningCommand = null;
152
153         public void start() {
154             new Thread JavaDoc(this).start();
155         }
156
157         public void run() {
158             scheduleRun(null);
159         }
160
161         protected void scheduleCommand(P4Command command) {
162             synchronized(lock) {
163                 scheduledCommands.add(command);
164             }
165         }
166
167         protected synchronized boolean isRunning() {
168             return runningCommand != null;
169         }
170
171         protected synchronized void scheduleRun(P4Command previousCommand) {
172             if(runningCommand != null) {
173                 if(runningCommand != previousCommand) {
174                     // A command is already running. The next command
175
// will be launched later.
176
return;
177                 }
178             }
179
180             synchronized(lock) {
181                 if(scheduledCommands.isEmpty()) {
182                     runningCommand = null;
183                 } else {
184                     runningCommand = scheduledCommands.get(0);
185                     scheduledCommands.remove(0);
186                 }
187             }
188
189             if(runningCommand == null) {
190                 schedulerDidComplete();
191             } else
192                 runningCommand.run(previousCommand, this);
193         }
194
195         public void commandDidComplete(P4CommandCompletion completion) {
196             if(completion.commandID == CMD_FSTAT) {
197                 // Update the file status only after "fstat" command only
198
fileStatus = completion.getObjectForKey(P4Results.OTHER, "action");
199                 if(fileStatus == null) {
200                     if(completion.hasErrors())
201                         fileStatus = "?";
202                     else
203                         fileStatus = "closed";
204                 }
205
206                 if(delegate != null)
207                     delegate.scmFileStatusDidChange(fileStatus);
208             }
209
210             lastCompletion = completion;
211
212             if(completion.hasErrors()) {
213                 // Doesn't run the other commands if there is an error in one command
214
synchronized(lock) {
215                     scheduledCommands.clear();
216                     runningCommand = null;
217                     delegate.scmCommandsDidComplete();
218                 }
219             } else
220                 scheduleRun(runningCommand);
221         }
222
223         public void schedulerDidComplete() {
224             if(delegate != null) {
225                 SwingUtilities.invokeLater(new Runnable JavaDoc() {
226                     public void run() {
227                         delegate.scmCommandsDidComplete();
228                     }
229                 });
230             }
231         }
232     }
233
234     protected class P4Command {
235
236         public int commandID;
237         public String JavaDoc[] commands;
238         public String JavaDoc[] inputArguments;
239         public P4CommandCompletion completion = null;
240
241         public P4Command(int commandID, String JavaDoc[] commands, String JavaDoc[] inputArguments) {
242             this.commandID = commandID;
243             this.commands = commands;
244             this.inputArguments = inputArguments;
245         }
246
247         public void run(P4Command previousCommand, P4CommandCompletionDelegate delegate) {
248             runCommand(commandID, commands, inputArguments, delegate);
249         }
250
251         protected boolean runCommand(int commandID, String JavaDoc[] params, String JavaDoc[] inputArguments, P4CommandCompletionDelegate delegate) {
252             String JavaDoc[] command = buildCommand(params);
253             boolean success = false;
254
255             try {
256                 Process JavaDoc p = Runtime.getRuntime().exec(command);
257
258                 completion = new P4CommandCompletion(p, commandID, delegate);
259
260                 if(inputArguments != null) {
261                     OutputStream os = p.getOutputStream();
262                     OutputStreamWriter osw = new OutputStreamWriter(os);
263                     BufferedWriter out = new BufferedWriter(osw);
264                     for(int i=0; i<inputArguments.length; i++) {
265                         out.write(inputArguments[i]);
266                         out.newLine();
267                     }
268                     out.flush();
269                     out.close();
270                 }
271
272                 success = (completion.processExitCode = p.waitFor()) == 0;
273                 completion.processTerminated();
274
275             } catch (Exception JavaDoc e) {
276                 console.print(e);
277             }
278             return success;
279         }
280
281         protected String JavaDoc[] buildCommand(String JavaDoc[] params) {
282             String JavaDoc[] command = new String JavaDoc[10+params.length];
283
284             int i = 0;
285             command[i++] = AWPrefs.getP4ExecPath();
286             command[i++] = "-s";
287             command[i++] = "-p";
288             command[i++] = AWPrefs.getP4Port();
289             command[i++] = "-u";
290             command[i++] = AWPrefs.getP4User();
291             command[i++] = "-P";
292             command[i++] = AWPrefs.getP4Password();
293             command[i++] = "-c";
294             command[i++] = AWPrefs.getP4Client();
295
296             for(int j=0; j<params.length; j++)
297                 command[i++] = params[j];
298
299             return command;
300         }
301     }
302
303     protected class P4CommandSubmit extends P4Command {
304
305         public String JavaDoc file;
306         public String JavaDoc description;
307         public boolean remainOpen;
308
309         public P4CommandSubmit(String JavaDoc file, String JavaDoc description, boolean remainOpen) {
310             super(CMD_SUBMIT, null, null);
311
312             this.file = file;
313             this.description = description;
314             this.remainOpen = remainOpen;
315         }
316
317         public void run(P4Command previousCommand, P4CommandCompletionDelegate delegate) {
318             // To submit, we have to get the depot file corresponding to the local file
319
String JavaDoc depotFile = previousCommand.completion.getObjectForKey(P4Results.OTHER, "depotFile");
320             if(depotFile != null) {
321                 String JavaDoc[] commands;
322                 if(remainOpen)
323                     commands = new String JavaDoc[] { "submit", "-r", "-i" };
324                 else
325                     commands = new String JavaDoc[] { "submit", "-i" };
326
327                 // Change: new - new means "default changelist"
328
runCommand(CMD_SUBMIT,
329                             commands,
330                             new String JavaDoc[] { "Change: new",
331                                        "Client: "+AWPrefs.getP4Client(),
332                                        "User: "+ AWPrefs.getP4User(),
333                                        "Description:\n\t"+description,
334                                        "Files:\n\t"+depotFile},
335                             delegate);
336             }
337         }
338     }
339
340     protected class P4Results {
341
342         public static final int ERROR = 0;
343         public static final int WARNING = 1;
344         public static final int TEXT = 2;
345         public static final int INFO = 3;
346         public static final int EXIT = 4;
347         public static final int OTHER = 5;
348
349         protected List JavaDoc[] texts = new List JavaDoc[6];
350
351         public P4Results() {
352             for(int i=0; i<texts.length; i++)
353                 texts[i] = new ArrayList JavaDoc();
354         }
355
356         public void reset() {
357             for(int i=0; i<texts.length; i++)
358                 texts[i].clear();
359         }
360
361         public void add(int index, String JavaDoc error) {
362             texts[index].add(error.trim());
363         }
364
365         public List JavaDoc get(int index) {
366             return texts[index];
367         }
368     }
369
370     protected interface P4CommandCompletionDelegate {
371         public void commandDidComplete(P4CommandCompletion completion);
372     }
373
374     protected class P4CommandCompletion implements StreamWatcherDelegate {
375
376         public P4Results results = new P4Results();
377         public int commandID = 0;
378         public P4CommandCompletionDelegate delegate = null;
379
380         public StreamWatcher errorStreamWatcher = null;
381         public StreamWatcher inputStreamWatcher = null;
382
383         public int processExitCode = 0;
384         public boolean processTerminated = false;
385
386         public P4CommandCompletion(Process JavaDoc p, int commandID, P4CommandCompletionDelegate delegate) {
387             results.reset();
388
389             this.commandID = commandID;
390             this.delegate = delegate;
391
392             errorStreamWatcher = new StreamWatcher(p.getErrorStream(), "error", this);
393             errorStreamWatcher.start();
394
395             inputStreamWatcher = new StreamWatcher(p.getInputStream(), "input", this);
396             inputStreamWatcher.start();
397         }
398
399         public boolean hasErrors() {
400             return results.get(P4Results.ERROR).size() > 0;
401         }
402
403         public String JavaDoc errorsDescription() {
404             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
405             for(Iterator JavaDoc iter = results.get(P4Results.ERROR).iterator(); iter.hasNext(); ) {
406                 sb.append((String JavaDoc)iter.next());
407             }
408             return sb.toString();
409         }
410
411         public String JavaDoc getObjectForKey(int index, String JavaDoc key) {
412             Iterator JavaDoc iter = results.get(index).iterator();
413             while(iter.hasNext()) {
414                 String JavaDoc text = (String JavaDoc)iter.next();
415                 if(text.startsWith(key)) {
416                     return text.substring(key.length()+1).trim();
417                 }
418             }
419             return null;
420         }
421
422         public synchronized void processTerminated() {
423             processTerminated = true;
424             notifyIfCommandCompleted();
425         }
426
427         public synchronized void notifyIfCommandCompleted() {
428             if(errorStreamWatcher == null && inputStreamWatcher == null && processTerminated) {
429                 // Command is completed once all stream watcher have terminated AND
430
// the process has terminated
431
if(delegate != null)
432                     delegate.commandDidComplete(this);
433             }
434         }
435
436         public synchronized void streamWatcherDidReceiveText(StreamWatcher sw, String JavaDoc line) {
437             if(P4.this.delegate != null)
438                 P4.this.delegate.scmLog(line);
439
440             int index = line.indexOf(':');
441             String JavaDoc text = line;
442             if(index != -1)
443                 text = line.substring(index+1);
444
445             if(line.startsWith("error:"))
446                 results.add(P4Results.ERROR, text);
447             else if(line.startsWith("warning:"))
448                 results.add(P4Results.WARNING, text);
449             else if(line.startsWith("text:"))
450                 results.add(P4Results.TEXT, text);
451             else if(line.startsWith("info:"))
452                 results.add(P4Results.INFO, text);
453             else if(line.startsWith("exit:"))
454                 results.add(P4Results.EXIT, text);
455             else
456                 results.add(P4Results.OTHER, text);
457         }
458
459         public synchronized void streamWatcherDidEnd(StreamWatcher sw) {
460             if(sw == errorStreamWatcher)
461                 errorStreamWatcher = null;
462             if(sw == inputStreamWatcher)
463                 inputStreamWatcher = null;
464
465             notifyIfCommandCompleted();
466         }
467     }
468
469     protected interface StreamWatcherDelegate {
470         public void streamWatcherDidReceiveText(StreamWatcher sw, String JavaDoc text);
471         public void streamWatcherDidEnd(StreamWatcher sw);
472     }
473
474     protected class StreamWatcher extends Thread JavaDoc {
475
476         public InputStream is;
477         public String JavaDoc type;
478         public StreamWatcherDelegate delegate;
479
480         public StreamWatcher(InputStream is, String JavaDoc type, StreamWatcherDelegate delegate) {
481             this.is = is;
482             this.type = type;
483             this.delegate = delegate;
484         }
485
486         public void run() {
487             try {
488                 BufferedReader br = new BufferedReader(new InputStreamReader(is));
489                 String JavaDoc line;
490                 while ( (line = br.readLine()) != null) {
491                     if(delegate != null)
492                         delegate.streamWatcherDidReceiveText(this, line);
493                 }
494             } catch (IOException e) {
495                 console.print(e);
496             }
497             if(delegate != null)
498                 delegate.streamWatcherDidEnd(this);
499         }
500     }
501
502 }
503
Popular Tags