001    /**
002     * Copyright 2005-2014 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.location.api.state;
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.kuali.rice.location.api.LocationConstants;
023    import org.w3c.dom.Element;
024    
025    import javax.xml.bind.annotation.XmlAccessType;
026    import javax.xml.bind.annotation.XmlAccessorType;
027    import javax.xml.bind.annotation.XmlAnyElement;
028    import javax.xml.bind.annotation.XmlElement;
029    import javax.xml.bind.annotation.XmlRootElement;
030    import javax.xml.bind.annotation.XmlType;
031    import java.io.Serializable;
032    import java.util.Collection;
033    
034    /**
035     * POJO implementation of StateContract that is immutable. Instances of State can be (un)marshalled to and from XML.
036     *
037     * @see StateContract
038     * @author Kuali Rice Team (rice.collab@kuali.org)
039     */
040    @XmlRootElement(name = State.Constants.ROOT_ELEMENT_NAME)
041    @XmlAccessorType(XmlAccessType.NONE)
042    @XmlType(name = State.Constants.TYPE_NAME, propOrder = {
043            State.Elements.CODE,
044            State.Elements.NAME,
045            State.Elements.COUNTRY_CODE,
046            State.Elements.ACTIVE,
047            CoreConstants.CommonElements.VERSION_NUMBER,
048            CoreConstants.CommonElements.FUTURE_ELEMENTS
049    })
050    public final class State extends AbstractDataTransferObject implements StateContract {
051    
052        private static final long serialVersionUID = 6097498602725305353L;
053    
054        @XmlElement(name = Elements.CODE, required = true)
055        private final String code;
056    
057        @XmlElement(name = Elements.NAME, required = true)
058        private final String name;
059    
060        @XmlElement(name = Elements.COUNTRY_CODE, required = true)
061        private final String countryCode;
062    
063        @XmlElement(name = Elements.ACTIVE, required = true)
064        private final boolean active;
065    
066        @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
067        private final Long versionNumber;
068    
069        @SuppressWarnings("unused")
070        @XmlAnyElement
071        private final Collection<Element> _futureElements = null;
072    
073        /**
074         * This constructor should never be called except during JAXB unmarshalling.
075         */
076        @SuppressWarnings("unused")
077        private State() {
078            this.code = null;
079            this.name = null;
080            this.countryCode = null;
081            this.active = false;
082            this.versionNumber = null;
083        }
084    
085        private State(Builder builder) {
086            code = builder.getCode();
087            name = builder.getName();
088            countryCode = builder.getCountryCode();
089            active = builder.isActive();
090            versionNumber = builder.getVersionNumber();
091        }
092    
093        /** {@inheritDoc} */
094        @Override
095        public String getCode() {
096            return code;
097        }
098    
099        /** {@inheritDoc} */
100        @Override
101        public String getName() {
102            return name;
103        }
104    
105        /** {@inheritDoc} */
106        @Override
107        public String getCountryCode() {
108            return countryCode;
109        }
110    
111        /** {@inheritDoc} */
112        @Override
113        public boolean isActive() {
114            return active;
115        }
116    
117        /** {@inheritDoc} */
118        @Override
119        public Long getVersionNumber() {
120            return versionNumber;
121        }
122    
123        /**
124         * This builder constructs a State enforcing the constraints of the {@link StateContract}.
125         */
126        public static class Builder implements StateContract, ModelBuilder, Serializable {
127    
128            private static final long serialVersionUID = 7077484401017765844L;
129    
130            private String code;
131    
132            private String name;
133    
134            private String countryCode;
135    
136            private boolean active;
137    
138            private Long versionNumber;
139    
140            private Builder(String code, String name, String countryCode) {
141                setCode(code);
142                setName(name);
143                setCountryCode(countryCode);
144            }
145    
146            /**
147             * creates a State with the required fields.
148             * @param code represents code for the State being built
149             * @param name represents full name for the State being built
150             * @param countryCode code for the Country this State is associated with
151             * @return a bootstrapped Builder defaulted with the passed in code, name, and countryCode.
152             */
153            public static Builder create(String code, String name, String countryCode) {
154                final Builder builder = new Builder(code, name, countryCode);
155                builder.setActive(true);
156                return builder;
157            }
158    
159            /**
160             * creates a Parameter from an existing {@link StateContract}.
161             */
162            public static Builder create(StateContract contract) {
163                final Builder builder = new Builder(contract.getCode(), contract.getName(), contract.getCountryCode());
164                builder.setActive(contract.isActive());
165                builder.setVersionNumber(contract.getVersionNumber());
166                return builder;
167            }
168    
169            @Override
170            public String getCode() {
171                return code;
172            }
173    
174            /**
175             * Sets the code to be used for the State created from this Builder.
176             * @param code String code for a State.
177             * @throws IllegalArgumentException if the passed in code is null or a blank String.
178             */
179            public void setCode(String code) {
180                if (StringUtils.isBlank(code)) {
181                    throw new IllegalArgumentException("code is blank");
182                }
183    
184                this.code = code;
185            }
186    
187            @Override
188            public String getName() {
189                return name;
190            }
191    
192            /**
193             * Sets the full name of the State created from this Builder.
194             * @param name String representing the full name for the State
195             * @throws IllegalArgumentException if the passed in name is null or a blank String.
196             */
197            public void setName(String name) {
198                if (StringUtils.isBlank(name)) {
199                    throw new IllegalArgumentException("name is blank");
200                }
201    
202                this.name = name;
203            }
204    
205            @Override
206            public String getCountryCode() {
207                return countryCode;
208            }
209    
210            /**
211             * Sets the Country code to be associated with the State created from this Builder.
212             * @param countryCode String representing the Country Code
213             * @throws IllegalArgumentException if the passed in countryCode is null or a blank String.
214             */
215            public void setCountryCode(String countryCode) {
216                if (StringUtils.isBlank(countryCode)) {
217                    throw new IllegalArgumentException("countryCode is blank");
218                }
219    
220                this.countryCode = countryCode;
221            }
222    
223            @Override
224            public boolean isActive() {
225                return active;
226            }
227    
228            public void setActive(boolean active) {
229                this.active = active;
230            }
231    
232            @Override
233            public Long getVersionNumber() {
234                return versionNumber;
235            }
236    
237            public void setVersionNumber(Long versionNumber) {
238                this.versionNumber = versionNumber;
239            }
240    
241            @Override
242            public State build() {
243                return new State(this);
244            }
245        }
246    
247        /**
248         * Defines some internal constants used on this class.
249         */
250        static class Constants {
251            final static String ROOT_ELEMENT_NAME = "state";
252            final static String TYPE_NAME = "StateType";
253        }
254    
255        /**
256         * A private class which exposes constants which define the XML element names to use
257         * when this object is marshalled to XML.
258         */
259        static class Elements {
260            final static String CODE = "code";
261            final static String NAME = "name";
262            final static String COUNTRY_CODE = "countryCode";
263            final static String ACTIVE = "active";
264        }
265    
266        public static class Cache {
267            public static final String NAME = LocationConstants.Namespaces.LOCATION_NAMESPACE_2_0 + "/" + State.Constants.TYPE_NAME;
268        }
269    }