com.carlomicieli.jtrains.value.objects.Address.java Source code

Java tutorial

Introduction

Here is the source code for com.carlomicieli.jtrains.value.objects.Address.java

Source

/*
 * Copyright 2014 the original author or authors.
 *
 *  Licensed under the Apache License, Version 2.0 (the 'License');
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an 'AS IS' BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.carlomicieli.jtrains.value.objects;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import org.apache.commons.lang.StringUtils;

import java.util.Objects;
import java.util.function.UnaryOperator;

/**
 * An immutable object value that represents an {@code Address}.
 *
 *  <p>
 *      {@code Address} objects are <strong>immutable</strong> and therefore {@code thread-safe}.
 *  </p>
 *
 * @author Carlo Micieli
 * @since 1.0
 */
public final class Address {
    @JsonProperty("street_address")
    private final String streetAddress;
    @JsonProperty("postal_code")
    private final String postalCode;
    private final String city;
    private final String locality;
    private final String state;
    private final String country;

    private Address(Builder b) {
        this.streetAddress = b.streetAddress;
        this.postalCode = b.postalCode;
        this.city = b.city;
        this.locality = b.locality;
        this.country = b.country;
        this.state = b.state;
    }

    @JsonCreator
    private Address(@JsonProperty("street_address") String streetAddress,
            @JsonProperty("postal_code") String postalCode, @JsonProperty("city") String city,
            @JsonProperty("locality") String locality, @JsonProperty("state") String state,
            @JsonProperty("country") String country) {
        this.streetAddress = streetAddress;
        this.postalCode = postalCode;
        this.city = city;
        this.locality = locality;
        this.state = state;
        this.country = country;
    }

    /**
     * Constructs new {@code Address} object.
     *
     * <p>
     *     <pre>
     *  Address maerklin = Address.build(
     *  b -> b.streetAddress("Stuttgarter Strae 55-57")
     *              .city("Goppingen")
     *              .postalCode("D-73033")
     *              .country("Germany")
     *              .locality("A")
     *              .state("Baden-Wurttemberg")
     *          );
     *     </pre>
     * </p>
     *
     * @param op the building {@code operator}
     * @return a new {@code Address}.
     */
    public static Address build(UnaryOperator<Builder> op) {
        return op.apply(new Builder()).build();
    }

    /**
     * Checks whether the provided {@code address} is empty.
     *
     * <p>
     *  An {@code address} is empty if it doesn't contain a valid value
     *  for at least one of the following fields: {@code streetAddress},
     *  {@code postalCode}, {@code city} or {@code country}.
     * </p>
     *
     * @param address the address to be checked
     * @return {@code true} if the {@code Address} is empty, {@code false} otherwise.
     */
    public static boolean isEmpty(Address address) {
        if (address == null)
            return true;

        return StringUtils.isBlank(address.streetAddress) || StringUtils.isBlank(address.postalCode)
                || StringUtils.isBlank(address.city) || StringUtils.isBlank(address.country);
    }

    public static class Builder {
        private String streetAddress;
        private String postalCode;
        private String city;
        private String locality;
        private String country;
        private String state;

        private Builder() {
        }

        public Builder city(String city) {
            this.city = city;
            return this;
        }

        public Builder country(String country) {
            this.country = country;
            return this;
        }

        public Builder locality(String locality) {
            this.locality = locality;
            return this;
        }

        public Builder postalCode(String code) {
            this.postalCode = code;
            return this;
        }

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

        public Builder streetAddress(String street) {
            this.streetAddress = street;
            return this;
        }

        private Address build() {
            return new Address(this);
        }
    }

    /**
     * Returns the street name.
     * @return the street name
     */
    public String getStreetAddress() {
        return streetAddress;
    }

    /**
     * Returns the postal code.
     * @return the postal code
     */
    public String getPostalCode() {
        return postalCode;
    }

    /**
    * Returns the city/town.
    * @return the city
    */
    public String getCity() {
        return city;
    }

    /**
     * Returns the locality (apartment number, building).
     * @return the locality
     */
    public String getLocality() {
        return locality;
    }

    /**
     * Returns the country name.
     * @return the country
     */
    public String getCountry() {
        return country;
    }

    /**
     * Returns the state.
     * @return the state
     */
    public String getState() {
        return state;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this)
            return true;
        if (!(obj instanceof Address))
            return false;

        Address that = (Address) obj;
        return Objects.equals(this.city, that.city) && Objects.equals(this.country, that.country)
                && Objects.equals(this.locality, that.locality) && Objects.equals(this.postalCode, that.postalCode)
                && Objects.equals(this.state, that.state) && Objects.equals(this.streetAddress, that.streetAddress);
    }

    @Override
    public int hashCode() {
        return Objects.hash(city, country, locality, postalCode, state, streetAddress);
    }

    @Override
    public String toString() {
        return com.google.common.base.Objects.toStringHelper(Address.class).omitNullValues()
                .add("locality", locality).add("streetAddress", streetAddress).add("postalCode", postalCode)
                .add("city", city).add("state", state).add("country", country).toString();
    }
}