/*
* Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Nuxeo - initial API and implementation
*
* $Id$
*/
package org.eclipse.ecr.core.api;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.ecr.core.api.ClientException;
import org.eclipse.ecr.core.api.DocumentException;
import org.eclipse.ecr.core.api.DocumentRef;
import org.eclipse.ecr.core.api.impl.DocsQueryProviderDef;
import org.eclipse.ecr.core.api.security.SecurityConstants;
import org.eclipse.ecr.core.model.Document;
import org.eclipse.ecr.core.model.DocumentIterator;
import org.eclipse.ecr.core.query.Query;
import org.eclipse.ecr.core.query.QueryException;
/**
* @author <a href="mailto:dm@nuxeo.com">Dragos Mihalache</a>
*/
@SuppressWarnings({"SuppressionAnnotation"})
final class DocsQueryProviderFactory {
private static final Log log = LogFactory.getLog(DocsQueryProviderFactory.class);
private final AbstractSession session;
DocsQueryProviderFactory(AbstractSession session) {
this.session = session;
}
public DocsQueryProvider getDQLbyType(DocsQueryProviderDef dqpDef)
throws ClientException {
final DocsQueryProvider dqp;
try {
switch (dqpDef.getType()) {
case TYPE_CHILDREN:
dqp = getDQPChildren(dqpDef.getParent());
break;
case TYPE_CHILDREN_NON_FOLDER:
dqp = getDQPChildrenNonFolder(dqpDef.getParent());
break;
case TYPE_CHILDREN_FOLDERS:
dqp = getDQPChildrenFolder(dqpDef.getParent());
break;
case TYPE_QUERY:
dqp = getDQPQueryResult(dqpDef.getQuery());
break;
case TYPE_QUERY_FTS:
dqp = getDQPQueryFtsResult(dqpDef.getQuery(),
dqpDef.getStartingPath());
break;
default:
throw new IllegalArgumentException("cannot get here");
}
} catch (DocumentException e) {
throw new ClientException("DocumentException", e);
}
return dqp;
}
private DocsQueryProvider getDQPQueryResult(String query)
throws ClientException {
final Query compiledQuery;
try {
compiledQuery = session.getSession().createQuery(query,
Query.Type.NXQL);
} catch (QueryException e1) {
throw new ClientException("qe", e1);
}
return new DocsQueryProvider() {
@Override
public DocumentIterator getDocs(int start) throws ClientException {
DocumentIterator documents;
try {
documents = (DocumentIterator) compiledQuery.execute().getDocuments(
start);
} catch (QueryException e) {
throw new ClientException("Query exception, ", e);
}
return documents;
}
@Override
public boolean accept(Document child) {
return true;
}
};
}
private DocsQueryProvider getDQPQueryFtsResult(String keywords, String startingPath)
throws ClientException {
final StringBuffer xpathPrefix = new StringBuffer("//");
// extract path elements and send as params
// so they could be escaped correctly
String[] pathElements = new String[0];
if (startingPath != null) {
pathElements = startingPath.split("\\/");
for (String element : pathElements) {
xpathPrefix.append("?/");
}
}
//final String xpathQ = xpathPrefix + "element(*, ecmnt:document)[jcr:contains(.,'*" + keywords
// + "*')]";
final String xpathQ = xpathPrefix + "element(*, ecmnt:document)[jcr:contains(.,'*?*')]";
String[] params = new String[pathElements.length + 1];
System.arraycopy(pathElements, 0, params, 0, pathElements.length);
params[params.length - 1] = keywords;
final Query compiledQuery;
try {
compiledQuery = session.getSession().createQuery(xpathQ,
Query.Type.XPATH, params);
} catch (QueryException e) {
log.error("Error executing xpath query: " + xpathQ, e);
throw new ClientException("qe", e);
}
DocsQueryProvider dqProvider = new DocsQueryProvider() {
@Override
public DocumentIterator getDocs(int start) throws ClientException {
DocumentIterator documents;
try {
documents = (DocumentIterator) compiledQuery.execute().getDocuments(
start);
} catch (QueryException e) {
throw new ClientException("Query exception, ", e);
}
return documents;
}
@Override
public boolean accept(Document child) {
return true;
}
};
return dqProvider;
}
private DocsQueryProvider getDQPChildren(DocumentRef parent)
throws DocumentException, ClientException {
final Document doc = session.resolveReference(parent);
session.checkPermission(doc, SecurityConstants.READ_CHILDREN);
DocsQueryProvider dqProvider = new DocsQueryProvider() {
@Override
public DocumentIterator getDocs(int start) throws ClientException {
DocumentIterator children;
try {
children = doc.getChildren(start);
} catch (DocumentException e) {
throw new ClientException("DocumentException", e);
}
return children;
}
@Override
public boolean accept(Document child) {
return true;
}
};
return dqProvider;
}
private DocsQueryProvider getDQPChildrenNonFolder(DocumentRef parent)
throws DocumentException, ClientException {
final Document doc = session.resolveReference(parent);
session.checkPermission(doc, SecurityConstants.READ_CHILDREN);
DocsQueryProvider dqProvider = new DocsQueryProvider() {
@Override
public DocumentIterator getDocs(int start) throws ClientException {
DocumentIterator children;
try {
children = doc.getChildren(start);
} catch (DocumentException e) {
throw new ClientException("DocumentException", e);
}
return children;
}
@Override
public boolean accept(Document child) throws ClientException {
try {
return !child.isFolder()
&& session.hasPermission(
child, SecurityConstants.READ);
} catch (DocumentException e) {
throw new ClientException("DocumentException", e);
}
}
};
return dqProvider;
}
private DocsQueryProvider getDQPChildrenFolder(DocumentRef parent)
throws DocumentException, ClientException {
final Document doc = session.resolveReference(parent);
session.checkPermission(doc, SecurityConstants.READ_CHILDREN);
DocsQueryProvider dqProvider = new DocsQueryProvider() {
@Override
public DocumentIterator getDocs(int start) throws ClientException {
DocumentIterator childrenIt;
try {
childrenIt = doc.getChildren(start);
} catch (DocumentException e) {
throw new ClientException("DocumentException", e);
}
return childrenIt;
}
@Override
public boolean accept(Document child) throws ClientException {
try {
return child.isFolder()
&& session.hasPermission(
child, SecurityConstants.READ);
} catch (DocumentException e) {
throw new ClientException("DocumentException", e);
}
}
};
return dqProvider;
}
}