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