package hudson.plugins.accurev.delegates;
import hudson.model.AbstractBuild;
import hudson.model.Job;
import hudson.model.Run;
import hudson.plugins.accurev.*;
import hudson.plugins.accurev.cmd.Command;
import hudson.plugins.accurev.cmd.ShowStreams;
import hudson.plugins.accurev.delegates.Relocation.RelocationOption;
import hudson.plugins.accurev.parsers.xml.ParseShowWorkspaces;
import hudson.scm.PollingResult;
import hudson.util.ArgumentListBuilder;
import org.apache.commons.lang.StringUtils;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
/**
* @author raymond
*/
public class WorkspaceDelegate extends ReftreeDelegate {
private static final Logger logger = Logger.getLogger(WorkspaceDelegate.class.getName());
public WorkspaceDelegate(AccurevSCM scm) {
super(scm);
}
@Override
public String getRefTree() {
return null;
}
@Override
protected PollingResult checkForChanges(Job<?, ?> project) throws IOException, InterruptedException, IllegalArgumentException {
localStream = scm.getPollingStream(project, listener);
return super.checkForChanges(project);
}
@Override
protected Relocation checkForRelocation() throws IOException, InterruptedException {
String depot = scm.getDepot();
String _accurevWorkspace = scm.getWorkspace();
Map<String, AccurevWorkspace> workspaces = getWorkspaces();
Map<String, AccurevStream> streams = ShowStreams.getStreams(scm, _accurevWorkspace, server, accurevEnv, jenkinsWorkspace, listener,
launcher);
if (workspaces == null) {
throw new IllegalArgumentException("Cannot determine workspace configuration information");
}
if (!workspaces.containsKey(_accurevWorkspace)) {
throw new IllegalArgumentException("The specified workspace does not appear to exist!");
}
AccurevWorkspace accurevWorkspace = workspaces.get(_accurevWorkspace);
if (!depot.equals(accurevWorkspace.getDepot())) {
throw new IllegalArgumentException("The specified workspace, " + _accurevWorkspace + ", is based in the depot " + accurevWorkspace.getDepot() + " not " + depot);
}
if (scm.isIgnoreStreamParent()) {
if (!streams.isEmpty()) {
AccurevStream workspaceStream = streams.values().iterator().next();
accurevWorkspace.setStream(workspaceStream);
String workspaceBasisStream = workspaceStream.getBasisName();
if (streams.containsKey(workspaceBasisStream)) {
workspaceStream.setParent(streams.get(workspaceBasisStream));
} else {
Map<String, AccurevStream> workspaceBasis = ShowStreams.getStreams(scm, workspaceBasisStream, server, accurevEnv, jenkinsWorkspace, listener,
launcher);
if (workspaceBasis == null) {
throw new IllegalArgumentException("Could not determine the workspace basis stream");
}
workspaceStream.setParent(workspaceBasis.get(workspaceBasisStream));
}
} else {
throw new IllegalArgumentException("Workspace stream not found " + _accurevWorkspace);
}
} else {
for (AccurevStream accurevStream : streams.values()) {
if (accurevWorkspace.getStreamNumber().equals(accurevStream.getNumber())) {
accurevWorkspace.setStream(accurevStream);
break;
}
}
}
final RemoteWorkspaceDetails remoteDetails = getRemoteWorkspaceDetails();
List<RelocationOption> relocationOptions = new ArrayList<>();
for (WorkspaceRelocation workspaceRelocationvalue : WorkspaceRelocation.values()) {
if (workspaceRelocationvalue.isRequired(accurevWorkspace, remoteDetails, localStream)) {
relocationOptions.add(workspaceRelocationvalue);
}
}
return new Relocation(relocationOptions, remoteDetails.getHostName(), accurevWorkingSpace.getRemote(), localStream);
}
/**
* Builds a command which gets executed and retrieves the following return data
*
* @return Map with Workspace name as key and Workspace Object as value.
* @throws IOException Failed to execute command or Parse data.
*/
private Map<String, AccurevWorkspace> getWorkspaces() throws IOException {
listener.getLogger().println("Getting a list of workspaces...");
String depot = scm.getDepot();
final ArgumentListBuilder cmd = new ArgumentListBuilder();
cmd.add("show");
Command.addServer(cmd, server);
cmd.add("-fx");
cmd.add("-p");
cmd.add(depot);
cmd.add("wspaces");
XmlPullParserFactory parser = XmlParserFactory.getFactory();
if (parser == null) throw new IOException("No XML Parser");
return AccurevLauncher.runCommand("Show workspaces command", accurevTool, launcher, cmd, scm.getOptionalLock(),
accurevEnv, jenkinsWorkspace, listener, logger, parser, new ParseShowWorkspaces(), null);
}
@Override
protected boolean validateCheckout(Run<?, ?> build) {
String workspace = scm.getWorkspace();
if (StringUtils.isEmpty(workspace)) {
listener.fatalError("Must specify a workspace");
return false;
}
return true;
}
@Override
protected String getPopulateFromMessage() {
return "from workspace";
}
@Override
protected ArgumentListBuilder getRelocateCommand() {
ArgumentListBuilder chwscmd = new ArgumentListBuilder();
chwscmd.add("chws");
Command.addServer(chwscmd, server);
chwscmd.add("-w");
chwscmd.add(scm.getWorkspace());
return chwscmd;
}
@Override
protected boolean isSteamColorEnabled() {
return true;
}
@Override
protected String getStreamColorStream() {
return scm.getWorkspace();
}
@Override
protected String getStreamColor() {
return "#FFEBB4";
}
@Override
protected String getChangeLogStream() {
return scm.getWorkspace();
}
@Override
protected void buildEnvVarsCustom(AbstractBuild<?, ?> build, Map<String, String> env) {
env.put("ACCUREV_WORKSPACE", scm.getWorkspace());
}
private enum WorkspaceRelocation implements RelocationOption {
HOST {
@Override
protected boolean isRequired(AccurevWorkspace accurevWorkspace, RemoteWorkspaceDetails remoteDetails, String localStream) {
return !accurevWorkspace.getHost().equalsIgnoreCase(remoteDetails.getHostName());
}
public void appendCommand(ArgumentListBuilder cmd, Relocation relocation) {
cmd.add("-m");
cmd.add(relocation.getNewHost());
}
},
STORAGE {
@Override
protected boolean isRequired(AccurevWorkspace accurevWorkspace, RemoteWorkspaceDetails remoteDetails, String localStream) {
String oldStorage = accurevWorkspace.getStorage()
.replace("/", remoteDetails.getFileSeparator())
.replace("\\", remoteDetails.getFileSeparator());
return !new File(oldStorage).equals(new File(remoteDetails.getPath()));
}
public void appendCommand(ArgumentListBuilder cmd, Relocation relocation) {
cmd.add("-l");
cmd.add(relocation.getNewPath());
}
},
REPARENT {
@Override
protected boolean isRequired(AccurevWorkspace accurevWorkspace, RemoteWorkspaceDetails remoteDetails, String localStream) {
return !localStream.equals(accurevWorkspace.getStream().getParent().getName());
}
@Override
public boolean isPopRequired() {
return false;
}
public void appendCommand(ArgumentListBuilder cmd, Relocation relocation) {
cmd.add("-b");
cmd.add(relocation.getNewParent());
}
};
public boolean isPopRequired() {
return true;
}
protected abstract boolean isRequired(AccurevWorkspace accurevWorkspace, RemoteWorkspaceDetails remoteDetails, String localStream);
}
}