org.seedstack.i18n.infrastructure.finders.jpa.TranslationJpaFinder Maven / Gradle / Ivy
/**
* Copyright (c) 2013-2015 by The SeedStack authors. All rights reserved.
*
* This file is part of SeedStack, An enterprise-oriented full development stack.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
package org.seedstack.i18n.infrastructure.finders.jpa;
import org.seedstack.i18n.api.LocaleService;
import org.seedstack.i18n.internal.domain.model.key.Key;
import org.seedstack.i18n.internal.domain.model.key.KeyRepository;
import org.seedstack.i18n.internal.domain.model.key.Translation;
import org.seedstack.i18n.rest.translation.TranslationAssembler;
import org.seedstack.i18n.rest.translation.TranslationFinder;
import org.seedstack.i18n.rest.translation.TranslationRepresentation;
import org.apache.commons.lang.StringUtils;
import org.seedstack.business.api.interfaces.finder.Range;
import org.seedstack.business.api.interfaces.finder.Result;
import org.seedstack.business.jpa.BaseJpaRangeFinder;
import org.seedstack.seed.core.utils.SeedCheckUtils;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.persistence.criteria.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
* This class provides methods to find translations.
*
* @author [email protected]
* Date: 15/05/2014
*/
public class TranslationJpaFinder extends BaseJpaRangeFinder implements TranslationFinder {
private static final String IS_APPROX = "isApprox";
private static final String IS_MISSING = "isMissing";
private static final String IS_OUTDATED = "isOutdated";
private static final String SEARCH_NAME = "searchName";
private static final String LOCALE = "locale";
private static final String ENTITY_ID = "entityId";
private static final String TRANSLATIONS = "translations";
private static final String OUTDATED = "outdated";
private static final String APPROXIMATE = "approximate";
private static final String VALUE = "value";
@Inject
private KeyRepository keyRepository;
@Inject
private LocaleService localeService;
@Inject
private TranslationAssembler translationAssembler;
@Inject
private EntityManager entityManager;
@Override
public List findTranslations(String localeId) {
List keys = keyRepository.loadAll();
List translationRepresentations = new ArrayList(keys.size());
String defaultLocale = localeService.getDefaultLocale();
for (Key key : keys) {
translationRepresentations.add(translationAssembler.assembleDtoFromAggregate(key.subKey(defaultLocale, localeId)));
}
return translationRepresentations;
}
@Override
public TranslationRepresentation findTranslation(String localeId, String keyId) {
Key key = keyRepository.load(keyId);
String defaultLocale = localeService.getDefaultLocale();
SeedCheckUtils.checkIfNotNull(defaultLocale);
if (key != null) {
return translationAssembler.assembleDtoFromAggregate(key.subKey(defaultLocale, localeId));
}
return null;
}
@Override
public Result findAllTranslations(Range range, Map criteria) {
return find(range, criteria);
}
@Override
protected List computeResultList(Range range, Map criteria) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery q = cb.createQuery(Key.class);
Root k = q.from(Key.class);
Predicate[] predicates = getPredicates(criteria, q, cb, k);
q.select(k);
if (predicates.length > 0) {
q.where(cb.and(predicates));
}
List keys;
// Get all the keys with their default translation
if (range != null) {
keys = entityManager.createQuery(q).setFirstResult((int) range.getOffset()).setMaxResults((int)range.getSize()).getResultList();
} else {
keys = entityManager.createQuery(q).getResultList();
}
List translationRepresentations = new ArrayList(keys.size());
String defaultLocale = localeService.getDefaultLocale();
for (Key key : keys) {
translationRepresentations.add(translationAssembler.assembleDtoFromAggregate(key.subKey(defaultLocale, (String) criteria.get(LOCALE))));
}
return translationRepresentations;
}
@Override
protected long computeFullRequestSize(Map criteria) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery q = cb.createQuery(Long.class);
Root k = q.from(Key.class);
q.select(cb.count(k));
if (criteria != null) {
q.where(cb.and(getPredicates(criteria, q, cb, k)));
}
return entityManager.createQuery(q).getSingleResult();
}
/**
* Extracts predicates from criteria.
*
* @param criteria criteria
* @param cb criteria builder
* @param k root key
* @return list of predicate
*/
private Predicate[] getPredicates(Map criteria, CriteriaQuery q, CriteriaBuilder cb, Root k) {
List predicates = new ArrayList();
if (criteria != null) {
// extract criteria from the map
Boolean isApprox = (Boolean) criteria.get(IS_APPROX);
Boolean isMissing = (Boolean) criteria.get(IS_MISSING);
Boolean isOutdated = (Boolean) criteria.get(IS_OUTDATED);
String searchName = (String) criteria.get(SEARCH_NAME);
String locale = (String) criteria.get(LOCALE);
// is the key LIKE searchName
if (StringUtils.isNotBlank(searchName)) {
predicates.add(cb.like(k.get(ENTITY_ID), "%" + searchName + "%"));
}
// if a default translation is available
if (isApprox != null || isOutdated != null) {
// join translation table
Join tln = k.join(TRANSLATIONS, JoinType.LEFT);
// WHERE locale = default locale
predicates.add(cb.equal(tln.get(ENTITY_ID).get(LOCALE), locale));
// is the key outdated
if (isOutdated != null) {
predicates.add(cb.equal(tln.get(OUTDATED), isOutdated));
}
// is the translation approximate
if (isApprox != null) {
predicates.add(cb.equal(tln.get(APPROXIMATE), isApprox));
}
}
// is the translation missing
if (isMissing != null) {
// SubQuery to find all the key which get a translation for the default locale
//noinspection unchecked
Subquery subquery = q.subquery(String.class);
Root fromKey = subquery.from(Key.class);
subquery.select(fromKey.get(ENTITY_ID));
Join join = fromKey.join(TRANSLATIONS, JoinType.LEFT);
subquery.where(cb.and(cb.equal(join.get(ENTITY_ID).get(LOCALE), locale), cb.notEqual(join.get(VALUE), "")));
// Find all keys not in the above subquery, ie. all the keys missing
predicates.add(cb.not(cb.in(k.get(ENTITY_ID)).value(subquery)));
}
}
return predicates.toArray(new Predicate[predicates.size()]);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy