CropTraitServiceImpl.java
/*
* 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 java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;
import org.gringlobal.api.exception.InvalidApiUsageException;
import org.gringlobal.api.v1.MultiOp;
import org.gringlobal.custom.elasticsearch.SearchException;
import org.gringlobal.model.Crop;
import org.gringlobal.model.CropTrait;
import org.gringlobal.model.CropTraitAttach;
import org.gringlobal.model.CropTraitLang;
import org.gringlobal.model.QCropTraitAttach;
import org.gringlobal.persistence.CropTraitLangRepository;
import org.gringlobal.persistence.CropTraitRepository;
import org.gringlobal.service.CropTraitAttachmentService;
import org.gringlobal.service.CropTraitAttachmentService.CropTraitAttachmentRequest;
import org.gringlobal.service.CropTraitCodeTranslationService;
import org.gringlobal.service.CropTraitCodeTranslationService.TranslatedCropTraitCode;
import org.gringlobal.service.CropTraitService;
import org.gringlobal.service.CropTraitTranslationService;
import org.gringlobal.service.CropTraitTranslationService.TranslatedCropTrait;
import org.gringlobal.service.filter.CropTraitCodeFilter;
import org.gringlobal.service.filter.CropTraitFilter;
import org.hibernate.Hibernate;
import org.springframework.beans.factory.annotation.Autowired;
// import org.springframework.cache.annotation.CacheConfig;
// import org.springframework.cache.annotation.CacheEvict;
// import org.springframework.cache.annotation.Cacheable;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
/**
* The Class CropTraitServiceImpl.
*/
@Service
@Transactional(readOnly = true)
@Validated
// @CacheConfig(cacheNames = { "cropTraits" })
@Slf4j
public class CropTraitServiceImpl extends FilteredTranslatedCRUDServiceImpl<CropTrait, CropTraitLang, TranslatedCropTrait, CropTraitFilter, CropTraitRepository> implements CropTraitService {
private static final String[] BOOST_FIELDS = { "langs.title", "langs.description" };
@Autowired
private CropTraitCodeTranslationService cropTraitCodeTranslationService;
@Component(value = "cropTraitAttachmentSupport")
@Transactional(readOnly = true)
protected static class CropTraitAttachmentSupport extends BaseAttachmentSupport<CropTrait, CropTraitAttach, CropTraitAttachmentRequest> implements CropTraitAttachmentService {
public CropTraitAttachmentSupport() {
super(QCropTraitAttach.cropTraitAttach.cropTrait().id, QCropTraitAttach.cropTraitAttach.id);
}
@Override
protected Path createRepositoryPath(CropTrait cropTrait) {
cropTrait = owningEntityRepository.getReferenceById(cropTrait.getId());
Hibernate.initialize(cropTrait.getCrop());
Crop crop = cropTrait.getCrop();
return Paths.get("/crop", crop.getName(), "trait", cropTrait.getId().toString());
}
@Override
@PreAuthorize("hasAuthority('GROUP_ADMINS') or @ggceSec.actionAllowed('CropTrait', 'WRITE')")
protected CropTraitAttach createAttach(CropTrait entity, CropTraitAttach source) {
CropTraitAttach attach = new CropTraitAttach();
attach.apply(source);
attach.setVirtualPath(source.getVirtualPath()); // SOAP uses this to create the record
attach.setCropTrait(entity);
return attach;
}
@Override
@PreAuthorize("hasAuthority('GROUP_ADMINS') or @ggceSec.actionAllowed('CropTrait', 'WRITE')")
public CropTraitAttach create(CropTraitAttach source) {
var owningEntity = owningEntityRepository.getReferenceById(source.getCropTrait().getId());
var attach = createAttach(owningEntity, source);
var savedAttach = repository.save(attach);
return _lazyLoad(savedAttach);
}
@Override
@PreAuthorize("hasAuthority('GROUP_ADMINS') or @ggceSec.actionAllowed('CropTrait', 'WRITE')")
public CropTraitAttach update(CropTraitAttach updated, CropTraitAttach target) {
target.apply(updated);
return _lazyLoad(repository.save(target));
}
@Override
@PreAuthorize("hasAuthority('GROUP_ADMINS') or @ggceSec.actionAllowed('CropTrait', 'WRITE')")
public CropTraitAttach remove(CropTraitAttach entity) {
return super.remove(entity);
}
}
@Component(value = "cropTraitTranslationSupport")
protected static class CropTraitTranslationSupport extends BaseTranslationSupport<CropTrait, CropTraitLang, TranslatedCropTrait, CropTraitFilter, CropTraitLangRepository> implements CropTraitTranslationService {
@Autowired
@Lazy
private CropTraitCodeTranslationService cropTraitCodeTranslationService;
public CropTraitTranslationSupport() {
super();
}
@Override
protected TranslatedCropTrait toTranslated(CropTrait entity, String title, String description) {
return TranslatedCropTrait.from(entity, title, description, cropTraitCodeTranslationService.getTranslated(entity.getCodes()));
}
@Override
public CropTraitLang update(CropTraitLang updated, CropTraitLang target) {
target.setTitle(updated.getTitle());
target.setDescription(updated.getDescription());
return _lazyLoad(repository.save(target));
}
}
@Override
public Page<TranslatedCropTrait> listFiltered(CropTraitFilter filter, Pageable page) throws SearchException {
return super.listFiltered(CropTrait.class, filter, page, BOOST_FIELDS);
}
@Override
public TranslatedCropTrait loadTranslated(long id) {
var translatedCropTrait = super.loadTranslated(id);
// initialize lazy data
if (translatedCropTrait.entity.getAttachments() != null) {
translatedCropTrait.entity.getAttachments().size();
translatedCropTrait.entity.getAttachments().forEach((cta) -> {
Hibernate.initialize(cta.getRepositoryFile());
if (cta.getAttachCooperator() != null) {
cta.getAttachCooperator().getId();
}
});
}
translatedCropTrait.attachments = translatedCropTrait.entity.getAttachments();
var traitCodeFilter = new CropTraitCodeFilter();
traitCodeFilter.cropTrait().id(Set.of(id));
List<TranslatedCropTraitCode> codes = cropTraitCodeTranslationService.list(traitCodeFilter, PageRequest.of(0, Integer.MAX_VALUE, Sort.by("title"))).getContent();
translatedCropTrait.codes = codes;
return translatedCropTrait;
}
@Override
// @Cacheable(key = "'ct-' + #id", unless = "#result == null")
public CropTrait get(long id) {
return super.get(id);
}
@Override
@Transactional
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'CREATE')")
public CropTrait create(CropTrait source) {
assert(source.getId() == null);
var target = new CropTrait();
target.apply(source);
return _lazyLoad(repository.save(target));
}
@Override
@Transactional
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'CREATE')")
public CropTrait createFast(CropTrait source) {
return repository.save(source);
}
@Override
@Transactional
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'CREATE')")
public TranslatedCropTrait create(TranslatedCropTrait source) {
return super.create(source);
}
@Override
@Transactional
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'CREATE')")
public MultiOp<CropTrait> create(List<CropTrait> inserts) {
return super.create(inserts);
}
@Override
@Transactional
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'CREATE')")
public MultiOp<CropTrait> createFast(List<CropTrait> inserts) {
return super.createFast(inserts);
}
@Override
@Transactional
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'WRITE')")
// @CacheEvict(key = "'ct-' + #target.id")
public CropTrait update(CropTrait input, CropTrait target) {
if (input == null) {
throw new InvalidApiUsageException("CropTrait must be provided.");
}
log.debug("Update CropTrait. Input data {}", input);
target.apply(input);
CropTrait saved = repository.save(target);
return _lazyLoad(saved);
}
@Override
@Transactional
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'WRITE')")
// @CacheEvict(key = "'ct-' + #target.id")
public CropTrait updateFast(CropTrait updated, CropTrait target) {
target.apply(updated);
return repository.save(target);
}
@Override
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'WRITE')")
// @CacheEvict(allEntries = true)
public MultiOp<CropTrait> update(List<CropTrait> updates) {
return super.update(updates);
}
@Override
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'DELETE')")
// @CacheEvict(key = "'ct-' + #entity.id")
public CropTrait remove(CropTrait entity) {
return super.remove(entity);
}
@Override
@PreAuthorize("@ggceSec.actionAllowed('CropTrait', 'DELETE')")
// @CacheEvict(allEntries = true)
public MultiOp<CropTrait> remove(List<CropTrait> deletes) {
return super.remove(deletes);
}
}