Skip to content

Commit 0235070

Browse files
committed
[JENKINS-18583] - Refactoring of PerforceSCM to remove newInstance()
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>
1 parent 043a336 commit 0235070

File tree

7 files changed

+334
-68
lines changed

7 files changed

+334
-68
lines changed

src/main/java/hudson/plugins/perforce/PerforceSCM.java

Lines changed: 57 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package hudson.plugins.perforce;
22

3+
import hudson.plugins.perforce.config.DepotType;
34
import com.tek42.perforce.Depot;
45
import com.tek42.perforce.PerforceException;
56
import com.tek42.perforce.model.Changelist;
@@ -22,6 +23,9 @@
2223
import hudson.matrix.MatrixRun;
2324
import hudson.model.*;
2425
import hudson.model.listeners.ItemListener;
26+
import hudson.plugins.perforce.config.CleanTypeConfig;
27+
import hudson.plugins.perforce.config.MaskViewConfig;
28+
import hudson.plugins.perforce.config.WorkspaceCleanupConfig;
2529
import hudson.plugins.perforce.utils.MacroStringHelper;
2630
import hudson.plugins.perforce.utils.ParameterSubstitutionException;
2731
import hudson.remoting.VirtualChannel;
@@ -54,6 +58,7 @@
5458
import java.io.StringWriter;
5559
import java.net.InetAddress;
5660
import java.util.*;
61+
import java.util.concurrent.atomic.AtomicLong;
5762
import java.util.logging.Level;
5863
import java.util.logging.Logger;
5964
import java.util.regex.Matcher;
@@ -275,7 +280,13 @@ public class PerforceSCM extends SCM {
275280
private String p4Charset = null;
276281
private String p4CommandCharset = null;
277282

278-
// Plugin constructor, (only?) used when a job configuration is saved
283+
/**
284+
* SCM constructor, (only?) used when a job configuration is saved.
285+
* This constructor uses data classes from {@link hudson.plugins.perforce.config}
286+
* to allow proper handling of hierarchical data in Stapler. In the current
287+
* state, these classes are not being used outside this constructor.
288+
*/
289+
// TODO: move data to configuration classes during the refactoring
279290
@DataBoundConstructor
280291
public PerforceSCM(
281292
String p4User,
@@ -311,7 +322,11 @@ public PerforceSCM(
311322
PerforceRepositoryBrowser browser,
312323
String excludedUsers,
313324
String excludedFiles,
314-
boolean excludedFilesCaseSensitivity) {
325+
boolean excludedFilesCaseSensitivity,
326+
DepotType depotType,
327+
WorkspaceCleanupConfig cleanWorkspace,
328+
MaskViewConfig useViewMask
329+
) {
315330

316331
this.configVersion = 1L;
317332

@@ -338,8 +353,37 @@ public PerforceSCM(
338353

339354
this.p4UpstreamProject = Util.fixEmptyAndTrim(p4UpstreamProject);
340355

341-
this.projectPath = Util.fixEmptyAndTrim(projectPath);
342-
356+
//TODO: move optional entries to external classes
357+
// Get data from the depot type
358+
if (depotType != null) {
359+
this.p4Stream = depotType.getP4Stream();
360+
this.clientSpec = depotType.getClientSpec();
361+
this.projectPath = Util.fixEmptyAndTrim(depotType.getProjectPath());
362+
this.useStreamDepot = depotType.useP4Stream();
363+
this.useClientSpec = depotType.useClientSpec();
364+
this.useViewMask = depotType.useProjectPath();
365+
}
366+
367+
// Get data from workspace cleanup settings
368+
if (cleanWorkspace != null) {
369+
setWipeRepoBeforeBuild(cleanWorkspace.isWipeRepoBeforeBuild());
370+
371+
CleanTypeConfig cleanType = cleanWorkspace.getCleanType();
372+
if (cleanType != null) {
373+
setWipeBeforeBuild(cleanType.isWipe());
374+
setQuickCleanBeforeBuild(cleanType.isQuick());
375+
setRestoreChangedDeletedFiles(cleanType.isRestoreChangedDeletedFiles());
376+
}
377+
}
378+
379+
// Setup view mask
380+
if (useViewMask != null) {
381+
setUseViewMask(true);
382+
setViewMask(hudson.Util.fixEmptyAndTrim(useViewMask.getViewMask()));
383+
setUseViewMaskForPolling(useViewMask.isUseViewMaskForPolling());
384+
setUseViewMaskForSyncing(useViewMask.isUseViewMaskForSyncing());
385+
}
386+
343387
this.clientOwner = Util.fixEmptyAndTrim(clientOwner);
344388

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

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

17781823
@Override
17791824
public SCM newInstance(StaplerRequest req, JSONObject formData) throws FormException {
1780-
PerforceSCM newInstance = (PerforceSCM)super.newInstance(req, formData);
1781-
String depotType = req.getParameter("p4.depotType");
1782-
boolean useStreamDepot = depotType.equals("stream");
1783-
boolean useClientSpec = depotType.equals("file");
1784-
newInstance.setUseStreamDepot(useStreamDepot);
1785-
if (useStreamDepot) {
1786-
newInstance.setP4Stream(req.getParameter("p4Stream"));
1787-
}
1788-
else {
1789-
newInstance.setUseClientSpec(useClientSpec);
1790-
if (useClientSpec) {
1791-
newInstance.setClientSpec(req.getParameter("clientSpec"));
1792-
}
1793-
else {
1794-
newInstance.setProjectPath(req.getParameter("projectPath"));
1795-
}
1796-
}
1797-
newInstance.setUseViewMask(req.getParameter("p4.useViewMask") != null);
1798-
newInstance.setViewMask(Util.fixEmptyAndTrim(req.getParameter("p4.viewMask")));
1799-
newInstance.setUseViewMaskForPolling(req.getParameter("p4.useViewMaskForPolling") != null);
1800-
newInstance.setUseViewMaskForSyncing(req.getParameter("p4.useViewMaskForSyncing") != null);
1801-
1802-
String cleanType = req.getParameter("p4.cleanType");
1803-
boolean useWipe = false;
1804-
boolean useQuickClean = false;
1805-
if(cleanType != null && req.getParameter("p4.cleanWorkspace") != null){
1806-
useWipe = cleanType.equals("wipe");
1807-
useQuickClean = cleanType.equals("quick");
1808-
}
1809-
newInstance.setWipeBeforeBuild(useWipe);
1810-
newInstance.setQuickCleanBeforeBuild(useQuickClean);
1811-
1812-
String wipeRepo = req.getParameter("p4.wipeRepoBeforeBuild");
1813-
newInstance.setWipeRepoBeforeBuild(wipeRepo != null);
1814-
1815-
newInstance.setRestoreChangedDeletedFiles(req.getParameter("p4.restoreChangedDeletedFiles") != null);
1816-
1817-
return newInstance;
1825+
return (PerforceSCM)super.newInstance(req, formData);
1826+
}
1827+
1828+
/**Generates a random key for p4.config.instanceID*/
1829+
private static final AtomicLong P4_INSTANCE_COUNTER = new AtomicLong();
1830+
public String generateP4InstanceID() {
1831+
// There's no problem even if the counter reaches overflow
1832+
return Long.toString(P4_INSTANCE_COUNTER.incrementAndGet());
18181833
}
18191834

18201835
/**
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package hudson.plugins.perforce.config;
25+
26+
import hudson.plugins.perforce.PerforceSCM;
27+
import org.kohsuke.stapler.DataBoundConstructor;
28+
29+
/**
30+
* Contains workspace cleanup options for {@link PerforceSCM}.
31+
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
32+
* @since TODO: define a version
33+
*/
34+
public class CleanTypeConfig {
35+
String value;
36+
boolean restoreChangedDeletedFiles;
37+
38+
@DataBoundConstructor
39+
public CleanTypeConfig(String value, Boolean restoreChangedDeletedFiles) {
40+
this.value = value;
41+
this.restoreChangedDeletedFiles = restoreChangedDeletedFiles != null ? restoreChangedDeletedFiles.booleanValue() : false;
42+
}
43+
44+
public boolean isQuick() {
45+
return value.equals("quick");
46+
}
47+
48+
public boolean isWipe() {
49+
return value.equals("wipe");
50+
}
51+
52+
public boolean isRestoreChangedDeletedFiles() {
53+
return restoreChangedDeletedFiles;
54+
}
55+
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package hudson.plugins.perforce.config;
25+
26+
import org.kohsuke.stapler.DataBoundConstructor;
27+
28+
/**
29+
* Provides databound-transfer of depot type parameters for ${@link PerforceSCM}.
30+
* Class is developed in order to resolve <a href="https://issues.jenkins-ci.org/browse/JENKINS-18583">JENKINS-18583 issue</a>
31+
* @see PerforceSCMceSCM
32+
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
33+
* @since TODO: define a version
34+
*/
35+
public class DepotType {
36+
public static final String USE_P4STREAM_MARKER="stream";
37+
public static final String USE_CLIENTSPEC_MARKER="file";
38+
public static final String USE_PROJECTPATH_MARKER="map";
39+
40+
String value;
41+
String p4Stream;
42+
String clientSpec;
43+
String projectPath;
44+
45+
@DataBoundConstructor
46+
public DepotType(String value, String p4Stream, String clientSpec, String projectPath) {
47+
this.value = (value != null) ? value : "";
48+
this.p4Stream = p4Stream;
49+
this.clientSpec = clientSpec;
50+
this.projectPath = projectPath;
51+
}
52+
53+
public String getProjectPath() {
54+
return projectPath;
55+
}
56+
57+
public boolean useProjectPath() {
58+
return value.equals(USE_PROJECTPATH_MARKER);
59+
}
60+
61+
public String getClientSpec() {
62+
return clientSpec;
63+
}
64+
65+
public boolean useClientSpec() {
66+
return value.equals(USE_CLIENTSPEC_MARKER);
67+
}
68+
69+
public String getP4Stream() {
70+
return p4Stream;
71+
}
72+
73+
public boolean useP4Stream() {
74+
return value.equals(USE_P4STREAM_MARKER);
75+
}
76+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package hudson.plugins.perforce.config;
25+
26+
import org.kohsuke.stapler.DataBoundConstructor;
27+
28+
/**
29+
* Defines masking options for {@link PerforceSCM}.
30+
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
31+
* @since TODO: define a version
32+
*/
33+
public class MaskViewConfig {
34+
String viewMask;
35+
boolean useViewMaskForPolling;
36+
boolean useViewMaskForSyncing;
37+
38+
@DataBoundConstructor
39+
public MaskViewConfig(String viewMask, boolean useViewMaskForPolling, boolean useViewMaskForSyncing) {
40+
this.viewMask = viewMask;
41+
this.useViewMaskForPolling = useViewMaskForPolling;
42+
this.useViewMaskForSyncing = useViewMaskForSyncing;
43+
}
44+
45+
public String getViewMask() {
46+
return viewMask;
47+
}
48+
49+
public boolean isUseViewMaskForPolling() {
50+
return useViewMaskForPolling;
51+
}
52+
53+
public boolean isUseViewMaskForSyncing() {
54+
return useViewMaskForSyncing;
55+
}
56+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright 2013 Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package hudson.plugins.perforce.config;
25+
26+
import hudson.plugins.perforce.PerforceSCM;
27+
import org.kohsuke.stapler.DataBoundConstructor;
28+
29+
/**
30+
* Defines workspace cleanup options for {@link PerforceSCM}.
31+
* @author Oleg Nenashev <nenashev@synopsys.com>, Synopsys Inc.
32+
* @since TODO: define a version
33+
*/
34+
public class WorkspaceCleanupConfig {
35+
CleanTypeConfig cleanType;
36+
boolean wipeRepoBeforeBuild;
37+
38+
@DataBoundConstructor
39+
public WorkspaceCleanupConfig(CleanTypeConfig cleanType, boolean wipeRepoBeforeBuild) {
40+
this.cleanType = cleanType;
41+
this.wipeRepoBeforeBuild = wipeRepoBeforeBuild;
42+
}
43+
44+
public CleanTypeConfig getCleanType() {
45+
return cleanType;
46+
}
47+
48+
public boolean isWipeRepoBeforeBuild() {
49+
return wipeRepoBeforeBuild;
50+
}
51+
}

0 commit comments

Comments
 (0)