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 }