| author | akozak | 2011-11-22 03:32:46 (EST) |
|---|---|---|
| committer | Winston Prakash | 2011-12-01 20:46:55 (EST) |
| commit | ecfaa4313f12dac7376ebc3bd22e4644d5351440 (patch) (side-by-side diff) | |
| tree | 4c4d156412be60ed431534205ea45d5ebed48843 | |
| parent | a6d7eec943c1bd98ff0a0b30bfeeaf15d45d620d (diff) | |
| download | org.eclipse.hudson.core-ecfaa4313f12dac7376ebc3bd22e4644d5351440.zip org.eclipse.hudson.core-ecfaa4313f12dac7376ebc3bd22e4644d5351440.tar.gz org.eclipse.hudson.core-ecfaa4313f12dac7376ebc3bd22e4644d5351440.tar.bz2 | |
Implement IProperty interface which represent job property (string, int, etc.). Apply new interface to FreeStyleProject
Signed-off-by: Winston Prakash <winston.prakash@gmail.com>
7 files changed, 268 insertions, 28 deletions
diff --git a/hudson-core/src/main/java/hudson/model/FreeStyleProject.java b/hudson-core/src/main/java/hudson/model/FreeStyleProject.java index ed4a24e..97f3a49 100644 --- a/hudson-core/src/main/java/hudson/model/FreeStyleProject.java +++ b/hudson-core/src/main/java/hudson/model/FreeStyleProject.java @@ -36,8 +36,6 @@ import javax.servlet.ServletException; public class FreeStyleProject extends Project<FreeStyleProject,FreeStyleBuild> implements TopLevelItem, IFreeStyleProject { - public static final String CUSTOM_WORKSPACE_PROPERTY_NAME = "customWorkspace"; - /** * See {@link #setCustomWorkspace(String)}. * @@ -61,17 +59,21 @@ public class FreeStyleProject extends Project<FreeStyleProject,FreeStyleBuild> i return FreeStyleBuild.class; } - public String getCustomWorkspace(boolean useParentValue) { - if (!useParentValue || isOverriddenProperty(CUSTOM_WORKSPACE_PROPERTY_NAME) || null != customWorkspace) { - return customWorkspace; + public String getCustomWorkspace(boolean useParentValue) throws IOException{ + StringProperty jobProperty = getCustomWorkspaceProperty(); + if (!useParentValue) { + return jobProperty.getOriginalValue(); } - return hasCascadingProject() ? getCascadingProject().getCustomWorkspace() : null; + return jobProperty.getValue(); } - public String getCustomWorkspace() { - return getCustomWorkspace(true); + public StringProperty getCustomWorkspaceProperty() throws IOException { + return (StringProperty)getProperty(PROPERTY_NAME.CUSTOM_WORKSPACE, StringProperty.class); } + public String getCustomWorkspace() throws IOException { + return getCustomWorkspace(true); + } /** * User-specified workspace directory, or null if it's up to Hudson. @@ -88,22 +90,13 @@ public class FreeStyleProject extends Project<FreeStyleProject,FreeStyleBuild> i * <p> * If this path is relative, it's resolved against {@link Node#getRootPath()} on the node where this workspace * is prepared. - * * @param customWorkspace new custom workspace to set * @since 1.320 * @throws IOException if any. */ public void setCustomWorkspace(String customWorkspace) throws IOException { - String workspace = StringUtils.trimToNull(customWorkspace); - if (!hasCascadingProject()) { - this.customWorkspace = workspace; - } else if (!StringUtils.equalsIgnoreCase(getCascadingProject().getCustomWorkspace(), workspace)) { - this.customWorkspace = workspace; - registerOverriddenProperty(CUSTOM_WORKSPACE_PROPERTY_NAME); - } else { - this.customWorkspace = null; - unRegisterOverriddenProperty(CUSTOM_WORKSPACE_PROPERTY_NAME); - } + StringProperty jobProperty = getCustomWorkspaceProperty(); + jobProperty.setValue(customWorkspace); save(); } diff --git a/hudson-core/src/main/java/hudson/model/Job.java b/hudson-core/src/main/java/hudson/model/Job.java index df33360..0696b71 100644 --- a/hudson-core/src/main/java/hudson/model/Job.java +++ b/hudson-core/src/main/java/hudson/model/Job.java @@ -20,6 +20,8 @@ package hudson.model; import hudson.Functions; import hudson.util.graph.GraphSeries; import hudson.widgets.Widget; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; import java.util.concurrent.CopyOnWriteArraySet; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; @@ -83,6 +85,7 @@ import net.sf.json.JSONException; import net.sf.json.JSONObject; import org.eclipse.hudson.api.model.IJob; +import org.eclipse.hudson.api.model.IProperty; import org.jvnet.localizer.Localizable; import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.CmdLineException; @@ -127,6 +130,13 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R */ private transient volatile boolean holdOffBuildUntilSave; private volatile LogRotator logRotator; + + private ConcurrentMap<Enum, IProperty> jobProperties = new ConcurrentHashMap<Enum, IProperty>(); + + public enum PROPERTY_NAME { + CUSTOM_WORKSPACE + } + /** * Not all plugins are good at calculating their health report quickly. * These fields are used to cache the health reports to speed up rendering @@ -199,6 +209,49 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R overriddenValues.remove(propertyName); } + /** + * Put job property to properties map. + * @param key key. + * @param property property instance. + */ + protected void putJobProperty(Enum key, IProperty property) { + jobProperties.put(key, property); + } + + /** + * Returns job property by specified key. + * @param key key. + * @return {@link IProperty} instance or null. + * @throws IOException if any. + */ + public IProperty getProperty(Enum key) throws IOException { + return getProperty(key, null); + } + + /** + * Returns null safe job property by specified key. if property is not present, try instantiate it. + * @param key key. + * @param clazz type of property.. + * @return {@link IProperty} instance or null. + * @throws IOException if any. + */ + public IProperty getProperty(Enum key, Class clazz) throws IOException { + IProperty t = jobProperties.get(key); + if (null == t && null != clazz) { + try { + t = (IProperty)clazz.newInstance(); + t.setJob(this); + t.setKey(key); + putJobProperty(key, t); + } catch (InstantiationException e) { + throw new IOException(e); + } catch (IllegalAccessException e) { + throw new IOException(e); + } + } + return t; + } + @Override public synchronized void save() throws IOException { if (allowSave.get()) { @@ -252,8 +305,16 @@ public abstract class Job<JobT extends Job<JobT, RunT>, RunT extends Run<JobT, R for (JobProperty p : properties) { p.setOwner(this); } + + if (null == jobProperties) { + jobProperties = new ConcurrentHashMap<Enum, IProperty>(); + } + for (IProperty property : jobProperties.values()) { + property.setJob(this); + } } + @Override public void onCopiedFrom(Item src) { super.onCopiedFrom(src); diff --git a/hudson-core/src/main/java/hudson/model/StringProperty.java b/hudson-core/src/main/java/hudson/model/StringProperty.java new file mode 100644 index 0000000..aa2824d --- a/dev/null +++ b/hudson-core/src/main/java/hudson/model/StringProperty.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * + * 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 hudson.model; + +import java.io.IOException; +import org.apache.commons.lang3.StringUtils; +import org.eclipse.hudson.api.model.IJob; +import org.eclipse.hudson.api.model.IProperty; + +/** + * String property. + * <p/> + * Date: 9/22/11 + * + * @author Nikita Levyankov + */ +public class StringProperty implements IProperty<String> { + + private Enum propertyKey; + private transient IJob job; + private String originalValue; + private boolean propertyOverridden; + + public void setKey(Enum propertyKey) { + this.propertyKey = propertyKey; + } + + public void setJob(IJob job) { + this.job = job; + } + + public StringProperty() { + } + + public void setValue(String value) throws IOException { + value = StringUtils.trimToNull(value); + if (!job.hasCascadingProject()) { + originalValue = value; + } else if (!StringUtils.equalsIgnoreCase( + (String) job.getCascadingProject().getProperty(propertyKey, this.getClass()).getValue(), value)) { + originalValue = value; + propertyOverridden = true; + } else { + this.originalValue = null; + propertyOverridden = false; + } + } + + public String getOriginalValue() { + return originalValue; + } + + public String getCascadingValue() throws IOException { + return job.hasCascadingProject() ? + (String) job.getCascadingProject().getProperty(propertyKey, this.getClass()).getValue() : null; + } + + public boolean isPropertyOverridden() { + return propertyOverridden; + } + + public String getValue() throws IOException { + if (isPropertyOverridden() || null != getOriginalValue()) { + return getOriginalValue(); + } + return getCascadingValue(); + } +} diff --git a/hudson-core/src/main/java/org/eclipse/hudson/api/model/IFreeStyleProject.java b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IFreeStyleProject.java index e90aefc..6182996 100644 --- a/hudson-core/src/main/java/org/eclipse/hudson/api/model/IFreeStyleProject.java +++ b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IFreeStyleProject.java @@ -14,6 +14,8 @@ *******************************************************************************/ package org.eclipse.hudson.api.model; +import java.io.IOException; + /** * FreeStyle project interface. * <p/> @@ -27,6 +29,7 @@ public interface IFreeStyleProject extends IProject { * Returns user-specified workspace directory, or null if it's up to Hudson * * @return string representation of directory. + * @throws IOException if any. */ - String getCustomWorkspace(); + String getCustomWorkspace() throws IOException; } diff --git a/hudson-core/src/main/java/org/eclipse/hudson/api/model/IJob.java b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IJob.java index 6b77e95..c18c92f 100644 --- a/hudson-core/src/main/java/org/eclipse/hudson/api/model/IJob.java +++ b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IJob.java @@ -17,7 +17,9 @@ package org.eclipse.hudson.api.model; import hudson.model.JobProperty; import hudson.model.JobPropertyDescriptor; import hudson.tasks.LogRotator; +import java.io.IOException; import java.util.Map; +import org.eclipse.hudson.api.model.IProperty; /** * Interface that represents Job. @@ -26,7 +28,7 @@ import java.util.Map; * * @author Nikita Levyankov */ -public interface IJob<T> { +public interface IJob<T extends IJob> { /** * Returns cascading project name. @@ -40,7 +42,24 @@ public interface IJob<T> { * * @return cascading project. */ - IJob getCascadingProject(); + T getCascadingProject(); + + /** + * Returns job property by specified key. + * + * @param key key. + * @param clazz IProperty subclass. + * @return {@link IProperty} instance or null. + * @throws java.io.IOException if any. + */ + IProperty getProperty(Enum key, Class<? extends IProperty> clazz) throws IOException; + + /** + * Checks whether current job is inherited from other project. + * + * @return boolean. + */ + boolean hasCascadingProject(); /** * @return whether the name of this job can be changed by user. diff --git a/hudson-core/src/main/java/org/eclipse/hudson/api/model/IProperty.java b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IProperty.java new file mode 100644 index 0000000..46dc8ab --- a/dev/null +++ b/hudson-core/src/main/java/org/eclipse/hudson/api/model/IProperty.java @@ -0,0 +1,81 @@ +/******************************************************************************* + * + * 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; + +import java.io.IOException; +import java.io.Serializable; + +/** + * Represents Properties for Job, + * <p/> + * Date: 9/22/11 + * + * @author Nikita Levyankov + */ +public interface IProperty<T> extends Serializable { + + /** + * Sets key for given property. + * + * @param key key. + */ + void setKey(Enum key); + + /** + * Sets the job, which is owner of current property. + * + * @param job {@link IJob} + */ + void setJob(IJob job); + + /** + * Sets property value. + * + * @param value value to set. + * @throws IOException if any. + */ + void setValue(T value) throws IOException; + + /** + * Returns original property value. + * + * @return T + */ + T getOriginalValue(); + + /** + * Returns cascading value if any. + * + * @return string. + * @throws IOException if any. + */ + T getCascadingValue() throws IOException; + + /** + * @return true if value inherited from cascading project, false - otherwise, + */ + boolean isPropertyOverridden(); + + /** + * Returns property value. If originalValue is not null or value was overridden for this + * property - call {@link #getOriginalValue()}, otherwise call {@link #getCascadingValue()}. + * + * @return string. + * @throws IOException if any. + */ + T getValue() throws IOException; + +} diff --git a/hudson-core/src/main/resources/lib/hudson/project/config-customWorkspace.jelly b/hudson-core/src/main/resources/lib/hudson/project/config-customWorkspace.jelly index f4fa3b7..7beebfb 100644 --- a/hudson-core/src/main/resources/lib/hudson/project/config-customWorkspace.jelly +++ b/hudson-core/src/main/resources/lib/hudson/project/config-customWorkspace.jelly @@ -17,11 +17,13 @@ <!-- custom workspace --> <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"> -<f:optionalBlock name="customWorkspace" title="${%Use custom workspace}" checked="${it.customWorkspace!=null}" - isCascadingValue="${it.isOverriddenProperty(it.CUSTOM_WORKSPACE_PROPERTY_NAME)}" - help="/help/project-config/custom-workspace.html"> - <f:entry title="${%Directory}"> - <f:textbox name="customWorkspace.directory" value="${it.customWorkspace}" /> - </f:entry> + <j:set var="customWorkspaceProperty" value="${it.getCustomWorkspaceProperty()}"/> + <j:set var="customWorkspace" value="${customWorkspaceProperty.getValue()}"/> + <f:optionalBlock name="customWorkspace" title="${%Use custom workspace}" checked="${customWorkspace!=null}" + isCascadingValue="${customWorkspaceProperty.isPropertyOverridden()}" + help="/help/project-config/custom-workspace.html"> + <f:entry title="${%Directory}"> + <f:textbox name="customWorkspace.directory" value="${customWorkspace}" /> + </f:entry> </f:optionalBlock> </j:jelly> |

