![JAR search and dependency download from the Maven repository](/logo.png)
net.yadaframework.persistence.repository.YadaLocaleDao Maven / Gradle / Ivy
package net.yadaframework.persistence.repository;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.List;
import java.util.Locale;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import net.yadaframework.components.YadaUtil;
import net.yadaframework.core.YadaConfiguration;
import net.yadaframework.exceptions.YadaInternalException;
import net.yadaframework.exceptions.YadaInvalidValueException;
import net.yadaframework.persistence.YadaSql;
/**
* Locale-related operations on entities
*/
@Repository
@Transactional(readOnly = true)
public class YadaLocaleDao {
@Autowired private YadaConfiguration config;
@Autowired private JdbcTemplate jdbcTemplate;
@PersistenceContext
private EntityManager em;
/**
* Finds all entities of the given type, then initializes all localized string attributes defined as Map<Locale, String>
* @param entityClass
* @return
*/
public List findAllWithLocalValues(Class> entityClass) {
@SuppressWarnings("unchecked")
List result = (List) YadaSql.instance().selectFrom("from " + entityClass.getSimpleName())
.query(em, entityClass).getResultList();
YadaUtil.prefetchLocalizedStringList(result, entityClass);
return result;
}
/**
* Finds an object of the given id, then initializes all localized string attributes defined as Map<Locale, String>
* @param entityId
* @param entityClass
* @return
*/
public entityClass findOneWithLocalValues(Long entityId, Class> entityClass) {
@SuppressWarnings("unchecked")
entityClass entity = (entityClass) em.find(entityClass, entityId);
if (entity!=null) {
YadaUtil.prefetchLocalizedStrings(entity, entityClass);
}
return entity;
}
/**
* Finds an object of the given id, then initializes all localized string attributes defined as Map<Locale, String>
* with recursion on the fields.
* @param entityId
* @param entityClass
* @return
*/
public entityClass findOneWithLocalValuesRecursive(Long entityId, Class> entityClass) {
@SuppressWarnings("unchecked")
entityClass entity = (entityClass) em.find(entityClass, entityId);
if (entity!=null) {
YadaUtil.prefetchLocalizedStringsRecursive(entity, entityClass);
}
return entity;
}
/**
* Get the localized value of an entity's attribute
* @param entity the entity instance
* @param attributeName the name of the attribute that must be defined as Map
* @return the localized value in the current locale, or in the default configured locale if the value is not set for that locale,
* or an empty string if no value is found.
*/
public String getLocalValue(Object entity, String attributeName) {
return getLocalValue(entity, attributeName, null);
}
/**
* Get the localized value of an entity's attribute
* @param entity the entity instance
* @param attributeName the name of the attribute that must be defined as Map
* @param locale the locale for the value, use null for the current request locale
* @param returnNull (optional) true if null must be returned when no value is present instead of the empty string
* @return the localized value in the specified locale, or in the default configured locale if the value is not set for that locale,
* or an empty string if no value is found or null if no value is found and returnNull is true.
*/
public String getLocalValue(Object entity, String attributeName, Locale locale, Boolean... returnNull) {
try {
Class extends Object> entityClass = entity.getClass();
Method getId = entityClass.getMethod("getId");
Long entityId = (Long) getId.invoke(entity);
return getLocalValue(entityId, entityClass, attributeName, locale, returnNull);
} catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new YadaInternalException("Can't get local value for object " + entity + " attribute " + attributeName, e);
}
}
/**
* Get the localized value of an entity's attribute
* @param entityId the id of the entity
* @param entityClass the class of the entity
* @param attributeName the name of the attribute that must be defined as Map
* @param locale the locale for the value, use null for the current request locale
* @param returnNull (optional) true if null must be returned when no value is present instead of the empty string
* @return the localized value in the specified locale, or in the default configured locale if the value is not set for that locale,
* or an empty string if no value is found or null if no value is found and returnNull is true.
*/
public String getLocalValue(long entityId, Class> entityClass, String attributeName, Locale locale, Boolean... returnNull) {
// select color from YadaArticle_color where YadaArticle_id=123 and locale="en_US"
if (locale==null) {
locale = LocaleContextHolder.getLocale();
}
String className = findClass(entityClass, attributeName);
if (className==null) {
throw new YadaInvalidValueException("The requested attirbute {} does not exist on {}", attributeName, entityClass);
}
String tableName = className + "_" + attributeName;
String idColumn = className + "_id";
YadaSql yadaSql = YadaSql.instance().selectFrom("select " + attributeName + " from " + tableName)
.where(idColumn + " = :entityId").and()
.where("locale = :localeString").and()
.setParameter("entityId", entityId)
.setParameter("localeString", locale.toString());
List> result = yadaSql.nativeQuery(em).getResultList();
if (result.isEmpty()) {
// Try with the default locale
Locale defaultLocale = config.getDefaultLocale();
if (defaultLocale!=null && !defaultLocale.equals(locale)) {
yadaSql.setParameter("localeString", defaultLocale.toString());
result = yadaSql.nativeQuery(em).getResultList();
}
}
if (result.isEmpty()) {
if (returnNull!=null && returnNull.length>0 && Boolean.TRUE.equals(returnNull[0])) {
return null;
}
return "";
}
return (String) result.get(0);
}
private boolean tableExists(String tableName) {
try (Connection connection = jdbcTemplate.getDataSource().getConnection()) {
DatabaseMetaData meta = connection.getMetaData();
ResultSet res = meta.getTables(null, null, tableName, new String[] {"TABLE"});
boolean result = res.first();
res.close();
return result;
} catch(Exception e) {
return false;
}
}
private String findClass(Class> entityClass, String attributeName) {
String className = entityClass.getSimpleName();
String tableName = className + "_" + attributeName;
boolean exists = tableExists(tableName);
if (!exists) {
// Try with the superclass
entityClass = entityClass.getSuperclass();
if (entityClass.equals(Object.class)) {
return null; // Bottom of the hierarchy
}
return findClass(entityClass, attributeName);
}
return className;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy