ImageGalleryServiceImpl.java
/*
* Copyright 2018 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.genesys.filerepository.service.impl;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import javax.persistence.EntityNotFoundException;
import org.genesys.blocks.security.SecurityContextUtil;
import org.genesys.filerepository.InvalidRepositoryPathException;
import org.genesys.filerepository.model.ImageGallery;
import org.genesys.filerepository.model.QImageGallery;
import org.genesys.filerepository.model.QRepositoryFolder;
import org.genesys.filerepository.model.RepositoryFile;
import org.genesys.filerepository.model.RepositoryFolder;
import org.genesys.filerepository.model.RepositoryImage;
import org.genesys.filerepository.persistence.ImageGalleryPersistence;
import org.genesys.filerepository.service.ImageGalleryService;
import org.genesys.filerepository.service.RepositoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.access.prepost.PostAuthorize;
import org.springframework.security.access.prepost.PostFilter;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import com.querydsl.jpa.impl.JPAQuery;
import com.querydsl.jpa.impl.JPAQueryFactory;
import lombok.extern.slf4j.Slf4j;
/**
* Image Gallery service.
*/
@Service
@Transactional(readOnly = true)
@Slf4j
public class ImageGalleryServiceImpl implements ImageGalleryService {
/** The document file persistence. */
@Autowired
private ImageGalleryPersistence imageGalleryPersistence;
/** The repository service. */
@Autowired
private RepositoryService repositoryService;
/** The jpa query factory. */
@Autowired
private JPAQueryFactory jpaQueryFactory;
/*
* (non-Javadoc)
* @see
* org.genesys.filerepository.service.ImageGalleryService#loadImageGallery(java.
* lang.String)
*/
@Override
@PostAuthorize("returnObject == null or hasRole('ADMINISTRATOR') or hasPermission(returnObject, 'read')")
public ImageGallery loadImageGallery(final Path path) throws InvalidRepositoryPathException {
PathValidator.checkValidPath(path);
final ImageGallery imageGallery = imageGalleryPersistence.findByFolder(repositoryService.getFolder(path));
return deepLoad(imageGallery);
}
@Override
@PostFilter("filterObject==null || hasRole('ADMINISTRATOR') || hasPermission(filterObject, 'read')")
public List<ImageGallery> loadImageGalleries(final List<Path> paths) throws InvalidRepositoryPathException {
List<String> normalizedPaths = new ArrayList<>(paths.size());
for (Path path : paths) {
PathValidator.checkValidPath(path);
normalizedPaths.add(path.normalize().toAbsolutePath().toString());
}
List<Long> folders = jpaQueryFactory.select(QRepositoryFolder.repositoryFolder.id).from(QRepositoryFolder.repositoryFolder).where(QRepositoryFolder.repositoryFolder.path.in(normalizedPaths)).fetch();
JPAQuery<ImageGallery> query = jpaQueryFactory.selectFrom(QImageGallery.imageGallery).where(QImageGallery.imageGallery.folder.id.in(folders));
return query.fetch()
.stream().map(this::deepLoad).collect(Collectors.toList());
}
@Override
@PostAuthorize("returnObject == null or hasRole('ADMINISTRATOR') or hasPermission(returnObject, 'read')")
public ImageGallery getImageGallery(RepositoryFolder folder) {
return imageGalleryPersistence.findByFolder(folder);
}
/**
* Loads {@link ImageGallery#getImages()} when not null.
*
* @param imageGallery the image gallery
* @return the image gallery
*/
private ImageGallery deepLoad(final ImageGallery imageGallery) {
// Fetch image info
if (imageGallery != null) {
imageGallery.getImages().size();
}
return imageGallery;
}
/*
* (non-Javadoc)
* @see
* org.genesys.filerepository.service.ImageGalleryService#createImageGallery(
* java.lang.String, java.lang.String, java.lang.String)
*/
@Override
@Transactional(rollbackFor = Throwable.class)
@PreAuthorize("isAuthenticated()")
public ImageGallery createImageGallery(final Path path, final String title, final String description) throws InvalidRepositoryPathException {
PathValidator.checkValidPath(path);
if ("/".equals(path.normalize().toAbsolutePath().toString())) {
throw new InvalidRepositoryPathException("Image gallery cannot be created at " + path);
}
log.debug("Creating ImageGallery at path={}", path);
RepositoryFolder repositoryFolder = repositoryService.ensureFolder(path);
ImageGallery imageGallery = imageGalleryPersistence.findByFolder(repositoryFolder);
if (imageGallery != null) {
return imageGallery;
}
if (!SecurityContextUtil.hasRole("ADMINISTRATOR") && !SecurityContextUtil.hasPermission(repositoryFolder, "WRITE")) {
throw new AccessDeniedException("No WRITE permission on " + repositoryFolder.getPath());
}
log.info("Creating new image gallery at path={}", path);
imageGallery = new ImageGallery();
imageGallery.setFolder(repositoryFolder);
imageGallery.setPath(path.toString());
imageGallery.setTitle(title);
imageGallery.setDescription(description);
final List<RepositoryImage> images = new ArrayList<>(repositoryService.listImages(Paths.get(imageGallery.getPath()), RepositoryFile.DEFAULT_SORT));
imageGallery.setImages(images);
imageGallery = imageGalleryPersistence.save(imageGallery);
ensureThumbnails(imageGallery);
return imageGallery;
}
/*
* (non-Javadoc)
* @see
* org.genesys.filerepository.service.ImageGalleryService#removeGallery(org.
* genesys.filerepository. model.ImageGallery)
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#imageGallery, 'delete')")
public ImageGallery removeGallery(final ImageGallery imageGallery) {
log.debug("Deleting ImageGallery with id={}", imageGallery.getId());
imageGalleryPersistence.delete(imageGallery);
return imageGallery;
}
/*
* (non-Javadoc)
* @see
* org.genesys.filerepository.service.ImageGalleryService#updateImageGalery(org.
* genesys2.server. filerepository.model.ImageGallery, java.lang.String,
* java.lang.String)
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#imageGallery, 'write')")
public ImageGallery updateImageGalery(final ImageGallery imageGallery, final String title, final String description) {
if (imageGallery.getId() == null) {
throw new EntityNotFoundException("The given id must not be null");
}
final ImageGallery imageGallery2 = imageGalleryPersistence.findById(imageGallery.getId()).orElseThrow(() -> new EntityNotFoundException("Record not found."));
imageGallery2.setTitle(title);
imageGallery2.setDescription(description);
imageGalleryPersistence.save(imageGallery2);
return deepLoad(imageGallery2);
}
/*
* (non-Javadoc)
* @see
* org.genesys.filerepository.service.ImageGalleryService#saveImageOrder(org.
* genesys.filerepository. model.ImageGallery)
*/
@Override
@Transactional
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#imageGallery, 'write')")
public ImageGallery saveImageOrder(final ImageGallery imageGallery) {
assert (imageGallery != null && imageGallery.getId() != null);
final ImageGallery imageGallery2 = imageGalleryPersistence.findById(imageGallery.getId()).orElseThrow(() -> new EntityNotFoundException("Record not found."));
imageGallery2.setImages(imageGallery.getImages());
imageGalleryPersistence.save(imageGallery2);
return deepLoad(imageGallery2);
}
@Override
public void ensureThumbnails(final ImageGallery imageGallery) {
assert (imageGallery != null && imageGallery.getId() != null);
final ImageGallery imageGallery2 = imageGalleryPersistence.findById(imageGallery.getId()).orElseThrow(() -> new EntityNotFoundException("Record not found."));
if (CollectionUtils.isEmpty(imageGallery2.getImages())) {
log.debug("ImageGallery has no images, skipping thumbnail generation for path={}", imageGallery2.getPath());
return;
}
imageGallery2.getImages().forEach(repositoryImage -> repositoryService.ensureThumbnails(repositoryImage));
}
/**
* List image galleries.
*
* @param pageable the pageable
* @return the page
*/
@Override
@PreAuthorize("hasRole('ADMINISTRATOR')")
public Page<ImageGallery> listImageGalleries(final Pageable pageable) {
return imageGalleryPersistence.findAll(pageable);
}
/*
* (non-Javadoc)
* @see
* org.genesys.filerepository.service.ImageGalleryService#listImageGalleries(
* java.lang.String, org.springframework.data.domain.Pageable)
*/
@Override
public Page<ImageGallery> listImageGalleries(final Path root, final Pageable pageable) throws InvalidRepositoryPathException {
PathValidator.checkValidPath(root);
List<RepositoryFolder> folders = repositoryService.listPathsRecursively(root);
// Remove folders user can't read
folders.removeIf(folder -> !SecurityContextUtil.hasRole("ADMINISTRATOR") && !SecurityContextUtil.hasPermission(folder, "READ"));
JPAQuery<ImageGallery> query = jpaQueryFactory.selectFrom(QImageGallery.imageGallery).where(QImageGallery.imageGallery.folder.in(folders));
long total = query.fetchCount();
List<ImageGallery> content = query.join(QImageGallery.imageGallery.folder).fetchJoin()
// page
.offset(pageable.getOffset()).limit(pageable.getPageSize())
// fetch
.fetch();
// content.forEach(imageGallery -> imageGallery.getImages().size());
// content.forEach(imageGallery -> imageGallery.getFolder().getId());
return new PageImpl<>(content, pageable, total);
}
}