GeoRegion.java

package org.genesys.server.model.impl;

import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.Lob;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import lombok.Getter;
import lombok.Setter;
import org.genesys.blocks.model.JsonViews;
import org.genesys.blocks.model.VersionedModel;
import org.genesys.custom.elasticsearch.IgnoreField;
import org.hibernate.annotations.Type;

import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIdentityReference;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonView;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

@Entity
@Table(name = "georegion")
@Cacheable
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "id", scope = GeoRegion.class)
@Getter
@Setter
public class GeoRegion extends VersionedModel {

	private static final ObjectMapper mapper = new ObjectMapper();

	private static final long serialVersionUID = -1L;

	@Size(max = 3)
	@NotNull
	@Column(length = 3, nullable = false, unique = true)
	private String isoCode;

	@Size(max = 250)
	@NotNull
	@Column(nullable = false, length = 250)
	private String name;

	@ManyToOne()
	@JoinColumn(name = "parentId")
	@JsonView({ JsonViews.Public.class })
	@JsonIgnoreProperties({ "parentRegion" })
	@IgnoreField
	private GeoRegion parentRegion;

	@OneToMany(fetch = FetchType.LAZY, mappedBy = "region")
	@JsonView({ JsonViews.Public.class })
	@JsonIdentityReference(alwaysAsId = true)
	@IgnoreField
	private List<Country> countries;

	@Lob
	@Type(type = "org.hibernate.type.TextType")
	@JsonIgnore
	private String nameL;

	@Transient
	@JsonIgnore
	private JsonNode nameJ;

	@IgnoreField
	public List<Country> getCountries() {
		return countries;
	}

	@IgnoreField
	public GeoRegion getParentRegion() {
		return parentRegion;
	}

	public void setName(Locale locale, String name) {
		try {
			this.nameJ = mapper.readTree(nameL);
			// ObjectNode newLang =
			// mapper.createObjectNode().put(locale.toLanguageTag(), name);
			// System.err.println(newLang);
		} catch (final IOException e) {
		}
	}

	public String getName(Locale locale) {
		return getNameLocal(locale);
	}

	private synchronized String getNameLocal(Locale locale) {
		if (this.nameJ == null && this.nameL != null) {
			try {
				this.nameJ = mapper.readTree(nameL);
			} catch (final IOException e) {
				e.printStackTrace();
			}
		}

		return this.nameJ != null && this.nameJ.has(locale.toLanguageTag()) ? this.nameJ.get(locale.toLanguageTag()).textValue() : this.name;
	}

	public static void sort(List<GeoRegion> all, Locale locale) {
		Collections.sort(all, new Comparator<GeoRegion>() {
			@Override
			public int compare(GeoRegion o1, GeoRegion o2) {
				return o1.getName(locale).compareTo(o2.getName(locale));
			}
		});
	}

	@Override
	public boolean canEqual(Object other) {
		return other instanceof GeoRegion;
	}
}