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.location.api.state;
017
018import org.apache.commons.lang.StringUtils;
019import org.kuali.rice.core.api.CoreConstants;
020import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
021import org.kuali.rice.core.api.mo.ModelBuilder;
022import org.kuali.rice.location.api.LocationConstants;
023import org.w3c.dom.Element;
024
025import javax.xml.bind.annotation.XmlAccessType;
026import javax.xml.bind.annotation.XmlAccessorType;
027import javax.xml.bind.annotation.XmlAnyElement;
028import javax.xml.bind.annotation.XmlElement;
029import javax.xml.bind.annotation.XmlRootElement;
030import javax.xml.bind.annotation.XmlType;
031import java.io.Serializable;
032import 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})
050public 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}