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.krms.api.repository.term;
017
018 import java.io.Serializable;
019 import java.util.Collection;
020 import java.util.List;
021
022 import javax.xml.bind.annotation.XmlAccessType;
023 import javax.xml.bind.annotation.XmlAccessorType;
024 import javax.xml.bind.annotation.XmlAnyElement;
025 import javax.xml.bind.annotation.XmlElement;
026 import javax.xml.bind.annotation.XmlElementWrapper;
027 import javax.xml.bind.annotation.XmlRootElement;
028 import javax.xml.bind.annotation.XmlType;
029
030 import org.apache.commons.lang.StringUtils;
031 import org.jdom.IllegalAddException;
032 import org.kuali.rice.core.api.CoreConstants;
033 import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
034 import org.kuali.rice.core.api.mo.ModelBuilder;
035 import org.kuali.rice.krms.api.repository.BuilderUtils;
036
037 /**
038 * Immutable DTO for Terms. Construction must be done via the {@link Builder} inner class.
039 *
040 * @author Kuali Rice Team (rice.collab@kuali.org)
041 *
042 */
043 @XmlRootElement(name = TermDefinition.Constants.ROOT_ELEMENT_NAME)
044 @XmlAccessorType(XmlAccessType.NONE)
045 @XmlType(name = TermDefinition.Constants.TYPE_NAME, propOrder = {
046 TermDefinition.Elements.ID,
047 TermDefinition.Elements.SPECIFICATION,
048 TermDefinition.Elements.DESCRIPTION,
049 TermDefinition.Elements.PARAMETERS,
050 CoreConstants.CommonElements.VERSION_NUMBER,
051 CoreConstants.CommonElements.FUTURE_ELEMENTS
052 })
053 public final class TermDefinition extends AbstractDataTransferObject implements TermDefinitionContract {
054
055 private static final long serialVersionUID = 1L;
056
057 @XmlElement(name = Elements.ID, required=false)
058 private final String id;
059 @XmlElement(name = Elements.SPECIFICATION, required=true)
060 private final TermSpecificationDefinition specification;
061 @XmlElement(name = Elements.DESCRIPTION, required=false)
062 private final String description;
063 @XmlElementWrapper(name = Elements.PARAMETERS, required=false)
064 @XmlElement(name = "parameter", required=false)
065 private final List<TermParameterDefinition> parameters;
066 @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
067 private final Long versionNumber;
068
069 @SuppressWarnings("unused")
070 @XmlAnyElement
071 private final Collection<org.w3c.dom.Element> _futureElements = null;
072
073 /**
074 * This constructor is for JAXB only. Do not invoke directly.
075 */
076 private TermDefinition() {
077 id = null;
078 specification = null;
079 description = null;
080 parameters = null;
081 versionNumber = null;
082 }
083
084 private TermDefinition(Builder builder) {
085 id = builder.getId();
086 specification = builder.getSpecification().build();
087 description = builder.getDescription();
088 parameters = BuilderUtils.convertFromBuilderList(builder.getParameters());
089 versionNumber = builder.getVersionNumber();
090 }
091
092 /**
093 * {@link ModelBuilder} for {@link TermDefinition}s.
094 *
095 * @author Kuali Rice Team (rice.collab@kuali.org)
096 *
097 */
098 public static class Builder implements TermDefinitionContract, ModelBuilder, Serializable {
099
100 private static final long serialVersionUID = 1L;
101
102 private String id;
103 private String description;
104 private TermSpecificationDefinition.Builder specification;
105 private List<TermParameterDefinition.Builder> parameters;
106 private Long versionNumber;
107
108 private Builder(String id, TermSpecificationDefinition.Builder termSpecificationDefinition,
109 List<TermParameterDefinition.Builder> termParameters) {
110 setId(id);
111 setSpecification(termSpecificationDefinition);
112 setParameters(termParameters);
113 }
114
115 /**
116 * static factory for creating a {@link Builder}.
117 *
118 * @param id may be null.
119 * @param termSpecification must not be null.
120 * @param termParameters may be null.
121 */
122 public static Builder create(String id, TermSpecificationDefinition.Builder termSpecification,
123 List<TermParameterDefinition.Builder> termParameters) {
124 return new Builder(id, termSpecification, termParameters);
125 }
126
127 /**
128 * static factory for creating a {@link Builder} from a {@link TermDefinitionContract}.
129 *
130 * @param term must be non-null.
131 */
132 public static Builder create(TermDefinitionContract term) {
133 if (term == null) throw new IllegalAddException("term may not be null");
134
135 // Convert TermParameterDefinitionContract to TermParameterDefinition:
136 List<TermParameterDefinition.Builder> outParams =
137 BuilderUtils.transform(term.getParameters(), TermParameterDefinition.Builder.toBuilder);
138
139 Builder builder = create(term.getId(),
140 // doing my TermSpecificationDefinitionContract conversion inline:
141 TermSpecificationDefinition.Builder.create(term.getSpecification()),
142 // this is made immutable in the setter
143 outParams
144 );
145 builder.setDescription(term.getDescription());
146 builder.setVersionNumber(term.getVersionNumber());
147 return builder;
148 }
149
150 public void setDescription(String description) {
151 this.description = description;
152 }
153
154 // Builder setters:
155
156 /**
157 * @param id the id to set. Should be null to build {@link TermDefinition}s for creation operations.
158 * @throws IllegalArgumentException if the id is non-null and only contains whitespace
159 */
160 public void setId(String id) {
161 if (id != null && StringUtils.isBlank(id)) {
162 throw new IllegalArgumentException("id must contain non-whitespace chars");
163 }
164 this.id = id;
165 }
166
167 /**
168 * @param termSpecification the termSpecification to set
169 * @throws IllegalArgumentException if termSpecification is null
170 */
171 public void setSpecification(TermSpecificationDefinition.Builder termSpecification) {
172 if (termSpecification == null) {
173 throw new IllegalArgumentException("termSpecification must not be null");
174 }
175 this.specification = termSpecification;
176 }
177
178 /**
179 * @param parameters the termParameters to set. May be null, or empty.
180 */
181 public void setParameters(List<TermParameterDefinition.Builder> parameters) {
182 this.parameters = parameters;
183 }
184
185 /**
186 * @param versionNumber the versionNumber to set. May be null.
187 */
188 public void setVersionNumber(Long versionNumber){
189 this.versionNumber = versionNumber;
190 }
191
192 // Builder getters:
193
194 /**
195 * @return the id
196 */
197 @Override
198 public String getId() {
199 return id;
200 }
201
202 /**
203 * @return the termSpecification
204 */
205 @Override
206 public TermSpecificationDefinition.Builder getSpecification() {
207 return specification;
208 }
209
210 @Override
211 public String getDescription() {
212 return description;
213 }
214
215 /**
216 * @return the termParameters
217 */
218 @Override
219 public List<TermParameterDefinition.Builder> getParameters() {
220 return parameters;
221 }
222
223 /**
224 * @return the version number
225 */
226 @Override
227 public Long getVersionNumber() {
228 return this.versionNumber;
229 }
230
231 /**
232 * Builds the {@link TermDefinition}, or dies trying.
233 *
234 * @see org.kuali.rice.core.api.mo.ModelBuilder#build()
235 * @throws IllegalStateException if builder validation fails
236 */
237 @Override
238 public TermDefinition build() {
239 return new TermDefinition(this);
240 }
241 }
242
243 /**
244 * @return the termId. May be null if this {@link TermDefinition} hasn't been persisted.
245 */
246 @Override
247 public String getId() {
248 return this.id;
249 }
250 /**
251 * @return the specification. Will never be null.
252 */
253 @Override
254 public TermSpecificationDefinition getSpecification() {
255 return this.specification;
256 }
257
258 @Override
259 public String getDescription() {
260 return description;
261 }
262
263 /**
264 * @return the parameters. May be empty, but will never be null.
265 */
266 @Override
267 public List<TermParameterDefinition> getParameters() {
268 return this.parameters;
269 }
270
271 /**
272 * @see org.kuali.rice.core.api.mo.common.Versioned#getVersionNumber()
273 */
274 @Override
275 public Long getVersionNumber() {
276 return versionNumber;
277 }
278
279 static class Constants {
280 public static final String ROOT_ELEMENT_NAME = "termDefinition";
281 public static final String TYPE_NAME = "termDefinitionType";
282 }
283
284 static class Elements {
285 public static final String ID = "id";
286 public static final String SPECIFICATION = "specification";
287 public static final String PARAMETERS = "parameters";
288 public static final String DESCRIPTION = "description";
289 }
290
291
292 }