net.yadaframework.persistence.entity.YadaPersistentEnum Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yadaweb Show documentation
Show all versions of yadaweb Show documentation
Some useful tasks for the Yada Framework
package net.yadaframework.persistence.entity;
import java.io.IOException;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.i18n.LocaleContextHolder;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.google.common.base.Objects;
import jakarta.persistence.Column;
import jakarta.persistence.ElementCollection;
import jakarta.persistence.Entity;
import jakarta.persistence.FetchType;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import jakarta.persistence.MapKeyColumn;
import jakarta.persistence.Table;
import jakarta.persistence.Transient;
import jakarta.persistence.UniqueConstraint;
import net.yadaframework.core.YadaLocalEnum;
import net.yadaframework.exceptions.YadaInvalidValueException;
/**
* Needed to store a localized enum in the database, on which to perform localized search and sort operations.
* To retrieve the localized value call {@link YadaPersistentEnum#getLocalText()}
* For every Enum class in Java there is a number of rows in the database holding the enum class name and its ordinals.
* For each such row there are a number of rows holding the localized values.
* E.g. the "ProcessState" enum with values "RUNNING" and "STOPPED" produces the following rows:
* Table YadaPersistentEnum (logical view)
*
*
* enumClassName enumName enumOrdinal langToText
*
*
* ProcessState RUNNING 0 en_US Executing it_IT In esecuzione
*
*
* ProcessState STOPPED 1 en_US Idle it_IT Fermo
*
*
*
*/
@JsonSerialize(using = YadaPersistentEnum.YadaPersistentEnumSerializer.class)
@Entity
@Table(
uniqueConstraints = @UniqueConstraint(columnNames={"enumClassName", "enumOrdinal"})
)
@Inheritance(strategy = InheritanceType.JOINED)
public class YadaPersistentEnum> {
@Deprecated // TODO delete because not used anymore for datatables
static class YadaPersistentEnumSerializer extends JsonSerializer> {
@Override
public void serialize(YadaPersistentEnum> value, JsonGenerator generator, SerializerProvider serializers) throws IOException, JsonProcessingException {
generator.writeString(value.getLocalText());
}
}
@SuppressWarnings("unused")
private final transient Logger log = LoggerFactory.getLogger(getClass());
@Id
@GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
@Column(nullable=false, length=191)
private String enumClassName; // ProcessState
private int enumOrdinal; // 2
@Column(nullable=false)
private String enumName; // "RUNNING"
@ElementCollection(fetch = FetchType.EAGER)
@MapKeyColumn(name="language", length=32) // th_TH_TH_#u-nu-thai
@Column(name="localText", length=128)
Map langToText = new HashMap<>(); // Language code to localized text: { "it_IT" = "In esecuzione", "en_US" = "Running" }
/**
* Check this instance with a normal enum for equality.
* This is the preferred way for checking enums.
* @param enumValue
* @return
*/
@Transient
public boolean equals(Enum extends YadaLocalEnum>> enumValue) {
return enumValue.getClass().getName().equals(this.enumClassName) && enumValue.ordinal() == this.enumOrdinal;
}
@Transient
@Override
public boolean equals(Object obj) {
if (obj instanceof YadaPersistentEnum == false || obj==null) {
return false;
}
YadaPersistentEnum other = (YadaPersistentEnum) obj;
return (this.enumClassName.equals(other.enumClassName) && this.enumOrdinal == other.enumOrdinal);
}
@Transient
@Override
public int hashCode() {
return Objects.hashCode(this.enumClassName, this.enumOrdinal);
}
/**
* Sets the attributes of a normal enum into this instance, but not the localized text
* @param enumValue
*/
@Transient
public void setEnum(E enumValue) {
this.enumClassName = enumValue.getClass().getName();
this.enumOrdinal = enumValue.ordinal();
this.enumName = enumValue.name();
}
/**
* Returns the localized value in the current locale
* @return
*/
@Transient
public String getLocalText() {
Locale locale = LocaleContextHolder.getLocale();
return langToText.get(locale.getLanguage());
}
/**
* Convert the localised enum back to a normal Enum instance. Same as getEnum()
* WARNING: the enum returned fails to be compared with the original enum. Use {@link #equals(Enum)} instead.
* @return
* @throws YadaInvalidValueException
* @see #getEnum()
*/
public E toEnum() throws YadaInvalidValueException {
return getEnum();
}
/**
* Convert the localised enum back to a normal Enum instance. Same as toEnum()
* WARNING: the enum returned fails to be compared with the original enum. Use {@link #equals(Enum)} instead.
* @return
* @throws YadaInvalidValueException
* @see #toEnum()
*/
public E getEnum() throws YadaInvalidValueException {
try {
Class enumClassClass = (Class) Class.forName(this.enumClassName);
E result = Enum.valueOf(enumClassClass, enumName);
if (result instanceof YadaLocalEnum) {
((YadaLocalEnum)result).setYadaPersistentEnum(this);
}
return result;
} catch (ClassNotFoundException e) {
throw new YadaInvalidValueException(e);
}
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public int getEnumOrdinal() {
return enumOrdinal;
}
public void setEnumOrdinal(int enumOrdinal) {
this.enumOrdinal = enumOrdinal;
}
public String getEnumName() {
return enumName;
}
public void setEnumName(String enumName) {
this.enumName = enumName;
}
public Map getLangToText() {
return langToText;
}
public void setLangToText(Map langToText) {
this.langToText = langToText;
}
public String getEnumClassName() {
return enumClassName;
}
public void setEnumClassName(String enumClassName) {
this.enumClassName = enumClassName;
}
}