aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakozak2011-11-24 09:07:55 (EST)
committerWinston Prakash2011-12-01 20:47:27 (EST)
commitb6ce36bb22265f7918e95c300056dccf4bffc7b3 (patch)
tree0447aea8aeefce34e77165a0616b6a6a1fd5cdcb
parent30607c9f8e8c56b2df6322cd87f7b355f61d439b (diff)
downloadorg.eclipse.hudson.core-b6ce36bb22265f7918e95c300056dccf4bffc7b3.zip
org.eclipse.hudson.core-b6ce36bb22265f7918e95c300056dccf4bffc7b3.tar.gz
org.eclipse.hudson.core-b6ce36bb22265f7918e95c300056dccf4bffc7b3.tar.bz2
Implement cascading functionality for Build Parameters
Signed-off-by: Winston Prakash <winston.prakash@gmail.com>
-rw-r--r--hudson-core/src/main/java/hudson/model/AbstractProject.java4
-rw-r--r--hudson-core/src/main/java/hudson/model/Items.java3
-rw-r--r--hudson-core/src/main/java/hudson/model/Job.java151
-rw-r--r--hudson-core/src/main/java/hudson/model/ParametersDefinitionProperty.java39
-rw-r--r--hudson-core/src/main/java/hudson/util/CascadingUtil.java60
-rw-r--r--hudson-core/src/main/java/org/eclipse/hudson/api/model/IProjectProperty.java5
-rw-r--r--hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/BaseProjectProperty.java11
-rw-r--r--hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/CopyOnWriteListProjectProperty.java55
-rw-r--r--hudson-core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly9
9 files changed, 286 insertions, 51 deletions
diff --git a/hudson-core/src/main/java/hudson/model/AbstractProject.java b/hudson-core/src/main/java/hudson/model/AbstractProject.java
index ed73899..422a0ed 100644
--- a/hudson-core/src/main/java/hudson/model/AbstractProject.java
+++ b/hudson-core/src/main/java/hudson/model/AbstractProject.java
@@ -843,7 +843,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
protected List<Action> createTransientActions() {
Vector<Action> ta = new Vector<Action>();
- for (JobProperty<? super P> p : properties)
+ for (JobProperty<? super P> p : getAllProperties())
ta.addAll(p.getJobActions((P)this));
for (TransientProjectActionFactory tpaf : TransientProjectActionFactory.all())
@@ -1386,7 +1386,7 @@ public abstract class AbstractProject<P extends AbstractProject<P,R>,R extends A
r.add(this);
for (SubTaskContributor euc : SubTaskContributor.all())
r.addAll(euc.forProject(this));
- for (JobProperty<? super P> p : properties)
+ for (JobProperty<? super P> p : getAllProperties())
r.addAll(p.getSubTasks());
return r;
}
diff --git a/hudson-core/src/main/java/hudson/model/Items.java b/hudson-core/src/main/java/hudson/model/Items.java
index d3b6cbb..ccae37d 100644
--- a/hudson-core/src/main/java/hudson/model/Items.java
+++ b/hudson-core/src/main/java/hudson/model/Items.java
@@ -22,6 +22,7 @@ import hudson.Extension;
import org.eclipse.hudson.api.model.project.property.AxisListProjectProperty;
import org.eclipse.hudson.api.model.project.property.BaseProjectProperty;
import org.eclipse.hudson.api.model.project.property.BooleanProjectProperty;
+import org.eclipse.hudson.api.model.project.property.CopyOnWriteListProjectProperty;
import org.eclipse.hudson.api.model.project.property.DescribableListProjectProperty;
import org.eclipse.hudson.api.model.project.property.ExternalProjectProperty;
import org.eclipse.hudson.api.model.project.property.IntegerProjectProperty;
@@ -148,10 +149,10 @@ public class Items {
XSTREAM.alias("log-rotator-property", LogRotatorProjectProperty.class);
XSTREAM.alias("result-property", ResultProjectProperty.class);
+ XSTREAM.alias("copy-write-list-property", CopyOnWriteListProjectProperty.class);
XSTREAM.alias("axis-list-property", AxisListProjectProperty.class);
XSTREAM.alias("describable-list-property", DescribableListProjectProperty.class);
XSTREAM.aliasField("project-properties", Job.class, "jobProperties");
- //TODO: think about migrating to xstream's annotations.
XSTREAM.alias("appointed-node-property", AppointedNode.class);
}
}
diff --git a/hudson-core/src/main/java/hudson/model/Job.java b/hudson-core/src/main/java/hudson/model/Job.java
index 4d8dcf9..17baabb 100644
--- a/hudson-core/src/main/java/hudson/model/Job.java
+++ b/hudson-core/src/main/java/hudson/model/Job.java
@@ -20,6 +20,7 @@ package hudson.model;
import hudson.Functions;
import hudson.util.CascadingUtil;
import java.util.concurrent.CopyOnWriteArraySet;
+import org.apache.commons.collections.ListUtils;
import org.apache.commons.collections.MapUtils;
import org.eclipse.hudson.api.model.project.property.AxisListProjectProperty;
import org.eclipse.hudson.api.model.project.property.BaseProjectProperty;
@@ -128,6 +129,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
private static transient final String PROJECT_PROPERTY_KEY_PREFIX = "has";
public static final String PROPERTY_NAME_SEPARATOR = ";";
public static final String LOG_ROTATOR_PROPERTY_NAME = "logRotator";
+ public static final String PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME = "parametersDefinitionProperties";
/**
* Next build number. Kept in a separate file because this is the only
@@ -173,6 +175,12 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
/**
* List of {@link UserProperty}s configured for this project.
+ * According to new implementation {@link ParametersDefinitionProperty} were moved from this collection. So, this
+ * field was left protected for backward compatibility. Don't use this field directly for adding or removing
+ * values. Use {@link #addProperty(JobProperty)}, {@link #removeProperty(JobProperty)},
+ * {@link #removeProperty(Class)} instead.
+ *
+ * @since 2.2.0
*/
protected CopyOnWriteList<JobProperty<? super JobT>> properties = new CopyOnWriteList<JobProperty<? super JobT>>();
@@ -407,6 +415,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
property.setJob(this);
}
convertLogRotatorProperty();
+ convertJobProperty();
}
void convertLogRotatorProperty() {
@@ -416,6 +425,12 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
}
}
+ void convertJobProperty() {
+ if (null != properties && null == getProperty(PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME)) {
+ setParameterDefinitionProperties(properties);
+ properties = null;
+ }
+ }
/**
* Initialize project properties if null.
*/
@@ -603,6 +618,22 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
return true;
}
+ public void setParameterDefinitionProperties(CopyOnWriteList<JobProperty<? super JobT>> properties) {
+ CopyOnWriteList parameterDefinitionProperties = new CopyOnWriteList();
+ for (JobProperty property : properties) {
+ if (property instanceof ParametersDefinitionProperty) {
+ parameterDefinitionProperties.add(property);
+ }
+ }
+ CascadingUtil.setParameterDefinitionProperties(this, PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME,
+ parameterDefinitionProperties);
+ }
+
+ public CopyOnWriteList<ParametersDefinitionProperty> getParameterDefinitionProperties() {
+ return CascadingUtil.getCopyOnWriteListProjectProperty(this, PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME)
+ .getValue();
+ }
+
@Override
protected SearchIndexBuilder makeSearchIndex() {
return super.makeSearchIndex().add(new SearchIndex() {
@@ -640,7 +671,16 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
*/
public void addProperty(JobProperty<? super JobT> jobProp) throws IOException {
((JobProperty) jobProp).setOwner(this);
- properties.add(jobProp);
+ if (((JobProperty) jobProp) instanceof ParametersDefinitionProperty) {
+ CopyOnWriteList list = CascadingUtil.getCopyOnWriteListProjectProperty(this,
+ PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME)
+ .getOriginalValue();
+ if (null != list) {
+ list.add(jobProp);
+ }
+ } else {
+ properties.add(jobProp);
+ }
save();
}
@@ -650,22 +690,39 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
* @since 1.279
*/
public void removeProperty(JobProperty<? super JobT> jobProp) throws IOException {
- properties.remove(jobProp);
+ if (((JobProperty) jobProp) instanceof ParametersDefinitionProperty) {
+ CopyOnWriteList list = CascadingUtil.getCopyOnWriteListProjectProperty(this,
+ PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME)
+ .getOriginalValue();
+ if (null != list) {
+ list.remove(jobProp);
+ }
+ } else {
+ properties.remove(jobProp);
+ }
save();
}
/**
* Removes the property of the given type.
*
- * @return
- * The property that was just removed.
+ * @return The property that was just removed.
* @since 1.279
*/
public <T extends JobProperty> T removeProperty(Class<T> clazz) throws IOException {
- for (JobProperty<? super JobT> p : properties) {
- if (clazz.isInstance(p)) {
- removeProperty(p);
- return clazz.cast(p);
+ CopyOnWriteList<JobProperty<? super JobT>> sourceProperties;
+ if (clazz.equals(ParametersDefinitionProperty.class)) {
+ sourceProperties = CascadingUtil.getCopyOnWriteListProjectProperty(this,
+ PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME).getOriginalValue();
+ } else {
+ sourceProperties = properties;
+ }
+ if (null != sourceProperties) {
+ for (JobProperty<? super JobT> p : sourceProperties) {
+ if (clazz.isInstance(p)) {
+ removeProperty(p);
+ return clazz.cast(p);
+ }
}
}
return null;
@@ -676,7 +733,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
*/
@SuppressWarnings("unchecked")
public Map<JobPropertyDescriptor, JobProperty<? super JobT>> getProperties() {
- return Descriptor.toMap((Iterable) properties); //TODO should we analyze properties from super psroject?
+ return Descriptor.toMap((Iterable) getAllProperties());
}
/**
@@ -685,7 +742,12 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
*/
@Exported(name = "property", inline = true)
public List<JobProperty<? super JobT>> getAllProperties() {
- return properties.getView();
+ CopyOnWriteList<ParametersDefinitionProperty> definitionProperties = getParameterDefinitionProperties();
+ List<JobProperty<? super JobT>> result = properties.getView();
+ if (null != definitionProperties) {
+ result = Collections.unmodifiableList(ListUtils.union(result, definitionProperties.getView()));
+ }
+ return result;
}
/**
@@ -693,9 +755,18 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
* this job.
*/
public <T extends JobProperty> T getProperty(Class<T> clazz) {
- for (JobProperty p : properties) {
- if (clazz.isInstance(p)) {
- return clazz.cast(p);
+ CopyOnWriteList<JobProperty<? super JobT>> sourceProperties;
+ if (clazz.equals(ParametersDefinitionProperty.class)) {
+ sourceProperties = CascadingUtil.getCopyOnWriteListProjectProperty(this,
+ PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME).getOriginalValue();
+ } else {
+ sourceProperties = properties;
+ }
+ if (null != sourceProperties) {
+ for (JobProperty p : sourceProperties) {
+ if (clazz.isInstance(p)) {
+ return clazz.cast(p);
+ }
}
}
return null;
@@ -706,9 +777,8 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
*/
public Collection<?> getOverrides() {
List<Object> r = new ArrayList<Object>();
- for (JobProperty<? super JobT> p : properties) {
+ for (JobProperty<? super JobT> p : getAllProperties())
r.addAll(p.getJobOverrides());
- }
return r;
}
@@ -1251,29 +1321,7 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
public synchronized void doConfigSubmit(StaplerRequest req,
StaplerResponse rsp) throws IOException, ServletException, FormException {
checkPermission(CONFIGURE);
-
- description = req.getParameter("description");
-
- keepDependencies = req.getParameter("keepDependencies") != null;
-
try {
- properties.clear();
-
- JSONObject json = req.getSubmittedForm();
- setLogRotator(req.getParameter("logrotate") != null ? LogRotator.DESCRIPTOR
- .newInstance(req, json.getJSONObject("logrotate")) : null);
-
- int i = 0;
- for (JobPropertyDescriptor d : JobPropertyDescriptor.getPropertyDescriptors(Job.this.getClass())) {
- String name = "jobProperty" + (i++);
- JSONObject config = json.getJSONObject(name);
- JobProperty prop = d.newInstance(req, config);
- if (prop != null) {
- prop.setOwner(this);
- properties.add(prop);
- }
- }
-
setAllowSave(false);
submit(req, rsp);
setAllowSave(true);
@@ -1305,8 +1353,33 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R
* Derived class can override this to perform additional config submission
* work.
*/
- protected void submit(StaplerRequest req, StaplerResponse rsp)
- throws IOException, ServletException, FormException {
+ protected void submit(StaplerRequest req, StaplerResponse rsp) throws IOException, ServletException, FormException {
+ JSONObject json = req.getSubmittedForm();
+ description = req.getParameter("description");
+ keepDependencies = req.getParameter("keepDependencies") != null;
+ properties.clear();
+ CopyOnWriteList parameterDefinitionProperties = new CopyOnWriteList();
+ int i = 0;
+ for (JobPropertyDescriptor d : JobPropertyDescriptor
+ .getPropertyDescriptors(Job.this.getClass())) {
+ String name = "jobProperty" + (i++);
+ JSONObject config = json.getJSONObject(name);
+ JobProperty prop = d.newInstance(req, config);
+
+ if (prop instanceof ParametersDefinitionProperty) {
+ prop.setOwner(this);
+ parameterDefinitionProperties.add(prop);
+ } else if (null != prop) {
+ prop.setOwner(this);
+ properties.add(prop);
+ }
+ }
+ setParameterDefinitionProperties(parameterDefinitionProperties);
+ LogRotator logRotator = null;
+ if (null != req.getParameter("logrotate")) {
+ logRotator = LogRotator.DESCRIPTOR.newInstance(req, json.getJSONObject("logrotate"));
+ }
+ setLogRotator(logRotator);
}
/**
diff --git a/hudson-core/src/main/java/hudson/model/ParametersDefinitionProperty.java b/hudson-core/src/main/java/hudson/model/ParametersDefinitionProperty.java
index 46e6002..1a5f43c 100644
--- a/hudson-core/src/main/java/hudson/model/ParametersDefinitionProperty.java
+++ b/hudson-core/src/main/java/hudson/model/ParametersDefinitionProperty.java
@@ -56,7 +56,17 @@ public class ParametersDefinitionProperty extends JobProperty<AbstractProject<?,
public ParametersDefinitionProperty(ParameterDefinition... parameterDefinitions) {
this.parameterDefinitions = Arrays.asList(parameterDefinitions);
}
-
+
+ /**
+ * This method is called for cascading update of owners.
+ *
+ * @param owner new owner.
+ * @since 2.2.0
+ */
+ public void setOwner(AbstractProject<?, ?> owner) {
+ super.setOwner(owner);
+ }
+
public AbstractProject<?,?> getOwner() {
return owner;
}
@@ -104,7 +114,7 @@ public class ParametersDefinitionProperty extends JobProperty<AbstractProject<?,
}
List<ParameterValue> values = new ArrayList<ParameterValue>();
-
+
JSONObject formData = req.getSubmittedForm();
JSONArray a = JSONArray.fromObject(formData.get("parameter"));
@@ -173,7 +183,7 @@ public class ParametersDefinitionProperty extends JobProperty<AbstractProject<?,
if (parameterized.isNullObject()) {
return null;
}
-
+
List<ParameterDefinition> parameterDefinitions = Descriptor.newInstancesFromHeteroList(
req, parameterized, "parameter", ParameterDefinition.all());
if(parameterDefinitions.isEmpty())
@@ -199,4 +209,27 @@ public class ParametersDefinitionProperty extends JobProperty<AbstractProject<?,
public String getUrlName() {
return null;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+
+ ParametersDefinitionProperty that = (ParametersDefinitionProperty) o;
+ if (parameterDefinitions != null ? !this.parameterDefinitions.equals(that.parameterDefinitions)
+ : that.parameterDefinitions != null) {
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ return parameterDefinitions != null ? parameterDefinitions.hashCode() : 0;
+ }
}
diff --git a/hudson-core/src/main/java/hudson/util/CascadingUtil.java b/hudson-core/src/main/java/hudson/util/CascadingUtil.java
index 467988d..c2df54d 100644
--- a/hudson-core/src/main/java/hudson/util/CascadingUtil.java
+++ b/hudson-core/src/main/java/hudson/util/CascadingUtil.java
@@ -15,11 +15,14 @@
package hudson.util;
import hudson.Functions;
+import hudson.model.AbstractProject;
import hudson.model.Describable;
import hudson.model.Descriptor;
import hudson.model.Hudson;
import hudson.model.Item;
import hudson.model.Job;
+import hudson.model.ParameterDefinition;
+import hudson.model.ParametersDefinitionProperty;
import hudson.triggers.Trigger;
import hudson.triggers.TriggerDescriptor;
import java.lang.reflect.InvocationTargetException;
@@ -35,6 +38,7 @@ import org.eclipse.hudson.api.model.IProjectProperty;
import org.eclipse.hudson.api.model.project.property.AxisListProjectProperty;
import org.eclipse.hudson.api.model.project.property.BaseProjectProperty;
import org.eclipse.hudson.api.model.project.property.BooleanProjectProperty;
+import org.eclipse.hudson.api.model.project.property.CopyOnWriteListProjectProperty;
import org.eclipse.hudson.api.model.project.property.DescribableListProjectProperty;
import org.eclipse.hudson.api.model.project.property.ExternalProjectProperty;
import org.eclipse.hudson.api.model.project.property.IntegerProjectProperty;
@@ -106,6 +110,19 @@ public class CascadingUtil {
}
/**
+ * Returns CopyOnWriteListProjectProperty by specified key. If property doesn't exists,
+ * it will be initialized and added to current job.
+ *
+ * @param currentJob job that should be analyzed.
+ * @param key key.
+ * @return {@link org.eclipse.hudson.api.model.project.property.CopyOnWriteListProjectProperty} instance.
+ * @throws NullPointerException if currentJob is null.
+ */
+ public static CopyOnWriteListProjectProperty getCopyOnWriteListProjectProperty(Job currentJob, String key) {
+ return getProjectProperty(currentJob, key, CopyOnWriteListProjectProperty.class);
+ }
+
+ /**
* Returns ResultProjectProperty by specified key. If property doesn't exists, it will be initialized and added to
* current job.
*
@@ -413,7 +430,7 @@ public class CascadingUtil {
*/
@SuppressWarnings("unchecked")
public static void setChildrenTrigger(Job job, TriggerDescriptor descriptor, String key, StaplerRequest req,
- JSONObject json) throws Descriptor.FormException {
+ JSONObject json) throws Descriptor.FormException {
TriggerProjectProperty property = CascadingUtil.getTriggerProjectProperty(job, key);
if (property.getValue() != null) {
property.getValue().stop();
@@ -437,4 +454,45 @@ public class CascadingUtil {
}
}
}
+
+ /**
+ * Sets parameterDefinitionProperties for current job. This method is recursively executed for cascading children
+ * for setting valid {@link ParametersDefinitionProperty#owner} value.
+ *
+ * @param job job.
+ * @param key parameter key,
+ * @param parameterDefinitionProperties new properties to set.
+ */
+ @SuppressWarnings("unchecked")
+ public static void setParameterDefinitionProperties(Job job,
+ String key,
+ CopyOnWriteList<ParametersDefinitionProperty> parameterDefinitionProperties) {
+ CopyOnWriteListProjectProperty projectProperty = getCopyOnWriteListProjectProperty(job, key);
+ CopyOnWriteList<ParametersDefinitionProperty> pdProperties
+ = new CopyOnWriteList<ParametersDefinitionProperty>();
+ //Create new instance for each parameter in order to set owner and use in cascading children.
+ for (ParametersDefinitionProperty pdp : parameterDefinitionProperties) {
+ ParametersDefinitionProperty copiedDefinitionProperty = new ParametersDefinitionProperty(
+ new ArrayList<ParameterDefinition>(pdp.getParameterDefinitions()));
+ copiedDefinitionProperty.setOwner((AbstractProject) job);
+ pdProperties.add(copiedDefinitionProperty);
+ }
+ projectProperty.setValue(pdProperties);
+ Set<String> cascadingChildrenNames = job.getCascadingChildrenNames();
+ //Iterate through cascading children and recursively update property for each child.
+ for (String childName : cascadingChildrenNames) {
+ AbstractProject childJob = (AbstractProject) Hudson.getInstance().getItem(childName);
+ //Check only direct children in order to avoid deep checking for properties overridden properties.
+ if (StringUtils.equals(job.getName(), childJob.getCascadingProjectName())) {
+ CopyOnWriteListProjectProperty childProperty = getCopyOnWriteListProjectProperty(childJob, key);
+ //If child value is equal to parent - mark this value as unmodified.
+ if (!projectProperty.allowOverrideValue(childProperty.getValue(), pdProperties)) {
+ projectProperty.setOverridden(false);
+ } else if (!childProperty.isOverridden()) {
+ //If child property was not overridden, update this property and cascading children if any.
+ setParameterDefinitionProperties(childJob, key, parameterDefinitionProperties);
+ }
+ }
+ }
+ }
}
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 4d62292..4761346 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
@@ -34,6 +34,11 @@ public interface IProjectProperty<T> extends Serializable {
void setKey(String key);
/**
+ * @return property key.
+ */
+ String getKey();
+
+ /**
* Sets the job, which is owner of current property.
*
* @param job {@link IJob}
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 a37f49a..64b1ba1 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
@@ -55,6 +55,13 @@ public class BaseProjectProperty<T> implements IProjectProperty<T> {
/**
* {@inheritDoc}
*/
+ public String getKey() {
+ return propertyKey;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
public void setJob(IJob job) {
if (null == job) {
throw new IllegalArgumentException(INVALID_JOB_EXCEPTION);
@@ -81,7 +88,7 @@ public class BaseProjectProperty<T> implements IProjectProperty<T> {
*/
@SuppressWarnings("unchecked")
public T getCascadingValue() {
- if (null == propertyKey) {
+ if (null == getKey()) {
throw new IllegalArgumentException(INVALID_PROPERTY_KEY_EXCEPTION);
}
return getJob().hasCascadingProject() ?
@@ -126,7 +133,7 @@ public class BaseProjectProperty<T> implements IProjectProperty<T> {
*/
@SuppressWarnings("unchecked")
public void setValue(T value) {
- if (null == propertyKey) {
+ if (null == getKey()) {
throw new IllegalArgumentException(INVALID_PROPERTY_KEY_EXCEPTION);
}
value = prepareValue(value);
diff --git a/hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/CopyOnWriteListProjectProperty.java b/hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/CopyOnWriteListProjectProperty.java
new file mode 100644
index 0000000..1c3c5ac
--- /dev/null
+++ b/hudson-core/src/main/java/org/eclipse/hudson/api/model/project/property/CopyOnWriteListProjectProperty.java
@@ -0,0 +1,55 @@
+/*******************************************************************************
+ *
+ * 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
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Nikita Levyankov
+ *
+ *******************************************************************************/
+package org.eclipse.hudson.api.model.project.property;
+
+import hudson.util.CopyOnWriteList;
+import org.eclipse.hudson.api.model.IJob;
+
+/**
+ * Project property for CopyOnWriteList
+ * <p/>
+ * Date: 11/1/11
+ *
+ * @author Nikita Levyankov
+ */
+public class CopyOnWriteListProjectProperty extends BaseProjectProperty<CopyOnWriteList> {
+
+ public CopyOnWriteListProjectProperty(IJob job) {
+ super(job);
+ }
+
+ @Override
+ public CopyOnWriteList getDefaultValue() {
+ CopyOnWriteList result = new CopyOnWriteList();
+ setOriginalValue(result, false);
+ return result;
+ }
+
+ @Override
+ protected boolean returnOriginalValue() {
+ return isOverridden() || (null != getOriginalValue() && !getOriginalValue().isEmpty());
+ }
+
+ @Override
+ public CopyOnWriteList getOriginalValue() {
+ CopyOnWriteList result = super.getOriginalValue();
+ return null != result ? result : getDefaultValue();
+ }
+
+ @Override
+ protected void clearOriginalValue(CopyOnWriteList originalValue) {
+ setOriginalValue(originalValue, false);
+ }
+}
diff --git a/hudson-core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly b/hudson-core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly
index cad4808..2a2da3e 100644
--- a/hudson-core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly
+++ b/hudson-core/src/main/resources/hudson/model/ParametersDefinitionProperty/config.jelly
@@ -1,6 +1,6 @@
<!-- **************************************************************************
#
-# Copyright (c) 2004-2009 Oracle Corporation.
+# Copyright (c) 2004-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
@@ -9,7 +9,7 @@
#
# Contributors:
#
-# Kohsuke Kawaguchi, Tom Huybrechts
+# Kohsuke Kawaguchi, Tom Huybrechts, Nikita Levyankov
#
#
#************************************************************************** -->
@@ -18,8 +18,11 @@
<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:d="jelly:define"
xmlns:l="/lib/layout" xmlns:t="/lib/hudson" xmlns:f="/lib/form"
xmlns:i="jelly:fmt" xmlns:p="/lib/hudson/project">
+ <j:set var="instancesProperty" value="${cu.getCopyOnWriteListProjectProperty(it, it.PARAMETERS_DEFINITION_JOB_PROPERTY_PROPERTY_NAME)}"/>
<f:optionalBlock name="parameterized" title="${%This build is parameterized}"
- checked="${instance!=null}" help="/help/project-config/parameterized-build.html">
+ isPropertyOverridden="${instancesProperty.isOverridden()}"
+ resetUrl="${jobUrl}/resetProjectProperty?propertyName=${instancesProperty.key}"
+ checked="${instance!=null}" help="/help/project-config/parameterized-build.html">
<f:nested>
<f:hetero-list name="parameter" hasHeader="true"
descriptors="${h.getParameterDescriptors()}" items="${instance.parameterDefinitions}"