001 /** 002 * Copyright 2005-2012 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 }