package com.aperture_software.glados_wiki.services;
import com.aperture_software.glados_wiki.entities.Page;
import com.aperture_software.glados_wiki.entities.PageContent;
import com.google.common.base.Optional;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.query.Query;
import org.mongodb.morphia.query.UpdateOperations;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Pattern;
/**
* Created with IntelliJ IDEA.
* User: jhyun
* Date: 13. Nov. 16
* Time: 11:07
*/
@Service
public class PageService {
private static Logger LOG = LoggerFactory.getLogger(PageService.class);
@Autowired
private Datastore datastore;
@Inject
private PageContentService pageContentService;
public Page update(Page page) {
datastore.save(page);
return page;
}
public Optional<Page> getPageByTitle(final String title) {
// by-title?
Query<Page> q = datastore.find(Page.class, "title", title);
if (q.countAll() > 0) {
return Optional.of(q.get());
} else {
return Optional.absent();
}
}
public boolean existsByTitle(String title) {
return datastore.find(Page.class, "title", title).countAll() > 0;
}
public Page createByTitle(String title) {
Page page = new Page();
page.setTitle(title);
datastore.save(page);
return page;
}
public Page addContent(PageContent pageContent) {
// TODO: version intergrity check.
//
Page page = pageContent.getPage();
page.getVersions().add(pageContent);
page.setMtime(new Date());
datastore.merge(page); // FIXME:
//
return datastore.get(Page.class, page.getId());
}
public Page rename(Page page, String newTitle) {
UpdateOperations<Page> updateOps = datastore.createUpdateOperations(Page.class).set("title", newTitle);
datastore.update(page, updateOps);
return datastore.get(page);
}
public void delete(Page page) {
datastore.delete(page);
}
public List<Page> listTagAssocs(Page page, final int offset, final int limit) {
Query<Page> q = datastore.createQuery(Page.class)
.offset(offset).limit(limit)
.order("title");
q.criteria("tags").hasThisOne(page.getTitle());
return q.asList();
}
public Optional<Page> getById(final String id) {
ObjectId id_ = new ObjectId(id);
Page p = datastore.get(Page.class, id_);
if (p != null) {
return Optional.of(p);
} else {
return Optional.absent();
}
}
public Page truncatePageVersions(Page page) {
List<PageContent> versions = pageContentService.listVersions(page, 0, Integer.MAX_VALUE);
PageContent current = page.getCurrent();
for (PageContent v : versions) {
if (v.getId().equals(current.getId()) == false) {
LOG.debug(String.format("TRUNCATE [%s] OF [%s]", v.getId(), page.getTitle()));
pageContentService.delete(v);
} else {
LOG.debug(String.format("SKIP TRUNCATE CURRENT VERSION [%s] OF [%s]", v.getId(), page.getTitle()));
}
}
//
current.setParent(null);
pageContentService.save(current);
//
List<PageContent> l2 = new ArrayList<PageContent>();
l2.add(current);
page.setVersions(l2);
this.update(page);
//
return page;
}
public ImmutablePair<Long, List<Page>> listPages(Optional<String> searchTerm, final int offset, final int limit) {
Query<Page> q = datastore.createQuery(Page.class);
if (searchTerm.isPresent()) {
final String s = searchTerm.get();
final Pattern p = Pattern.compile(searchTerm.get(), Pattern.CASE_INSENSITIVE | Pattern.MULTILINE);
//
//List<PageContent> pageContents = datastore.createQuery(PageContent.class).filter("content", p).asList();
q.or(q.criteria("title").containsIgnoreCase(s), q.criteria("tags").containsIgnoreCase(s)/*, q.criteria("current").hasAnyOf(pageContents)*/);
}
//LOG.debug(q.toString());
return new ImmutablePair<Long, List<Page>>(q.countAll(),
q.offset(offset).limit(limit).order("title").asList());
}
}