/*
* Copyright (C) 2003-2008 eXo Platform SAS.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Affero General Public License
* as published by the Free Software Foundation; either version 3
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see<http://www.gnu.org/licenses/>.
*/
package org.exoplatform.services.cms.documents.impl;
import java.util.*;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import org.exoplatform.container.xml.InitParams;
import org.exoplatform.container.xml.ObjectParameter;
import org.exoplatform.container.xml.ValueParam;
import org.exoplatform.services.cms.documents.DocumentTypeService;
import org.exoplatform.services.cms.templates.TemplateService;
import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.ext.common.SessionProvider;
import org.exoplatform.services.log.ExoLogger;
import org.exoplatform.services.log.Log;
import org.picocontainer.Startable;
/**
* Created by The eXo Platform SARL Author : Dang Van Minh
* minh.dang@exoplatform.com Oct 6, 2009 3:39:28 AM
*/
public class DocumentTypeServiceImpl implements DocumentTypeService, Startable {
private static final Log LOG = ExoLogger.getLogger(DocumentTypeServiceImpl.class.getName());
private final static String OWNER = "exo:owner";
private final static String QUERY = " SELECT * FROM nt:resource WHERE";
private final static String CONTENT_QUERY = " SELECT * FROM nt:base WHERE ";
private final static String EXO_DATE_MODIFIED = "exo:dateModified";
private final static String JCR_MINE_TYPE = "jcr:mimeType";
private final static String JCR_PRIMARY_TYPE = "jcr:primaryType";
private final static String SQL = "sql";
private final static String AND = " AND ";
private final static String CONTAINS = " contains";
private final static String SINGLE_QUOTE = "'";
private final static String OR = " OR ";
private final static String BEGIN_BRANCH = " ( ";
private final static String END_BRANCH = " ) ";
private RepositoryService repositoryService_;
private TemplateService templateService_;
private InitParams params_;
private static final String OPEN_DESKTOP_PROVIDER_REGEX="^exo.remote-edit\\.([a-z]+)$";
private static final String OPEN_PROVIDER_RESOURCEBUNDLE_SUFFIX = ".label";
private static final String OPEN_PROVIDER_STYLE_SUFFIX = ".ico";
private final String OPEN_DOCUMENT_ON_DESKTOP_ICO = "uiIconOpenOnDesktop";
private final String OPEN_DOCUMENT_IN_DESKTOP_RESOURCE_KEY = "OpenInOfficeConnector.label.exo.remote-edit.desktop";
private void init() {
//load desktop application from system property to init-params
Properties properties = System.getProperties();
for (String key : properties.stringPropertyNames()){
if(key.matches(OPEN_DESKTOP_PROVIDER_REGEX)) {
List<String> _mimetypes = Arrays.asList(properties.getProperty(key)!=null?properties.getProperty(key).split(","):null);
String _resourceBundle = properties.getProperty(key + OPEN_PROVIDER_RESOURCEBUNDLE_SUFFIX);
String _ico = properties.getProperty(key + OPEN_PROVIDER_STYLE_SUFFIX);
if(params_.get(key) !=null ){
params_.remove(key);
}
ObjectParameter _objectParameter = new ObjectParameter();
_objectParameter.setName(key);
_objectParameter.setObject(new DocumentType(_mimetypes, _resourceBundle, _ico));
params_.addParam(_objectParameter);
}
}
}
public DocumentTypeServiceImpl(RepositoryService repoService,
InitParams initParams,
TemplateService templateService) {
repositoryService_ = repoService;
templateService_ = templateService;
params_ = initParams;
}
public List<String> getAllSupportedType() {
List<String> supportedType = new ArrayList<String>();
Iterator iter = params_.getObjectParamIterator();
ObjectParameter objectParam = null;
while (iter.hasNext()) {
objectParam = (ObjectParameter) iter.next();
if (Boolean.parseBoolean(((DocumentType)objectParam.getObject()).getDisplayInFilter())) {
supportedType.add(objectParam.getName());
}
}
Collections.sort(supportedType);
return supportedType;
}
public List<Node> getAllDocumentsByDocumentType(String documentType,
String workspace,
SessionProvider sessionProvider) throws Exception {
return getAllDocumentsByType(workspace, sessionProvider, getMimeTypes(documentType));
}
public List<Node> getAllDocumentsByType(String workspace,
SessionProvider sessionProvider,
String mimeType) throws Exception {
return getAllDocumentsByType(workspace, sessionProvider, new String[] { mimeType });
}
public List<Node> getAllDocumentsByUser(String workspace,
SessionProvider sessionProvider,
String[] mimeTypes,
String userName) throws Exception {
Session session = sessionProvider.getSession(workspace,
repositoryService_.getCurrentRepository());
List<Node> resultList = new ArrayList<Node>();
QueryResult results = null;
results = executeQuery(session, buildQueryByMimeTypes(mimeTypes, userName), SQL);
NodeIterator iterator = results.getNodes();
Node documentNode = null;
while (iterator.hasNext()) {
documentNode = iterator.nextNode();
resultList.add(documentNode.getParent());
}
return resultList;
}
public List<Node> getAllDocumentsByType(String workspace,
SessionProvider sessionProvider,
String[] mimeTypes) throws Exception {
return getAllDocumentsByUser(workspace, sessionProvider, mimeTypes, null);
}
public String[] getMimeTypes(String documentType) {
Iterator iter = params_.getObjectParamIterator();
ObjectParameter objectParam = null;
List<String> mimeTypes = new ArrayList<String>();
while (iter.hasNext()) {
objectParam = (ObjectParameter) iter.next();
if (objectParam.getName().equals(documentType)) {
mimeTypes = ((DocumentType) objectParam.getObject()).getMimeTypes();
break;
}
}
return mimeTypes.toArray(new String[mimeTypes.size()]);
}
public boolean isContentsType(String documentType) {
Iterator iter = params_.getObjectParamIterator();
ObjectParameter objectParam = null;
while (iter.hasNext()) {
objectParam = (ObjectParameter) iter.next();
if (objectParam.getName().equals(documentType)) {
return Boolean.parseBoolean(((DocumentType) objectParam.getObject()).getContentsType());
}
}
return false;
}
public List<Node> getAllDocumentByContentsType(String documentType,
String workspace,
SessionProvider sessionProvider,
String userName) throws Exception {
if (isContentsType(documentType)) {
Session session = sessionProvider.getSession(workspace,
repositoryService_.getCurrentRepository());
List<Node> resultList = new ArrayList<Node>();
QueryResult results = null;
try {
// Execute sql query and return a results
results = executeQuery(session, buildQueryByContentsType(userName), SQL);
} catch (PathNotFoundException e) {
if (LOG.isErrorEnabled()) {
LOG.error("An unexpected exception appear", e);
}
} catch (RepositoryException e) {
if (LOG.isErrorEnabled()) {
LOG.error("An unexpected exception appear", e);
}
}
NodeIterator iterator = results.getNodes();
while (iterator.hasNext()) {
resultList.add(iterator.nextNode());
}
return resultList;
}
return null;
}
private QueryResult executeQuery(Session session, String statement, String language) {
try {
QueryManager queryManager = session.getWorkspace().getQueryManager();
Query query = queryManager.createQuery(statement, language);
return query.execute();
} catch (RepositoryException e) {
if (LOG.isErrorEnabled()) {
LOG.error("SQL query fail", e);
}
return null;
}
}
private String buildQueryByMimeTypes(String[] mimeTypes, String userName) {
StringBuilder query = new StringBuilder();
if (userName == null) {
for (String mimeType : mimeTypes) {
if (query.length() > 0)
query.append(OR);
query.append(CONTAINS)
.append("(")
.append(JCR_MINE_TYPE)
.append(",")
.append(SINGLE_QUOTE)
.append(mimeType.trim())
.append(SINGLE_QUOTE)
.append(")");
}
} else {
query.append(BEGIN_BRANCH);
for (String mimeType : mimeTypes) {
if (query.length() > BEGIN_BRANCH.length())
query.append(OR);
query.append(CONTAINS)
.append("(")
.append(JCR_MINE_TYPE)
.append(",")
.append(SINGLE_QUOTE)
.append(mimeType.trim())
.append(SINGLE_QUOTE)
.append(")");
}
query.append(END_BRANCH);
query.append(AND);
query.append("(")
.append(OWNER)
.append("=")
.append(SINGLE_QUOTE)
.append(userName)
.append(SINGLE_QUOTE)
.append(")");
}
query.append(" ORDER BY " + EXO_DATE_MODIFIED);
return QUERY + query.toString();
}
private String buildQueryByContentsType(String userName) throws PathNotFoundException, RepositoryException {
List<String> contentsType = templateService_.getAllDocumentNodeTypes();
StringBuilder constraint = new StringBuilder();
if (userName == null) {
for (String contentType : contentsType) {
if (constraint.length() > 0)
constraint.append(OR);
constraint.append("(")
.append(JCR_PRIMARY_TYPE)
.append("=")
.append(SINGLE_QUOTE)
.append(contentType)
.append(SINGLE_QUOTE)
.append(")");
}
} else {
constraint.append(BEGIN_BRANCH);
for (String contentType : contentsType) {
if (constraint.length() > BEGIN_BRANCH.length())
constraint.append(OR);
constraint.append("(")
.append(JCR_PRIMARY_TYPE)
.append("=")
.append(SINGLE_QUOTE)
.append(contentType)
.append(SINGLE_QUOTE)
.append(")");
}
constraint.append(END_BRANCH);
constraint.append(AND);
constraint.append("(")
.append(OWNER)
.append("=")
.append(SINGLE_QUOTE)
.append(userName)
.append(SINGLE_QUOTE)
.append(")");
}
constraint.append(" ORDER BY " + EXO_DATE_MODIFIED);
return CONTENT_QUERY + constraint.toString();
}
@Override
public DocumentType getDocumentType(String mimeType) {
DocumentType documentTypeResult=null;
for(DocumentType documentType: params_.getObjectParamValues(DocumentType.class)){
if(documentType.getMimeTypes().contains(mimeType)){
documentTypeResult = documentType;
}
}
if(documentTypeResult==null)
documentTypeResult= new DocumentType(Arrays.asList(new String[] {mimeType}),
OPEN_DOCUMENT_IN_DESKTOP_RESOURCE_KEY, OPEN_DOCUMENT_ON_DESKTOP_ICO);
return documentTypeResult;
}
@Override
public void start() {
init();
}
@Override
public void stop() {
}
}