View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.krms.api.repository.function;
17  
18  import java.io.Serializable;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.Collections;
22  import java.util.List;
23  
24  import javax.xml.bind.annotation.XmlAccessType;
25  import javax.xml.bind.annotation.XmlAccessorType;
26  import javax.xml.bind.annotation.XmlAnyElement;
27  import javax.xml.bind.annotation.XmlElement;
28  import javax.xml.bind.annotation.XmlElementWrapper;
29  import javax.xml.bind.annotation.XmlRootElement;
30  import javax.xml.bind.annotation.XmlType;
31  
32  import org.apache.commons.lang.StringUtils;
33  import org.kuali.rice.core.api.CoreConstants;
34  import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
35  import org.kuali.rice.core.api.mo.ModelBuilder;
36  import org.kuali.rice.krms.api.repository.category.CategoryDefinition;
37  import org.kuali.rice.krms.api.repository.category.CategoryDefinitionContract;
38  import org.kuali.rice.krms.api.repository.type.KrmsTypeDefinition;
39  import org.w3c.dom.Element;
40  
41  /**
42   * An immutable representation of a function definition.
43   * 
44   * @see FunctionDefinitionContract
45   * 
46   * @author Kuali Rice Team (rice.collab@kuali.org)
47   *
48   */
49  @XmlRootElement(name = FunctionDefinition.Constants.ROOT_ELEMENT_NAME)
50  @XmlAccessorType(XmlAccessType.NONE)
51  @XmlType(name = FunctionDefinition.Constants.TYPE_NAME, propOrder = {
52  		FunctionDefinition.Elements.ID,
53  		FunctionDefinition.Elements.NAMESPACE,
54  		FunctionDefinition.Elements.NAME,
55  		FunctionParameterDefinition.Elements.DESCRIPTION,
56  		FunctionDefinition.Elements.RETURN_TYPE,
57  		FunctionDefinition.Elements.TYPE_ID,
58  		FunctionDefinition.Elements.ACTIVE,
59          CoreConstants.CommonElements.VERSION_NUMBER,
60          FunctionDefinition.Elements.PARAMETERS,
61          FunctionDefinition.Elements.CATEGORIES,
62          CoreConstants.CommonElements.FUTURE_ELEMENTS
63  })
64  public class FunctionDefinition extends AbstractDataTransferObject implements FunctionDefinitionContract {
65  
66  	private static final long serialVersionUID = 1391030685309770560L;
67  
68  	@XmlElement(name = Elements.ID, required = false)
69  	private final String id;
70  	
71  	@XmlElement(name = Elements.NAMESPACE, required = true)
72  	private final String namespace;
73  	
74  	@XmlElement(name = Elements.NAME, required = true)
75  	private final String name;
76  	
77  	@XmlElement(name = Elements.DESCRIPTION, required = false)
78  	private final String description;
79  	
80  	@XmlElement(name = Elements.RETURN_TYPE, required = true)
81  	private final String returnType;
82  	
83  	@XmlElement(name = Elements.TYPE_ID, required = true)
84  	private final String typeId;
85  	
86  	@XmlElement(name = Elements.ACTIVE, required = true)
87  	private final boolean active;
88  	
89  	@XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
90  	private final Long versionNumber;
91  	
92  	@XmlElementWrapper(name = Elements.PARAMETERS, required = false)
93  	@XmlElement(name = Elements.PARAMETER, required = false)
94  	private final List<FunctionParameterDefinition> parameters;
95  
96      @XmlElementWrapper(name = Elements.CATEGORIES, required = false)
97      @XmlElement(name = Elements.CATEGORY, required = false)
98      private final List<CategoryDefinition> categories;
99  	
100 	@SuppressWarnings("unused")
101     @XmlAnyElement
102     private final Collection<Element> _futureElements = null;
103 	
104 	/**
105      * Private constructor used only by JAXB.
106      */
107     private FunctionDefinition() {
108     	this.id = null;
109     	this.namespace = null;
110     	this.name = null;
111     	this.description = null;
112     	this.returnType = null;
113     	this.typeId = null;
114     	this.active = true;
115     	this.versionNumber = null;
116     	this.parameters = null;
117         this.categories = null;
118     }
119     
120     private FunctionDefinition(Builder builder) {
121     	this.id = builder.getId();
122     	this.namespace = builder.getNamespace();
123     	this.name = builder.getName();
124     	this.description = builder.getDescription();
125     	this.returnType = builder.getReturnType();
126     	this.typeId = builder.getTypeId();
127     	this.active = builder.isActive();
128     	this.versionNumber = builder.getVersionNumber();
129     	this.parameters = new ArrayList<FunctionParameterDefinition>();
130     	for (FunctionParameterDefinition.Builder parameter : builder.getParameters()) {
131     		this.parameters.add(parameter.build());
132     	}
133         this.categories = new ArrayList<CategoryDefinition>();
134         for (CategoryDefinition.Builder category : builder.getCategories()) {
135             this.categories.add(category.build());
136         }
137     }
138     
139 	@Override
140 	public String getId() {
141 		return id;
142 	}
143 
144 	@Override
145 	public String getNamespace() {
146 		return namespace;
147 	}
148 
149 	@Override
150 	public String getName() {
151 		return name;
152 	}
153 
154 	@Override
155 	public String getDescription() {
156 		return description;
157 	}
158 	
159 	@Override
160 	public String getReturnType() {
161 		return returnType;
162 	}
163 
164 	@Override
165 	public String getTypeId() {
166 		return typeId;
167 	}
168 
169 	@Override
170 	public boolean isActive() {
171 		return active;
172 	}
173 	
174 	@Override
175 	public Long getVersionNumber() {
176 		return versionNumber;
177 	}
178 	
179 	@Override
180 	public List<FunctionParameterDefinition> getParameters() {
181 		return Collections.unmodifiableList(parameters);
182 	}
183 
184     @Override
185     public List<CategoryDefinition> getCategories() {
186         return Collections.unmodifiableList(categories);
187     }
188 
189 	/**
190 	 * A builder which can be used to construct {@link FunctionDefinition}
191 	 * instances.  Enforces the constraints of the {@link FunctionDefinitionContract}.
192 	 * 
193 	 * @author Kuali Rice Team (rice.collab@kuali.org)
194 	 *
195 	 */
196 	public static final class Builder implements FunctionDefinitionContract, ModelBuilder, Serializable  {
197     	    	
198     	private static final long serialVersionUID = -4470376239998290245L;
199     	
200 		private String id;
201     	private String namespace;
202     	private String name;
203     	private String description;
204     	private String returnType;
205     	private String typeId;
206     	private boolean active;
207     	private Long versionNumber;
208     	private List<FunctionParameterDefinition.Builder> parameters;
209         private List<CategoryDefinition.Builder> categories;
210     	
211         private Builder(String namespace, String name, String returnType, String typeId) {
212         	setNamespace(namespace);
213         	setName(name);
214         	setReturnType(returnType);
215         	setTypeId(typeId);
216         	setActive(true);
217         	setParameters(new ArrayList<FunctionParameterDefinition.Builder>());
218             setCategories(new ArrayList<CategoryDefinition.Builder>());
219         }
220         
221         /**
222          * Creates a function definition builder with the given required values.  This builder
223          * is the only means by which a {@link FunctionDefinition} object should be created.
224          * 
225          * <p>Will default the active flag to true.
226          * 
227          * @param namespace the namespace of the function definition to create, must not be null or blank
228          * @param name the name of the function definition to create, must not be null or blank
229          * @param returnType the return type of the function definition to create, must not be null or blank
230          * @param typeId the return type id of the function definition to create, must not be null or blank
231          * 
232          * @return a builder with the required values already initialized
233          * 
234          * @throws IllegalArgumentException if any of the given arguments is null or blank
235          */
236         public static Builder create(String namespace, String name, String returnType, String typeId) {
237         	return new Builder(namespace, name, returnType, typeId);
238         }
239         
240         /**
241          * Creates and populates a builder with the data on the given {@link FunctionDefinitionContract}.
242          * This is similar in nature to a "copy constructor" for {@link FunctionDefinition}.
243          * 
244          * @param contract an object implementing the {@link FunctionDefinitionContract} from which
245          * to copy property values
246          *  
247          * @return a builder with the values from the contract already initialized
248          * 
249          * @throws IllegalArgumentException if the given contract is null
250          */
251         public static Builder create(FunctionDefinitionContract contract) {
252         	if (contract == null) {
253         		throw new IllegalArgumentException("contract was null");
254         	}
255         	Builder builder = create(contract.getNamespace(), contract.getName(), contract.getReturnType(), contract.getTypeId());
256         	builder.setId(contract.getId());
257         	builder.setDescription(contract.getDescription());
258         	builder.setActive(contract.isActive());
259         	builder.setVersionNumber(contract.getVersionNumber());
260         	for (FunctionParameterDefinitionContract parameter : contract.getParameters()) {
261         		builder.getParameters().add(FunctionParameterDefinition.Builder.create(parameter));
262         	}
263             for (CategoryDefinitionContract category : contract.getCategories()) {
264                 builder.getCategories().add(CategoryDefinition.Builder.create(category));
265             }
266         	return builder;
267         }
268 
269         @Override
270         public FunctionDefinition build() {
271         	return new FunctionDefinition(this);
272         }
273         
274         @Override
275 		public String getId() {
276 			return this.id;
277 		}
278 
279         /**
280          * Sets the id for the function definition that will be returned by this builder.
281          * 
282          * @param id the function definition id to set
283          */
284 		public void setId(String id) {
285 			this.id = id;
286 		}
287 
288 		@Override
289 		public String getNamespace() {
290 			return this.namespace;
291 		}
292 
293         /**
294          * Sets the namespace code for the function definition that will be returned by this builder.
295          * The namespace must not be null or blank.
296          * 
297          * @param namespace the namespace code to set on this builder, must not be null or blank
298          * 
299          * @throws IllegalArgumentException if the given namespace is null or blank
300          */
301 		public void setNamespace(String namespace) {
302 			if (StringUtils.isBlank(namespace)) {
303 				throw new IllegalArgumentException("namespace was blank");
304 			}
305 			this.namespace = namespace;
306 		}
307 
308 		@Override
309 		public String getName() {
310 			return this.name;
311 		}
312 
313 		/**
314          * Sets the name for the function definition that will be returned by this builder.
315          * The name must not be null or blank.
316          * 
317          * @param name the name to set on this builder, must not be null or blank
318          * 
319          * @throws IllegalArgumentException if the given name is null or blank
320          */
321 		public void setName(String name) {
322 			if (StringUtils.isBlank(name)) {
323 				throw new IllegalArgumentException("name was blank");
324 			}
325 			this.name = name;
326 		}
327 		
328 		@Override
329 		public String getDescription() {
330 			return this.description;
331 		}
332 
333         /**
334          * Sets the description for the function definition that will be returned by this builder.
335          * 
336          * @param description the description to set on this builder
337          */
338 		public void setDescription(String description) {
339 			this.description = description;
340 		}
341 
342 		@Override
343 		public String getReturnType() {
344 			return this.returnType;
345 		}
346 
347 		/**
348          * Sets the return type for the function definition that will be
349          * returned by this builder.  This can be one of a set of "built-in"
350          * data types or a custom datatype represented as a fully qualified
351          * java class name.  The returnType must not be null or blank.
352          * 
353          * @param returnType the returnType to set on this builder, must not be null or blank
354          * 
355          * @throws IllegalArgumentException if the given returnType is null or blank
356          */
357 		public void setReturnType(String returnType) {
358 			if (StringUtils.isBlank(returnType)) {
359 				throw new IllegalArgumentException("returnType was blank");
360 			}
361 			this.returnType = returnType;
362 		}
363 
364 		@Override
365 		public String getTypeId() {
366 			return this.typeId;
367 		}
368 
369 		/**
370          * Sets the id of the {@link KrmsTypeDefinition} which defines the
371          * actual implementation of this function.  The typeId must not be
372          * null or blank.
373          * 
374          * @param typeId the typeId to set on this builder, must not be null or blank
375          * 
376          * @throws IllegalArgumentException if the given typeId is null or blank
377          */
378 		public void setTypeId(String typeId) {
379 			if (StringUtils.isBlank(typeId)) {
380 				throw new IllegalArgumentException("typeId was blank");
381 			}
382 			this.typeId = typeId;
383 		}
384 
385 		@Override
386 		public boolean isActive() {
387 			return this.active;
388 		}
389 
390 		/**
391          * Sets the active flag for the function definition that will be
392          * returned by this builder.
393          * 
394          * @param active the active flag to set
395          */
396 		public void setActive(boolean active) {
397 			this.active = active;
398 		}
399 
400 		@Override
401 		public Long getVersionNumber() {
402 			return this.versionNumber;
403 		}
404 
405 		/**
406          * Sets the version number for the function definition that will be
407          * returned by this builder.
408          * 
409          * <p>In general, this value should not be manually set on the builder,
410          * but rather copied from an existing {@link FunctionDefinitionContract} when
411          * invoking {@link Builder#create(FunctionDefinitionContract)}.
412          * 
413          * @param versionNumber the version number to set
414          */
415 		public void setVersionNumber(Long versionNumber) {
416 			this.versionNumber = versionNumber;
417 		}
418 		
419 		@Override
420 		public List<FunctionParameterDefinition.Builder> getParameters() {
421 			return this.parameters;
422 		}
423 
424 		/**
425          * Sets the parameters for the function definition that will be returned by this builder.
426          * This list is a list of builders for each of the {@link FunctionParameterDefinition}
427          * instances that will form the parameters of this function definition.  The given list
428          * must not be null.
429          * 
430          * @param parameters a list of builders for the parameters which will be specified on this function definition
431          * 
432          * @throws IllegalArgumentException if the given parameters list is null 
433          */
434 		public void setParameters(List<FunctionParameterDefinition.Builder> parameters) {
435 			if (parameters == null) {
436 				throw new IllegalArgumentException("parameters was null");
437 			}
438 			this.parameters = parameters;
439 		}
440 
441         @Override
442         public List<CategoryDefinition.Builder> getCategories() {
443             return this.categories;
444         }
445 
446         /**
447          * Sets the category for the function definition that will be returned by this builder.
448          * This list is a list of builders for each of the {@link CategoryDefinition}
449          * instances that will form the categories of this function definition.  The given list
450          * must not be null.
451          *
452          * @param categories a list of builders for the categories which will be specified on this function definition
453          *
454          * @throws IllegalArgumentException if the given categories list is null
455          */
456         public void setCategories(List<CategoryDefinition.Builder> categories) {
457             if (categories == null) {
458                 throw new IllegalArgumentException("categories was null");
459             }
460             this.categories = categories;
461         }
462 
463 	}
464 	
465 	/**
466      * Defines some internal constants used on this class.
467      */
468     static class Constants {
469         final static String ROOT_ELEMENT_NAME = "function";
470         final static String TYPE_NAME = "FunctionType";
471     }
472 
473     /**
474      * A private class which exposes constants which define the XML element names to use
475      * when this object is marshalled to XML.
476      */
477     static class Elements {
478         final static String ID = "id";
479         final static String NAMESPACE = "namespace";
480         final static String NAME = "name";
481         final static String DESCRIPTION = "description";
482         final static String RETURN_TYPE = "returnType";
483         final static String TYPE_ID = "typeId";
484         final static String ACTIVE = "active";
485         final static String PARAMETERS = "parameters";
486         final static String PARAMETER = "parameter";
487         final static String CATEGORIES = "categories";
488         final static String CATEGORY = "category";
489     }
490     
491 }