001/**
002 * Copyright 2005-2016 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 */
016package org.kuali.rice.krms.api.repository.type;
017
018import java.io.Serializable;
019import java.util.Collection;
020
021import javax.xml.bind.annotation.XmlAccessType;
022import javax.xml.bind.annotation.XmlAccessorType;
023import javax.xml.bind.annotation.XmlAnyElement;
024import javax.xml.bind.annotation.XmlElement;
025import javax.xml.bind.annotation.XmlRootElement;
026import javax.xml.bind.annotation.XmlType;
027
028import org.apache.commons.lang.StringUtils;
029import org.kuali.rice.core.api.CoreConstants;
030import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
031import org.kuali.rice.core.api.mo.ModelBuilder;
032import org.kuali.rice.krms.api.KrmsConstants;
033
034/**
035 * Concrete model object implementation of KRMS KrmsAttributeDefinition. 
036 * <p>immutable. To construct an instance of a KrmsTypeAttribute, use the {@link KrmsTypeAttribute.Builder} class.
037 * Instances of KrmsAttributeDefinition can be (un)marshalled to and from XML. </p>
038 *
039 * @see KrmsAttributeDefinitionContract
040 *
041 * @author Kuali Rice Team (rice.collab@kuali.org)
042 */
043@XmlRootElement(name = KrmsAttributeDefinition.Constants.ROOT_ELEMENT_NAME)
044@XmlAccessorType(XmlAccessType.NONE)
045@XmlType(name = KrmsAttributeDefinition.Constants.TYPE_NAME, propOrder = {
046                KrmsAttributeDefinition.Elements.ID,
047                KrmsAttributeDefinition.Elements.NAME,
048                KrmsAttributeDefinition.Elements.NAMESPACE,
049        KrmsAttributeDefinition.Elements.LABEL,
050        KrmsAttributeDefinition.Elements.DESCRIPTION,
051                KrmsAttributeDefinition.Elements.ACTIVE,
052                KrmsAttributeDefinition.Elements.COMPONENT_NAME,
053        CoreConstants.CommonElements.VERSION_NUMBER,
054                CoreConstants.CommonElements.FUTURE_ELEMENTS
055})
056public final class KrmsAttributeDefinition extends AbstractDataTransferObject implements KrmsAttributeDefinitionContract {
057        private static final long serialVersionUID = -6356968810972165031L;
058        
059        @XmlElement(name = Elements.ID, required=true)
060        private final String id;
061        @XmlElement(name = Elements.NAME, required=true)
062        private final String name;
063        @XmlElement(name = Elements.NAMESPACE, required=true)
064        private final String namespace;
065    @XmlElement(name = Elements.LABEL, required=false)
066    private final String label;
067    @XmlElement(name = Elements.DESCRIPTION, required=false)
068    private final String description;
069        @XmlElement(name = Elements.ACTIVE, required=false)
070        private final boolean active;
071        @XmlElement(name = Elements.COMPONENT_NAME, required=false)
072        private final String componentName;
073    @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
074    private final Long versionNumber;
075        
076        @SuppressWarnings("unused")
077    @XmlAnyElement
078    private final Collection<org.w3c.dom.Element> _futureElements = null;
079        
080         /** 
081     * This constructor should never be called.  It is only present for use during JAXB unmarshalling. 
082     */
083    private KrmsAttributeDefinition() {
084        this.id = null;
085        this.name = null;
086        this.namespace = null;
087        this.label = null;
088        this.description = null;
089        this.active = true;       // default to true
090        this.componentName = null;
091        this.versionNumber = null;
092    }
093    
094    /**
095         * Constructs a KrmsAttributeDefinition from the given builder.  This constructor is private and should only
096         * ever be invoked from the builder.
097         * 
098         * @param builder the Builder from which to construct the KrmsAttributeDefinition
099         */
100    private KrmsAttributeDefinition(Builder builder) {
101        this.id = builder.getId();
102        this.name = builder.getName();
103        this.namespace = builder.getNamespace();
104        this.label = builder.getLabel();
105        this.description = builder.getDescription();
106        this.active = builder.isActive();
107        this.componentName = builder.getComponentName();
108        this.versionNumber = builder.getVersionNumber();
109    }
110    
111    @Override
112        public String getId() {
113                return this.id;
114        }
115        
116    @Override
117        public String getName() {
118                return this.name;
119        }
120
121    @Override
122        public String getNamespace() {
123                return this.namespace;
124        }
125
126    @Override
127        public String getLabel() {
128                return this.label;
129        }
130
131    @Override
132    public String getDescription() {
133        return description;
134    }
135
136    @Override
137    public boolean isActive() {
138                return this.active; 
139        }
140
141    @Override
142        public String getComponentName() {
143                return this.componentName;
144        }
145        
146    @Override
147    public Long getVersionNumber() {
148        return versionNumber;
149    }
150        
151        /**
152     * This builder is used to construct instances of KrmsAttributeDefinition.  It enforces the constraints of the {@link KrmsAttributeDefinitionContract}.
153     */
154    public static class Builder implements KrmsAttributeDefinitionContract, ModelBuilder, Serializable {                
155                private static final long serialVersionUID = -2110564370088779631L;
156                
157                private String id;
158        private String name;
159        private String namespace;
160        private String label;
161        private String description;
162        private boolean active;
163        private String componentName;
164        private Long versionNumber;
165
166                /**
167                 * Private constructor for creating a builder with all of it's required attributes.
168                 */
169        private Builder(String id, String name, String namespace) {
170            setId(id);
171            setName(name);
172            setNamespace(namespace);
173                        setActive(true);
174        }
175
176        /**
177         * fluent interface that sets the label of the KrmsAttributeDefinition.
178         *
179         * @param label the label used when the attribute is displayed; may be null or blank
180         * @return a Builder object with the label attribute set
181         */
182        public Builder label(String label){
183                setLabel(label);
184                return this;
185        }
186
187        /**
188         * fluent interface that sets the componentName of the KrmsAttributeDefinition.
189         * @param componentName the name of the component used to display the attribute;
190         * can be null or blank
191         * @return a Builder object with the componentName set
192         */
193        public Builder componentName(String componentName){
194                setComponentName(componentName);
195                return this;
196        }
197        /**
198         * Creates a builder from the given parameters.
199         * 
200         * @param id the KrmsAttributeDefinition id
201         * @param name the KrmsAttributeDefinition name
202         * @param namespace the KrmsAttributeDefinition namespace
203         * @return an instance of the builder with the fields already populated
204         * @throws IllegalArgumentException if either the id, name or namespace is null or blank
205         */
206        public static Builder create(String id, String name, String namespace) {
207            return new Builder(id, name, namespace);
208        }
209
210        /**
211         * Creates a builder by populating it with data from the given {@link KrmsAttributeDefinitionContract}.
212         * 
213         * @param contract the contract from which to populate this builder
214         * @return an instance of the builder populated with data from the contract
215         * @throws IllegalArgumentException if the contract is null or blank
216         */
217        public static Builder create(KrmsAttributeDefinitionContract contract) {
218                if (contract == null) {
219                throw new IllegalArgumentException("contract is null");
220            }
221            Builder builder =  new Builder(contract.getId(), contract.getName(), contract.getNamespace());
222            builder.setActive(contract.isActive());
223            builder.setLabel(contract.getLabel());
224            builder.setDescription(contract.getDescription());
225            builder.setComponentName(contract.getComponentName());
226            builder.setVersionNumber(contract.getVersionNumber());
227            return builder;
228        }
229
230                /**
231                 * Sets the value of the id on this builder to the given value.
232                 * 
233                 * @param id the id value to set, must be null or non-blank
234                 * @throws IllegalArgumentException if the id is non-null and blank
235                 */
236        public void setId(String id) {
237            if (null != id && StringUtils.isBlank(id)) {
238                throw new IllegalArgumentException("id must be null or non-blank");
239            }
240            this.id = id;
241        }
242
243        /**
244         * sets the name of the attribute. must not be null or blank.
245         * @param name the name of the attribute;
246         * @throws IllegalArgumentException if the name is non-null and blank
247         */
248                public void setName(String name) {
249            if (StringUtils.isBlank(name)) {
250                throw new IllegalArgumentException("name is blank");
251            }
252                        this.name = name;
253                }
254
255        /**
256         * sets the namespace of the attribute. must not be null or blank.
257         * @param namespace the namespace of the attribute;
258         * @throws IllegalArgumentException if the namespace is non-null and blank
259         */
260                public void setNamespace(String namespace) {
261            if (StringUtils.isBlank(namespace)) {
262                throw new IllegalArgumentException("namespace is blank");
263            }
264                        this.namespace = namespace;
265                }
266
267        /**
268         * sets the label to be displayed with the attribute.
269         * @param label string to display as label; May be null or empty
270         */
271                public void setLabel(String label) {
272                        this.label = label;
273                }
274
275        /**
276         * sets the description of the attribute
277         * @param description string; Optional, may be null or empty
278         */
279        public void setDescription(String description) {
280            this.description = description;
281        }
282
283        /**
284         * sets the name of the component used to display the attribute
285         * @param componentName; May be null or empty
286         */
287                public void setComponentName(String componentName) {
288                        this.componentName = componentName;
289                }
290                
291        /**
292         * sets the active indicator value
293         * @param active boolean value to set
294         */
295                public void setActive(boolean active) {
296                        this.active = active;
297                }
298
299        /**
300         * Sets the version number for this object.  In general, this value should only
301         * be null if the object has not yet been stored to a persistent data store.
302         * This version number is generally used for the purposes of optimistic locking.
303         * @param versionNumber the version number, or null if one has not been assigned yet.
304         */
305        public void setVersionNumber(Long versionNumber){
306            this.versionNumber = versionNumber;
307        }
308        
309                @Override
310                public String getId() {
311                        return id;
312                }
313
314                @Override
315                public String getName() {
316                        return name;
317                }
318
319                @Override
320                public String getNamespace() {
321                        return namespace;
322                }
323
324                @Override
325                public String getComponentName() {
326                        return componentName;
327                }
328
329                @Override
330                public String getLabel() {
331                        return label;
332                }
333
334        @Override
335        public String getDescription() {
336            return description;
337        }
338
339        @Override
340                public boolean isActive() {
341                        return active;
342                }
343
344        @Override
345        public Long getVersionNumber() {
346            return versionNumber;
347        }
348
349                /**
350                 * Builds an instance of a CampusType based on the current state of the builder.
351                 * 
352                 * @return the fully-constructed CampusType
353                 */
354        @Override
355        public KrmsAttributeDefinition build() {
356            return new KrmsAttributeDefinition(this);
357        }
358                
359    }
360
361        /**
362         * Defines some internal constants used on this class.
363         */
364        static class Constants {
365                final static String ROOT_ELEMENT_NAME = "KrmsAttributeDefinition";
366                final static String TYPE_NAME = "KrmsAttributionDefinitionType";
367        }
368        
369        /**
370         * A private class which exposes constants which define the XML element names to use
371         * when this object is marshalled to XML.
372         */
373        public static class Elements {
374                final static String ID = "id";
375                final static String NAME = "name";
376                final static String NAMESPACE = "namespace";
377                final static String LABEL = "label";
378        final static String DESCRIPTION = "description";
379                final static String COMPONENT_NAME = "componentName";
380                final static String ACTIVE = "active";
381    }
382
383    public static class Cache {
384        public static final String NAME = KrmsConstants.Namespaces.KRMS_NAMESPACE_2_0 + "/" + KrmsAttributeDefinition.Constants.TYPE_NAME;
385    }
386}