KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > team > internal > ccvs > core > client > Command


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  * Matt McCutchen <hashproduct+eclipse@gmail.com> - Bug 179174 CVS client sets timestamps back when replacing
11  *******************************************************************************/

12 package org.eclipse.team.internal.ccvs.core.client;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.HashMap JavaDoc;
16 import java.util.List JavaDoc;
17 import java.util.Map JavaDoc;
18
19 import org.eclipse.core.resources.IFile;
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.core.runtime.*;
22 import org.eclipse.osgi.util.NLS;
23 import org.eclipse.team.internal.ccvs.core.*;
24 import org.eclipse.team.internal.ccvs.core.client.listeners.ICommandOutputListener;
25
26 /**
27  * Abstract base class for command requests.
28  * Provides a framework for implementing command execution.
29  */

30 public abstract class Command extends Request {
31     /*** Command singleton instances ***/
32     public final static Add ADD = new Add();
33     public final static Admin ADMIN = new Admin();
34     public final static Annotate ANNOTATE = new Annotate();
35     public final static Checkout CHECKOUT = new CheckoutWithOverwrite();
36     public final static Commit COMMIT = new Commit();
37     public final static Diff DIFF = new Diff();
38     public final static RDiff RDIFF = new RDiff();
39     public final static Editors EDITORS = new Editors();
40     public final static Import IMPORT = new Import();
41     public final static Log LOG = new Log();
42     public final static Remove REMOVE = new Remove();
43     public final static Status STATUS = new Status();
44     public final static Tag TAG = new Tag();
45     // The CUSTOM_TAG command has special handling for added and removed resources.
46
// This behavior supports branching with local changes in the workspace
47
public final static Tag CUSTOM_TAG = new Tag(true);
48     public final static RTag RTAG = new RTag();
49     public final static Update UPDATE = new Update();
50     public final static Update REPLACE = new Replace();
51     public final static SyncUpdate SYNCUPDATE = new SyncUpdate();
52     public final static Version VERSION = new Version();
53     public final static NOOPCommand NOOP = new NOOPCommand();
54     
55     // Empty argument array
56
public final static String JavaDoc[] NO_ARGUMENTS = new String JavaDoc[0];
57
58     /*** Global options ***/
59     // Empty global option array
60
public static final GlobalOption[] NO_GLOBAL_OPTIONS = new GlobalOption[0];
61     // Do not change file contents
62
public static final GlobalOption DO_NOT_CHANGE = new GlobalOption("-n"); //$NON-NLS-1$
63
// Do not record this operation into CVS command history
64
public static final GlobalOption DO_NOT_LOG = new GlobalOption("-l"); //$NON-NLS-1$
65
// Make new working files read-only
66
public static final GlobalOption MAKE_READ_ONLY = new GlobalOption("-r"); //$NON-NLS-1$
67
// Trace command execution
68
public static final GlobalOption TRACE_EXECUTION = new GlobalOption("-t"); //$NON-NLS-1$
69

70     /*** Global options: quietness ***/
71     // Don't be quiet (normal verbosity)
72
public static final QuietOption VERBOSE = new QuietOption(""); //$NON-NLS-1$
73
// Be somewhat quiet (suppress informational messages)
74
public static final QuietOption PARTLY_QUIET = new QuietOption("-q"); //$NON-NLS-1$
75
// Be really quiet (silent but for serious problems)
76
public static final QuietOption SILENT = new QuietOption("-Q"); //$NON-NLS-1$
77

78     /*** Local options: common to many commands ***/
79     // Empty local option array
80
public static final LocalOption[] NO_LOCAL_OPTIONS = new LocalOption[0];
81     // valid for: annotate checkout commit diff export log rdiff remove rtag status tag update
82
public static final LocalOption RECURSE = new LocalOption("-R"); //$NON-NLS-1$
83
public static final LocalOption DO_NOT_RECURSE = new LocalOption("-l"); //$NON-NLS-1$
84
// valid for: checkout export update
85
public static final LocalOption PRUNE_EMPTY_DIRECTORIES = new LocalOption("-P"); //$NON-NLS-1$
86
// valid for: checkout export update
87
public static final LocalOption MESSAGE_OPTION = new LocalOption("-m"); //$NON-NLS-1$
88

89     /*** Local options: keyword substitution mode ***/
90     // valid for: add admin checkout export import update
91
private static final Map JavaDoc ksubstOptionMap = new HashMap JavaDoc();
92     public static final KSubstOption KSUBST_BINARY = new KSubstOption("-kb"); //$NON-NLS-1$
93
public static final KSubstOption KSUBST_TEXT = new KSubstOption("-ko"); //$NON-NLS-1$
94
public static final KSubstOption KSUBST_TEXT_EXPAND = new KSubstOption("-kkv"); //$NON-NLS-1$
95
public static final KSubstOption KSUBST_TEXT_EXPAND_LOCKER = new KSubstOption("-kkvl"); //$NON-NLS-1$
96
public static final KSubstOption KSUBST_TEXT_VALUES_ONLY = new KSubstOption("-kv"); //$NON-NLS-1$
97
public static final KSubstOption KSUBST_TEXT_KEYWORDS_ONLY = new KSubstOption("-kk"); //$NON-NLS-1$
98

99     /*** Default command output listener ***/
100     protected static final ICommandOutputListener DEFAULT_OUTPUT_LISTENER = new CommandOutputListener();
101     
102     /**
103      * Prevents client code from instantiating us.
104      */

105     protected Command() { }
106
107     /**
108      * Provides the default command output listener which is used to accumulate errors.
109      *
110      * Subclasses can override this method in order to properly interpret information
111      * received from the server.
112      */

113     protected ICommandOutputListener getDefaultCommandOutputListener() {
114         return DEFAULT_OUTPUT_LISTENER;
115     }
116
117     /**
118      * Sends the command's arguments to the server.
119      * [template method]
120      * <p>
121      * The default implementation sends all arguments. Subclasses may override
122      * this method to provide alternate behaviour.
123      * </p>
124      *
125      * @param session the CVS session
126      * @param arguments the arguments that were supplied by the caller of execute()
127      */

128     protected void sendArguments(Session session, String JavaDoc[] arguments) throws CVSException {
129         for (int i = 0; i < arguments.length; ++i) {
130             session.sendArgument(arguments[i]);
131         }
132     }
133
134     /**
135      * Describes the local resource state to the server prior to command execution.
136      * [template method]
137      * <p>
138      * Commands must override this method to inform the server about the state of
139      * local resources using the Entries, Modified, Unchanged, and Questionable
140      * requests as needed.
141      * </p>
142      * <p>
143      * This method should return the resources that are of interest to the
144      * <code>Command#commandFinished()</code> method. In most cases, it
145      * is the same resources that are provided but in some cases (e.g. Commit)
146      * the resources to be passed to the above method are different.
147      * </p>
148      *
149      * @param session the CVS session
150      * @param globalOptions the global options for the command
151      * @param localOptions the local options for the command
152      * @param resources the resource arguments for the command
153      * @param monitor the progress monitor
154      * @return ICVSResource[]
155      */

156     protected abstract ICVSResource[] sendLocalResourceState(Session session, GlobalOption[] globalOptions,
157         LocalOption[] localOptions, ICVSResource[] resources, IProgressMonitor monitor)
158         throws CVSException;
159
160     /**
161      * Cleans up after command execution.
162      * [template method]
163      * <p>
164      * The default implementation is a no-op. Subclasses may override this
165      * method to follow up command execution on the server with clean up
166      * operations on local resources.
167      * </p>
168      *
169      * @param session the CVS session
170      * @param globalOptions the global options for the command
171      * @param localOptions the local options for the command
172      * @param resources the resource arguments for the command
173      * @param monitor the progress monitor
174      * @param status the status accumulated so far. If the code == CVSStatus.SERVER_ERROR
175      * then the command failed
176      * @return status the status past in plus any additional status accumulated during the finish
177      */

178     protected IStatus commandFinished(Session session, GlobalOption[] globalOptions,
179         LocalOption[] localOptions, ICVSResource[] resources, IProgressMonitor monitor,
180         IStatus status) throws CVSException {
181             return status;
182     }
183
184     /**
185      * Sends the local working directory path prior to command execution.
186      * [template method]
187      * <p>
188      * The default implementation sends the paths of local root directory
189      * (assuming it exists). Subclasses may override this method to provide
190      * alternate behaviour.
191      * </p>
192      *
193      * @param session the CVS session
194      */

195     protected void sendLocalWorkingDirectory(Session session) throws CVSException {
196         ICVSFolder localRoot = session.getLocalRoot();
197         if (localRoot.isCVSFolder()) {
198             session.sendLocalRootDirectory();
199         } else {
200             session.sendConstructedRootDirectory();
201         }
202     }
203
204     /**
205      * Computes an array of ICVSResources corresponding to command arguments.
206      * [template method]
207      * <p>
208      * The default implementation assumes that all arguments supplied to the
209      * command represent resources in the local root that are to be manipulated.
210      * Subclasses must override this method if this assumption does not hold.
211      * </p>
212      * @param session the CVS session
213      * @param localOptions the command local options
214      * @param arguments the command arguments
215      * @return the resource arguments for the command
216      */

217     protected ICVSResource[] computeWorkResources(Session session,
218         LocalOption[] localOptions, String JavaDoc[] arguments) throws CVSException {
219         ICVSFolder localRoot = session.getLocalRoot();
220
221         if (arguments.length == 0) {
222             // As a convenience, passing no arguments to the CVS command
223
// implies the command will operate on the local root folder.
224
return new ICVSResource[] { localRoot };
225         } else {
226             // Assume all arguments represent resources that are descendants
227
// of the local root folder.
228
ICVSResource[] resources = new ICVSResource[arguments.length];
229             for (int i = 0; i < arguments.length; i++) {
230                 ICVSResource resource = localRoot.getChild(arguments[i]);
231                 // file does not exist, it could have been deleted. It doesn't matter
232
// which type we return since only the name of the resource is used
233
// and sent to the server.
234
if(resource==null) {
235                     if(localRoot.getName().length()==0) {
236                         // Return a folder because it is the safest choice when
237
// localRoot is a handle to the IWorkspaceRoot!
238
resource = localRoot.getFolder(arguments[i]);
239                     } else {
240                         resource = localRoot.getFile(arguments[i]);
241                     }
242                 }
243                 resources[i] = resource;
244             }
245             return resources;
246         }
247     }
248
249     /**
250      * Send an array of Resources.
251      * @param localOptions
252      *
253      * @see Command#sendFileStructure(ICVSResource,IProgressMonitor,boolean,boolean,boolean)
254      */

255     protected void sendFileStructure(Session session, ICVSResource[] resources,
256         LocalOption[] localOptions, boolean emptyFolders, IProgressMonitor monitor) throws CVSException {
257         checkResourcesManaged(session, resources);
258         
259         new FileStructureVisitor(session, localOptions, emptyFolders, true).visit(session, resources, monitor);
260     }
261
262     /**
263      * Checks that all work resources are managed.
264      * @param session TODO
265      * @param resources the resource arguments for the command
266      *
267      * @throws CVSException if some resources are not managed
268      */

269     protected void checkResourcesManaged(Session session, ICVSResource[] resources) throws CVSException {
270         for (int i = 0; i < resources.length; ++i) {
271             ICVSFolder folder;
272             if (resources[i].isFolder()) {
273                 folder = (ICVSFolder) resources[i];
274             }
275             else {
276                 folder = resources[i].getParent();
277             }
278             if (!folder.isCVSFolder() && folder.exists()) {
279                 IStatus status = new CVSStatus(IStatus.ERROR,CVSStatus.ERROR,NLS.bind(CVSMessages.Command_argumentNotManaged, new String JavaDoc[] { folder.getName() }),session.getLocalRoot());
280                 throw new CVSException(status);
281             }
282         }
283     }
284         
285     /**
286      * Executes a CVS command.
287      * <p>
288      * Dispatches the commands, retrieves the results, and determines whether or
289      * not an error occurred. A listener may be supplied to capture message text
290      * that would normally be written to the standard error and standard output
291      * streams of a command line CVS client.
292      * </p>
293      * @param session the open CVS session
294      * @param globalOptions the array of global options, or NO_GLOBAL_OPTIONS
295      * @param localOptions the array of local options, or NO_LOCAL_OPTIONS
296      * @param arguments the array of arguments (usually filenames relative to localRoot), or NO_ARGUMENTS
297      * @param listener the command output listener, or null to discard all messages
298      * @param monitor the progress monitor
299      * @return a status code indicating success or failure of the operation
300      * @throws CVSException if a fatal error occurs (e.g. connection timeout)
301      */

302     public final IStatus execute(final Session session, final GlobalOption[] globalOptions,
303         final LocalOption[] localOptions, final String JavaDoc[] arguments, final ICommandOutputListener listener,
304         IProgressMonitor pm) throws CVSException {
305         final IStatus[] status = new IStatus[1];
306         ICVSRunnable job = new ICVSRunnable() {
307             public void run(IProgressMonitor monitor) throws CVSException {
308                 // update the global and local options
309
GlobalOption[] gOptions = filterGlobalOptions(session, globalOptions);
310                 LocalOption[] lOptions = filterLocalOptions(session, gOptions, localOptions);
311                 
312                 // print the invocation string to the console
313
if (session.isOutputToConsole() || Policy.isDebugProtocol()) {
314                     IPath commandRootPath;
315                     IResource resource = session.getLocalRoot().getIResource();
316                     if (resource == null) {
317                         commandRootPath = Path.EMPTY;
318                     } else {
319                         commandRootPath = resource.getFullPath();
320                     }
321                     String JavaDoc line = constructCommandInvocationString(commandRootPath, gOptions, lOptions, arguments);
322                     ConsoleListeners.getInstance().commandInvoked(session, line);
323                     if (Policy.isDebugProtocol()) Policy.printProtocolLine("CMD> " + line); //$NON-NLS-1$
324
}
325                 
326                 // run the command
327
try {
328                     session.setCurrentCommand(Command.this);
329                     status[0] = doExecute(session, gOptions, lOptions, arguments, listener, monitor);
330                     notifyConsoleOnCompletion(session, status[0], null);
331                 } catch (CVSException e) {
332                     notifyConsoleOnCompletion(session, null, e);
333                     throw e;
334                 } catch (RuntimeException JavaDoc e) {
335                     notifyConsoleOnCompletion(session, null, e);
336                     throw e;
337                 }
338             }
339         };
340         if (isWorkspaceModification()) {
341             session.getLocalRoot().run(job, pm);
342         } else {
343             job.run(pm);
344         }
345         return status[0];
346     }
347     
348     /**
349      * Return whether this command modifies the workspace.
350      * If <code>true</code> is returned, a scheduling rule on
351      * the session local root is obtained. Otherwise, no
352      * scheduling rule is obtained. By default, <code>true</code>
353      * is returned
354      * @return whether this command modifies the workspace
355      */

356     protected boolean isWorkspaceModification() {
357         return true;
358     }
359
360     private void notifyConsoleOnCompletion(Session session, IStatus status, Exception JavaDoc exception) {
361         ConsoleListeners.getInstance().commandCompleted(session, status, exception);
362         if (Policy.isDebugProtocol()) {
363             if (status != null) Policy.printProtocolLine("RESULT> " + status.toString()); //$NON-NLS-1$
364
else Policy.printProtocolLine("RESULT> " + exception.toString()); //$NON-NLS-1$
365
}
366     }
367
368     protected IStatus doExecute(Session session, GlobalOption[] globalOptions,
369         LocalOption[] localOptions, String JavaDoc[] arguments, ICommandOutputListener listener,
370         IProgressMonitor monitor) throws CVSException {
371         ICVSResource[] resources = null;
372         /*** setup progress monitor ***/
373         monitor = Policy.monitorFor(monitor);
374         monitor.beginTask(null, 100);
375         Policy.checkCanceled(monitor);
376         try {
377             /*** prepare for command ***/
378             // clear stale command state from previous runs
379
session.setNoLocalChanges(DO_NOT_CHANGE.isElementOf(globalOptions));
380             session.setModTime(null);
381
382             /*** initiate command ***/
383             // send global options
384
for (int i = 0; i < globalOptions.length; i++) {
385                 globalOptions[i].send(session);
386             }
387             Policy.checkCanceled(monitor);
388             // send local options
389
for (int i = 0; i < localOptions.length; i++) {
390                 localOptions[i].send(session);
391             }
392             Policy.checkCanceled(monitor);
393             // compute the work resources
394
resources = computeWorkResources(session, localOptions, arguments);
395             Policy.checkCanceled(monitor);
396             // send local working directory state contributes 48% of work
397
resources = sendLocalResourceState(session, globalOptions, localOptions,
398                     resources, Policy.infiniteSubMonitorFor(monitor, 48));
399             Policy.checkCanceled(monitor);
400             // send arguments
401
sendArguments(session, arguments);
402             // send local working directory path
403
sendLocalWorkingDirectory(session);
404
405             // if no listener was provided, use the command's default in order to get error reporting
406
if (listener == null) listener = getDefaultCommandOutputListener();
407
408             /*** execute command and process responses ***/
409             // Processing responses contributes 50% of work.
410
IStatus status = executeRequest(session, listener, Policy.subMonitorFor(monitor, 50));
411
412             // Finished adds last 2% of work.
413
status = commandFinished(session, globalOptions, localOptions, resources, Policy.subMonitorFor(monitor, 2),
414                 status);
415             return status;
416         } finally {
417             monitor.done();
418         }
419     }
420     
421     /**
422      * Constucts the CVS command invocation string corresponding to the arguments.
423      *
424      * @param globalOptions the global options
425      * @param localOption the local options
426      * @param arguments the arguments
427      * @return the command invocation string
428      */

429     private String JavaDoc constructCommandInvocationString(IPath commandRootPath, GlobalOption[] globalOptions,
430         LocalOption[] localOptions, String JavaDoc[] arguments) {
431         StringBuffer JavaDoc commandLine = new StringBuffer JavaDoc("cvs"); //$NON-NLS-1$
432
for (int i = 0; i < globalOptions.length; ++i) {
433             String JavaDoc option = globalOptions[i].toString();
434             if (option.length() == 0) continue;
435             commandLine.append(' ');
436             commandLine.append(option);
437         }
438         commandLine.append(' ');
439         commandLine.append(getRequestId());
440         for (int i = 0; i < localOptions.length; ++i) {
441             String JavaDoc option = localOptions[i].toString();
442             if (option.length() == 0) continue;
443             commandLine.append(' ');
444             commandLine.append(option);
445         }
446         for (int i = 0; i < arguments.length; ++i) {
447             if (arguments[i].length() == 0) continue;
448             commandLine.append(" \""); //$NON-NLS-1$
449
IPath completePath = commandRootPath;
450             if (!arguments[i].equals(Session.CURRENT_LOCAL_FOLDER)) {
451                 completePath = completePath.append(arguments[i]);
452             }
453             commandLine.append(completePath.toString());
454             commandLine.append('"');
455         }
456         return commandLine.toString();
457     }
458
459     /**
460      * Superclass for all CVS command options
461      */

462     protected static abstract class Option {
463         protected String JavaDoc option, argument;
464         protected Option(String JavaDoc option, String JavaDoc argument) {
465             this.option = option;
466             this.argument = argument;
467         }
468         /**
469          * Determines if this option is an element of an array of options
470          * @param array the array of options
471          * @return true iff the array contains this option
472          */

473         public boolean isElementOf(Option[] array) {
474             return findOption(array, option) != null;
475         }
476         /**
477          * Returns the option part of the option
478          */

479         String JavaDoc getOption() {
480             return option;
481         }
482         /**
483          * Compares two options for equality.
484          * @param other the other option
485          */

486         public boolean equals(Object JavaDoc other) {
487             if (this == other) return true;
488             if (other instanceof Option) {
489                 Option otherOption = (Option) other;
490                 return option.equals(otherOption.option);
491             }
492             return false;
493         }
494         /**
495          * Sends the option to a CVS server
496          * @param session the CVS session
497          */

498         public abstract void send(Session session) throws CVSException;
499         /*
500          * To make debugging a tad easier.
501          */

502         public String JavaDoc toString() {
503             if (argument != null && argument.length() != 0) {
504                 return option + " \"" + argument + '"'; //$NON-NLS-1$
505
} else {
506                 return option;
507             }
508         }
509     }
510     /**
511      * Option subtype for global options that are common to all commands.
512      */

513     public static class GlobalOption extends Option {
514         protected GlobalOption(String JavaDoc option) {
515             super(option, null);
516         }
517         public void send(Session session) throws CVSException {
518             session.sendGlobalOption(option);
519         }
520         /**
521          * Add the given global option to the end of the provided list
522          *
523          * @param newOption
524          * @param options
525          * @return GlobalOption[]
526          */

527         protected GlobalOption[] addToEnd(GlobalOption[] options) {
528             GlobalOption[] globalOptions = new GlobalOption[options.length + 1];
529             System.arraycopy(options, 0, globalOptions, 0, options.length);
530             globalOptions[globalOptions.length - 1] = this;
531             return globalOptions;
532         }
533     }
534     /**
535      * Option subtype for global quietness options.
536      */

537     public static final class QuietOption extends GlobalOption {
538         private QuietOption(String JavaDoc option) {
539             super(option);
540         }
541         public void send(Session session) throws CVSException {
542             if (option.length() != 0) super.send(session);
543         }
544     }
545     /**
546      * Option subtype for local options that vary from command to command.
547      */

548     public static class LocalOption extends Option {
549         protected LocalOption(String JavaDoc option) {
550             super(option, null);
551         }
552         protected LocalOption(String JavaDoc option, String JavaDoc argument) {
553             super(option, argument);
554         }
555         public void send(Session session) throws CVSException {
556             session.sendArgument(option);
557             if (argument != null) session.sendArgument(argument);
558         }
559         public LocalOption[] addTo(LocalOption[] options) {
560             if (this.isElementOf(options)) {
561                 return options;
562             }
563             LocalOption[] newOptions = new LocalOption[options.length + 1];
564             System.arraycopy(options, 0, newOptions, 0, options.length);
565             newOptions[options.length] = this;
566             return newOptions;
567         }
568         public LocalOption[] removeFrom(LocalOption[] options) {
569             if (!this.isElementOf(options)) {
570                 return options;
571             }
572             List JavaDoc result = new ArrayList JavaDoc();
573             for (int i = 0; i < options.length; i++) {
574                 Command.LocalOption option = options[i];
575                 if (!option.equals(this)) {
576                     result.add(option);
577                 }
578             }
579             return (LocalOption[]) result.toArray(new LocalOption[result.size()]);
580         }
581     }
582     /**
583      * Options subtype for keyword substitution options.
584      */

585     public static class KSubstOption extends LocalOption {
586         private boolean isUnknownMode;
587         private KSubstOption(String JavaDoc option) {
588             this(option, false);
589         }
590         private KSubstOption(String JavaDoc option, boolean isUnknownMode) {
591             super(option);
592             this.isUnknownMode = isUnknownMode;
593             ksubstOptionMap.put(option, this);
594         }
595         /**
596          * Gets the KSubstOption instance for the specified mode.
597          *
598          * @param mode the mode, e.g. -kb
599          * @return an instance for that mode
600          */

601         public static KSubstOption fromMode(String JavaDoc mode) {
602             if (mode.length() == 0) mode = "-kkv"; // use default //$NON-NLS-1$
603
KSubstOption option = (KSubstOption) ksubstOptionMap.get(mode);
604             if (option == null) option = new KSubstOption(mode, true);
605             return option;
606         }
607         /**
608          * Gets the KSubstOption instance for the specified file.
609          *
610          * @param file the file to get the option for
611          * @return an instance for that mode
612          */

613         public static KSubstOption fromFile(IFile file) {
614             if (CVSProviderPlugin.isText(file))
615                 return getDefaultTextMode();
616             return KSUBST_BINARY;
617         }
618         /**
619          * Returns an array of all valid modes.
620          */

621         public static KSubstOption[] getAllKSubstOptions() {
622             return (KSubstOption[]) ksubstOptionMap.values().toArray(new KSubstOption[ksubstOptionMap.size()]);
623         }
624         /**
625          * Returns the entry line mode string for this instance. Note that it might return blank strings
626          * for certain options. For UI, use {@link #toMode()} which will always return the a string
627          * containing the keyword substitution.
628          */

629         public String JavaDoc toEntryLineMode() {
630             if (KSUBST_TEXT_EXPAND.equals(this)) return ""; //$NON-NLS-1$
631
return getOption();
632         }
633         
634         /**
635          * Returns the entry line mode string for this instance.
636          */

637         public String JavaDoc toMode(){
638             return getOption();
639         }
640         
641         /**
642          * Returns true if the substitution mode requires no data translation
643          * during file transfer.
644          */

645         public boolean isBinary() {
646             return KSUBST_BINARY.equals(this);
647         }
648         /**
649          * Returns a short localized text string describing this mode.
650          */

651         public String JavaDoc getShortDisplayText() {
652             if (isUnknownMode)
653                 return NLS.bind(CVSMessages.KSubstOption_unknown_short, new String JavaDoc[] { option });
654             if (option.equals("-kb")) //$NON-NLS-1$
655
return CVSMessages.KSubstOption__kb_short;
656             if (option.equals("-kkv")) //$NON-NLS-1$
657
return CVSMessages.KSubstOption__kkv_short;
658             if (option.equals("-ko")) //$NON-NLS-1$
659
return CVSMessages.KSubstOption__ko_short;
660             if (option.equals("-kk")) //$NON-NLS-1$
661
return CVSMessages.KSubstOption__kk_short;
662             if (option.equals("-kv")) //$NON-NLS-1$
663
return CVSMessages.KSubstOption__kv_short;
664             if (option.equals("-kkvl")) //$NON-NLS-1$
665
return CVSMessages.KSubstOption__kkvl_short;
666             return NLS.bind(CVSMessages.KSubstOption_unknown_short, new String JavaDoc[] { option });
667         }
668         /**
669          * Returns a long localized text string describing this mode.
670          */

671         public String JavaDoc getLongDisplayText() {
672             if (isUnknownMode)
673                 return NLS.bind(CVSMessages.KSubstOption_unknown_long, new String JavaDoc[] { option });
674             if (option.equals("-kb")) //$NON-NLS-1$
675
return CVSMessages.KSubstOption__kb_long;
676             if (option.equals("-kkv")) //$NON-NLS-1$
677
return CVSMessages.KSubstOption__kkv_long;
678             if (option.equals("-ko")) //$NON-NLS-1$
679
return CVSMessages.KSubstOption__ko_long;
680             if (option.equals("-kk")) //$NON-NLS-1$
681
return CVSMessages.KSubstOption__kk_long;
682             if (option.equals("-kv")) //$NON-NLS-1$
683
return CVSMessages.KSubstOption__kv_long;
684             if (option.equals("-kkvl")) //$NON-NLS-1$
685
return CVSMessages.KSubstOption__kkvl_long;
686             return NLS.bind(CVSMessages.KSubstOption_unknown_long, new String JavaDoc[] { option });
687         }
688         /**
689          * Return the text mode that will be used by default
690          */

691         public static KSubstOption getDefaultTextMode() {
692             return CVSProviderPlugin.getPlugin().getDefaultTextKSubstOption();
693         }
694     }
695
696     /**
697      * Makes a -m log message option.
698      * Valid for: add commit import
699      */

700     public static LocalOption makeArgumentOption(LocalOption option, String JavaDoc argument) {
701         if(argument == null) {
702             argument = ""; //$NON-NLS-1$
703
}
704         return new LocalOption(option.getOption(), argument);
705     }
706     
707     /**
708      * Makes a -r or -D option for a tag.
709      * Valid for: checkout export history rdiff update
710      */

711     public static LocalOption makeTagOption(CVSTag tag) {
712         int type = tag.getType();
713         switch (type) {
714             case CVSTag.BRANCH:
715             case CVSTag.VERSION:
716                 return new LocalOption("-r", tag.getName()); //$NON-NLS-1$
717
case CVSTag.DATE:
718                 return new LocalOption("-D", tag.getName()); //$NON-NLS-1$
719
default:
720                 // tag must not be HEAD
721
throw new IllegalArgumentException JavaDoc(CVSMessages.Command_invalidTag);
722         }
723     }
724
725     /**
726      * Find a specific option in an array of options
727      * @param array the array of options
728      * @param option the option string to search for
729      * @return the first element matching the option string, or null if none
730      */

731     public static Option findOption(Option[] array, String JavaDoc option) {
732         for (int i = 0; i < array.length; ++i) {
733             if (array[i].getOption().equals(option)) return array[i];
734         }
735         return null;
736     }
737
738     /**
739      * Collect all arguments of a specific option from an array of options
740      * @param array the array of options
741      * @param option the option string to search for
742      * @return an array of all arguments of belonging to matching options
743      */

744     protected static String JavaDoc[] collectOptionArguments(Option[] array, String JavaDoc option) {
745         List JavaDoc /* of String */ list = new ArrayList JavaDoc();
746         for (int i = 0; i < array.length; ++i) {
747             if (array[i].getOption().equals(option)) {
748                 list.add(array[i].argument);
749             }
750         }
751         return (String JavaDoc[]) list.toArray(new String JavaDoc[list.size()]);
752     }
753     
754     /**
755      * Allows commands to filter the set of global options to be sent.
756      * This method invokes the method of the same name on the session
757      * itself in order to get any session wide or globally set options.
758      * Subclasses that override this method should call the superclass.
759      *
760      * @param session the session
761      * @param globalOptions the global options, read-only
762      * @return the filtered global options
763      */

764     protected GlobalOption[] filterGlobalOptions(Session session, GlobalOption[] globalOptions) {
765         return session.filterGlobalOptions(globalOptions);
766     }
767     
768     /**
769      * Allows commands to filter the set of local options to be sent.
770      * Subclasses that override this method should call the superclass.
771      *
772      * @param session the session
773      * @param globalOptions the global options, read-only
774      * @param localOptions the local options, read-only
775      * @return the filtered local options
776      */

777     protected LocalOption[] filterLocalOptions(Session session, GlobalOption[] globalOptions, LocalOption[] localOptions) {
778         return localOptions;
779     }
780     
781     /**
782      * Execute a CVS command on an array of ICVSResource. This method simply converts
783      * the ICVSResource to String paths relative to the local root of the session and
784      * invokes <code>execute(Session, GlobalOption[], LocalOption[], String[], ICommandOutputListener, IProgressMonitor)</code>.
785      * </p>
786      * @param session the open CVS session
787      * @param globalOptions the array of global options, or NO_GLOBAL_OPTIONS
788      * @param localOptions the array of local options, or NO_LOCAL_OPTIONS
789      * @param arguments the array of ICVSResource to be operated on
790      * @param listener the command output listener, or null to discard all messages
791      * @param monitor the progress monitor
792      * @return a status code indicating success or failure of the operation
793      * @throws CVSException if a fatal error occurs (e.g. connection timeout)
794      *
795      * @see Command#execute(Session, GlobalOption[], LocalOption[], String[], ICommandOutputListener, IProgressMonitor)
796      */

797     public final IStatus execute(Session session, GlobalOption[] globalOptions, LocalOption[] localOptions, ICVSResource[] arguments,
798         ICommandOutputListener listener, IProgressMonitor pm) throws CVSException {
799         
800         String JavaDoc[] stringArguments = convertArgumentsForOpenSession(arguments, session);
801         return execute(session, globalOptions, localOptions, stringArguments, listener, pm);
802     }
803     
804     protected String JavaDoc[] convertArgumentsForOpenSession(ICVSResource[] arguments, Session openSession) throws CVSException {
805         // Convert arguments
806
List JavaDoc stringArguments = new ArrayList JavaDoc(arguments.length);
807         for (int i = 0; i < arguments.length; i++) {
808             stringArguments.add(arguments[i].getRelativePath(openSession.getLocalRoot()));
809         }
810         return (String JavaDoc[]) stringArguments.toArray(new String JavaDoc[stringArguments.size()]);
811     }
812     
813     /**
814      * Method mergeStatus.
815      * @param status
816      * @param cVSStatus
817      * @return IStatus
818      */

819     protected IStatus mergeStatus(IStatus accumulatedStatus, IStatus newStatus) {
820         if (accumulatedStatus.isMultiStatus()) {
821             ((MultiStatus)accumulatedStatus).merge(newStatus);
822             return accumulatedStatus;
823         }
824         if (accumulatedStatus.isOK()) return newStatus;
825         if (newStatus.isOK()) return accumulatedStatus;
826         MultiStatus result = new MultiStatus(CVSProviderPlugin.ID, IStatus.INFO,
827                 new IStatus[] {accumulatedStatus, newStatus},
828                 NLS.bind(CVSMessages.Command_warnings, new String JavaDoc[] { getDisplayText() }), null);
829         return result;
830     }
831 }
832
Popular Tags