001 /**
002 * Copyright 2005-2011 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016 package org.kuali.rice.kew.api.document.attribute;
017
018 import java.io.Serializable;
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.Collections;
022 import java.util.HashMap;
023 import java.util.List;
024 import java.util.Map;
025
026 import javax.xml.bind.annotation.XmlAccessType;
027 import javax.xml.bind.annotation.XmlAccessorType;
028 import javax.xml.bind.annotation.XmlAnyElement;
029 import javax.xml.bind.annotation.XmlElement;
030 import javax.xml.bind.annotation.XmlElementWrapper;
031 import javax.xml.bind.annotation.XmlRootElement;
032 import javax.xml.bind.annotation.XmlType;
033
034 import org.apache.commons.lang.StringUtils;
035 import org.kuali.rice.core.api.CoreConstants;
036 import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
037 import org.kuali.rice.core.api.mo.ModelBuilder;
038 import org.kuali.rice.kew.api.document.PropertyDefinition;
039 import org.w3c.dom.Element;
040
041 /**
042 * Encapsulates parameters that can be sent to an attribute when using that attribute to perform various operations
043 * (primarily, in the case of workflow attributes, during the generation of XML).
044 *
045 * @author Kuali Rice Team (rice.collab@kuali.org)
046 */
047 @XmlRootElement(name = WorkflowAttributeDefinition.Constants.ROOT_ELEMENT_NAME)
048 @XmlAccessorType(XmlAccessType.NONE)
049 @XmlType(name = WorkflowAttributeDefinition.Constants.TYPE_NAME, propOrder = {
050 WorkflowAttributeDefinition.Elements.ATTRIBUTE_NAME,
051 WorkflowAttributeDefinition.Elements.PARAMETERS,
052 WorkflowAttributeDefinition.Elements.PROPERTY_DEFINITIONS,
053 CoreConstants.CommonElements.FUTURE_ELEMENTS
054 })
055 public final class WorkflowAttributeDefinition extends AbstractDataTransferObject {
056
057 @XmlElement(name = Elements.ATTRIBUTE_NAME, required = true)
058 private final String attributeName;
059
060 @XmlElementWrapper(name = Elements.PARAMETERS, required = false)
061 @XmlElement(name = Elements.PARAMETER, required = false)
062 private final List<String> parameters;
063
064 @XmlElementWrapper(name = Elements.PROPERTY_DEFINITIONS, required = false)
065 @XmlElement(name = Elements.PROPERTY_DEFINITION, required = false)
066 private final List<PropertyDefinition> propertyDefinitions;
067
068 @SuppressWarnings("unused")
069 @XmlAnyElement
070 private final Collection<Element> _futureElements = null;
071
072 /**
073 * Private constructor used only by JAXB.
074 */
075 private WorkflowAttributeDefinition() {
076 this.attributeName = null;
077 this.parameters = null;
078 this.propertyDefinitions = null;
079 }
080
081 private WorkflowAttributeDefinition(Builder builder) {
082 this.attributeName = builder.getAttributeName();
083 if (builder.getParameters() == null) {
084 this.parameters = Collections.emptyList();
085 } else {
086 this.parameters = new ArrayList<String>(builder.getParameters());
087 }
088 if (builder.getPropertyDefinitions() == null) {
089 this.propertyDefinitions = Collections.emptyList();
090 } else {
091 this.propertyDefinitions = new ArrayList<PropertyDefinition>(builder.getPropertyDefinitions());
092 }
093 }
094
095 /**
096 * Returns the name of the attribute for this workflow attribute definition. Should never be a null or blank value.
097 *
098 * @return the name of the attribute for this workflow attribute definition
099 */
100 public String getAttributeName() {
101 return attributeName;
102 }
103
104 /**
105 * Returns an unmodifiable list of parameters that will be used to construct the attribute as a list of string
106 * values. This list will never be null but it may be empty.
107 *
108 * @return the list of parameters used to construct the attribute
109 */
110 public List<String> getParameters() {
111 return Collections.unmodifiableList(parameters);
112 }
113
114 /**
115 * Returns an unmodifiable list of property names and values that will be passed to the attribute upon construction.
116 * This list will never be null but it may be empty.
117 *
118 * @return the list of property names and values to will be be passed to the attribute upon construction
119 */
120 public List<PropertyDefinition> getPropertyDefinitions() {
121 return Collections.unmodifiableList(propertyDefinitions);
122 }
123
124 /**
125 * Returns the property definitions on this attribute definition as a map of strings instead of a list of
126 * {@code PropertyDefinition} objects.
127 *
128 * @return a map representation of the property definitions on this workflow attribute definition
129 */
130 public Map<String, String> getPropertyDefinitionsAsMap() {
131 Map<String, String> propertiesDefinitionsMap = new HashMap<String, String>();
132 for (PropertyDefinition propertyDefinition : getPropertyDefinitions()) {
133 propertiesDefinitionsMap.put(propertyDefinition.getName(), propertyDefinition.getValue());
134 }
135 return Collections.unmodifiableMap(propertiesDefinitionsMap);
136 }
137
138 /**
139 * A builder which can be used to construct instances of {@code WorkflowAttributeDefinition}.
140 */
141 public final static class Builder implements Serializable, ModelBuilder {
142
143 private static final long serialVersionUID = 7549637048594326790L;
144
145 private String attributeName;
146 private List<String> parameters;
147 private List<PropertyDefinition> propertyDefinitions;
148
149 private Builder(String attributeName) {
150 setAttributeName(attributeName);
151 setParameters(new ArrayList<String>());
152 setPropertyDefinitions(new ArrayList<PropertyDefinition>());
153 }
154
155 private Builder(WorkflowAttributeDefinition definition) {
156 setAttributeName(definition.getAttributeName());
157 setParameters(definition.getParameters());
158 setPropertyDefinitions(definition.getPropertyDefinitions());
159 }
160
161 /**
162 * Creates a new builder copying the properties from the given definition into it.
163 *
164 * @param definition the definition from which to copy properties
165 * @return a builder initialized with the properties copied from the given definition
166 */
167 public static Builder create(WorkflowAttributeDefinition definition) {
168 if (definition == null) {
169 throw new IllegalArgumentException("definition was null");
170 }
171 return new Builder(definition);
172 }
173
174 /**
175 * Constructs a builder which is initialized with the given attribute name.
176 *
177 * @param attributeName the attribute name to use when initializing this builder, cannot be a null or empty
178 * value
179 *
180 * @return an instance of a builder initialized with the given attribute name
181 *
182 * @throws IllegalArgumentException if {@code attributeName} is a null or blank value
183 */
184 public static Builder create(String attributeName) {
185 return new Builder(attributeName);
186
187 }
188
189 @Override
190 public WorkflowAttributeDefinition build() {
191 return new WorkflowAttributeDefinition(this);
192 }
193
194 /**
195 * Returns the attribute name that is set on this builder.
196 *
197 * @return the attribute name this is set on this builder
198 */
199 public String getAttributeName() {
200 return attributeName;
201 }
202
203 /**
204 * Returns a list of string parameters that have been set on this builder.
205 *
206 * @return a list of string parameters that have been set on this builder
207 */
208 public List<String> getParameters() {
209 return parameters;
210 }
211
212 /**
213 * Returns a list of {@code PropertyDefinition} objects that have been set on this builder.
214 *
215 * @return a list of property definitions that have been set on this builder
216 */
217 public List<PropertyDefinition> getPropertyDefinitions() {
218 return propertyDefinitions;
219 }
220
221 /**
222 * Sets the attribute name on this builder to the given value. Must not be a null or blank value.
223 *
224 * @param attributeName the value of the attributeName to set
225 * @throws IllegalArgumentException if {@code attributeName} is a null or blank value
226 */
227 public void setAttributeName(String attributeName) {
228 if (StringUtils.isBlank(attributeName)) {
229 throw new IllegalArgumentException("attributeName was null or blank");
230 }
231 this.attributeName = attributeName;
232 }
233
234 /**
235 * Adds a parameter to the list of parameters maintained by this builder.
236 *
237 * @param parameter the parameter value to add
238 */
239 public void addParameter(String parameter) {
240 parameters.add(parameter);
241 }
242
243 /**
244 * Removes a parameter with the given value from the list of parameters maintained by this builder.
245 *
246 * @param parameter the parameter value to remove
247 */
248 public void removeParameter(String parameter) {
249 parameters.remove(parameter);
250 }
251
252 /**
253 * Sets the list of parameters on this builder.
254 *
255 * @param parameters the list of parameters to set
256 */
257 public void setParameters(List<String> parameters) {
258 this.parameters = new ArrayList<String>(parameters);
259 }
260
261 /**
262 * Adds the given property definition to the list of property definitions maintained by this builder.
263 *
264 * @param propertyDefinition the property definition to set, should not be null
265 * @throws IllegalArgumentException if the given property definition is null
266 */
267 public void addPropertyDefinition(PropertyDefinition propertyDefinition) {
268 if (propertyDefinition == null) {
269 throw new IllegalArgumentException("propertyDefinition must be non-null.");
270 }
271 propertyDefinitions.add(propertyDefinition);
272 }
273
274 /**
275 * Sets the list of property definitions maintained by this build to the given list.
276 *
277 * @param propertyDefinitions the list of property definitions to set
278 */
279 public void setPropertyDefinitions(List<PropertyDefinition> propertyDefinitions) {
280 if (propertyDefinitions == null) {
281 setPropertyDefinitions(new ArrayList<PropertyDefinition>());
282 }
283 this.propertyDefinitions = new ArrayList<PropertyDefinition>(propertyDefinitions);
284
285 }
286
287 /**
288 * Add a property definition constructed from the given name and value to the list of property definitions
289 * on this builder.
290 *
291 * @param name name of the property definition to add, must not be a null or blank value
292 * @param value value of the property definition to add
293 *
294 * @throws IllegalArgumentException if the given name is a null or blank value
295 */
296 public void addPropertyDefinition(String name, String value) {
297 addPropertyDefinition(PropertyDefinition.create(name, value));
298 }
299
300 /**
301 * Returns the property definition on this build which has the given name if it exists. This method will return
302 * a null value if a definition with the given name cannot be found.
303 *
304 * @param name the name of the property definition to retrieve
305 *
306 * @return the property definition with the given name, or null if no such property definition is found
307 *
308 * @throws IllegalArgumentException if the given name is a null or blank value
309 */
310 public PropertyDefinition getPropertyDefinition(String name) {
311 if (StringUtils.isBlank(name)) {
312 throw new IllegalArgumentException("name was null or blank");
313 }
314 for (PropertyDefinition propertyDefinition : propertyDefinitions) {
315 if (propertyDefinition.equals(name)) {
316 return propertyDefinition;
317 }
318 }
319 return null;
320 }
321
322
323 }
324
325 /**
326 * Defines some internal constants used on this class.
327 */
328 static class Constants {
329 final static String ROOT_ELEMENT_NAME = "workflowAttributeDefinition";
330 final static String TYPE_NAME = "WorkflowAttributeDefinitionType";
331 }
332
333 /**
334 * A private class which exposes constants which define the XML element names to use when this object is marshalled to XML.
335 */
336 static class Elements {
337 final static String ATTRIBUTE_NAME = "attributeName";
338 final static String PARAMETERS = "parameters";
339 final static String PARAMETER = "parameter";
340 final static String PROPERTY_DEFINITIONS = "propertyDefinitions";
341 final static String PROPERTY_DEFINITION = "propertyDefinition";
342 }
343
344 }