blob: 84f0803a61cc88dd1f39b1067e347f2c29424a94 [file] [log] [blame]
/*****************************************************************************
* Sun Public License Notice
*
* The contents of this file are subject to the Sun Public License Version
* 1.0 (the "License"). You may not use this file except in compliance with
* the License. A copy of the License is available at http://www.sun.com/
*
* The Original Code is the CVS Client Library.
* The Initial Developer of the Original Code is Robert Greig.
* Portions created by Robert Greig are Copyright (C) 2000.
* All Rights Reserved.
*
* Contributor(s): Robert Greig.
*****************************************************************************/
package org.netbeans.lib.cvsclient.command.checkout;
import com.intellij.util.ThrowableRunnable;
import org.jetbrains.annotations.NonNls;
import org.netbeans.lib.cvsclient.IClientEnvironment;
import org.netbeans.lib.cvsclient.IRequestProcessor;
import org.netbeans.lib.cvsclient.connection.AuthenticationException;
import org.netbeans.lib.cvsclient.command.*;
import org.netbeans.lib.cvsclient.event.ICvsListenerRegistry;
import org.netbeans.lib.cvsclient.event.IEventSender;
import org.netbeans.lib.cvsclient.file.AbstractFileObject;
import org.netbeans.lib.cvsclient.file.DirectoryObject;
import org.netbeans.lib.cvsclient.file.ICvsFileSystem;
import org.netbeans.lib.cvsclient.progress.IProgressViewer;
import org.netbeans.lib.cvsclient.progress.sending.DummyRequestsProgressHandler;
import org.netbeans.lib.cvsclient.request.CommandRequest;
import org.netbeans.lib.cvsclient.request.ExpandModulesRequest;
import org.netbeans.lib.cvsclient.request.Requests;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author Robert Greig
*/
public final class CheckoutCommand extends AbstractCommand implements IUpdatingCommand {
// Constants ==============================================================
@NonNls public static final String EXAM_DIR = "server: Updating ";
// Fields =================================================================
private final List<String> modules = new ArrayList<String>();
private boolean pruneDirectories;
private boolean resetStickyOnes;
private boolean useHeadIfNotFound;
private String updateByDate;
private String updateByRevisionOrTag;
private String alternativeCheckoutDirectory;
private KeywordSubstitution keywordSubstitution;
private boolean printToOutput;
private final ThrowableRunnable<IOCommandException> myAfterCheckout;
// Setup ==================================================================
public CheckoutCommand(final ThrowableRunnable<IOCommandException> afterCheckout) {
myAfterCheckout = afterCheckout;
}
// Implemented ============================================================
/**
* Execute this command.
*
* @param requestProcessor the client services object that provides any necessary
* services to this command, including the ability to actually process
* all the requests
*/
public boolean execute(IRequestProcessor requestProcessor,
IEventSender eventSender,
ICvsListenerRegistry listenerRegistry,
IClientEnvironment clientEnvironment,
IProgressViewer progressViewer) throws CommandException, AuthenticationException {
final ExpandedModules expandedModules = new ExpandedModules();
if (!expandModules(expandedModules, listenerRegistry, requestProcessor, clientEnvironment)) {
return false;
}
return checkout(expandedModules, requestProcessor, listenerRegistry, clientEnvironment);
}
/**
* Resets all switches in the command.
* After calling this method, the command should have no switches defined
* and should behave defaultly.
*/
public void resetCvsCommand() {
super.resetCvsCommand();
setRecursive(true);
setResetStickyOnes(false);
setUseHeadIfNotFound(false);
setUpdateByDate(null);
setUpdateByRevisionOrTag(null);
setKeywordSubstitution(null);
setPruneDirectories(false);
setPrintToOutput(false);
}
/**
* This method returns how the command would looklike when typed on the command line.
* Each command is responsible for constructing this information.
*
* @return <command's name> [<parameters>] files/dirs. Example: checkout -p CvsCommand.java
*/
public String getCvsCommandLine() {
@NonNls final StringBuffer cvsCommandLine = new StringBuffer("checkout ");
cvsCommandLine.append(getCvsArguments());
for (final String module : modules) {
cvsCommandLine.append(module);
cvsCommandLine.append(' ');
}
return cvsCommandLine.toString();
}
// Accessing ==============================================================
public void addModule(String module) {
modules.add(module);
}
public void clearModules() {
this.modules.clear();
}
private String getAlternativeCheckoutDirectory() {
return alternativeCheckoutDirectory;
}
public void setAlternativeCheckoutDirectory(String alternativeCheckoutDirectory) {
this.alternativeCheckoutDirectory = alternativeCheckoutDirectory;
}
private boolean isPruneDirectories() {
return pruneDirectories;
}
public void setPruneDirectories(boolean pruneDirectories) {
this.pruneDirectories = pruneDirectories;
}
private boolean isResetStickyOnes() {
return resetStickyOnes;
}
public void setResetStickyOnes(boolean resetStickyOnes) {
this.resetStickyOnes = resetStickyOnes;
}
private boolean isUseHeadIfNotFound() {
return useHeadIfNotFound;
}
public void setUseHeadIfNotFound(boolean useHeadIfNotFound) {
this.useHeadIfNotFound = useHeadIfNotFound;
}
private String getUpdateByDate() {
return updateByDate;
}
public void setUpdateByDate(String updateByDate) {
this.updateByDate = updateByDate;
}
private String getUpdateByRevisionOrTag() {
return updateByRevisionOrTag;
}
public void setUpdateByRevisionOrTag(String updateByRevisionOrTag) {
this.updateByRevisionOrTag = updateByRevisionOrTag;
}
private KeywordSubstitution getKeywordSubstitution() {
return keywordSubstitution;
}
public void setKeywordSubstitution(KeywordSubstitution keywordSubstitution) {
this.keywordSubstitution = keywordSubstitution;
}
public void setPrintToOutput(final boolean printToOutput) {
this.printToOutput = printToOutput;
}
public boolean isPrintToOutput() {
return this.printToOutput;
}
// Utils ==================================================================
private boolean expandModules(ExpandedModules expandedModules,
ICvsListenerRegistry listenerRegistry,
IRequestProcessor requestProcessor,
IClientEnvironment clientEnvironment) throws CommandException, AuthenticationException {
final Requests requests = new Requests(new ExpandModulesRequest(), clientEnvironment);
addModuleArguments(requests);
requests.addLocalPathDirectoryRequest();
expandedModules.registerListeners(listenerRegistry);
try {
return requestProcessor.processRequests(requests, new DummyRequestsProgressHandler());
}
finally {
expandedModules.unregisterListeners(listenerRegistry);
}
}
private boolean checkout(ExpandedModules expandedModules,
IRequestProcessor requestProcessor,
ICvsListenerRegistry listenerRegistry,
IClientEnvironment clientEnvironment) throws CommandException, AuthenticationException {
// we first see whether the modules specified actually exist
// checked out already. If so, we must work something like an update
// command and send modified files to the server.
processExistingModules(expandedModules, clientEnvironment);
final ICvsFiles cvsFiles;
try {
if (getFileObjects().size() > 0) {
cvsFiles = scanFileSystem(clientEnvironment);
}
else {
cvsFiles = null;
}
}
catch (IOException ex) {
throw new IOCommandException(ex);
}
final Requests requests = new Requests(CommandRequest.CHECKOUT, clientEnvironment);
if (getAlternativeCheckoutDirectory() != null) {
requests.addArgumentRequest("-d");
requests.addArgumentRequest(getAlternativeCheckoutDirectory());
}
requests.addArgumentRequest(!isRecursive(), "-l");
requests.addArgumentRequest(isResetStickyOnes(), "-A");
requests.addArgumentRequest(isUseHeadIfNotFound(), "-f");
requests.addArgumentRequest(getUpdateByDate(), "-D");
requests.addArgumentRequest(getUpdateByRevisionOrTag(), "-r");
requests.addArgumentRequest(getKeywordSubstitution(), "-k");
requests.addArgumentRequest(isPrintToOutput(), "-p");
if (cvsFiles != null) {
addFileRequests(cvsFiles, requests, clientEnvironment);
}
addModuleArguments(requests);
requests.addLocalPathDirectoryRequest();
final DirectoryPruner directoryPruner;
if (isPruneDirectories()) {
directoryPruner = new DirectoryPruner(clientEnvironment);
}
else {
directoryPruner = null;
}
if (directoryPruner != null) {
directoryPruner.registerListeners(listenerRegistry);
}
try {
return requestProcessor.processRequests(requests, new DummyRequestsProgressHandler());
}
finally {
try {
if (myAfterCheckout != null) {
myAfterCheckout.run();
}
} finally {
if (directoryPruner != null) {
directoryPruner.unregisterListeners(listenerRegistry);
try {
directoryPruner.pruneEmptyDirectories();
}
catch (IOException ex) {
throw new IOCommandException(ex);
}
}
}
}
}
private void addModuleArguments(Requests requests) {
for (final String module : modules) {
requests.addArgumentRequest(module);
}
}
private void processExistingModules(ExpandedModules expandedModules, IClientEnvironment clientEnvironment) {
final ICvsFileSystem cvsFileSystem = clientEnvironment.getCvsFileSystem();
for (final String moduleName : expandedModules.getModules()) {
if (moduleName.equals(".")) {
addFileObject(DirectoryObject.getRoot());
break;
}
final File moduleFile = cvsFileSystem.getLocalFileSystem().getFile(moduleName);
final AbstractFileObject abstractFileObject;
final DirectoryObject directoryObject;
if (moduleFile.isFile()) {
abstractFileObject = cvsFileSystem.getLocalFileSystem().getFileObject(moduleFile);
directoryObject = abstractFileObject.getParent();
}
else {
directoryObject = cvsFileSystem.getLocalFileSystem().getDirectoryObject(moduleFile);
abstractFileObject = directoryObject;
}
if (clientEnvironment.getAdminReader().hasCvsDirectory(directoryObject, cvsFileSystem)) {
addFileObject(abstractFileObject);
}
}
}
private String getCvsArguments() {
@NonNls final StringBuffer cvsArguments = new StringBuffer();
if (!isRecursive()) {
cvsArguments.append("-l ");
}
if (isResetStickyOnes()) {
cvsArguments.append("-A ");
}
if (isUseHeadIfNotFound()) {
cvsArguments.append("-f ");
}
if (isPrintToOutput()) {
cvsArguments.append("-p ");
}
if (isPruneDirectories()) {
cvsArguments.append("-P ");
}
if (getKeywordSubstitution() != null) {
cvsArguments.append("-k");
cvsArguments.append(getKeywordSubstitution());
cvsArguments.append(' ');
}
if (getUpdateByRevisionOrTag() != null && getUpdateByRevisionOrTag().length() > 0) {
cvsArguments.append("-r ");
cvsArguments.append(getUpdateByRevisionOrTag());
cvsArguments.append(' ');
}
if (getUpdateByDate() != null && getUpdateByDate().length() > 0) {
cvsArguments.append("-D ");
cvsArguments.append(getUpdateByDate());
cvsArguments.append(' ');
}
return cvsArguments.toString();
}
@Override
public void setUpdateByRevisionOrDate(String revision, String date) {
setUpdateByRevisionOrTag(revision);
setUpdateByDate(date);
}
}