Commit 38bd99c5 authored by Maxym Borodenko's avatar Maxym Borodenko

Draft: Generic translation service

parent 2a835625
......@@ -15,17 +15,12 @@
*/
package org.gringlobal.model;
import java.util.List;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
......@@ -33,7 +28,6 @@ import javax.validation.constraints.Size;
import org.gringlobal.custom.validation.javax.OneLine;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
......@@ -44,7 +38,7 @@ import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@Entity
@Table(name = "code_value")
@JsonIdentityInfo(scope = CodeValue.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class CodeValue extends CooperatorOwnedModel {
public class CodeValue extends TranslatedCooperatorOwnedModel<CodeValueLang, CodeValue> {
private static final long serialVersionUID = 5594016438978094923L;
/**
......@@ -72,10 +66,6 @@ public class CodeValue extends CooperatorOwnedModel {
@Column(nullable = false, length = CODEVALUE_LENGTH)
private String value;
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "entity")
@JsonIgnore
private List<CodeValueLang> langs;
public CodeValue() {
}
......@@ -111,12 +101,4 @@ public class CodeValue extends CooperatorOwnedModel {
public void setValue(final String value) {
this.value = value;
}
public List<CodeValueLang> getLangs() {
return langs;
}
public void setLangs(List<CodeValueLang> langs) {
this.langs = langs;
}
}
\ No newline at end of file
......@@ -35,7 +35,7 @@ import org.gringlobal.custom.validation.javax.CodeValueField;
@Entity
@Table(name = "crop_trait")
@JsonIdentityInfo(scope = CropTrait.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class CropTrait extends CooperatorOwnedModel implements Copyable<CropTrait> {
public class CropTrait extends TranslatedCooperatorOwnedModel<CropTraitLang, CropTrait> implements Copyable<CropTrait> {
private static final long serialVersionUID = -368513465504238634L;
@Basic
......@@ -121,10 +121,6 @@ public class CropTrait extends CooperatorOwnedModel implements Copyable<CropTrai
@Column(name = "original_value_type_code", length = 20)
private String originalValueTypeCode;
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "entity")
@JsonIgnore
private List<CropTraitLang> cropTraitLangs;
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "cropTrait")
@JsonIgnore
private List<CropTraitCode> codes;
......@@ -264,14 +260,6 @@ public class CropTrait extends CooperatorOwnedModel implements Copyable<CropTrai
this.originalValueTypeCode = originalValueTypeCode;
}
public List<CropTraitLang> getCropTraitLangs() {
return cropTraitLangs;
}
public void setCropTraitLangs(final List<CropTraitLang> cropTraitLangs) {
this.cropTraitLangs = cropTraitLangs;
}
public List<CropTraitCode> getCodes() {
return codes;
}
......
......@@ -15,14 +15,11 @@
*/
package org.gringlobal.model;
import java.util.List;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import com.fasterxml.jackson.annotation.JsonIdentityInfo;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.ObjectIdGenerators;
......@@ -33,7 +30,7 @@ import com.fasterxml.jackson.annotation.ObjectIdGenerators;
@Entity
@Table(name = "crop_trait_code")
@JsonIdentityInfo(scope = CropTraitCode.class, generator = ObjectIdGenerators.PropertyGenerator.class, property = "id")
public class CropTraitCode extends CooperatorOwnedModel {
public class CropTraitCode extends TranslatedCooperatorOwnedModel<CropTraitCodeLang, CropTraitCode> {
private static final long serialVersionUID = 3419091039669933935L;
@NotNull
......@@ -53,10 +50,6 @@ public class CropTraitCode extends CooperatorOwnedModel {
@Column(name = "crop_trait_code_id")
private Long id;
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "entity")
@JsonIgnore
private List<CropTraitCodeLang> codeLangs;
public CropTraitCode() {
}
......@@ -88,11 +81,4 @@ public class CropTraitCode extends CooperatorOwnedModel {
this.id = id;
}
public List<CropTraitCodeLang> getCodeLangs() {
return codeLangs;
}
public void setCodeLangs(final List<CropTraitCodeLang> codeLangs) {
this.codeLangs = codeLangs;
}
}
\ No newline at end of file
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.model;
import com.fasterxml.jackson.annotation.JsonIgnore;
import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;
import java.util.List;
/**
* Abstract class for entities that include a list of {@link CooperatorOwnedLang}s.
*
* @author Maxym Borodenko
*/
@MappedSuperclass
public abstract class TranslatedCooperatorOwnedModel<L extends CooperatorOwnedLang<E>, E extends CooperatorOwnedModel> extends CooperatorOwnedModel {
private static final long serialVersionUID = 4781533164313599537L;
@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.REMOVE }, mappedBy = "entity")
@JsonIgnore
protected List<L> langs;
public List<L> getLangs() {
return langs;
}
public void setLangs(List<L> langs) {
this.langs = langs;
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service;
import org.gringlobal.model.CodeValue;
import org.gringlobal.service.filter.CodeValueFilter;
/**
* @author Maxym Borodenko
*/
public interface CodeValueTranslationService extends TranslationService<CodeValue, CodeValueFilter> {
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service;
import org.gringlobal.model.CropTraitCode;
import org.gringlobal.service.filter.CropTraitCodeFilter;
/**
* @author Maxym Borodenko
*/
public interface CropTraitCodeTranslationService extends TranslationService<CropTraitCode, CropTraitCodeFilter> {
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service;
import org.gringlobal.model.CropTrait;
import org.gringlobal.service.filter.CropTraitFilter;
/**
* @author Maxym Borodenko
*/
public interface CropTraitTranslationService extends TranslationService<CropTrait, CropTraitFilter> {
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service;
import org.gringlobal.model.TranslatedCooperatorOwnedModel;
import org.gringlobal.service.filter.TranslatedEntityFilter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;
/**
* @author Maxym Borodenko
*/
@Transactional(readOnly = true)
public interface TranslationService<E extends TranslatedCooperatorOwnedModel<?, ?>, F extends TranslatedEntityFilter<?, ?>> {
Page<Translation<E>> list(F filter, Pageable page);
Translation<E> getTranslated(E entity);
class Translation<E extends TranslatedCooperatorOwnedModel<?, ?>> {
public E entity;
public String title;
public String description;
public Translation(E entity, String title, String description) {
this.entity = entity;
this.title = title;
this.description = description;
}
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service.filter;
import java.io.Serializable;
import java.util.List;
import com.querydsl.core.types.Predicate;
import org.genesys.blocks.model.filters.StringFilter;
import org.gringlobal.model.CodeValue;
import org.gringlobal.model.QCodeValue;
/**
* Filters for {@link CodeValue}
*
* @author Maxym Borodenko
*/
public class CodeValueFilter extends TranslatedEntityFilter<CodeValueFilter, CodeValue> implements Serializable {
private static final long serialVersionUID = 293637893841985270L;
/** The groupName */
public StringFilter groupName;
/** The value */
public StringFilter value;
/**
* Builds the query.
*
* @return the predicate
*/
@Override
public List<Predicate> collectPredicates() {
return collectPredicates(QCodeValue.codeValue);
}
/**
* Builds the query.
*
* @param codeValue the codeValue
* @return the predicate
*/
public List<Predicate> collectPredicates(QCodeValue codeValue) {
final List<Predicate> predicates = super.collectPredicates(codeValue);
if (groupName != null) {
predicates.add(groupName.buildQuery(codeValue.groupName));
}
if (value != null) {
predicates.add(value.buildQuery(codeValue.value));
}
return predicates;
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service.filter;
import java.io.Serializable;
import java.util.List;
import java.util.Set;
import com.querydsl.core.types.Predicate;
import org.apache.commons.collections4.CollectionUtils;
import org.gringlobal.model.CropTraitCode;
import org.gringlobal.model.QCropTraitCode;
/**
* Filters for {@link CropTraitCode}
*
* @author Maxym Borodenko
*/
public class CropTraitCodeFilter extends TranslatedEntityFilter<CropTraitCodeFilter, CropTraitCode> implements Serializable {
private static final long serialVersionUID = 4897011321599706146L;
/** The code */
public Set<String> code;
/** The cropTraitFilter */
public CropTraitFilter cropTrait;
/**
* Builds the query.
*
* @return the predicate
*/
@Override
public List<Predicate> collectPredicates() {
return collectPredicates(QCropTraitCode.cropTraitCode);
}
/**
* Builds the query.
*
* @param cropTraitCode the cropTraitCode
* @return the predicate
*/
public List<Predicate> collectPredicates(QCropTraitCode cropTraitCode) {
final List<Predicate> predicates = super.collectPredicates(cropTraitCode);
if (CollectionUtils.isNotEmpty(code)) {
predicates.add(cropTraitCode.code.in(code));
}
if (cropTrait != null) {
predicates.addAll(cropTrait.collectPredicates(cropTraitCode.cropTrait));
}
return predicates;
}
/**
* CropTrait filter.
*
* @return the CropTrait filter
*/
public synchronized CropTraitFilter cropTrait() {
return this.cropTrait == null ? this.cropTrait = new CropTraitFilter() : this.cropTrait;
}
}
......@@ -29,7 +29,7 @@ import org.gringlobal.model.QCropTrait;
/**
* Filters for {@link CropTrait}
*/
public class CropTraitFilter extends CooperatorOwnedModelFilter<CropTraitFilter, CropTrait> implements Serializable {
public class CropTraitFilter extends TranslatedEntityFilter<CropTraitFilter, CropTrait> implements Serializable {
private static final long serialVersionUID = -2527974104119727590L;
......@@ -62,7 +62,7 @@ public class CropTraitFilter extends CooperatorOwnedModelFilter<CropTraitFilter,
* @return the predicate
*/
public List<Predicate> collectPredicates(QCropTrait cropTrait) {
final List<Predicate> predicates = super.collectPredicates(cropTrait, cropTrait._super);
final List<Predicate> predicates = super.collectPredicates(cropTrait);
if (CollectionUtils.isNotEmpty(crop)) {
predicates.add(cropTrait.crop.id.in(crop));
......@@ -74,7 +74,7 @@ public class CropTraitFilter extends CooperatorOwnedModelFilter<CropTraitFilter,
predicates.add(cropTrait.categoryCode.in(categoryCode));
}
if (description != null) {
predicates.add(description.buildQuery(cropTrait.cropTraitLangs.any().description));
predicates.add(description.buildQuery(cropTrait.langs.any().description));
}
return predicates;
......
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service.filter;
import java.util.List;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.EntityPathBase;
import org.gringlobal.model.CooperatorOwnedLang;
import org.gringlobal.model.QCooperatorOwnedModel;
import org.gringlobal.model.TranslatedCooperatorOwnedModel;
/**
* @author Maxym Borodenko
*/
public abstract class TranslatedEntityFilter<T extends TranslatedEntityFilter<T, E>, E extends TranslatedCooperatorOwnedModel<? extends CooperatorOwnedLang<E>, E>>
extends CooperatorOwnedModelFilter<T, E> {
protected List<Predicate> collectPredicates(final EntityPathBase<E> instance) {
return super.collectPredicates(instance, QCooperatorOwnedModel.cooperatorOwnedModel);
}
}
/*
* Copyright 2020 Global Crop Diversity Trust
*
* 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 org.gringlobal.service.impl;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.stream.Collectors;
import com.querydsl.core.BooleanBuilder;
import com.querydsl.core.Tuple;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Order;
import com.querydsl.core.types.OrderSpecifier;
import com.querydsl.core.types.Predicate;
import com.querydsl.core.types.dsl.Expressions;
import com.querydsl.core.types.dsl.ListPath;
import com.querydsl.core.types.dsl.PathBuilder;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.gringlobal.model.CooperatorOwnedLang;
import org.gringlobal.model.QCooperatorOwnedLang;
import org.gringlobal.model.QTranslatedCooperatorOwnedModel;
import org.gringlobal.model.SysLang;
import org.gringlobal.model.TranslatedCooperatorOwnedModel;
import org.gringlobal.service.LanguageService;
import org.gringlobal.service.TranslationService;
import org.gringlobal.service.filter.TranslatedEntityFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* @author Maxym Borodenko
*/
public abstract class BaseTranslationSupport<T extends TranslatedCooperatorOwnedModel<L, T>, L extends CooperatorOwnedLang<T>,
F extends TranslatedEntityFilter<?, T>> implements TranslationService<T, F> {
@Autowired
protected JPAQueryFactory jpaQueryFactory;
@PersistenceContext
protected EntityManager em;
@Autowired
protected JpaRepository<T, Long> owningEntityRepository;
@Autowired
private LanguageService languageService;
private final Class<T> targetType;
private final Class<L> langType;
protected abstract Class<