com.carlomicieli.jtrains.core.models.Railway.java Source code

Java tutorial

Introduction

Here is the source code for com.carlomicieli.jtrains.core.models.Railway.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.core.models;

import com.carlomicieli.jtrains.infrastructure.mapping.EntityLink;
import com.carlomicieli.jtrains.util.Fun;
import com.carlomicieli.jtrains.util.Slug;
import com.carlomicieli.jtrains.validation.constraints.ContainsDefault;
import com.carlomicieli.jtrains.validation.constraints.ISOCountry;
import com.carlomicieli.jtrains.value.objects.LocalizedField;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.bson.types.ObjectId;
import org.hibernate.validator.constraints.NotBlank;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Locale;
import java.util.Objects;
import java.util.Optional;
import java.util.function.UnaryOperator;

/**
 * It represents a operator of the rail transport.
 *
 * @author Carlo Micieli
 * @since 1.0
 */
public final class Railway {
    private final ObjectId _id;

    @NotBlank(message = "railway.name.required")
    @Size(min = 2, max = 10, message = "railway.name.size.notmet")
    private final String name;

    @NotBlank(message = "railway.slug.required")
    private final String slug;

    @Size(max = 100, message = "railway.companyName.size.notmet")
    private final String companyName;

    @NotNull(message = "railway.description.required")
    @ContainsDefault(message = "railway.description.default.required")
    private final LocalizedField<String> description;

    @NotBlank(message = "railway.country.required")
    @ISOCountry(message = "railway.country.code.invalid")
    private final String country;

    //@Past(message = "railway.operatingSince.past.notmet")
    private final LocalDate operatingSince;
    //@Past(message = "railway.operatingUntil.past.notmet")
    private final LocalDate operatingUntil;

    private final LocalDateTime lastModified;

    protected Railway(ObjectId id, String name, String slug, String companyName, LocalizedField<String> description,
            String country, LocalDate operatingSince, LocalDate operatingUntil, LocalDateTime lastModified) {
        this._id = id;
        this.name = name;
        this.slug = slug;
        this.companyName = companyName;
        this.description = description;
        this.country = country;
        this.operatingSince = operatingSince;
        this.operatingUntil = operatingUntil;
        this.lastModified = lastModified;
    }

    private Railway(Builder b) {
        this._id = b.id;
        this.name = b.name;
        this.slug = Slug.orElseGet(b.slug, () -> Slug.of(b.name));
        this.companyName = b.companyName;
        this.description = b.description;
        this.country = b.country;
        this.operatingSince = b.operatingSince;
        this.operatingUntil = b.operatingUntil;
        this.lastModified = b.lastModified;
    }

    public static Railway build(UnaryOperator<Builder> op) {
        return op.apply(new Builder()).build();
    }

    public EntityLink asLink() {
        return EntityLink.to(Railway.class).with(this, Railway::getSlug, Railway::getName);
    }

    /**
     * The {@code Railway} builder class.
     */
    public static class Builder {
        private String name;
        private ObjectId id;
        private LocalizedField<String> description;
        private String companyName;
        private String country;
        private String slug;
        private LocalDate operatingSince;
        private LocalDate operatingUntil;
        private LocalDateTime lastModified;

        private Builder() {
        }

        public Builder id(ObjectId id) {
            this.id = id;
            return this;
        }

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

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

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

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

        public Builder operatingSince(LocalDate start) {
            this.operatingSince = start;
            return this;
        }

        public Builder operatingUntil(LocalDate end) {
            this.operatingUntil = end;
            return this;
        }

        public Builder lastModified(LocalDateTime lm) {
            this.lastModified = lm;
            return this;
        }

        public Builder description(String desc) {
            this.description = Fun.lazy(description, () -> LocalizedField.of(desc));
            return this;
        }

        public Builder description(Locale lang, String desc) {
            this.description = Fun.lazyApply(description, () -> LocalizedField.of(lang, desc),
                    field -> field.with(lang, desc));
            return this;
        }

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

    /**
     * Returns the {@code Railway} id.
     *
     * @return the unique id
     */
    public ObjectId getId() {
        return _id;
    }

    /**
     * Returns the {@code Railway} name.
     * <p>
     * This field usually contains the acronym from the company name.
     * </p>
     *
     * @return the railway name
     */
    public String getName() {
        return name;
    }

    /**
     * Returns the {@code Railway} slug.
     * <p>
     * If the slug is not set this method will return
     * the encoded value for {@link com.carlomicieli.jtrains.core.models.Railway#getName()}.
     * </p>
     *
     * @return the slug
     */
    public String getSlug() {
        return slug;
    }

    /**
     * Returns the full {@code Railway} company name.
     *
     * @return the full company name
     */
    public String getCompanyName() {
        return companyName;
    }

    /**
     * Returns the {@code Railway} description.
     *
     * @return the description
     */
    public LocalizedField<String> getDescription() {
        return description;
    }

    /**
     * Returns the {@code Railway} country code.
     * <p>
     * The country is following {@code ISO 3166-1 alpha-2} code standard.
     * </p>
     *
     * @return the country code
     */
    public String getCountry() {
        return country;
    }

    /**
     * Returns the starting year of operations.
     *
     * @return the year
     */
    public LocalDate getOperatingSince() {
        return operatingSince;
    }

    /**
     * Returns the finishing year of operations.
     *
     * @return the year
     */
    public LocalDate getOperatingUntil() {
        return operatingUntil;
    }

    /**
     * Returns the last modified timestamp.
     *
     * @return the timestamp
     */
    public LocalDateTime getLastModified() {
        return lastModified;
    }

    /**
     * Returns a keyword for the current {@code Railway}.
     * <p>
     * The application could opt to show this value as string representation
     * for the current {@code Railway} instead of the usual {@code Railway#toString()}.
     * </p>
     * <p>
     *  Valid labels include the {@code Railway#getName()} and the {@code Railway#getCompanyName()} (if available).
     * </p>
     *
     * @return the keyword string
     */
    public String getLabel() {
        return Optional.ofNullable(getCompanyName()).map(cn -> String.join("", getName(), " (", cn, ")"))
                .orElse(getName());
    }

    /**
     * Checks whether the {@code Railway} company is still active.
     * @return {@code true} if active, {@code false} otherwise.
     */
    public boolean isActive() {
        return operatingUntil == null;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, slug, companyName, description, country, operatingSince, operatingUntil);
    }

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

        Railway that = (Railway) obj;
        return new EqualsBuilder().append(name, that.name).append(slug, that.slug)
                .append(companyName, that.companyName).append(description, that.description)
                .append(country, that.country).append(operatingSince, that.operatingSince)
                .append(operatingUntil, that.operatingUntil).isEquals();
    }

    @Override
    public String toString() {
        return com.google.common.base.Objects.toStringHelper(this).omitNullValues().add("name", name)
                .add("slug", slug).add("companyName", companyName).add("active", isActive()).toString();
    }
}