package org.exoplatform.wiki.service.impl;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Iterator;
import java.util.List;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Session;
import javax.jcr.Value;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import org.chromattic.api.ChromatticSession;
import org.chromattic.common.IO;
import org.exoplatform.commons.utils.ObjectPageList;
import org.exoplatform.commons.utils.PageList;
import org.exoplatform.container.configuration.ConfigurationManager;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.wiki.mow.api.WikiNodeType;
import org.exoplatform.wiki.mow.core.api.wiki.AttachmentImpl;
import org.exoplatform.wiki.mow.core.api.wiki.PageImpl;
import org.exoplatform.wiki.mow.core.api.wiki.Template;
import org.exoplatform.wiki.service.DataStorage;
import org.exoplatform.wiki.service.search.SearchResult;
import org.exoplatform.wiki.service.search.TemplateSearchData;
import org.exoplatform.wiki.service.search.TemplateSearchResult;
import org.exoplatform.wiki.service.search.TitleSearchResult;
import org.exoplatform.wiki.service.search.WikiSearchData;
import org.exoplatform.wiki.template.plugin.WikiTemplatePagePlugin;
import org.exoplatform.wiki.utils.Utils;
public class JCRDataStorage implements DataStorage{
private static final Log log = ExoLogger.getLogger(JCRDataStorage.class);
private static final int searchSize = 10;
private WikiTemplatePagePlugin templatePlugin;
public void setTemplatePagePlugin(WikiTemplatePagePlugin plugin) {
this.templatePlugin = plugin;
}
public PageList<SearchResult> search(ChromatticSession session, WikiSearchData data) throws Exception {
List<SearchResult> resultList = new ArrayList<SearchResult>();
search(session, data, resultList, false);
return new ObjectPageList<SearchResult>(resultList, searchSize);
}
private void search(ChromatticSession session,
WikiSearchData data,
List<SearchResult> resultList,
boolean onlyHomePages) throws Exception {
String statement = data.getStatement(onlyHomePages);
QueryManager qm = session.getJCRSession().getWorkspace().getQueryManager();
Query q = qm.createQuery(statement, Query.SQL);
QueryResult result = q.execute();
RowIterator iter = result.getRows();
while (iter.hasNext()) {
SearchResult tempResult = getResult(iter.nextRow());
// If contains, merges with the exist
if (!isContains(resultList, tempResult)) {
resultList.add(tempResult);
}
}
}
public void initDefaultTemplatePage(ChromatticSession crmSession, ConfigurationManager configurationManager, String path) {
if (templatePlugin != null) {
try {
Iterator<String> iterator = templatePlugin.getSourcePaths().iterator();
Session session = crmSession.getJCRSession();
InputStream is = null;
while (iterator.hasNext()) {
try {
String sourcePath = iterator.next();
is = configurationManager.getInputStream(sourcePath);
int type = ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW;
if(((Node)session.getItem(path)).hasNode(WikiNodeType.WIKI_TEMPLATE_CONTAINER)) {
type = ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING;
}
session.importXML(path, is, type);
session.save();
} finally {
if (is != null) {
is.close();
}
}
}
} catch (Exception e) {
log.info("Failed to init default template page because: " + e.getCause());
}
}
}
private SearchResult getResult(Row row) throws Exception {
String type = row.getValue("jcr:primaryType").getString();
String path = row.getValue("jcr:path").getString();
String title = (row.getValue("title") == null ? null : row.getValue("title").getString());
String excerpt = null;
Calendar updateDate = GregorianCalendar.getInstance();
Calendar createdDate = GregorianCalendar.getInstance();
if (WikiNodeType.WIKI_ATTACHMENT_CONTENT.equals(type)) {
// Transform to Attachment result
type = WikiNodeType.WIKI_ATTACHMENT.toString();
excerpt = row.getValue("rep:excerpt(.)").getString();
path = path.substring(0, path.lastIndexOf("/"));
if(!path.endsWith(WikiNodeType.Definition.CONTENT)){
AttachmentImpl searchAtt = (AttachmentImpl) org.exoplatform.wiki.utils.Utils.getObject(path,
WikiNodeType.WIKI_ATTACHMENT);
updateDate = searchAtt.getUpdatedDate();
PageImpl page = searchAtt.getParentPage();
createdDate.setTime(page.getCreatedDate());
title = page.getTitle();
} else {
String pagePath = path.substring(0, path.lastIndexOf("/" + WikiNodeType.Definition.CONTENT));
type = WikiNodeType.WIKI_PAGE_CONTENT.toString();
PageImpl page = (PageImpl) org.exoplatform.wiki.utils.Utils.getObject(pagePath,
WikiNodeType.WIKI_PAGE);
title = page.getTitle();
updateDate.setTime(page.getUpdatedDate());
createdDate.setTime(page.getCreatedDate());
}
} else if (WikiNodeType.WIKI_ATTACHMENT.equals(type)) {
AttachmentImpl searchAtt = (AttachmentImpl) org.exoplatform.wiki.utils.Utils.getObject(path,
WikiNodeType.WIKI_ATTACHMENT);
updateDate = searchAtt.getUpdatedDate();
PageImpl page = searchAtt.getParentPage();
createdDate.setTime(page.getCreatedDate());
} else if (WikiNodeType.WIKI_PAGE.equals(type)) {
PageImpl page = (PageImpl) Utils.getObject(path, type);
updateDate.setTime(page.getUpdatedDate());
createdDate.setTime(page.getCreatedDate());
}
SearchResult result = new SearchResult(excerpt, title, path, type, updateDate, createdDate);
return result;
}
private TitleSearchResult getTitleSearchResult(Row row) throws Exception {
String type = row.getValue("jcr:primaryType").getString();
String path = row.getValue("jcr:path").getString();
String fullTitle = (row.getValue(WikiNodeType.Definition.FILE_TYPE) == null ? row.getValue(WikiNodeType.Definition.TITLE)
.getString()
: row.getValue(WikiNodeType.Definition.TITLE)
.getString()
.concat(row.getValue(WikiNodeType.Definition.FILE_TYPE)
.getString()));
TitleSearchResult result = new TitleSearchResult(fullTitle, path, type);
return result;
}
public List<SearchResult> searchRenamedPage(ChromatticSession session, WikiSearchData data) throws Exception {
List<SearchResult> resultList = new ArrayList<SearchResult>() ;
String statement = data.getStatementForRenamedPage() ;
QueryManager qm = session.getJCRSession().getWorkspace().getQueryManager();
Query q = qm.createQuery(statement, Query.SQL);
QueryResult result = q.execute();
NodeIterator iter = result.getNodes() ;
while(iter.hasNext()) {
try {
resultList.add(getResult(iter.nextNode()));
} catch (Exception e) {
log.debug("Failed to add item search result", e);
}
}
return resultList ;
}
private SearchResult getResult(Node node)throws Exception {
SearchResult result = new SearchResult() ;
result.setPageName(node.getName()) ;
String title = node.getProperty(WikiNodeType.Definition.TITLE).getString();
InputStream data = node.getNode(WikiNodeType.Definition.CONTENT).getNode("jcr:content").getProperty("jcr:data").getStream();
byte[] bytes = IO.getBytes(data);
String content = new String(bytes, "UTF-8");
if(content.length() > 100) content = content.substring(0, 100) + "...";
result.setExcerpt(content) ;
result.setTitle(title) ;
return result ;
}
public InputStream getAttachmentAsStream(String path, ChromatticSession session) throws Exception {
Node attContent = (Node)session.getJCRSession().getItem(path) ;
return attContent.getProperty("jcr:data").getStream() ;
}
public List<TitleSearchResult> searchDataByTitle(ChromatticSession session, WikiSearchData data) throws Exception {
List<TitleSearchResult> resultList = new ArrayList<TitleSearchResult>();
searchDataByTitle(session, data, resultList, true);
searchDataByTitle(session, data, resultList, false);
return resultList;
}
private void searchDataByTitle(ChromatticSession session,
WikiSearchData data,
List<TitleSearchResult> resultList,
boolean onlyHomePages) throws Exception {
String statement = data.getStatementForTitle(onlyHomePages);
QueryManager qm = session.getJCRSession().getWorkspace().getQueryManager();
Query q = qm.createQuery(statement, Query.SQL);
QueryResult result = q.execute();
RowIterator iter = result.getRows();
while (iter.hasNext()) {
try {
resultList.add(getTitleSearchResult(iter.nextRow()));
} catch (Exception e) {
log.debug("Failed to search date by title", e);
}
}
}
private List<String> valuesToList(Value[] values) throws Exception {
List<String> list = new ArrayList<String>();
if (values.length < 1) return list;
String s;
for (int i = 0; i < values.length; ++i) {
s = values[i].getString();
if (s != null && s.trim().length() > 0) list.add(s);
}
return list;
}
private boolean isContains(List<SearchResult> list, SearchResult result) throws Exception {
AttachmentImpl att = null;
PageImpl page = null;
if (WikiNodeType.WIKI_ATTACHMENT.equals(result.getType())) {
att = (AttachmentImpl) Utils.getObject(result.getPath(), WikiNodeType.WIKI_ATTACHMENT);
} else if (WikiNodeType.WIKI_ATTACHMENT_CONTENT.equals(result.getType())) {
String attPath = result.getPath().substring(0, result.getPath().lastIndexOf("/"));
att = (AttachmentImpl) Utils.getObject(attPath, WikiNodeType.WIKI_ATTACHMENT);
} else if(WikiNodeType.WIKI_PAGE.equals(result.getType()) || WikiNodeType.WIKI_HOME.equals(result.getType())){
page = (PageImpl) Utils.getObject(result.getPath(), WikiNodeType.WIKI_PAGE);
} else if (WikiNodeType.WIKI_PAGE_CONTENT.equals(result.getType())) {
att = (AttachmentImpl) Utils.getObject(result.getPath(), WikiNodeType.WIKI_ATTACHMENT);
page = att.getParentPage();
}
if (att != null || page != null) {
Iterator<SearchResult> iter = list.iterator();
while (iter.hasNext()) {
SearchResult child = iter.next();
if (WikiNodeType.WIKI_ATTACHMENT.equals(child.getType()) || WikiNodeType.WIKI_PAGE_CONTENT.equals(child.getType())) {
AttachmentImpl tempAtt = (AttachmentImpl) Utils.getObject(child.getPath(),
WikiNodeType.WIKI_ATTACHMENT);
if (att != null && att.equals(tempAtt)) {
// Merge data
if (child.getExcerpt()==null && result.getExcerpt()!=null ){
child.setExcerpt(result.getExcerpt());
}
return true;
}
if (page != null && page.getName().equals(tempAtt.getParentPage())) {
return true;
}
}
else if (WikiNodeType.WIKI_PAGE.equals(child.getType())) {
if (page != null && page.getPath().equals(child.getPath())) {
iter.remove();
return false;
}
}
}
}
return false;
}
@Override
public List<TemplateSearchResult> searchTemplate(ChromatticSession session,
TemplateSearchData data) throws Exception {
List<TemplateSearchResult> resultList = new ArrayList<TemplateSearchResult>();
String statement = data.getStatement();
QueryManager qm = session.getJCRSession().getWorkspace().getQueryManager();
Query q = qm.createQuery(statement, Query.SQL);
QueryResult result = q.execute();
RowIterator iter = result.getRows();
while (iter.hasNext()) {
TemplateSearchResult tempResult = getTemplateResult(iter.nextRow());
resultList.add(tempResult);
}
return resultList;
}
private TemplateSearchResult getTemplateResult(Row row) throws Exception {
String type = row.getValue("jcr:primaryType").getString();
String path = row.getValue("jcr:path").getString();
String title = (row.getValue("title") == null ? null : row.getValue("title").getString());
Template template = (Template) org.exoplatform.wiki.utils.Utils.getObject(path,
WikiNodeType.WIKI_PAGE);
String description = template.getDescription();
TemplateSearchResult result = new TemplateSearchResult(template.getName(),
title,
path,
type,
null,
null,
description);
return result;
}
}