summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakozak2011-11-23 10:01:09 (EST)
committer Winston Prakash2011-12-01 20:47:12 (EST)
commit4e01a2ecd322a88d81aefffb8faafc6f367addab (patch)
tree70c54721207f3c0f4cf9ba7b12fc274fe73c1161
parentbdf469bfe5cf37551fe567c4af2dbb3916b967c5 (diff)
downloadorg.eclipse.hudson.core-4e01a2ecd322a88d81aefffb8faafc6f367addab.zip
org.eclipse.hudson.core-4e01a2ecd322a88d81aefffb8faafc6f367addab.tar.gz
org.eclipse.hudson.core-4e01a2ecd322a88d81aefffb8faafc6f367addab.tar.bz2
Introduce isModified field in order to trigger Property changes from UI. Implement workaround for equals methods absence
Signed-off-by: Winston Prakash <winston.prakash@gmail.com>
-rw-r--r--hudson-core/src/main/java/hudson/matrix/MatrixProject.java54
-rw-r--r--hudson-core/src/main/java/hudson/model/AbstractProject.java102
-rw-r--r--hudson-core/src/main/java/hudson/model/BaseBuildableProject.java2
-rw-r--r--hudson-core/src/main/java/hudson/model/FreeStyleProject.java10
-rw-r--r--hudson-core/src/main/java/hudson/model/Job.java42
-rw-r--r--hudson-core/src/main/java/org/eclipse/hudson/api/model/IProjectProperty.java18
-rw-r--r--hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/BaseProjectProperty.java25
-rw-r--r--hudson-core/src/test/java/hudson/model/FreeStyleProjectTest.java5
-rw-r--r--hudson-core/src/test/java/hudson/model/LegacyProjectTest.java21
-rw-r--r--hudson-core/src/test/java/org/eclipse/hudson/api/model/project/property/ProjectPropertyTest.java1
-rw-r--r--hudson-war/src/main/webapp/scripts/cascading.js39
11 files changed, 260 insertions, 59 deletions
diff --git a/hudson-core/src/main/java/hudson/matrix/MatrixProject.java b/hudson-core/src/main/java/hudson/matrix/MatrixProject.java
index 2c32527..47b66cb 100644
--- a/hudson-core/src/main/java/hudson/matrix/MatrixProject.java
+++ b/hudson-core/src/main/java/hudson/matrix/MatrixProject.java
@@ -50,7 +50,12 @@ import hudson.util.FormValidation;
import hudson.util.FormValidation.Kind;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
+import org.apache.commons.lang3.StringUtils;
import org.eclipse.hudson.api.matrix.IMatrixProject;
+import org.eclipse.hudson.api.model.project.property.AxisListProjectProperty;
+import org.eclipse.hudson.api.model.project.property.BooleanProjectProperty;
+import org.eclipse.hudson.api.model.project.property.ResultProjectProperty;
+import org.eclipse.hudson.api.model.project.property.StringProjectProperty;
import org.kohsuke.stapler.HttpResponse;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
@@ -171,7 +176,11 @@ public class MatrixProject extends BaseBuildableProject<MatrixProject, MatrixBui
* @inheritDoc
*/
public void setAxes(AxisList axes) throws IOException {
- getAxesListProjectProperty(AXES_PROPERTY_NAME).setValue(axes);
+ setAxes(axes, true);
+ }
+
+ protected void setAxes(AxisList axes, boolean forceModify) throws IOException {
+ setProjectPropertyValue(AXES_PROPERTY_NAME, AxisListProjectProperty.class, axes, forceModify);
rebuildConfigurations();
save();
}
@@ -187,7 +196,7 @@ public class MatrixProject extends BaseBuildableProject<MatrixProject, MatrixBui
* @inheritDoc
*/
public void setRunSequentially(boolean runSequentially) throws IOException {
- getBooleanProperty(RUN_SEQUENTIALLY_PROPERTY_NAME).setValue(runSequentially);
+ setProjectPropertyValue(RUN_SEQUENTIALLY_PROPERTY_NAME, BooleanProjectProperty.class, runSequentially, true);
save();
}
@@ -202,7 +211,12 @@ public class MatrixProject extends BaseBuildableProject<MatrixProject, MatrixBui
* @inheritDoc
*/
public void setCombinationFilter(String combinationFilter) throws IOException {
- getStringProperty(COMBINATION_FILTER_PROPERTY_NAME).setValue(combinationFilter);
+ setCombinationFilter(combinationFilter, true);
+ }
+
+ protected void setCombinationFilter(String combinationFilter, boolean forceModify) throws IOException {
+ setProjectPropertyValue(COMBINATION_FILTER_PROPERTY_NAME, StringProjectProperty.class, combinationFilter,
+ forceModify);
rebuildConfigurations();
save();
}
@@ -218,7 +232,12 @@ public class MatrixProject extends BaseBuildableProject<MatrixProject, MatrixBui
* @inheritDoc
*/
public void setTouchStoneCombinationFilter(String touchStoneCombinationFilter) {
- getStringProperty(TOUCH_STONE_COMBINATION_FILTER_PROPERTY_NAME).setValue(touchStoneCombinationFilter);
+ setTouchStoneCombinationFilter(touchStoneCombinationFilter, true);
+ }
+
+ protected void setTouchStoneCombinationFilter(String touchStoneCombinationFilter, boolean forceModify) {
+ setProjectPropertyValue(TOUCH_STONE_COMBINATION_FILTER_PROPERTY_NAME, StringProjectProperty.class,
+ touchStoneCombinationFilter, forceModify);
}
/**
@@ -232,7 +251,12 @@ public class MatrixProject extends BaseBuildableProject<MatrixProject, MatrixBui
* @inheritDoc
*/
public void setTouchStoneResultCondition(Result touchStoneResultCondition) {
- getResultProperty(TOUCH_STONE_RESULT_CONDITION_PROPERTY_NAME).setValue(touchStoneResultCondition);
+ setTouchStoneResultCondition(touchStoneResultCondition, true);
+ }
+
+ protected void setTouchStoneResultCondition(Result touchStoneResultCondition, boolean forceModify) {
+ setProjectPropertyValue(TOUCH_STONE_RESULT_CONDITION_PROPERTY_NAME, ResultProjectProperty.class,
+ touchStoneResultCondition, forceModify);
}
/**
@@ -246,7 +270,12 @@ public class MatrixProject extends BaseBuildableProject<MatrixProject, MatrixBui
* @inheritDoc
*/
public void setCustomWorkspace(String customWorkspace) throws IOException {
- getStringProperty(CUSTOM_WORKSPACE_PROPERTY_NAME).setValue(customWorkspace);
+ setCustomWorkspace(customWorkspace, true);
+ }
+
+ protected void setCustomWorkspace(String customWorkspace, boolean forceModify) throws IOException {
+ setProjectPropertyValue(CUSTOM_WORKSPACE_PROPERTY_NAME, StringProjectProperty.class, customWorkspace,
+ forceModify);
}
@Override
@@ -572,20 +601,23 @@ public class MatrixProject extends BaseBuildableProject<MatrixProject, MatrixBui
COMBINATION_FILTER_PROPERTY_NAME)) : null);
if (req.getParameter(HAS_TOUCH_STONE_COMBINATION_FILTER_PARAM)!=null) {
- setTouchStoneCombinationFilter(Util.nullify(req.getParameter(TOUCH_STONE_COMBINATION_FILTER_PARAM)));
- setTouchStoneResultCondition(Result.fromString(req.getParameter(TOUCH_STONE_RESULT_CONDITION_PARAM)));
+ setTouchStoneCombinationFilter(
+ StringUtils.trimToNull(req.getParameter(TOUCH_STONE_COMBINATION_FILTER_PARAM)), false);
+ setTouchStoneResultCondition(
+ Result.fromString(req.getParameter(TOUCH_STONE_RESULT_CONDITION_PARAM)), false);
} else {
- setTouchStoneCombinationFilter(null);
+ setTouchStoneCombinationFilter(null, false);
}
setCustomWorkspace(
- req.hasParameter(CUSTOM_WORKSPACE_PARAM) ? req.getParameter(CUSTOM_WORKSPACE_DIRECTORY_PARAM) : null);
+ req.hasParameter(CUSTOM_WORKSPACE_PARAM) ? req.getParameter(CUSTOM_WORKSPACE_DIRECTORY_PARAM) : null,
+ false);
// parse system axes
DescribableList<Axis, AxisDescriptor> newAxes = DescribableListUtil.buildFromHetero(this, req, json, "axis",
Axis.all());
checkAxisNames(newAxes);
- setAxes(new AxisList(newAxes.toList()));
+ setAxes(new AxisList(newAxes.toList()), false);
setRunSequentially(json.has(RUN_SEQUENTIALLY_PROPERTY_NAME));
diff --git a/hudson-core/src/main/java/hudson/model/AbstractProject.java b/hudson-core/src/main/java/hudson/model/AbstractProject.java
index 0cc428c..8401848 100644
--- a/hudson-core/src/main/java/hudson/model/AbstractProject.java
+++ b/hudson-core/src/main/java/hudson/model/AbstractProject.java
@@ -39,6 +39,7 @@ import hudson.model.RunMap.Constructor;
import hudson.model.labels.LabelAtom;
import hudson.model.labels.LabelExpression;
import org.eclipse.hudson.api.model.IProjectProperty;
+import org.eclipse.hudson.api.model.project.property.BooleanProjectProperty;
import org.eclipse.hudson.api.model.project.property.IntegerProjectProperty;
import hudson.model.queue.CauseOfBlockage;
import hudson.model.queue.SubTask;
@@ -95,6 +96,7 @@ import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.eclipse.hudson.api.model.IAbstractProject;
import org.eclipse.hudson.api.model.project.property.SCMProjectProperty;
+import org.eclipse.hudson.api.model.project.property.StringProjectProperty;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.stapler.ForwardToView;
@@ -344,56 +346,57 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
void convertBlockBuildWhenUpstreamBuildingProperty() throws IOException {
- if (null == getProperty(BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME)) {
+ if (blockBuildWhenUpstreamBuilding && null == getProperty(BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME)) {
setBlockBuildWhenUpstreamBuilding(blockBuildWhenUpstreamBuilding);
blockBuildWhenUpstreamBuilding = false;
}
}
void convertBlockBuildWhenDownstreamBuildingProperty() throws IOException {
- if (null == getProperty(BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME)) {
+ if (blockBuildWhenDownstreamBuilding
+ && null == getProperty(BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME)) {
setBlockBuildWhenDownstreamBuilding(blockBuildWhenDownstreamBuilding);
blockBuildWhenDownstreamBuilding = false;
}
}
void convertConcurrentBuildProperty() throws IOException {
- if (null == getProperty(CONCURRENT_BUILD_PROPERTY_NAME)) {
+ if (concurrentBuild && null == getProperty(CONCURRENT_BUILD_PROPERTY_NAME)) {
setConcurrentBuild(concurrentBuild);
concurrentBuild = false;
}
}
void convertCleanWorkspaceRequiredProperty() throws IOException {
- if (null == getProperty(CLEAN_WORKSPACE_REQUIRED_PROPERTY_NAME)) {
+ if (cleanWorkspaceRequired && null == getProperty(CLEAN_WORKSPACE_REQUIRED_PROPERTY_NAME)) {
setCleanWorkspaceRequired(cleanWorkspaceRequired);
cleanWorkspaceRequired = false;
}
}
void convertQuietPeriodProperty() throws IOException {
- if (null == getProperty(QUIET_PERIOD_PROPERTY_NAME)) {
+ if (null != quietPeriod && null == getProperty(QUIET_PERIOD_PROPERTY_NAME)) {
setQuietPeriod(quietPeriod);
quietPeriod = null;
}
}
void convertScmCheckoutRetryCountProperty() throws IOException {
- if (null == getProperty(SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME)) {
+ if (null != scmCheckoutRetryCount && null == getProperty(SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME)) {
setScmCheckoutRetryCount(scmCheckoutRetryCount);
scmCheckoutRetryCount = null;
}
}
void convertJDKProperty() throws IOException {
- if (null == getProperty(JDK_PROPERTY_NAME)) {
+ if (null != jdk && null == getProperty(JDK_PROPERTY_NAME)) {
setJDK(jdk);
jdk = null;
}
}
void convertScmProperty() throws IOException {
- if (null == getProperty(SCM_PROPERTY_NAME)) {
+ if (null != scm && null == getProperty(SCM_PROPERTY_NAME)) {
setScm(scm);
scm = null;
}
@@ -422,7 +425,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
return Hudson.CONCURRENT_BUILD && getBooleanProperty(CONCURRENT_BUILD_PROPERTY_NAME).getValue();
}
public void setConcurrentBuild(boolean b) throws IOException {
- getBooleanProperty(CONCURRENT_BUILD_PROPERTY_NAME).setValue(b);
+ setConcurrentBuild(b, true);
+ }
+
+ public void setConcurrentBuild(boolean b, boolean forceModify) throws IOException {
+ setProjectPropertyValue(CONCURRENT_BUILD_PROPERTY_NAME, BooleanProjectProperty.class, b, forceModify);
save();
}
@@ -431,7 +438,12 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
public void setCleanWorkspaceRequired(boolean cleanWorkspaceRequired) {
- getBooleanProperty(CLEAN_WORKSPACE_REQUIRED_PROPERTY_NAME).setValue(cleanWorkspaceRequired);
+ setCleanWorkspaceRequired(cleanWorkspaceRequired, true);
+ }
+
+ public void setCleanWorkspaceRequired(boolean cleanWorkspaceRequired, boolean forceModify) {
+ setProjectPropertyValue(CLEAN_WORKSPACE_REQUIRED_PROPERTY_NAME, BooleanProjectProperty.class,
+ cleanWorkspaceRequired, forceModify);
}
/**
* If this project is configured to be always built on this node,
@@ -643,7 +655,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @throws IOException if any.
*/
public void setQuietPeriod(Integer seconds) throws IOException {
- getIntegerProperty(QUIET_PERIOD_PROPERTY_NAME).setValue(seconds);
+ setQuietPeriod(seconds, true);
+ }
+
+ protected void setQuietPeriod(Integer seconds, boolean forceModify) throws IOException {
+ setProjectPropertyValue(QUIET_PERIOD_PROPERTY_NAME, IntegerProjectProperty.class, seconds, forceModify);
save();
}
@@ -654,8 +670,14 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
public void setScmCheckoutRetryCount(Integer retryCount) {
- getIntegerProperty(SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME).setValue(retryCount);
+ setScmCheckoutRetryCount(retryCount, true);
}
+
+ public void setScmCheckoutRetryCount(Integer retryCount, boolean forceModify) {
+ setProjectPropertyValue(SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME, IntegerProjectProperty.class, retryCount,
+ forceModify);
+ }
+
/**
* Sets scmCheckoutRetryCount, Uses {@link NumberUtils#isNumber(String)} for checking retryCount param.
* If it is not valid number, null will be set.
@@ -664,11 +686,15 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @throws IOException if any.
*/
protected void setScmCheckoutRetryCount(String scmCheckoutRetryCount) throws IOException {
+ setScmCheckoutRetryCount(scmCheckoutRetryCount, true);
+ }
+
+ protected void setScmCheckoutRetryCount(String scmCheckoutRetryCount, boolean forceModify) throws IOException {
Integer retryCount = null;
if (NumberUtils.isNumber(scmCheckoutRetryCount)) {
retryCount = NumberUtils.createInteger(scmCheckoutRetryCount);
}
- setScmCheckoutRetryCount(retryCount);
+ setScmCheckoutRetryCount(retryCount, forceModify);
}
/**
@@ -689,13 +715,16 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
* @throws IOException if any.
*/
protected void setQuietPeriod(String seconds) throws IOException {
+ setQuietPeriod(seconds, true);
+ }
+
+ protected void setQuietPeriod(String seconds, boolean forceModify) throws IOException {
Integer period = null;
if (NumberUtils.isNumber(seconds)) {
period = NumberUtils.createInteger(seconds);
}
- setQuietPeriod(period);
+ setQuietPeriod(period, forceModify);
}
-
/**
* Checks whether scmRetryCount is configured
*
@@ -724,7 +753,12 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
public void setBlockBuildWhenDownstreamBuilding(boolean b) throws IOException {
- getBooleanProperty(BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME).setValue(b);
+ setBlockBuildWhenDownstreamBuilding(b, true);
+ }
+
+ public void setBlockBuildWhenDownstreamBuilding(boolean b, boolean forceModify) throws IOException {
+ setProjectPropertyValue(BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME,
+ BooleanProjectProperty.class, b, forceModify);
save();
}
@@ -733,7 +767,12 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
public void setBlockBuildWhenUpstreamBuilding(boolean b) throws IOException {
- getBooleanProperty(BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME).setValue(b);
+ setBlockBuildWhenUpstreamBuilding(b, true);
+ }
+
+ public void setBlockBuildWhenUpstreamBuilding(boolean b, boolean forceModify) throws IOException {
+ setProjectPropertyValue(BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME,
+ BooleanProjectProperty.class, b, forceModify);
save();
}
@@ -1078,7 +1117,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
public void setJDK(String jdk) {
- getStringProperty(JDK_PROPERTY_NAME).setValue(jdk);
+ setJDK(jdk, true);
+ }
+
+ public void setJDK(String jdk, boolean forceModify) {
+ setProjectPropertyValue(JDK_PROPERTY_NAME, StringProjectProperty.class, jdk, forceModify);
}
public BuildAuthorizationToken getAuthToken() {
@@ -1570,7 +1613,11 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
@SuppressWarnings("unchecked")
public void setScm(SCM scm) throws IOException {
- getProperty(SCM_PROPERTY_NAME, SCMProjectProperty.class).setValue(scm);
+ setScm(scm, true);
+ }
+
+ public void setScm(SCM scm, boolean forceModify) throws IOException {
+ setProjectPropertyValue(SCM_PROPERTY_NAME, SCMProjectProperty.class, scm, forceModify);
//save();
}
@@ -1854,12 +1901,13 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
makeDisabled(null != req.getParameter("disable"));
setCascadingProjectName(StringUtils.trimToNull(req.getParameter("cascadingProjectName")));
- setJDK(req.getParameter("jdk"));
- setQuietPeriod(null != req.getParameter("hasCustomQuietPeriod") ? req.getParameter("quiet_period") : null);
+ setJDK(req.getParameter("jdk"), false);
+ setQuietPeriod(null != req.getParameter("hasCustomQuietPeriod") ? req.getParameter("quiet_period") : null,
+ false);
setScmCheckoutRetryCount(null != req.getParameter("hasCustomScmCheckoutRetryCount")
- ? req.getParameter("scmCheckoutRetryCount") : null);
- setBlockBuildWhenDownstreamBuilding(null != req.getParameter("blockBuildWhenDownstreamBuilding"));
- setBlockBuildWhenUpstreamBuilding(null != req.getParameter("blockBuildWhenUpstreamBuilding"));
+ ? req.getParameter("scmCheckoutRetryCount") : null, false);
+ setBlockBuildWhenDownstreamBuilding(null != req.getParameter("blockBuildWhenDownstreamBuilding"), false);
+ setBlockBuildWhenUpstreamBuilding(null != req.getParameter("blockBuildWhenUpstreamBuilding"), false);
if (req.getParameter("hasSlaveAffinity") != null) {
// New logic for handling whether this choice came from the dropdown or textfield.
@@ -1876,15 +1924,15 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
}
- setCleanWorkspaceRequired(null != req.getParameter("cleanWorkspaceRequired"));
+ setCleanWorkspaceRequired(null != req.getParameter("cleanWorkspaceRequired"), false);
canRoam = assignedNode==null;
- setConcurrentBuild(req.getSubmittedForm().has("concurrentBuild"));
+ setConcurrentBuild(req.getSubmittedForm().has("concurrentBuild"), false);
authToken = BuildAuthorizationToken.create(req);
- setScm(SCMS.parseSCM(req,this));
+ setScm(SCMS.parseSCM(req,this), false);
for (Trigger t : triggers)
t.stop();
diff --git a/hudson-core/src/main/java/hudson/model/BaseBuildableProject.java b/hudson-core/src/main/java/hudson/model/BaseBuildableProject.java
index 4d3ec47..109dcd3 100644
--- a/hudson-core/src/main/java/hudson/model/BaseBuildableProject.java
+++ b/hudson-core/src/main/java/hudson/model/BaseBuildableProject.java
@@ -214,7 +214,7 @@ public abstract class BaseBuildableProject<P extends BaseBuildableProject<P,B>,B
* @param req {@link StaplerRequest}
* @param json {@link JSONObject}
* @param descriptors list of descriptors.
- * @throws hudson.model.Descriptor.FormException
+ * @throws hudson.model.Descriptor.FormException if any.
*/
@SuppressWarnings("unchecked")
protected void buildPublishers( StaplerRequest req, JSONObject json, List<Descriptor<Publisher>> descriptors) throws FormException{
diff --git a/hudson-core/src/main/java/hudson/model/FreeStyleProject.java b/hudson-core/src/main/java/hudson/model/FreeStyleProject.java
index 569b621..ee6084f 100644
--- a/hudson-core/src/main/java/hudson/model/FreeStyleProject.java
+++ b/hudson-core/src/main/java/hudson/model/FreeStyleProject.java
@@ -23,6 +23,7 @@ import java.io.IOException;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.hudson.api.model.IFreeStyleProject;
+import org.eclipse.hudson.api.model.project.property.StringProjectProperty;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
@@ -87,7 +88,12 @@ public class FreeStyleProject extends Project<FreeStyleProject,FreeStyleBuild> i
* @throws IOException if any.
*/
public void setCustomWorkspace(String customWorkspace) throws IOException {
- getStringProperty(CUSTOM_WORKSPACE_PROPERTY_NAME).setValue(customWorkspace);
+ setCustomWorkspace(customWorkspace, true);
+ }
+
+ protected void setCustomWorkspace(String customWorkspace, boolean forceModify) throws IOException {
+ setProjectPropertyValue(CUSTOM_WORKSPACE_PROPERTY_NAME, StringProjectProperty.class, customWorkspace,
+ forceModify);
save();
}
@@ -96,7 +102,7 @@ public class FreeStyleProject extends Project<FreeStyleProject,FreeStyleBuild> i
throws IOException, ServletException, Descriptor.FormException {
super.submit(req, rsp);
setCustomWorkspace(
- req.hasParameter("customWorkspace") ? req.getParameter("customWorkspace.directory") : null);
+ req.hasParameter("customWorkspace") ? req.getParameter("customWorkspace.directory") : null, false);
}
@Override
diff --git a/hudson-core/src/main/java/hudson/model/Job.java b/hudson-core/src/main/java/hudson/model/Job.java
index f1fec03..b51d30d 100644
--- a/hudson-core/src/main/java/hudson/model/Job.java
+++ b/hudson-core/src/main/java/hudson/model/Job.java
@@ -382,7 +382,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
}
void convertLogRotatorProperty() {
- if (null == getProperty(LOG_ROTATOR_PROPERTY_NAME)) {
+ if (null != logRotator && null == getProperty(LOG_ROTATOR_PROPERTY_NAME)) {
setLogRotator(logRotator);
logRotator = null;
}
@@ -551,11 +551,36 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
*
* @param logRotator log rotator.
*/
- @SuppressWarnings("unchecked")
public void setLogRotator(LogRotator logRotator) {
- getProperty(LOG_ROTATOR_PROPERTY_NAME, LogRotatorProjectProperty.class).setValue(logRotator);
+ setLogRotator(logRotator, true);
+ }
+
+ public void setLogRotator(LogRotator logRotator, boolean forceModify) {
+ setProjectPropertyValue(LOG_ROTATOR_PROPERTY_NAME, LogRotatorProjectProperty.class, logRotator, forceModify);
+ }
+
+ /**
+ * Update project property with new value. ForceModify flag is taken into account.
+ * If property is null - it will be initialized and added to current job.
+ *
+ * @param key property key.
+ * @param clazz property class.
+ * @param value new value.
+ * @param forceModify true - to set property value even if it was not modified from UI. Basically this parameter is
+ * used for cascading functionality.
+ */
+ @SuppressWarnings("unchecked")
+ protected void setProjectPropertyValue(String key, Class clazz, Object value, boolean forceModify) {
+ IProjectProperty property = getProperty(key, clazz);
+ if (null != property) {
+ if (forceModify) {
+ property.setModified(forceModify);
+ }
+ property.setValue(value);
+ }
}
+
/**
* Perform log rotation.
*/
@@ -1417,6 +1442,15 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
setCascadingProjectName(projectName);
}
+ public synchronized void doModifyCascadingProperty(@QueryParameter(fixEmpty = true) String propertyName) {
+ if (null != propertyName) {
+ IProjectProperty property = getProperty(propertyName);
+ if (null != property) {
+ property.setModified(true);
+ }
+ }
+ }
+
/**
* Sets cascadingProject name.
*
@@ -1431,7 +1465,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
this.cascadingProject = (JobT) Functions.getItemByName(Hudson.getInstance().getAllItems(this.getClass()),
cascadingProjectName);
for (IProjectProperty property : jobProperties.values()) {
- property.setOverridden(property.getValue() != property.getCascadingValue());
+ property.setOverridden(property.isModified());
}
}
}
diff --git a/hudson-core/src/main/java/org/eclipse/hudson/api/model/IProjectProperty.java b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IProjectProperty.java
index a4f11b8..64bda37 100644
--- a/hudson-core/src/main/java/org/eclipse/hudson/api/model/IProjectProperty.java
+++ b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IProjectProperty.java
@@ -42,6 +42,12 @@ public interface IProjectProperty<T> extends Serializable {
/**
* Sets property value.
+ * If property has cascading value, than modified flag will be checked.
+ * If property was modified and {@link #allowOverrideValue(Object, Object)} method returns true, that value will be
+ * set to current property.<br/>
+ * If property doesn't have cascading value, than value will be set directly.
+ *
+ * NOTE: use should call {@link #setModified(boolean)} method before setting cascading value.
*
* @param value value to set.
*/
@@ -101,4 +107,16 @@ public interface IProjectProperty<T> extends Serializable {
* @param overridden true - mark property as overridden, false - otherwise.
*/
void setOverridden(boolean overridden);
+
+ /**
+ * Method set modified state for current property.
+ *
+ * @param modified true if property was modified by user.
+ */
+ void setModified(boolean modified);
+
+ /**
+ * @return true if property was modified, false - otherwise.
+ */
+ boolean isModified();
}
diff --git a/hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/BaseProjectProperty.java b/hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/BaseProjectProperty.java
index 3c51644..0a506de 100644
--- a/hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/BaseProjectProperty.java
+++ b/hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/BaseProjectProperty.java
@@ -35,6 +35,7 @@ public class BaseProjectProperty<T> implements IProjectProperty<T> {
private transient IJob job;
private T originalValue;
private boolean propertyOverridden;
+ private boolean modified;
/**
* Instantiate new property.
@@ -79,6 +80,20 @@ public class BaseProjectProperty<T> implements IProjectProperty<T> {
/**
* {@inheritDoc}
*/
+ public void setModified(boolean modified) {
+ this.modified = modified;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isModified() {
+ return modified;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
@SuppressWarnings("unchecked")
public T getCascadingValue() {
if (null == propertyKey) {
@@ -126,10 +141,12 @@ public class BaseProjectProperty<T> implements IProjectProperty<T> {
} else {
T cascadingValue = getCascadingValue();
T candidateValue = null == value ? getDefaultValue() : value;
- if (allowOverrideValue(cascadingValue, candidateValue)) {
- setOriginalValue(value, true);
- } else {
- resetValue();
+ if (isModified()) {
+ if (allowOverrideValue(cascadingValue, candidateValue)) {
+ setOriginalValue(value, true);
+ } else {
+ resetValue();
+ }
}
}
}
diff --git a/hudson-core/src/test/java/hudson/model/FreeStyleProjectTest.java b/hudson-core/src/test/java/hudson/model/FreeStyleProjectTest.java
index 14b1688..9cf4538 100644
--- a/hudson-core/src/test/java/hudson/model/FreeStyleProjectTest.java
+++ b/hudson-core/src/test/java/hudson/model/FreeStyleProjectTest.java
@@ -258,6 +258,7 @@ public class FreeStyleProjectTest {
parentProject.setCustomWorkspace(parentCustomWorkspace);
FreeStyleProjectMock childProject = new FreeStyleProjectMock("child");
childProject.setCascadingProject(parentProject);
+ childProject.getStringProperty(FreeStyleProject.CUSTOM_WORKSPACE_PROPERTY_NAME).setModified(true);
childProject.setCustomWorkspace(childCustomWorkspace);
assertEquals(childCustomWorkspace, childProject.getCustomWorkspace());
}
@@ -306,6 +307,7 @@ public class FreeStyleProjectTest {
parentProject.setJDK(parentJdkName);
FreeStyleProjectMock childProject = new FreeStyleProjectMock("child");
childProject.setCascadingProject(parentProject);
+ childProject.getStringProperty(AbstractProject.JDK_PROPERTY_NAME).setModified(true);
childProject.setJDK(childJdkName);
assertEquals(childJdkName, childProject.getJDKName());
}
@@ -379,6 +381,7 @@ public class FreeStyleProjectTest {
parentProject.setQuietPeriod(parentQuietPeriod);
FreeStyleProjectMock childProject = new FreeStyleProjectMock("child");
childProject.setCascadingProject(parentProject);
+ childProject.getIntegerProperty(AbstractProject.QUIET_PERIOD_PROPERTY_NAME).setModified(true);
childProject.setQuietPeriod(childQuietPeriod);
Hudson hudson = createMock(Hudson.class);
@@ -452,6 +455,7 @@ public class FreeStyleProjectTest {
replayAll();
assertEquals(childProject.getScmCheckoutRetryCount(), globalScmCheckoutRetryCount);
childProject.setCascadingProject(parentProject);
+ childProject.getIntegerProperty(AbstractProject.SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME).setModified(true);
childProject.setScmCheckoutRetryCount(scmCheckoutRetryCount);
assertEquals(childProject.getScmCheckoutRetryCount(), Integer.parseInt(scmCheckoutRetryCount));
verifyAll();
@@ -465,6 +469,7 @@ public class FreeStyleProjectTest {
parentProject.setScmCheckoutRetryCount(parentScmCheckoutRetryCount);
FreeStyleProjectMock childProject = new FreeStyleProjectMock("child");
childProject.setCascadingProject(parentProject);
+ childProject.getIntegerProperty(AbstractProject.SCM_CHECKOUT_RETRY_COUNT_PROPERTY_NAME).setModified(true);
childProject.setScmCheckoutRetryCount(childScmCheckoutRetryCount);
Hudson hudson = createMock(Hudson.class);
diff --git a/hudson-core/src/test/java/hudson/model/LegacyProjectTest.java b/hudson-core/src/test/java/hudson/model/LegacyProjectTest.java
index 539c50f..d22732e 100644
--- a/hudson-core/src/test/java/hudson/model/LegacyProjectTest.java
+++ b/hudson-core/src/test/java/hudson/model/LegacyProjectTest.java
@@ -19,6 +19,8 @@ import hudson.tasks.Maven;
import hudson.tasks.junit.JUnitResultArchiver;
import java.io.File;
import java.net.URISyntaxException;
+import org.eclipse.hudson.api.model.IProjectProperty;
+import org.eclipse.hudson.api.model.project.property.BooleanProjectProperty;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
@@ -62,7 +64,9 @@ public class LegacyProjectTest {
project.initProjectProperties();
assertNull(project.getProperty(FreeStyleProject.CUSTOM_WORKSPACE_PROPERTY_NAME));
project.convertCustomWorkspaceProperty();
- assertNotNull(project.getProperty(FreeStyleProject.CUSTOM_WORKSPACE_PROPERTY_NAME));
+ IProjectProperty property = project.getProperty(FreeStyleProject.CUSTOM_WORKSPACE_PROPERTY_NAME);
+ assertNotNull(property);
+ assertEquals("/tmp", property.getValue());
}
/**
@@ -149,7 +153,10 @@ public class LegacyProjectTest {
project.initProjectProperties();
assertNull(project.getProperty(AbstractProject.BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME));
project.convertBlockBuildWhenDownstreamBuildingProperty();
- assertNotNull(project.getProperty(AbstractProject.BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME));
+ BooleanProjectProperty property = (BooleanProjectProperty)project.getProperty(
+ AbstractProject.BLOCK_BUILD_WHEN_DOWNSTREAM_BUILDING_PROPERTY_NAME);
+ assertNotNull(property);
+ assertTrue(property.getValue());
}
/**
@@ -165,7 +172,10 @@ public class LegacyProjectTest {
project.initProjectProperties();
assertNull(project.getProperty(AbstractProject.BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME));
project.convertBlockBuildWhenUpstreamBuildingProperty();
- assertNotNull(project.getProperty(AbstractProject.BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME));
+ BooleanProjectProperty property = (BooleanProjectProperty)project.getProperty(
+ AbstractProject.BLOCK_BUILD_WHEN_UPSTREAM_BUILDING_PROPERTY_NAME);
+ assertNotNull(property);
+ assertTrue(property.getValue());
}
/**
@@ -181,7 +191,10 @@ public class LegacyProjectTest {
project.initProjectProperties();
assertNull(project.getProperty(AbstractProject.CONCURRENT_BUILD_PROPERTY_NAME));
project.convertConcurrentBuildProperty();
- assertNotNull(project.getProperty(AbstractProject.CONCURRENT_BUILD_PROPERTY_NAME));
+ BooleanProjectProperty property = (BooleanProjectProperty)project.getProperty(
+ AbstractProject.CONCURRENT_BUILD_PROPERTY_NAME);
+ assertNotNull(property);
+ assertTrue(property.getValue());
}
/**
diff --git a/hudson-core/src/test/java/org/eclipse/hudson/api/model/project/property/ProjectPropertyTest.java b/hudson-core/src/test/java/org/eclipse/hudson/api/model/project/property/ProjectPropertyTest.java
index 38f2d9c..f544a6d 100644
--- a/hudson-core/src/test/java/org/eclipse/hudson/api/model/project/property/ProjectPropertyTest.java
+++ b/hudson-core/src/test/java/org/eclipse/hudson/api/model/project/property/ProjectPropertyTest.java
@@ -486,6 +486,7 @@ public class ProjectPropertyTest {
project.setCascadingProject(parent);
//If value set to null, need to check whether default value is equals to cascading
+ property.setModified(true);
property.setValue(null);
assertTrue(property.isOverridden());
String overriddenValue = "newValue";
diff --git a/hudson-war/src/main/webapp/scripts/cascading.js b/hudson-war/src/main/webapp/scripts/cascading.js
index 00a96e7..43c61d2 100644
--- a/hudson-war/src/main/webapp/scripts/cascading.js
+++ b/hudson-war/src/main/webapp/scripts/cascading.js
@@ -1,7 +1,7 @@
/*******************************************************************************
*
- * Copyright (c) 2004-2010 Oracle Corporation.
+ * Copyright (c) 2011 Oracle Corporation.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -31,10 +31,14 @@ hudsonRules["A.reset-button"] = function(e) {
e = null; // avoid memory leak
}
-jQuery(document).ready(function(){
- jQuery('select[name=cascadingProjectName]').change(function() {
- var url = window.location.href;
- var jobUrl = url.substr(0, url.lastIndexOf('/'))+'/updateCascadingProject';
+function getJobUrl() {
+ var url = window.location.href;
+ return url.substr(0, url.lastIndexOf('/'))
+}
+
+function onCascadingProjectUpdated() {
+ jQuery('select[name=cascadingProjectName]').change(function() {
+ var jobUrl = getJobUrl()+'/updateCascadingProject';
var cascadingProject = jQuery(this).val();
new Ajax.Request(jobUrl+'?projectName='+cascadingProject, {
method : 'get',
@@ -43,4 +47,27 @@ jQuery(document).ready(function(){
}
});
});
-}); \ No newline at end of file
+}
+
+function onProjectPropertyChanged() {
+ jQuery('input').change(function() {
+ var ref = jQuery(this).attr('id');
+ var cascadingProperty = '';
+ if (ref != '') {
+ cascadingProperty = jQuery(this).attr('name');
+ } else {
+ var childRef = jQuery(this).parents('tr').attr('nameref');
+ cascadingProperty = jQuery('#'+childRef).attr('name');
+ }
+ var jobUrl = getJobUrl()+'/modifyCascadingProperty?propertyName='+cascadingProperty;
+ new Ajax.Request(jobUrl, {
+ method : 'get'
+ });
+ });
+}
+
+jQuery(document).ready(function(){
+ onCascadingProjectUpdated();
+ onProjectPropertyChanged();
+});
+