Address.java

package com.tradecloud.domain.party.base;

import com.tradecloud.common.base.PersistenceBase;
import com.tradecloud.domain.place.City;
import com.tradecloud.domain.place.Country;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.ManyToOne;
import javax.xml.bind.annotation.*;

/**
 * New Address entity. Use this instead of NameAddress.
 */
@Entity
@XmlAccessorType(XmlAccessType.FIELD)
@XmlRootElement(name = "Address")
public class Address extends PersistenceBase implements Comparable<Address> {

    /*
     * Required
     */
    @XmlAttribute
    protected String addressLine1;

    @ManyToOne
    @XmlElement(name = "City")
    protected City city;

    @ManyToOne
    @XmlElement(name = "Country")
    protected Country country;

    /*
     * Optional
     */
    @XmlAttribute
    protected String addressLine2;

    @XmlAttribute
    protected String addressLine3;

    @XmlAttribute
    protected String postCode;

    @XmlAttribute
    protected String state;

    @Enumerated(value = EnumType.STRING)
    protected AddressType addressType;

    public static AddressBuilder createBuilder() {
        return new AddressBuilder();
    }

    /**
     * Constructor taking all fields.
     *
     * @param addressLine1
     * @param city
     * @param country
     * @param addressLine2
     * @param addressLine3
     * @param postCode
     * @param state
     */
    public Address(String addressLine1, String addressLine2, String addressLine3, String postCode, City city, String state, Country country) {
        super();
        this.addressLine1 = addressLine1;
        this.city = city;
        this.country = country;
        this.addressLine2 = addressLine2;
        this.addressLine3 = addressLine3;
        this.postCode = postCode;
        this.state = state;
    }

    /**
     * Constructor.
     */
    public Address() {
    }

    public Address(Address address) {
        super();
        this.addressLine1 = address.getAddressLine1();
        this.city = address.getCity();
        this.country = address.getCountry();
        this.addressLine2 = address.getAddressLine2();
        this.addressLine3 = address.getAddressLine3();
        this.postCode = address.getPostCode();
        this.state = address.getState();
    }

    /**
     * UID.
     */
    private static final long serialVersionUID = 1L;

    public String getAddressLine1() {
        return addressLine1;
    }

    public void setAddressLine1(String addressLine1) {
        this.addressLine1 = addressLine1;
    }

    public City getCity() {
        return city;
    }

    public void setCity(City city) {
        this.city = city;
    }

    public Country getCountry() {
        return country;
    }

    public void setCountry(Country country) {
        this.country = country;
    }

    public String getAddressLine2() {
        return addressLine2;
    }

    public void setAddressLine2(String addressLine2) {
        this.addressLine2 = addressLine2;
    }

    public String getAddressLine3() {
        return addressLine3;
    }

    public void setAddressLine3(String addressLine3) {
        this.addressLine3 = addressLine3;
    }

    public String getPostCode() {
        return postCode;
    }

    public void setPostCode(String postCode) {
        this.postCode = postCode;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(addressLine1).append(addressLine2).append(addressLine3).append(city).append(country).append(postCode)
                .append(state).toHashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        Address other = (Address) obj;
        return new EqualsBuilder().append(addressLine1, other.addressLine1).append(addressLine2, other.addressLine2)
                .append(addressLine3, other.addressLine3).append(city, other.city).append(country, other.country).append(postCode, other.postCode)
                .append(state, other.state).isEquals();
    }

    @Override
    public int compareTo(Address other) {
        if (getAddressLine1().compareToIgnoreCase(other.getAddressLine1()) != 0) {
            return getAddressLine1().compareToIgnoreCase(getAddressLine1());
        }
        if (getCity().compareTo(other.getCity()) != 0) {
            return getCity().compareTo(getCity());
        }
        if (getCountry().compareTo(other.getCountry()) != 0) {
            return getCountry().compareTo(other.getCountry());
        }
        if (getAddressLine2().compareToIgnoreCase(other.getAddressLine2()) != 0) {
            return getAddressLine2().compareToIgnoreCase(getAddressLine2());
        }
        if (getAddressLine3().compareToIgnoreCase(other.getAddressLine3()) != 0) {
            return getAddressLine3().compareToIgnoreCase(getAddressLine3());
        }
        if (getPostCode().compareToIgnoreCase(other.getPostCode()) != 0) {
            return getPostCode().compareToIgnoreCase(getPostCode());
        }
        if (getState().compareToIgnoreCase(other.getState()) != 0) {
            return getState().compareToIgnoreCase(getState());
        }
        // All fields are equal
        return 0;
    }

    @XmlTransient
    public static class AddressBuilder {

        protected String addressLine1;
        protected String addressLine2;
        protected String addressLine3;
        protected String postCode;
        protected String state;
        protected City city;
        protected Country country;

        /**
         * Private constructor to prevent instantiation.
         */
        private AddressBuilder() {
        }

        public Address build() {
            validate();
            return new Address(addressLine1, addressLine2, addressLine3, postCode, city, state, country);
        }

        /**
         * Put validation logic here.
         */
        private void validate() {
            // TODO Auto-generated method stub

        }

        public AddressBuilder setAddressLine1(String addressLine1) {
            this.addressLine1 = addressLine1;
            return this;
        }

        public AddressBuilder setAddressLine2(String addressLine2) {
            this.addressLine2 = addressLine2;
            return this;
        }

        public AddressBuilder setAddressLine3(String addressLine3) {
            this.addressLine3 = addressLine3;
            return this;
        }

        public AddressBuilder setPostCode(String postCode) {
            this.postCode = postCode;
            return this;
        }

        public AddressBuilder setState(String state) {
            this.state = state;
            return this;
        }

        public AddressBuilder setCity(City city) {
            this.city = city;
            return this;
        }

        public AddressBuilder setCountry(Country country) {
            this.country = country;
            return this;
        }
    }

    public AddressType getAddressType() {
        return addressType;
    }

    public void setAddressType(AddressType addressType) {
        this.addressType = addressType;
    }

    @Override
    public String toString() {
        return "Address [addressLine1=" + addressLine1 + ", city=" + city + ", country=" + country + ", addressLine2=" + addressLine2
                + ", addressLine3=" + addressLine3 + ", postCode=" + postCode + ", state=" + state + "]";
    }

    /**
     * Pretty print the address so that it prints as you'd read it on a single line. Used to simplify the UI
     *
     * @return Returns the address on a single line
     */
    public String prettyPrint() {
        String separator = ", ";
        return prettyPrint(separator);
    }

    public String prettyPrint(String separator) {
        StringBuilder builder = new StringBuilder();
        appendIfNotNull(addressLine1, builder, separator);
        appendIfNotNull(addressLine2, builder, separator);
        appendIfNotNull(addressLine3, builder, separator);
        if (city != null) {
            appendIfNotNull(city.getName(), builder, separator);
        }
        appendIfNotNull(state, builder, separator);
        appendIfNotNull(postCode, builder, separator);
        if (country != null) {
            appendIfNotNull(country.getName(), builder, separator);
        }
        return builder.toString();
    }

    private void appendIfNotNull(String stringToAdd, StringBuilder builder, String separator) {
        if (stringToAdd != null) {
            if (builder.length() > 0) {
                builder.append(separator);
            }
            builder.append(stringToAdd);
        }
    }

    /**
     * Checks if any of the values are populated.
     *
     * @return boolean true if any of the values are populated, false otherwise
     */
    public boolean isPopulated() {
        if (addressLine1 == null && addressLine2 == null && addressLine3 == null && city == null && state == null && postCode == null
                && country == null) {
            return false;
        }
        return true;
    }
}