package net.pechorina.kontempl.service;
import net.pechorina.kontempl.data.*;
import net.pechorina.kontempl.repos.PageRepo;
import net.pechorina.kontempl.repos.SiteRepo;
import net.pechorina.kontempl.utils.CloneFactory;
import net.pechorina.kontempl.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Service
public class PageService {
static final Logger logger = LoggerFactory.getLogger(PageService.class);
@Autowired
private PageRepo pageRepo;
@Autowired
private SiteRepo siteRepo;
@Autowired
private ImageFileService imageFileService;
@Autowired
private DocFileService docFileService;
@Autowired
private PageTreeService pageTreeService;
@Autowired
private Environment env;
@Transactional
public Page getPage(Integer id) {
logger.debug("getPage(" + id + ")");
Page p = pageRepo.findOne(id);
fetchPageProperties(p);
return p;
}
@Transactional
public Page getPage(Site site, String name) {
logger.debug("getPage(" + name + ")");
Page p = pageRepo.findBySiteAndName(site, name);
fetchPageProperties(p);
return p;
}
private void fetchPageProperties(Page p) {
if (p != null) {
List<PageProperty> props = p.getProperties();
if (props != null) props.size();
}
}
@Transactional
public List<Page> listPageParents(Page page) {
List<Page> pages = new ArrayList<>();
Page thisPage = page;
while (thisPage.getParentId() != 0) {
Page parent = pageRepo.findOne(thisPage.getParentId());
fetchPageProperties(parent);
pages.add(parent);
thisPage = parent;
}
Collections.reverse(pages);
return pages;
}
@Transactional
@Cacheable("pageCache")
public Page getPageCached(Site site, String pageName) {
Page p = getPage(site, pageName);
if (p != null) {
ImageFile im = imageFileService.getMainImageForPage(p.getId());
logger.debug("ImageFile: " + im);
if (im != null) {
p.setMainImage(im);
logger.debug("Main image retrieved and set");
}
List<ImageFile> images = imageFileService.listImagesForPageOrdered(p.getId());
if (images != null) p.setImages(images);
List<DocFile> files = docFileService.listDocsForPageOrdered(p.getId());
if (files != null) p.setDocs(files);
}
return p;
}
@Transactional
@CacheEvict(value = {"pageCache"}, allEntries = true)
public Page savePage(Page page) {
pageTreeService.resetPageTreeCache();
return pageRepo.saveAndFlush(page);
}
@Transactional
@CacheEvict(value = {"pageCache"}, allEntries = true)
public void deletePage(Page page) {
pageTreeService.resetPageTreeCache();
deleteSubPages(page);
// remove images
imageFileService.removeAllImagesForPage(page);
pageRepo.delete(page);
logger.debug("Page: " + page.getId() + "/" + page.getName() + " removed");
}
@Transactional
@CacheEvict(value = {"pageCache"}, allEntries = true)
public void deletePage(Integer id) {
pageTreeService.resetPageTreeCache();
Page p = pageRepo.findOne(id);
if (p != null) deletePage(p);
}
@Transactional
public void deleteSubPages(Page parent) {
List<Page> pages = pageRepo.listSubPages(parent.getId(), parent.getSiteId());
pages.forEach(this::deletePage);
}
public Page beforeSave(Page page) {
if (page.getName().isEmpty()) {
String pl = StringUtils.convertNameToPath(page.getTitle());
page.setName(pl);
}
return page;
}
@Transactional
public int getMaxSortindex(Page parent) {
int si = 0;
List<Page> l = pageRepo.listSubPages(parent.getId(), parent.getSiteId());
if (l != null && l.size() > 0) {
Page lastPage = l.get( l.size() - 1 );
if (lastPage != null) {
si = lastPage.getSortindex();
}
}
return si;
}
@Transactional
@CacheEvict(value = {"pageCache"}, allEntries = true)
public void movePage(Page p, String direction) {
pageTreeService.resetPageTreeCache();
if (p == null) return;
List<Page> pages = pageRepo.listSubPages(p.getParentId(), p.getSiteId());
int idx = pages.indexOf(p);
int newIdx = 0;
if (direction.equalsIgnoreCase("UP")) {
// moving element up the list
if (idx > 0) {
newIdx = idx -1;
}
}
else {
// moving element down the list
if (idx < (pages.size() - 1)) {
newIdx = idx + 1;
}
else {
newIdx = idx;
}
}
logger.debug("Old index: " + idx + " New index: " + newIdx + " Total elements: " + pages.size());
Page element = pages.remove(idx);
pages.add(newIdx, element);
// renumber all elements
int i = 10;
for(Page page: pages) {
page.setSortindex(i);
pageRepo.save(page);
i += 10;
}
}
@Transactional
public void movePage(Page p, int dstIndex, int newParentId) {
Page page = p;
if (newParentId != p.getParentId()) {
// change parent
p.setParentId(newParentId);
page = pageRepo.saveAndFlush(p);
}
setPosition(page, dstIndex);
}
@Transactional
public int getPosition(Page p) {
List<Page> siblings = pageRepo.listSubPages(p.getParentId(), p.getSiteId());
if (siblings == null) return 0;
return siblings.indexOf(p);
}
private void setPosition(Page p, int pos ) {
List<Page> siblings = pageRepo.listSubPages(p.getParentId(), p.getSiteId());
int currentIndex = siblings.indexOf(p);
if (currentIndex != pos) {
siblings.remove(currentIndex);
// 12345 2-4 1245
siblings.add(pos, p);
logger.debug("save new order by altering sortindex");
int idx = 1;
for (Page pg: siblings) {
logger.debug(" -- "+ pg.getId() + "/" + pg.getName());
pg.setSortindex(idx);
pageRepo.save(pg);
idx++;
}
}
}
@Transactional
@CacheEvict(value = {"pageCache"}, allEntries = true)
public Page copyPage(Page src) {
pageTreeService.resetPageTreeCache();
Page newPage = CloneFactory.copyPage(src);
String newName = findNewPageName(src.getSite(), src.getName());
newPage.setName(newName);
String newTitle = src.getTitle() + " - Copy";
newPage.setTitle(newTitle);
int sortIndex = getMaxSortindex(src) + 10;
newPage.setSortindex(sortIndex);
Page savedNewPage = pageRepo.saveAndFlush(newPage);
// copy page images
List<ImageFile> images = imageFileService.listImagesForPage(src.getId());
if (images != null &&(images.size() > 0)) {
for(ImageFile im: images) {
imageFileService.copyFileToPage(im, src, savedNewPage);
}
}
return savedNewPage;
}
@Transactional
public String findNewPageName(Site site, String name) {
int idx = 1;
boolean run = true;
String newName = name + "-" + idx;
while(run) {
long c = pageRepo.countPagesForName(site, newName);
if (c > 0) {
idx++;
newName = name + "-" + idx;
}
else {
run = false;
}
}
return newName;
}
@CacheEvict(value = {"pageCache"}, allEntries = true)
public void resetPageCache() {
pageTreeService.resetPageTreeCache();
}
@Transactional
public List<Page> listAll() {
return pageRepo.findAll();
}
@Transactional
public List<Page> listBySite(Site site) {
return pageRepo.findBySite(site);
}
@Transactional
public boolean findOtherPagesWithSameName(Integer pageId, String name) {
Page p = pageRepo.findOne(pageId);
long c = pageRepo.countOtherPagesForName(p.getSite(), pageId, name);
return (c > 0);
}
@Transactional
public List<Page> listPageChildren(Page p) {
List<Page> children = pageRepo.listSubPages(p.getId(), p.getSiteId());
for(Page c: children) {
ImageFile f = imageFileService.getMainImageForPage(c.getId());
c.setMainImage(f);
}
return children;
}
}