View Javadoc

1   /*
2    * Copyright 2011 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 1.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/ecl1.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.Collection;
20  import java.util.List;
21  
22  import javax.xml.bind.annotation.XmlAccessType;
23  import javax.xml.bind.annotation.XmlAccessorType;
24  import javax.xml.bind.annotation.XmlAnyElement;
25  import javax.xml.bind.annotation.XmlElement;
26  import javax.xml.bind.annotation.XmlElementWrapper;
27  import javax.xml.bind.annotation.XmlRootElement;
28  import javax.xml.bind.annotation.XmlType;
29  
30  import org.apache.commons.lang.StringUtils;
31  import org.apache.commons.lang.builder.EqualsBuilder;
32  import org.apache.commons.lang.builder.HashCodeBuilder;
33  import org.apache.commons.lang.builder.ToStringBuilder;
34  import org.jdom.IllegalAddException;
35  import org.kuali.rice.core.api.CoreConstants;
36  import org.kuali.rice.core.api.mo.ModelBuilder;
37  import org.kuali.rice.core.api.mo.ModelObjectComplete;
38  import org.kuali.rice.krms.api.repository.BuilderUtils;
39  
40  /**
41   * Immutable DTO for Terms.  Construction must be done via the {@link Builder} inner class.
42   * 
43   * @author Kuali Rice Team (rice.collab@kuali.org)
44   *
45   */
46  @XmlRootElement(name = TermDefinition.Constants.ROOT_ELEMENT_NAME)
47  @XmlAccessorType(XmlAccessType.NONE)
48  @XmlType(name = TermDefinition.Constants.TYPE_NAME, propOrder = {
49  		TermDefinition.Elements.ID,
50  		TermDefinition.Elements.SPECIFICATION,
51  		TermDefinition.Elements.PARAMETERS,
52          CoreConstants.CommonElements.VERSION_NUMBER,
53  		CoreConstants.CommonElements.FUTURE_ELEMENTS
54  })
55  public final class TermDefinition implements TermDefinitionContract, ModelObjectComplete {
56  	
57  	private static final long serialVersionUID = 1L;
58  	
59  	@XmlElement(name = Elements.ID, required=false)
60  	private final String id;
61  	@XmlElement(name = Elements.SPECIFICATION, required=true)
62  	private final TermSpecificationDefinition specification;
63  	@XmlElementWrapper(name = Elements.PARAMETERS, required=false)
64  	@XmlElement(name = "parameter", required=false)
65  	private final List<TermParameterDefinition> parameters;
66      @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
67      private final Long versionNumber;
68  	
69  	@SuppressWarnings("unused")
70      @XmlAnyElement
71      private final Collection<org.w3c.dom.Element> _futureElements = null;
72  	
73  	/**
74  	 * This constructor is for JAXB only.  Do not invoke directly.
75  	 */
76  	private TermDefinition() {
77  		id = null;
78  		specification = null;
79  		parameters = null;
80          versionNumber = null;
81  	}
82  	
83  	private TermDefinition(Builder builder) {
84  		id = builder.getId();
85  		specification = builder.getSpecification().build();
86  		parameters = BuilderUtils.convertFromBuilderList(builder.getParameters());
87  		versionNumber = builder.getVersionNumber();
88  	}
89  	
90  	/**
91  	 * {@link ModelBuilder} for {@link TermDefinition}s.
92  	 * 
93  	 * @author Kuali Rice Team (rice.collab@kuali.org)
94  	 *
95  	 */
96  	public static class Builder implements TermDefinitionContract, ModelBuilder, Serializable {
97  		
98  		private static final long serialVersionUID = 1L;
99  		
100 		private String id;
101 		private TermSpecificationDefinition.Builder specification;
102 		private List<TermParameterDefinition.Builder> parameters;
103         private Long versionNumber;
104 		
105 		private Builder(String id, TermSpecificationDefinition.Builder termSpecificationDefinition, 
106 				List<TermParameterDefinition.Builder> termParameters) {
107 			setId(id);
108 			setSpecification(termSpecificationDefinition);
109 			setParameters(termParameters);
110 		}
111 
112 		/**
113 		 * static factory for creating a {@link Builder}.
114 		 * 
115 		 * @param id may be null.
116 		 * @param termSpecification must not be null.
117 		 * @param termParameters may be null.
118 		 */
119 		public static Builder create(String id, TermSpecificationDefinition.Builder termSpecification, 
120 				List<TermParameterDefinition.Builder> termParameters) {
121 			return new Builder(id, termSpecification, termParameters);
122 		}
123 		
124 		/**
125 		 * static factory for creating a {@link Builder} from a {@link TermDefinitionContract}.
126 		 * 
127 		 * @param term must be non-null.
128 		 */
129 		public static Builder create(TermDefinitionContract term) {
130 			if (term == null) throw new IllegalAddException("term may not be null");
131 			
132 			// Convert TermParameterDefinitionContract to TermParameterDefinition:
133 			List<TermParameterDefinition.Builder> outParams =
134 				BuilderUtils.transform(term.getParameters(), TermParameterDefinition.Builder.toBuilder);
135 
136 			Builder builder = create(term.getId(), 
137 					// doing my TermSpecificationDefinitionContract conversion inline:
138 					TermSpecificationDefinition.Builder.create(term.getSpecification()),
139 					// this is made immutable in the setter
140 					outParams 
141 					);
142 			builder.setVersionNumber(term.getVersionNumber());
143 			return builder;
144 		}
145 		
146 		// Builder setters:
147 		
148 		/**
149 		 * @param id the id to set.  Should be null to build {@link TermDefinition}s for creation operations.
150 		 * @throws IllegalArgumentException if the id is non-null and only contains whitespace
151 		 */
152 		public void setId(String id) {
153 			if (id != null && StringUtils.isBlank(id)) {
154 				throw new IllegalArgumentException("id must contain non-whitespace chars");
155 			}
156 			this.id = id;
157 		}
158 		
159 		/**
160 		 * @param termSpecification the termSpecification to set
161 		 * @throws IllegalArgumentException if termSpecification is null
162 		 */
163 		public void setSpecification(TermSpecificationDefinition.Builder termSpecification) {
164 			if (termSpecification == null) {
165 				throw new IllegalArgumentException("termSpecification must not be null");
166 			}
167 			this.specification = termSpecification;
168 		}
169 		
170 		/**
171 		 * @param parameters the termParameters to set.  May be null, or empty.
172 		 */
173 		public void setParameters(List<TermParameterDefinition.Builder> parameters) {
174 			this.parameters = parameters;
175 		}
176 
177 		/**
178 		 * @param versionNumber the versionNumber to set.  May be null.
179 		 */
180         public void setVersionNumber(Long versionNumber){
181             this.versionNumber = versionNumber;
182         }
183         
184 		// Builder getters:
185 		
186 		/**
187 		 * @return the id
188 		 */
189 		@Override
190 		public String getId() {
191 			return id;
192 		}
193 
194 		/**
195 		 * @return the termSpecification
196 		 */
197 		@Override
198 		public TermSpecificationDefinition.Builder getSpecification() {
199 			return specification;
200 		}
201 		
202 		
203 
204 		/**
205 		 * @return the termParameters
206 		 */
207 		@Override
208 		public List<TermParameterDefinition.Builder> getParameters() {
209 			return parameters;
210 		}
211 		
212 		/**
213 		 * @return the version number
214 		 */
215         @Override
216         public Long getVersionNumber() {
217             return this.versionNumber;
218         }
219         
220 		/**
221 		 * Builds the {@link TermDefinition}, or dies trying.
222 		 * 
223 		 * @see org.kuali.rice.core.api.mo.ModelBuilder#build()
224 		 * @throws IllegalStateException if builder validation fails
225 		 */
226 		@Override
227 		public TermDefinition build() {
228 			return new TermDefinition(this);
229 		}
230 	}
231 	
232 	/**
233 	 * @return the termId.  May be null if this {@link TermDefinition} hasn't been persisted.
234 	 */
235 	@Override
236 	public String getId() {
237 		return this.id;
238 	}
239 	/**
240 	 * @return the specification.  Will never be null.
241 	 */
242 	@Override
243 	public TermSpecificationDefinition getSpecification() {
244 		return this.specification;
245 	}
246 	/**
247 	 * @return the parameters.  May be empty, but will never be null.
248 	 */
249 	@Override
250 	public List<TermParameterDefinition> getParameters() {
251 		return this.parameters;
252 	}
253 	
254 	/**
255 	 * @see org.kuali.rice.core.api.mo.common.Versioned#getVersionNumber()
256 	 */
257     @Override
258     public Long getVersionNumber() {
259         return versionNumber;
260     }
261 
262     /**
263 	 * @see java.lang.Object#hashCode()
264 	 */
265 	@Override
266 	public int hashCode() {
267 		return HashCodeBuilder.reflectionHashCode(this, Constants.HASH_CODE_EQUALS_EXCLUDE);
268 	}
269 	
270 	/**
271 	 * @see java.lang.Object#equals(java.lang.Object)
272 	 */
273 	@Override
274 	public boolean equals(Object obj) {
275 		if (obj == null) return false;
276 		return EqualsBuilder.reflectionEquals(this, obj, Constants.HASH_CODE_EQUALS_EXCLUDE);
277 	}
278 	
279 	/**
280 	 * @see java.lang.Object#toString()
281 	 */
282 	@Override
283 	public String toString() {
284 		return ToStringBuilder.reflectionToString(this);
285 	}
286 
287 	static class Constants {
288 		public static final String ROOT_ELEMENT_NAME = "termDefinition";
289 		public static final String TYPE_NAME = "termDefinitionType";
290 		final static String[] HASH_CODE_EQUALS_EXCLUDE = { CoreConstants.CommonElements.FUTURE_ELEMENTS };
291 	}
292 
293 	static class Elements {
294 		public static final String ID = "id";
295 		public static final String SPECIFICATION = "specification";
296 		public static final String PARAMETERS = "parameters";
297 	}
298 	
299 	
300 }