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.postalcode;
017
018
019import org.apache.commons.lang.StringUtils;
020import org.kuali.rice.core.api.CoreConstants;
021import org.kuali.rice.core.api.mo.AbstractDataTransferObject;
022import org.kuali.rice.core.api.mo.ModelBuilder;
023import org.kuali.rice.location.api.LocationConstants;
024import org.w3c.dom.Element;
025
026import javax.xml.bind.annotation.XmlAccessType;
027import javax.xml.bind.annotation.XmlAccessorType;
028import javax.xml.bind.annotation.XmlAnyElement;
029import javax.xml.bind.annotation.XmlElement;
030import javax.xml.bind.annotation.XmlRootElement;
031import javax.xml.bind.annotation.XmlType;
032import java.io.Serializable;
033import java.util.Collection;
034
035/**
036 * An immutable representation of a {@link PostalCodeContract}.
037 *
038 * <p>To construct an instance of a PostalCode, use the {@link PostalCode.Builder} class.
039 *
040 * @see PostalCodeContract
041 * @author Kuali Rice Team (rice.collab@kuali.org)
042 */
043@XmlRootElement(name = PostalCode.Constants.ROOT_ELEMENT_NAME)
044@XmlAccessorType(XmlAccessType.NONE)
045@XmlType(name = PostalCode.Constants.TYPE_NAME, propOrder = {
046        PostalCode.Elements.CODE,
047        PostalCode.Elements.CITY_NAME,
048        PostalCode.Elements.COUNTRY_CODE,
049        PostalCode.Elements.STATE_CODE,
050        PostalCode.Elements.ACTIVE,
051        PostalCode.Elements.COUNTY_CODE,
052        CoreConstants.CommonElements.VERSION_NUMBER,
053        CoreConstants.CommonElements.FUTURE_ELEMENTS
054})
055public final class PostalCode extends AbstractDataTransferObject implements PostalCodeContract {
056
057    private static final long serialVersionUID = 6097498602725305353L;
058
059    @XmlElement(name = Elements.CODE, required = true)
060    private final String code;
061
062    @XmlElement(name = Elements.CITY_NAME, required = false)
063    private final String cityName;
064
065    @XmlElement(name = Elements.COUNTRY_CODE, required = true)
066    private final String countryCode;
067
068    @XmlElement(name = Elements.STATE_CODE, required = false)
069    private final String stateCode;
070
071    @XmlElement(name = Elements.COUNTY_CODE, required = false)
072    private final String countyCode;
073
074    @XmlElement(name = Elements.ACTIVE, required = true)
075    private final boolean active;
076
077    @XmlElement(name = CoreConstants.CommonElements.VERSION_NUMBER, required = false)
078    private final Long versionNumber;
079
080    @SuppressWarnings("unused")
081    @XmlAnyElement
082    private final Collection<Element> _futureElements = null;
083
084    /**
085     * This constructor should never be called except during JAXB unmarshalling.
086     */
087    @SuppressWarnings("unused")
088    private PostalCode() {
089        this.code = null;
090        this.cityName = null;
091        this.countryCode = null;
092        this.stateCode = null;
093        this.countyCode = null;
094        this.active = false;
095        this.versionNumber = null;
096    }
097
098    private PostalCode(Builder builder) {
099        code = builder.getCode();
100        cityName = builder.getCityName();
101        countryCode = builder.getCountryCode();
102        stateCode = builder.getStateCode();
103        countyCode = builder.getCountyCode();
104        active = builder.isActive();
105        versionNumber = builder.getVersionNumber();
106    }
107
108    /** {@inheritDoc} */
109    @Override
110    public String getCode() {
111        return code;
112    }
113
114    /** {@inheritDoc} */
115    @Override
116    public String getCityName() {
117        return cityName;
118    }
119
120    /** {@inheritDoc} */
121    @Override
122    public String getCountryCode() {
123        return countryCode;
124    }
125
126    /** {@inheritDoc} */
127    @Override
128    public String getStateCode() {
129        return stateCode;
130    }
131
132    /** {@inheritDoc} */
133    @Override
134    public String getCountyCode() {
135        return countyCode;
136    }
137
138    /** {@inheritDoc} */
139    @Override
140    public boolean isActive() {
141        return active;
142    }
143
144    /** {@inheritDoc} */
145    @Override
146    public Long getVersionNumber() {
147        return versionNumber;
148    }
149
150    /**
151     * This builder constructs a PostalCode enforcing the constraints of the {@link PostalCodeContract}.
152     */
153    public static class Builder implements PostalCodeContract, ModelBuilder, Serializable {
154
155        private static final long serialVersionUID = 7077484401017765844L;
156
157        private String code;
158        private String cityName;
159        private String countryCode;
160        private String stateCode;
161        private String countyCode;
162        private boolean active;
163        private Long versionNumber;
164
165        private Builder(String code, String countryCode) {
166            setCode(code);
167            setCountryCode(countryCode);
168        }
169
170        /**
171         * creates a PostalCode builder with the required fields.
172         */
173        public static Builder create(String code, String countryCode) {
174            final Builder builder = new Builder(code, countryCode);
175            builder.setActive(true);
176            return builder;
177        }
178
179        /**
180         * creates a PostalCode builder from an existing {@link PostalCodeContract}.
181         */
182        public static Builder create(PostalCodeContract contract) {
183            final Builder builder = new Builder(contract.getCode(), contract.getCountryCode());
184            builder.setActive(contract.isActive());
185            builder.setVersionNumber(contract.getVersionNumber());
186            if (StringUtils.isNotBlank(contract.getCountyCode())) {
187                builder.setCountyCode(contract.getCountyCode());
188            }
189
190            if (StringUtils.isNotBlank(contract.getCityName())) {
191                builder.setCityName(contract.getCityName());
192            }
193
194            if (StringUtils.isNotBlank(contract.getStateCode())) {
195                builder.setStateCode(contract.getStateCode());
196            }
197            return builder;
198        }
199
200        @Override
201        public String getCode() {
202            return code;
203        }
204
205        /**
206         * Sets the code for the PostalCode created from this Builder.
207         *
208         * @param code String code for the PostalCode
209         * @throws IllegalArgumentException if the passed in code is null or a blank String.
210         */
211        public void setCode(String code) {
212            if (StringUtils.isBlank(code)) {
213                throw new IllegalArgumentException("code is blank");
214            }
215
216            this.code = code;
217        }
218
219        @Override
220        public String getCityName() {
221            return cityName;
222        }
223
224        /**
225         * Sets the name of the city associated with the PostalCode to be created from this Builder.
226         *
227         * @param cityName String representing the name of the City
228         * @throws IllegalArgumentException if the passed in cityname is null or a blank String.
229         */
230        public void setCityName(String cityName) {
231            if (StringUtils.isBlank(cityName)) {
232                throw new IllegalArgumentException("cityName is blank");
233            }
234
235            this.cityName = cityName;
236        }
237
238        @Override
239        public String getCountryCode() {
240            return countryCode;
241        }
242
243        /**
244         * Sets the Country code to be associated with the PostalCode created from this Builder.
245         *
246         * @param countryCode String representing the Country Code
247         * @throws IllegalArgumentException if the passed in countryCode is null or a blank String.
248         * @see org.kuali.rice.location.api.country.CountryContract
249         */
250        public void setCountryCode(String countryCode) {
251            if (StringUtils.isBlank(countryCode)) {
252                throw new IllegalArgumentException("countryCode is blank");
253            }
254
255            this.countryCode = countryCode;
256        }
257
258        @Override
259        public String getStateCode() {
260            return stateCode;
261        }
262
263        /**
264         * Sets the State code to be associated with the PostalCode created from this Builder.
265         *
266         * @param stateCode String representing the State code
267         * @throws IllegalArgumentException if the passed in stateCode is null or a blank String.
268         * @see org.kuali.rice.location.api.state.StateContract
269         */
270        public void setStateCode(String stateCode) {
271            if (StringUtils.isBlank(stateCode)) {
272                throw new IllegalArgumentException("stateCode is blank");
273            }
274
275            this.stateCode = stateCode;
276        }
277
278        @Override
279        public String getCountyCode() {
280            return countyCode;
281        }
282
283        /**
284         * Sets the County code to be associated with the PostalCode created from this Builder.
285         *
286         * @param countyCode String representing the County code
287         * @throws IllegalArgumentException if the passed in countyCode is null or a blank String.
288         * @see org.kuali.rice.location.api.county.CountyContract
289         */
290        public void setCountyCode(String countyCode) {
291            if (StringUtils.isBlank(countyCode)) {
292                throw new IllegalArgumentException("countyCode is blank");
293            }
294
295            this.countyCode = countyCode;
296        }
297
298        @Override
299        public boolean isActive() {
300            return active;
301        }
302
303        public void setActive(boolean active) {
304            this.active = active;
305        }
306
307        @Override
308        public Long getVersionNumber() {
309            return versionNumber;
310        }
311
312        public void setVersionNumber(Long versionNumber) {
313            this.versionNumber = versionNumber;
314        }
315
316        @Override
317        public PostalCode build() {
318            return new PostalCode(this);
319        }
320    }
321
322    /**
323     * Defines some internal constants used on this class.
324     */
325    static class Constants {
326        final static String ROOT_ELEMENT_NAME = "postalCode";
327        final static String TYPE_NAME = "PostalCodeType";
328    }
329
330    /**
331     * A private class which exposes constants which define the XML element names to use
332     * when this object is marshalled to XML.
333     */
334    static class Elements {
335        final static String CODE = "code";
336        final static String CITY_NAME = "cityName";
337        final static String COUNTRY_CODE = "countryCode";
338        final static String STATE_CODE = "stateCode";
339        final static String COUNTY_CODE = "countyCode";
340        final static String ACTIVE = "active";
341    }
342
343    public static class Cache {
344        public static final String NAME = LocationConstants.Namespaces.LOCATION_NAMESPACE_2_0 + "/" + PostalCode.Constants.TYPE_NAME;
345    }
346}