package org.exoplatform.ecm.REST.category;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import org.exoplatform.common.http.HTTPStatus;
import org.exoplatform.services.cms.link.LinkManager;
import org.exoplatform.services.cms.taxonomy.TaxonomyService;
import org.exoplatform.services.cms.templates.TemplateService;
import org.exoplatform.services.jcr.core.ManageableRepository;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.exoplatform.services.rest.resource.ResourceContainer;
import utils.*;
/**
* Get categories and documents belonging to category.
* 1. Url pattern = * /categories/all/{repoName}/{catePath:.*} (* /categories/all/{repoName} ) if catePath = ""
* then return all category in repository. if catePath != "" then return all categories and
* document defined in
* {@link org.exoplatform.services.cms.templates.TemplateService#getAllDocumentNodeTypes(String)
* (TemplateService.getAllDocumentNodeTypes)}. Result returned is json object of
* {@link CategoryNode}
* 2. Url pattern = * /categories/articles/{repoName}/{catePath:.*}/: catePath
* is (Category path or Category/document path) if catePath points to category
* node: Return all document in this CategoryNode {@link CategoryNode} if
* catePath points to a document node: Return this document node
* {@link DocumentContent}
*
* @author hoanghung JUL 01, 2010
*/
@Path("/categories/")
public class CategoryContentRESTService implements ResourceContainer {
private TaxonomyService taxonomyService_;
private TemplateService templateService_;
private LinkManager linkManager_;
private static final Log LOG = ExoLogger.getLogger(CategoryContentRESTService.class.getName());
private List documentTypes = new ArrayList();
public CategoryContentRESTService(TaxonomyService taxonomyService, TemplateService templateService, LinkManager linkManager) throws Exception {
taxonomyService_ = taxonomyService;
templateService_ = templateService;
linkManager_ = linkManager;
}
@GET
@Path("/all/{repoName}/{catePath:.*}/")
public Response getCategory(@PathParam("repoName") String repoName, @PathParam("catePath") String catePath) {
List listCategoryNode = new ArrayList();
//if catePath isn't empty
if (catePath != null && !catePath.trim().isEmpty()) {
String taxonomyTree = catePath.split("/")[0];
String path = catePath.substring(taxonomyTree.length());
//get path
if (path.startsWith("/")) {
path = path.substring(1);
}
try {
Node taxonomyTreeNode = taxonomyService_.getTaxonomyTree(repoName, taxonomyTree);
//if taxonomy tree doesn't exist, throw exception
if (taxonomyTreeNode == null)
throw new PathNotFoundException("Can't find category " + taxonomyTree);
Node category;
NodeIterator iterNode;
//if path is empty, get root nodes
if (path.equals("")) {
iterNode = taxonomyTreeNode.getNodes();
}
//else get path nodes
else {
iterNode = taxonomyTreeNode.getNode(path).getNodes();
}
CategoryNode categoryNode;
//for each node
while (iterNode.hasNext()) {
category = iterNode.nextNode();
//Create a category node
categoryNode = getCategoryNode(category);
// and add it to the list
if (categoryNode != null)
listCategoryNode.add(categoryNode);
}
} catch (PathNotFoundException exc) {
LOG.error("Path Not found " + exc.getMessage(), exc);
return Response.status(HTTPStatus.NOT_FOUND).entity(exc.getMessage()).build();
} catch (Exception e) {
LOG.error(e);
return Response.serverError().build();
}
}
// create a listResultNode object to sort the categories
ListResultNode listResultNode = new ListResultNode();
Collections.sort(listCategoryNode, new NameComparator());
listResultNode.setLstNode(listCategoryNode);
return Response.ok(listResultNode, new MediaType("application", "json")).build();
}
@GET
@Path("/articles/{repoName}/{docPath:.*}/")
public Response getArticles(@PathParam("repoName") String repoName, @PathParam("docPath") String docPath) {
DocumentContent docNode = null;
ListResultNode listResultNode = new ListResultNode();
if (docPath != null) {
//extract taxonomy tree
String taxonomyTree = docPath.split("/")[0];
String path = docPath.substring(taxonomyTree.length());
//extract path
if (path.startsWith("/")) {
path = path.substring(1);
}
try {
//list the document types
if (documentTypes.isEmpty())
documentTypes = templateService_.getAllDocumentNodeTypes(repoName);
//get taxonomy tree parent node
Node taxonomyNode = taxonomyService_.getTaxonomyTree(repoName,taxonomyTree);
//if null, error
if (taxonomyNode == null)
throw new PathNotFoundException("Can't find category " + taxonomyTree);
//if path not empty, get child node
if (!path.equals("")) {
taxonomyNode = taxonomyNode.getNode(path);
}
//if the taxonomy is a link, make a list of taxonomy trees, get the article content
if (linkManager_.isLink(taxonomyNode)) {
docNode = getArticleContent(linkManager_.getTarget(taxonomyNode));
return Response.ok(docNode, new MediaType("application", "json")).build();
}
//if its a category
else if (taxonomyNode.isNodeType("exo:taxonomy")) {
//create a list of child nodes, sort it, return it.
listResultNode.setLstNode(getArticleNode(taxonomyNode, documentTypes));
Collections.sort(listResultNode.getLstNode(), new NameComparator());
return Response.ok(listResultNode, new MediaType("application", "json")).build();
}
} catch (PathNotFoundException exc) {
LOG.error("Path Not found " + exc.getMessage(), exc);
return Response.status(HTTPStatus.NOT_FOUND).entity(exc.getMessage()).build();
} catch (Exception e) {
LOG.error(e);
return Response.serverError().build();
}
}
return Response.ok().build();
}
/**
* Return a category node
*
*/
private CategoryNode getCategoryNode(Node node) {
CategoryNode categoryNode = null;
try {
if (node.isNodeType("exo:taxonomy")) {
categoryNode = new CategoryNode(node.getName(), getType(node));
}
else if (linkManager_.isLink(node)) {
node = linkManager_.getTarget(node);
categoryNode = new CategoryNode(node.getName(), getType(node));
}
} catch (Exception e) {
LOG.error(e);
}
return categoryNode;
}
/**
* Get content of document node.
* @param node
* @return
* @throws Exception
*/
private DocumentContent getArticleContent(Node node) throws Exception {
DocumentContent documentContent = new DocumentContent(node.getName(), getType(node));
// If node is added mix rss-enabled then get exo:content property
if (node.hasProperty("exo:content")) {
documentContent.setContent(node.getProperty("exo:content").getString());
}
// Some node have exo:text so we override value of exo:content
if (node.hasProperty("exo:text")) {
documentContent.setContent(node.getProperty("exo:text").getString());
}
return documentContent;
}
/**
* Get all child nodes of Document Type
*
*/
private List getArticleNode(Node node, List allDocumentType) throws Exception {
List docs = new ArrayList();
//get child nodes
NodeIterator nodes = node.getNodes();
Node docNode;
//get all taxonomy trees
List taxonomyTrees = taxonomyService_.getAllTaxonomyTrees(((ManageableRepository) node.getSession().getRepository()).getConfiguration().getName());
//for each child node
while (nodes.hasNext()) {
docNode = nodes.nextNode();
//if its a link
if (linkManager_.isLink(docNode)) {
//get target of link
docNode = linkManager_.getTarget(docNode);
//if is of support type, add to doc list
if (allDocumentType.contains(docNode.getPrimaryNodeType().getName())) {
docs.add(getArticleContent(docNodes));
}
}
}
return docs;
}
/**
* Return nodeType
*
*/
private String getType(Node node) throws Exception {
if (node.isNodeType("exo:taxonomy")) {
return "category";
} else if (node.getPrimaryNodeType().getName().equals("exo:article")) {
return "article";
}
return node.getPrimaryNodeType().getName();
}
}