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