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.category;
017    
018    import org.apache.commons.lang.StringUtils;
019    import org.kuali.rice.core.api.CoreConstants;
020    import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
021    import org.kuali.rice.core.api.mo.ModelBuilder;
022    import org.w3c.dom.Element;
023    
024    import javax.xml.bind.annotation.XmlAccessType;
025    import javax.xml.bind.annotation.XmlAccessorType;
026    import javax.xml.bind.annotation.XmlAnyElement;
027    import javax.xml.bind.annotation.XmlElement;
028    import javax.xml.bind.annotation.XmlRootElement;
029    import javax.xml.bind.annotation.XmlType;
030    import java.io.Serializable;
031    import java.util.Collection;
032    
033    /**
034     * An immutable representation of a category definition.
035     *
036     * @author Kuali Rice Team (rice.collab@kuali.org)
037     *
038     */
039    
040    @XmlRootElement(name = CategoryDefinition.Constants.ROOT_ELEMENT_NAME)
041    @XmlAccessorType(XmlAccessType.NONE)
042    @XmlType(name = CategoryDefinition.Constants.TYPE_NAME, propOrder = {
043                    CategoryDefinition.Elements.ID,
044                    CategoryDefinition.Elements.NAME,
045                    CategoryDefinition.Elements.NAMESPACE,
046            CoreConstants.CommonElements.VERSION_NUMBER,
047                    CoreConstants.CommonElements.FUTURE_ELEMENTS
048    })
049    public class CategoryDefinition extends AbstractDataTransferObject implements CategoryDefinitionContract {
050    
051        private static final long serialVersionUID = -4748818967880857017L;
052    
053        @XmlElement(name = Elements.ID, required=true)
054        private final String id;
055        @XmlElement(name = Elements.NAME, required=true)
056        private final String name;
057        @XmlElement(name = Elements.NAMESPACE, required=true)
058        private final String namespace;
059        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
060        private final Long versionNumber;
061    
062        @SuppressWarnings("unused")
063        @XmlAnyElement
064        private final Collection<Element> _futureElements = null;
065    
066        /**
067        * This constructor should never be called.  It is only present for use during JAXB unmarshalling.
068        */
069       private CategoryDefinition() {
070           this.id = null;
071           this.name = null;
072           this.namespace = null;
073           this.versionNumber = null;
074       }
075    
076        /**
077             * Constructs a CategoryDefinition from the given builder.  This constructor is private and should only
078             * ever be invoked from the builder.
079             *
080             * @param builder the Builder from which to construct the CategoryDefinition
081             */
082        private CategoryDefinition(Builder builder) {
083            this.id = builder.getId();
084            this.name = builder.getName();
085            this.namespace = builder.getNamespace();
086            this.versionNumber = builder.getVersionNumber();
087        }
088    
089        @Override
090            public String getId() {
091                    return this.id;
092            }
093    
094        @Override
095            public String getName() {
096                    return this.name;
097            }
098    
099        @Override
100            public String getNamespace() {
101                    return this.namespace;
102            }
103    
104        @Override
105        public Long getVersionNumber() {
106            return versionNumber;
107        }
108    
109        /**
110         * This builder is used to construct instances of CategoryDefinition.  It enforces the constraints of the {@link org.kuali.rice.krms.api.repository.category.CategoryDefinitionContract}.
111         */
112        public static class Builder implements CategoryDefinitionContract, ModelBuilder, Serializable {
113    
114            private static final long serialVersionUID = -5775478956373560840L;
115    
116            private String id;
117            private String name;
118            private String namespace;
119            private Long versionNumber;
120    
121            /**
122             * Private constructor for creating a builder with all of it's required attributes.
123             *
124             * @param id the CategoryDefinition id
125             * @param name the CategoryDefinition name
126             * @param namespace the CategoryDefinition namespace
127             */
128            private Builder(String id, String name, String namespace) {
129                setId(id);
130                setName(name);
131                setNamespace(namespace);
132            }
133    
134            /**
135             * Creates a builder from the given parameters.
136             *
137             * @param id the CategoryDefinition id
138             * @param name the CategoryDefinition name
139             * @param namespace the CategoryDefinition namespace
140             * @return an instance of the builder with the fields already populated
141             * @throws IllegalArgumentException if the either the id, name or namespace is null or blank
142             */
143            public static Builder create(String id, String name, String namespace) {
144                return new Builder(id, name, namespace);
145            }
146    
147            /**
148             * Creates a builder by populating it with data from the given {@link CategoryDefinition}.
149             *
150             * @param category the category from which to populate this builder
151             * @return an instance of the builder populated with data from the contract
152             */
153            public static Builder create(CategoryDefinitionContract category) {
154                if (category == null) {
155                    throw new IllegalArgumentException("contract is null");
156                }
157                Builder builder =  new Builder(category.getId(), category.getName(), category.getNamespace());
158                builder.setVersionNumber(category.getVersionNumber());
159                return builder;
160            }
161    
162            /**
163             * Sets the value of the id on this builder to the given value.
164             *
165             * @param id the id value to set, must be null or non-blank
166             * @throws IllegalArgumentException if the id is non-null and blank
167             */
168            public void setId(String id) {
169                if (null != id && StringUtils.isBlank(id)) {
170                    throw new IllegalArgumentException("id must be null or non-blank");
171                }
172                this.id = id;
173            }
174    
175            /**
176             * Sets the name for the category definition that will be returned by this builder.
177             * The name must not be null or blank.
178             *
179             * @param name the name to set on this builder, must not be null or blank
180             *
181             * @throws IllegalArgumentException if the given name is null or blank
182             */
183            public void setName(String name) {
184                if (StringUtils.isBlank(name)) {
185                    throw new IllegalArgumentException("name is blank");
186                }
187                this.name = name;
188            }
189    
190            /**
191             * Sets the namespace code for the category definition that will be returned by this builder.
192             * The namespace must not be null or blank.
193             *
194             * @param namespace the namespace code to set on this builder, must not be null or blank
195             *
196             * @throws IllegalArgumentException if the given namespace is null or blank
197             */
198            public void setNamespace(String namespace) {
199                if (StringUtils.isBlank(namespace)) {
200                    throw new IllegalArgumentException("namespace is blank");
201                }
202                this.namespace = namespace;
203            }
204    
205            /**
206             * Sets the version number on this builder to the given value.
207             *
208             * @param versionNumber the version number to set
209             */
210            public void setVersionNumber(Long versionNumber){
211                this.versionNumber = versionNumber;
212            }
213    
214            @Override
215            public String getId() {
216                return this.id;
217            }
218    
219            @Override
220            public String getName() {
221                return this.name;
222            }
223    
224            @Override
225            public String getNamespace() {
226                return this.namespace;
227            }
228    
229            @Override
230            public Long getVersionNumber() {
231                return this.versionNumber;
232            }
233    
234            /**
235             * Builds an instance of a CategoryDefinition based on the current state of the builder.
236             *
237             * @return the fully-constructed CampusType
238             */
239            @Override
240            public CategoryDefinition build() {
241                return new CategoryDefinition(this);
242            }
243    
244        }
245    
246        /**
247         * Defines some internal constants used on this class.
248         */
249        static class Constants {
250            final static String ROOT_ELEMENT_NAME = "category";
251            final static String TYPE_NAME = "CategoryType";
252        }
253    
254        /**
255         * A private class which exposes constants which define the XML element names to use
256         * when this object is marshalled to XML.
257         */
258        public static class Elements {
259            final static String ID = "id";
260            final static String NAME = "name";
261            final static String NAMESPACE = "namespace";
262        }
263    }
264    
265