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.coreservice.api.component;
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 an {@link ComponentContract}.
035     *
036     * Use the class {@link Component.Builder} to construct an Component object.
037     * 
038     * @see ComponentContract
039     */
040    @XmlRootElement(name = Component.Constants.ROOT_ELEMENT_NAME)
041    @XmlAccessorType(XmlAccessType.NONE)
042    @XmlType(name = Component.Constants.TYPE_NAME, propOrder = {
043        Component.Elements.NAMESPACE_CODE,
044        Component.Elements.CODE,
045        Component.Elements.NAME,
046        Component.Elements.COMPONENT_SET_ID,
047        Component.Elements.ACTIVE,
048        CoreConstants.CommonElements.VERSION_NUMBER,
049        CoreConstants.CommonElements.OBJECT_ID,
050        CoreConstants.CommonElements.FUTURE_ELEMENTS
051    })
052    public final class Component extends AbstractDataTransferObject implements ComponentContract {
053            
054            private static final long serialVersionUID = -5114772381708593543L;
055    
056            @XmlElement(name = Elements.NAMESPACE_CODE, required=true)
057            private final String namespaceCode;
058            
059        @XmlElement(name = Elements.CODE, required=true)
060        private final String code;
061    
062        @XmlElement(name = Elements.NAME, required=true)
063        private final String name;
064    
065        @XmlElement(name = Elements.COMPONENT_SET_ID, required = false)
066        private final String componentSetId;
067    
068        @XmlElement(name = Elements.ACTIVE, required=false)
069        private final boolean active;
070    
071        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
072        private final Long versionNumber;
073        
074        @XmlElement(name = CoreConstants.CommonElements.OBJECT_ID, required = false)
075            private final String objectId;
076    
077        @SuppressWarnings("unused")
078        @XmlAnyElement
079        private final Collection<Element> _futureElements = null;
080    
081        /** 
082         * This constructor should never be called.  It is only present for use during JAXB unmarshalling. 
083         */
084        private Component() {
085            this.namespaceCode = null;
086            this.code = null;
087            this.name = null;
088            this.componentSetId = null;
089            this.active = true;
090            this.versionNumber = null;
091            this.objectId = null;
092        }
093    
094            /**
095             * Constructs a Component 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 component
099             */
100        private Component(Builder builder) {
101                    namespaceCode = builder.getNamespaceCode();
102                    code = builder.getCode();
103            name = builder.getName();
104            componentSetId = builder.getComponentSetId();
105            active = builder.isActive();
106            versionNumber = builder.getVersionNumber();
107            this.objectId = builder.getObjectId();
108        }
109        
110        
111        @Override
112        public String getNamespaceCode() {
113                    return namespaceCode;
114            }
115    
116        @Override
117            public String getCode() {
118                    return code;
119            }
120    
121        @Override
122            public String getName() {
123                    return name;
124            }
125    
126        @Override
127        public String getComponentSetId() {
128            return componentSetId;
129        }
130    
131        @Override
132            public boolean isActive() {
133                    return active;
134            }
135    
136        @Override
137            public Long getVersionNumber() {
138                    return versionNumber;
139            }
140        
141        @Override
142            public String getObjectId() {
143                    return objectId;
144            }
145    
146            /**
147         * This builder is used to construct instances of Component.  It enforces the constraints of the {@link ComponentContract}.
148         */
149        public static final class Builder implements ComponentContract, ModelBuilder, Serializable {
150    
151                    private static final long serialVersionUID = 5548130104299578283L;
152    
153                    private String namespaceCode;
154                    private String code;
155            private String name;
156            private String componentSetId;
157            private boolean active;
158            private Long versionNumber;
159            private String objectId;
160    
161                    /**
162                     * Private constructor for creating a builder with all of it's required attributes.
163                     */
164            private Builder(String namespaceCode, String code, String name) {
165                            setNamespaceCode(namespaceCode);
166                setCode(code);
167                setName(name);
168                            setActive(true);
169            }
170    
171            /**
172                     * Constructs a Namespace builder given the namcespace code, component code, and name
173                     * which are all required.  Defaults the active indicator to true.
174                     *
175                     * @param namespaceCode the namespace code to use when constructing this builder
176                     * @param code the component code to use when constructing this builder
177                     * @param name the component name to use when constructing this builder
178                     * @throws IllegalArgumentException if any of the parameters are null or blank
179                     */
180            public static Builder create(String namespaceCode, String code, String name) {
181                return new Builder(namespaceCode, code, name);
182            }
183    
184            /**
185             * Creates a builder by populating it with data from the given {@link ComponentContract}.
186             * 
187             * @param contract the contract from which to populate this builder
188             * @return an instance of the builder populated with data from the contract
189             */
190            public static Builder create(ComponentContract contract) {
191                Builder builder = new Builder(contract.getNamespaceCode(), contract.getCode(), contract.getName());
192                builder.setComponentSetId(contract.getComponentSetId());
193                builder.setActive(contract.isActive());
194                builder.setVersionNumber(contract.getVersionNumber());
195                builder.setObjectId(contract.getObjectId());
196                return builder;
197            }
198    
199                    /**
200                     * Sets the value of the namespace code on this builder to the given value.
201                 *
202                 * @param namespaceCode the namespace code value to set, must not be null or blank
203                 * @throws IllegalArgumentException if the given namespace code is null or blank
204                 */
205            public void setNamespaceCode(String namespaceCode) {
206                            if (StringUtils.isBlank(namespaceCode)) {
207                               throw new IllegalArgumentException("namespaceCode is null");
208                       }
209                       this.namespaceCode = namespaceCode;
210               }
211                    
212                    /**
213                     * Sets the value of the component code on this builder to the given value.
214                     *
215                     * @param code the component code value to set, must not be null or blank
216                     * @throws IllegalArgumentException if the given component code is null or blank
217                     */
218            public void setCode(String code) {
219                if (StringUtils.isBlank(code)) {
220                    throw new IllegalArgumentException("code is blank");
221                }
222                this.code = code;
223            }
224    
225                    /**
226                     * Sets the value of the component name on this builder to the given value.
227                 *
228                 * @param name the component name value to set, must not be null or blank
229                 * @throws IllegalArgumentException if the given component name is null or blank
230                 */
231            public void setName(String name) {
232                if (StringUtils.isBlank(name)) {
233                    throw new IllegalArgumentException("name is blank");
234                }
235                this.name = name;
236            }
237    
238            @Override
239                    public boolean isActive() {
240                            return active;
241                    }
242    
243                    public void setActive(boolean active) {
244                            this.active = active;
245                    }
246    
247            @Override
248                    public String getNamespaceCode() {
249                            return namespaceCode;
250                    }
251    
252            @Override
253                    public String getCode() {
254                            return code;
255                    }
256    
257            @Override
258                    public String getName() {
259                            return name;
260                    }
261    
262            @Override
263            public String getComponentSetId() {
264                return componentSetId;
265            }
266    
267            public void setComponentSetId(String componentSetId) {
268                if (componentSetId != null && StringUtils.isBlank(componentSetId)) {
269                    throw new IllegalArgumentException("componentSetId should be either null or a non-blank value");
270                }
271                this.componentSetId = componentSetId;
272            }
273    
274            @Override
275                    public Long getVersionNumber() {
276                            return versionNumber;
277                    }
278    
279                    public void setVersionNumber(Long versionNumber) {
280                            this.versionNumber = versionNumber;
281                    }
282                    
283                    @Override
284            public String getObjectId() {
285                    return objectId;
286            }
287                    
288                    public void setObjectId(String objectId) {
289                    this.objectId = objectId;
290            }
291    
292                    /**
293                     * Builds an instance of a Component based on the current state of the builder.
294                     *
295                     * @return the fully-constructed Component
296                     */
297                    @Override
298            public Component build() {
299                return new Component(this);
300            }
301    
302        }
303            
304            /**
305             * Defines some internal constants used on this class.
306             */
307            static class Constants {
308               final static String ROOT_ELEMENT_NAME = "component";
309               final static String TYPE_NAME = "ComponentType";
310            }
311       
312            /**
313             * A private class which exposes constants which define the XML element names to use
314             * when this object is marshalled to XML.
315             */
316            static class Elements {
317                final static String CODE = "code";
318                final static String NAME = "name";
319                    final static String NAMESPACE_CODE = "namespaceCode";
320            final static String COMPONENT_SET_ID = "componentSetId";
321                    final static String ACTIVE = "active";
322            }
323    
324        public static class Cache {
325            public static final String NAME = CoreConstants.Namespaces.CORE_NAMESPACE_2_0 + "/" + Component.Constants.TYPE_NAME;
326        }
327       
328    }