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.term;
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.BuilderUtils;
37  import org.kuali.rice.krms.api.repository.BuilderUtils.Transformer;
38  import org.kuali.rice.krms.api.repository.category.CategoryDefinition;
39  import org.kuali.rice.krms.api.repository.category.CategoryDefinitionContract;
40  
41  /**
42   * Immutable DTO for TermSpecifications.  Construction must be done via the {@link Builder} inner class.
43   * 
44   * @author Kuali Rice Team (rice.collab@kuali.org)
45   *
46   */
47  @XmlRootElement(name = TermSpecificationDefinition.Constants.ROOT_ELEMENT_NAME)
48  @XmlAccessorType(XmlAccessType.NONE)
49  @XmlType(name = TermSpecificationDefinition.Constants.TYPE_NAME, propOrder = {
50  		TermSpecificationDefinition.Elements.ID,
51  		TermSpecificationDefinition.Elements.NAME,
52          TermSpecificationDefinition.Elements.NAMESPACE,
53          TermSpecificationDefinition.Elements.TYPE,
54          TermSpecificationDefinition.Elements.DESCRIPTION,
55          TermSpecificationDefinition.Elements.ACTIVE,
56          CoreConstants.CommonElements.VERSION_NUMBER,
57          TermSpecificationDefinition.Elements.CATEGORIES,
58  		CoreConstants.CommonElements.FUTURE_ELEMENTS
59  })
60  public final class TermSpecificationDefinition extends AbstractDataTransferObject implements TermSpecificationDefinitionContract {
61  	
62  	private static final long serialVersionUID = 1L;
63  	
64  	@XmlElement(name = Elements.ID, required=false)
65  	private final String id;
66      @XmlElement(name = Elements.NAME, required=true)
67      private final String name;
68      @XmlElement(name = Elements.NAMESPACE, required=true)
69      private final String namespace;
70  	@XmlElement(name = Elements.TYPE, required=true)
71  	private final String type;
72      @XmlElement(name = Elements.DESCRIPTION, required=false)
73      private final String description;
74      @XmlElement(name = Elements.ACTIVE, required = false)
75      private final boolean active;
76      @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
77      private final Long versionNumber;
78  
79      @XmlElementWrapper(name = Elements.CATEGORIES, required = false)
80      @XmlElement(name = Elements.CATEGORY, required = false)
81      private final List<CategoryDefinition> categories;
82  
83  	
84  	@SuppressWarnings("unused")
85      @XmlAnyElement
86      private final Collection<org.w3c.dom.Element> _futureElements = null;
87  	
88  	/**
89  	 * For JAXB use only, shouldn't ever be invoked directly
90  	 */
91  	private TermSpecificationDefinition() {
92  		id = null;
93  		name = null;
94          namespace = null;
95  		type = null;
96          description = null;
97          active = true;
98          versionNumber = null;
99          this.categories = null;
100 	}
101 	
102 	/**
103 	 * Private constructor enforces use of Builder
104 	 * 
105 	 * @param b the builder to use
106 	 */
107 	private TermSpecificationDefinition(Builder b) {
108 		id = b.getId();
109 		name = b.getName();
110         namespace = b.getNamespace();
111 		type = b.getType();
112         description = b.getDescription();
113         active = b.isActive();
114 		versionNumber = b.getVersionNumber();
115         this.categories = constructCategories(b.getCategories());
116 	}
117 
118     private static List<CategoryDefinition> constructCategories(List<CategoryDefinition.Builder> categoryBuilders) {
119     	List<CategoryDefinition> categories = new ArrayList<CategoryDefinition>();
120     	if (categoryBuilders != null) {
121     		for (CategoryDefinition.Builder categoryBuilder : categoryBuilders) {
122     			categories.add(categoryBuilder.build());
123     		}
124     	}
125     	return categories;
126     }
127 
128 	/**
129 	 * Builder for the {@link TermSpecificationDefinition} immutable DTO.  Instantiate using static factory method(s).
130 	 * 
131 	 * @author Kuali Rice Team (rice.collab@kuali.org)
132 	 */
133 	public static class Builder implements TermSpecificationDefinitionContract, ModelBuilder, Serializable {
134 		
135 		private static final long serialVersionUID = 1L;
136 		
137 		private String termSpecificationId;
138 		private String name;
139         private String namespace;
140 		private String type;
141         private String description;
142         private boolean active;
143         private Long versionNumber;
144         private List<CategoryDefinition.Builder> categories;
145 
146 		private static final String NON_NULL_NON_EMPTY_ERROR =  " must be non-null and must contain non-whitespace chars"; 
147 
148 		/**
149 		 * {@link Transformer} to ease converting lists to Builder types
150 		 */
151 		public static final Transformer<TermSpecificationDefinitionContract, TermSpecificationDefinition.Builder>
152 		toBuilder = new BuilderUtils.Transformer<TermSpecificationDefinitionContract, TermSpecificationDefinition.Builder>() {
153 			public TermSpecificationDefinition.Builder transform(TermSpecificationDefinitionContract input) {
154 				return TermSpecificationDefinition.Builder.create(input);
155 			}
156 		};
157 		
158 		private Builder(String termSpecificationId, String name, String namespace, String type) {
159 			// weird to use setters in constructor .. oh well.
160 			setId(termSpecificationId);
161 			setNamespace(namespace);
162 			setName(name);
163 			setType(type);
164             setActive(true);
165             setCategories(new ArrayList<CategoryDefinition.Builder>());
166 		}
167 		
168 		/**
169 		 * static factory for a {@link Builder} from a complete set of field values for this object.
170 		 * 
171 		 *
172          * @param termSpecificationId the primary key field.  Must be null for service methods that
173          * create {@link org.kuali.rice.krms.api.repository.term.TermSpecificationDefinitionContract}s, and must be non-null & contain non-whitespace
174          * chars otherwise.
175          * @param name the name for the {@link org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition}.  Must be non-null;.
176          * @param namespace the namespace for the {@link org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition}.  Must be non-null & contain non-whitespace.
177          *@param type the type for the {@link org.kuali.rice.krms.api.repository.term.TermSpecificationDefinition}  @return a {@link Builder} object
178 		 * @throws IllegalArgumentException if invalid parameters are supplied.
179 		 */
180 		public static Builder create(String termSpecificationId, String name, String namespace, String type) {
181 			return new Builder(termSpecificationId, name, namespace, type);
182 		}
183 		
184 		/**
185 		 * static factory for a {@link Builder} from a {@link TermSpecificationDefinitionContract}.
186 		 * 
187 		 * @param termSpecification may not be null;
188 		 * @throws IllegalArgumentException if termSpecification is null, or violates the field invariants of the {@link Builder}.
189 		 */
190 		public static Builder create(TermSpecificationDefinitionContract termSpecification) {
191 			if (termSpecification == null) throw new IllegalArgumentException("termSpecification must be non-null");
192 			Builder builder =new Builder(termSpecification.getId(), termSpecification.getName(), termSpecification.getNamespace(),
193                     termSpecification.getType());
194             builder.setDescription(termSpecification.getDescription());
195             builder.setActive(termSpecification.isActive());
196 			builder.setVersionNumber(termSpecification.getVersionNumber());
197             for (CategoryDefinitionContract category : termSpecification.getCategories()) {
198                 builder.getCategories().add(CategoryDefinition.Builder.create(category));
199             }
200 
201 			return builder;
202 		}
203 
204         public void setDescription(String description) {
205             this.description = description;
206         }
207 
208         // Setters
209 		
210 		/**
211 		 * @param termSpecificationId the key for this {@link TermSpecificationDefinition}.  Must be null for
212 		 * service methods that create {@link TermSpecificationDefinitionContract}s, and otherwise must be non-null & contain 
213 		 * non-whitespace chars.
214 		 */
215 		public void setId(String termSpecificationId) {
216 			if (termSpecificationId != null && StringUtils.isBlank(termSpecificationId))
217 				throw new IllegalArgumentException("termSpecificationId must contain non-whitespace chars");
218 			this.termSpecificationId = termSpecificationId;
219 		}
220 		
221 		/**
222 		 * @param namespace the namespace to set.  Must be non-null and contain non-whitespace chars;
223 		 */
224 		public void setNamespace(String namespace) {
225 			if (StringUtils.isBlank(namespace)) {
226 				throw new IllegalArgumentException("namespace" + NON_NULL_NON_EMPTY_ERROR);
227 			}
228 			this.namespace = namespace;
229 		}
230 		
231 		/**
232 		 * @param name the name to set.  Must be non-null and contain non-whitespace chars;
233 		 */
234 		public void setName(String name) {
235 			if (StringUtils.isBlank(name)) {
236 				throw new IllegalArgumentException("name" + NON_NULL_NON_EMPTY_ERROR);
237 			}
238 			this.name = name;
239 		}
240 		/**
241 		 * @param type the type to set. Must be non-null and contain non-whitespace chars;
242 		 */
243 		public void setType(String type) {
244 			if (StringUtils.isBlank(type)) {
245 				throw new IllegalArgumentException("type" + NON_NULL_NON_EMPTY_ERROR);
246 			}
247 			this.type = type;
248 		}
249 		
250 		/**
251 		 * @param versionNumber the versionNumber to set.  May be null.
252 		 */
253         public void setVersionNumber(Long versionNumber){
254             this.versionNumber = versionNumber;
255         }
256 
257         public void setActive(boolean active) {
258             this.active = active;
259         }
260 
261         /**
262          * @param categories the categories to set.  May not be null but can be an empty set.
263          */
264         public void setCategories(List<CategoryDefinition.Builder> categories) {
265             if (categories == null) {
266                 throw new IllegalArgumentException("categories was null");
267             }
268             this.categories = categories;
269         }
270         
271 		// Getters
272 		
273 		/**
274 		 * @return the termSpecificationId
275 		 */
276 		@Override
277 		public String getId() {
278 			return this.termSpecificationId;
279 		}
280 
281 		/**
282 		 * @return the namespace
283 		 */
284 		@Override
285 		public String getNamespace() {
286 			return this.namespace;
287 		}
288 
289 		/**
290 		 * @return the name
291 		 */
292 		@Override
293 		public String getName() {
294 			return this.name;
295 		}
296 
297 		/**
298 		 * @return the type
299 		 */
300 		@Override
301 		public String getType() {
302 			return this.type;
303 		}
304 
305         @Override
306         public String getDescription() {
307             return this.description;
308         }
309 
310         /**
311 		 * @return the version number
312 		 */
313         @Override
314         public Long getVersionNumber() {
315             return this.versionNumber;
316         }
317 
318         @Override
319         public boolean isActive() {
320             return active;
321         }
322 
323         /**
324          * @return the categories
325          */
326         @Override
327         public List<CategoryDefinition.Builder> getCategories() {
328             return this.categories;
329         }
330 
331 
332 		/**
333 		 * Constructs a {@link TermSpecificationDefinition}
334 		 * @see org.kuali.rice.core.api.mo.ModelBuilder#build()
335 		 */
336 		@Override
337 		public TermSpecificationDefinition build() {
338 			return new TermSpecificationDefinition(this);
339 		}
340 	}
341 
342 	/**
343 	 * This value will be non-null for persisted  
344 	 * @see org.kuali.rice.krms.api.repository.term.TermSpecificationDefinitionContract#getId()
345 	 */
346 	@Override
347 	public String getId() {
348 		return id;
349 	}
350 
351 	/**
352 	 * @see org.kuali.rice.krms.api.repository.term.TermSpecificationDefinitionContract#getName()
353 	 */
354 	@Override
355 	public String getName() {
356 		return name;
357 	}
358 
359     @Override
360     public String getNamespace() {
361         return namespace;
362     }
363 
364 	/**
365 	 * @see org.kuali.rice.krms.api.repository.term.TermSpecificationDefinitionContract#getType()
366 	 */
367 	@Override
368 	public String getType() {
369 		return type;
370 	}
371 
372     @Override
373     public String getDescription() {
374         return description;
375     }
376 
377     @Override
378     public boolean isActive() {
379         return active;
380     }
381 
382     /**
383 	 * @see org.kuali.rice.core.api.mo.common.Versioned#getVersionNumber()
384 	 */
385     @Override
386     public Long getVersionNumber() {
387         return versionNumber;
388     }
389 
390     /**
391      * @see TermSpecificationDefinitionContract#getCategories()
392      */
393     @Override
394     public List<CategoryDefinition> getCategories() {
395         return Collections.unmodifiableList(categories);
396     }
397 	
398 	/**
399 	 * Defines some internal constants used on this class.
400 	 */
401 	static class Constants {
402 		final static String ROOT_ELEMENT_NAME = "termSpecification";
403 		final static String TYPE_NAME = "TermSpecificationType";
404 	}
405 	
406 	static class Elements {
407 		public static final String ID = "id";
408 		public static final String NAME = "name";
409         public final static String NAMESPACE = "namespace";
410         public static final String TYPE = "type";
411         public static final String DESCRIPTION = "description";
412         public static final String ACTIVE = "active";
413         public final static String CATEGORIES = "categories";
414         public final static String CATEGORY = "category";
415     }
416 	
417 
418 }