Skip to content

Commit

Permalink
[JENKINS-18583] - Refactoring of PerforceSCM to remove newInstance()
Browse files Browse the repository at this point in the history
This change removes need in newInstance() handler and also provides classes for future refactoring.
In addition, the change adds instance IDs to config.jelly, therefore there won't be conflicts between radioButtons().
Resolves https://issues.jenkins-ci.org/browse/JENKINS-18583

Signed-off-by: Oleg Nenashev <nenashev@synopsys.com>
  • Loading branch information
oleg-nenashev committed Nov 24, 2013
1 parent 043a336 commit 0235070
Show file tree
Hide file tree
Showing 7 changed files with 334 additions and 68 deletions.
99 changes: 57 additions & 42 deletions src/main/java/hudson/plugins/perforce/PerforceSCM.java
@@ -1,5 +1,6 @@
package hudson.plugins.perforce;

import hudson.plugins.perforce.config.DepotType;
import com.tek42.perforce.Depot;
import com.tek42.perforce.PerforceException;
import com.tek42.perforce.model.Changelist;
Expand All @@ -22,6 +23,9 @@
import hudson.matrix.MatrixRun;
import hudson.model.*;
import hudson.model.listeners.ItemListener;
import hudson.plugins.perforce.config.CleanTypeConfig;
import hudson.plugins.perforce.config.MaskViewConfig;
import hudson.plugins.perforce.config.WorkspaceCleanupConfig;
import hudson.plugins.perforce.utils.MacroStringHelper;
import hudson.plugins.perforce.utils.ParameterSubstitutionException;
import hudson.remoting.VirtualChannel;
Expand Down Expand Up @@ -54,6 +58,7 @@
import java.io.StringWriter;
import java.net.InetAddress;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
Expand Down Expand Up @@ -275,7 +280,13 @@ public class PerforceSCM extends SCM {
private String p4Charset = null;
private String p4CommandCharset = null;

// Plugin constructor, (only?) used when a job configuration is saved
/**
* SCM constructor, (only?) used when a job configuration is saved.
* This constructor uses data classes from {@link hudson.plugins.perforce.config}
* to allow proper handling of hierarchical data in Stapler. In the current
* state, these classes are not being used outside this constructor.
*/
// TODO: move data to configuration classes during the refactoring
@DataBoundConstructor
public PerforceSCM(
String p4User,
Expand Down Expand Up @@ -311,7 +322,11 @@ public PerforceSCM(
PerforceRepositoryBrowser browser,
String excludedUsers,
String excludedFiles,
boolean excludedFilesCaseSensitivity) {
boolean excludedFilesCaseSensitivity,
DepotType depotType,
WorkspaceCleanupConfig cleanWorkspace,
MaskViewConfig useViewMask
) {

this.configVersion = 1L;

Expand All @@ -338,8 +353,37 @@ public PerforceSCM(

this.p4UpstreamProject = Util.fixEmptyAndTrim(p4UpstreamProject);

this.projectPath = Util.fixEmptyAndTrim(projectPath);

//TODO: move optional entries to external classes
// Get data from the depot type
if (depotType != null) {
this.p4Stream = depotType.getP4Stream();
this.clientSpec = depotType.getClientSpec();
this.projectPath = Util.fixEmptyAndTrim(depotType.getProjectPath());
this.useStreamDepot = depotType.useP4Stream();
this.useClientSpec = depotType.useClientSpec();
this.useViewMask = depotType.useProjectPath();
}

// Get data from workspace cleanup settings
if (cleanWorkspace != null) {
setWipeRepoBeforeBuild(cleanWorkspace.isWipeRepoBeforeBuild());

CleanTypeConfig cleanType = cleanWorkspace.getCleanType();
if (cleanType != null) {
setWipeBeforeBuild(cleanType.isWipe());
setQuickCleanBeforeBuild(cleanType.isQuick());
setRestoreChangedDeletedFiles(cleanType.isRestoreChangedDeletedFiles());
}
}

// Setup view mask
if (useViewMask != null) {
setUseViewMask(true);
setViewMask(hudson.Util.fixEmptyAndTrim(useViewMask.getViewMask()));
setUseViewMaskForPolling(useViewMask.isUseViewMaskForPolling());
setUseViewMaskForSyncing(useViewMask.isUseViewMaskForSyncing());
}

this.clientOwner = Util.fixEmptyAndTrim(clientOwner);

if (p4SysRoot != null) {
Expand Down Expand Up @@ -461,6 +505,7 @@ protected Depot getDepot(Launcher launcher, FilePath workspace, AbstractProject
return depot;
}


/**
* Override of SCM.buildEnvVars() in order to setup the last change we have
* sync'd to as a Hudson
Expand Down Expand Up @@ -1777,44 +1822,14 @@ public String getDisplayName() {

@Override
public SCM newInstance(StaplerRequest req, JSONObject formData) throws FormException {
PerforceSCM newInstance = (PerforceSCM)super.newInstance(req, formData);
String depotType = req.getParameter("p4.depotType");
boolean useStreamDepot = depotType.equals("stream");
boolean useClientSpec = depotType.equals("file");
newInstance.setUseStreamDepot(useStreamDepot);
if (useStreamDepot) {
newInstance.setP4Stream(req.getParameter("p4Stream"));
}
else {
newInstance.setUseClientSpec(useClientSpec);
if (useClientSpec) {
newInstance.setClientSpec(req.getParameter("clientSpec"));
}
else {
newInstance.setProjectPath(req.getParameter("projectPath"));
}
}
newInstance.setUseViewMask(req.getParameter("p4.useViewMask") != null);
newInstance.setViewMask(Util.fixEmptyAndTrim(req.getParameter("p4.viewMask")));
newInstance.setUseViewMaskForPolling(req.getParameter("p4.useViewMaskForPolling") != null);
newInstance.setUseViewMaskForSyncing(req.getParameter("p4.useViewMaskForSyncing") != null);

String cleanType = req.getParameter("p4.cleanType");
boolean useWipe = false;
boolean useQuickClean = false;
if(cleanType != null && req.getParameter("p4.cleanWorkspace") != null){
useWipe = cleanType.equals("wipe");
useQuickClean = cleanType.equals("quick");
}
newInstance.setWipeBeforeBuild(useWipe);
newInstance.setQuickCleanBeforeBuild(useQuickClean);

String wipeRepo = req.getParameter("p4.wipeRepoBeforeBuild");
newInstance.setWipeRepoBeforeBuild(wipeRepo != null);

newInstance.setRestoreChangedDeletedFiles(req.getParameter("p4.restoreChangedDeletedFiles") != null);

return newInstance;
return (PerforceSCM)super.newInstance(req, formData);
}

/**Generates a random key for p4.config.instanceID*/
private static final AtomicLong P4_INSTANCE_COUNTER = new AtomicLong();
public String generateP4InstanceID() {
// There's no problem even if the counter reaches overflow
return Long.toString(P4_INSTANCE_COUNTER.incrementAndGet());
}

/**
Expand Down
55 changes: 55 additions & 0 deletions src/main/java/hudson/plugins/perforce/config/CleanTypeConfig.java
@@ -0,0 +1,55 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.perforce.config;

import hudson.plugins.perforce.PerforceSCM;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* Contains workspace cleanup options for {@link PerforceSCM}.
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since TODO: define a version
*/
public class CleanTypeConfig {
String value;
boolean restoreChangedDeletedFiles;

@DataBoundConstructor
public CleanTypeConfig(String value, Boolean restoreChangedDeletedFiles) {
this.value = value;
this.restoreChangedDeletedFiles = restoreChangedDeletedFiles != null ? restoreChangedDeletedFiles.booleanValue() : false;
}

public boolean isQuick() {
return value.equals("quick");
}

public boolean isWipe() {
return value.equals("wipe");
}

public boolean isRestoreChangedDeletedFiles() {
return restoreChangedDeletedFiles;
}
}
76 changes: 76 additions & 0 deletions src/main/java/hudson/plugins/perforce/config/DepotType.java
@@ -0,0 +1,76 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.perforce.config;

import org.kohsuke.stapler.DataBoundConstructor;

/**
* Provides databound-transfer of depot type parameters for ${@link PerforceSCM}.
* Class is developed in order to resolve <a href="https://issues.jenkins-ci.org/browse/JENKINS-18583">JENKINS-18583 issue</a>
* @see PerforceSCMceSCM
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since TODO: define a version
*/
public class DepotType {
public static final String USE_P4STREAM_MARKER="stream";
public static final String USE_CLIENTSPEC_MARKER="file";
public static final String USE_PROJECTPATH_MARKER="map";

String value;
String p4Stream;
String clientSpec;
String projectPath;

@DataBoundConstructor
public DepotType(String value, String p4Stream, String clientSpec, String projectPath) {
this.value = (value != null) ? value : "";
this.p4Stream = p4Stream;
this.clientSpec = clientSpec;
this.projectPath = projectPath;
}

public String getProjectPath() {
return projectPath;
}

public boolean useProjectPath() {
return value.equals(USE_PROJECTPATH_MARKER);
}

public String getClientSpec() {
return clientSpec;
}

public boolean useClientSpec() {
return value.equals(USE_CLIENTSPEC_MARKER);
}

public String getP4Stream() {
return p4Stream;
}

public boolean useP4Stream() {
return value.equals(USE_P4STREAM_MARKER);
}
}
56 changes: 56 additions & 0 deletions src/main/java/hudson/plugins/perforce/config/MaskViewConfig.java
@@ -0,0 +1,56 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.perforce.config;

import org.kohsuke.stapler.DataBoundConstructor;

/**
* Defines masking options for {@link PerforceSCM}.
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since TODO: define a version
*/
public class MaskViewConfig {
String viewMask;
boolean useViewMaskForPolling;
boolean useViewMaskForSyncing;

@DataBoundConstructor
public MaskViewConfig(String viewMask, boolean useViewMaskForPolling, boolean useViewMaskForSyncing) {
this.viewMask = viewMask;
this.useViewMaskForPolling = useViewMaskForPolling;
this.useViewMaskForSyncing = useViewMaskForSyncing;
}

public String getViewMask() {
return viewMask;
}

public boolean isUseViewMaskForPolling() {
return useViewMaskForPolling;
}

public boolean isUseViewMaskForSyncing() {
return useViewMaskForSyncing;
}
}
@@ -0,0 +1,51 @@
/*
* The MIT License
*
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package hudson.plugins.perforce.config;

import hudson.plugins.perforce.PerforceSCM;
import org.kohsuke.stapler.DataBoundConstructor;

/**
* Defines workspace cleanup options for {@link PerforceSCM}.
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
* @since TODO: define a version
*/
public class WorkspaceCleanupConfig {
CleanTypeConfig cleanType;
boolean wipeRepoBeforeBuild;

@DataBoundConstructor
public WorkspaceCleanupConfig(CleanTypeConfig cleanType, boolean wipeRepoBeforeBuild) {
this.cleanType = cleanType;
this.wipeRepoBeforeBuild = wipeRepoBeforeBuild;
}

public CleanTypeConfig getCleanType() {
return cleanType;
}

public boolean isWipeRepoBeforeBuild() {
return wipeRepoBeforeBuild;
}
}

0 comments on commit 0235070

Please sign in to comment.