@Context UriInfo uriInfo,
@PathParam("csid") String csid,
@PathParam("indexid") String indexid) {
- Response result = Response.noContent().build();
+ Response result = Response.status(Response.Status.OK).entity("Reindex complete.").type("text/plain").build();
boolean success = false;
ensureCSID(csid, READ);
try {
RemoteServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = (RemoteServiceContext<PoxPayloadIn, PoxPayloadOut>) createServiceContext(uriInfo);
DocumentHandler handler = createDocumentHandler(ctx);
- success = getRepositoryClient(ctx).reindex(handler, csid);
+ success = getRepositoryClient(ctx).reindex(handler, csid, indexid);
} catch (Exception e) {
throw bigReThrow(e, ServiceMessages.REINDEX_FAILED, csid);
}
@Context Request request,
@Context UriInfo uriInfo,
@PathParam("indexid") String indexid) {
- Response result = Response.noContent().build();;
+ Response result = Response.noContent().build();
boolean success = false;
String docType = null;
tkz.nextToken(); //skip
return tkz.nextToken();
}
+
+ /**
+ * Should return
+ * @throws Exception
+ * @throws DocumentException
+ */
+ @Override
+ public String getDocumentsToIndexQuery(String indexId, String csid) throws DocumentException, Exception {
+ return null;
+ }
/* (non-Javadoc)
* @see org.collectionspace.services.common.document.DocumentHandler#getServiceContextPath()
/** The Constant DEFAULT_PAGE_SIZE_INIT. */
public static final int DEFAULT_PAGE_SIZE_INIT = 40; // Default page size if one is specified in the service-config.xml
public static final int DEFAULT_PAGE_SIZE_MAX_INIT = 1000; // Default page size max if one is specified in the service-config.xml
+ public static final String DEFAULT_SELECT_CLAUSE = "SELECT * FROM ";
/** The Constant PAGE_SIZE_DEFAULT_PROPERTY. */
public static final String PAGE_SIZE_DEFAULT_PROPERTY = "pageSizeDefault";
public static final String PAGE_SIZE_MAX_PROPERTY = "pageSizeMax";
+ /** The select clause. */
+ protected String selectClause;
/** The where clause. */
protected String whereClause; // Filtering clause. Omit the "WHERE".
/** The order by clause. */
* @param thePageSize the page size
*/
public DocumentFilter(String theWhereClause, int theStartPage, int thePageSize) {
- this(theWhereClause, EMPTY_ORDER_BY_CLAUSE, theStartPage, thePageSize);
+ this(DEFAULT_SELECT_CLAUSE, theWhereClause, EMPTY_ORDER_BY_CLAUSE, theStartPage, thePageSize);
}
/**
* @param theStartPage the start page
* @param thePageSize the page size
*/
- public DocumentFilter(String theWhereClause, String theOrderByClause, int theStartPage, int thePageSize) {
+ public DocumentFilter(String theSelectClause, String theWhereClause, String theOrderByClause, int theStartPage, int thePageSize) {
+ this.selectClause = theSelectClause;
this.whereClause = theWhereClause;
this.orderByClause = theOrderByClause;
this.startPage = (theStartPage > 0) ? theStartPage : 0;
DocumentFilter.defaultPageSize = theDefaultPageSize;
}
+ /**
+ * Gets the select clause.
+ *
+ * @return the select clause
+ */
+ public String getSelectClause() {
+ return selectClause != null ? selectClause : DEFAULT_SELECT_CLAUSE;
+ }
+
/**
* Gets the where clause.
*
return whereClause;
}
+ /**
+ * Sets the select clause.
+ *
+ * @param theSelectClause the new select clause
+ */
+ public void setSelectClause(String theSelectClause) {
+ this.selectClause = theSelectClause;
+ }
+
/**
* Sets the where clause.
*
package org.collectionspace.services.common.document;
import java.util.Map;
+
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.query.QueryContext;
import org.collectionspace.services.lifecycle.Lifecycle;
*/
public String getUnQProperty(String qProp);
+ /**
+ * get a query string that will be used to return a set of documents that should be indexed/re-index
+ * @throws Exception
+ * @throws DocumentException
+ */
+ public String getDocumentsToIndexQuery(String indexId, String csid) throws DocumentException, Exception;
+
/**
* Creates the CMIS query from the service context. Each document handler is responsible for returning a valid CMIS query using the
* information in the current service context -which includes things like the query parameters, etc.
String docType;
/** The doc filter. */
DocumentFilter docFilter;
+ /** The Select clause. */
+ String selectClause;
/** The where clause. */
String whereClause;
/** The order by clause. */
whereClause = theWhereClause;
orderByClause = theOrderByClause;
}
+
+ public QueryContext(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx,
+ String theSelectClause, String theWhereClause, String theOrderByClause) throws DocumentNotFoundException, DocumentException {
+ this(ctx);
+ selectClause = theSelectClause;
+ whereClause = theWhereClause;
+ orderByClause = theOrderByClause;
+ }
/**
* Instantiates a new query context.
DocumentHandler handler) throws DocumentNotFoundException, DocumentException {
this(ctx);
if (handler == null) {
- throw new IllegalArgumentException(
- "Document handler is missing.");
+ throw new IllegalArgumentException("Document handler is missing.");
}
docFilter = handler.getDocumentFilter();
if (docFilter == null) {
- throw new IllegalArgumentException(
- "Document handler has no Filter specified.");
+ throw new IllegalArgumentException("Document handler has no Filter specified.");
}
+ selectClause = docFilter.getSelectClause();
whereClause = docFilter.getWhereClause();
orderByClause = docFilter.getOrderByClause();
}
return docFilter;
}
+ /**
+ * Sets/changes the select clause
+ *
+ * @param newSelectClause
+ */
+ public void setSelectClause(String newSelectClause) {
+ this.selectClause = newSelectClause;
+ }
+
+ /**
+ * Gets the select clause.
+ *
+ * @return the select clause
+ */
+ public String getSelectClause() {
+ return selectClause;
+ }
+
/**
* Gets the where clause.
*
//import org.nuxeo.ecm.core.client.NuxeoClient;
+
import org.collectionspace.services.jaxb.InvocableJAXBSchema;
//import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;
//import org.collectionspace.services.nuxeo.client.java.NxConnect;
private static Pattern kwdSearchProblemChars = Pattern.compile("[\\:\\(\\)\\*\\%\\.]");
private static Pattern kwdSearchHyphen = Pattern.compile(" - ");
private static Pattern advSearchSqlWildcard = Pattern.compile(".*?[I]*LIKE\\s*\\\"\\%\\\".*?");
+ // Base Nuxeo document type for all CollectionSpace documents/resources
+ public static String COLLECTIONSPACE_DOCUMENT_TYPE = "CollectionSpaceDocument";
+ public static final String NUXEO_DOCUMENT_TYPE = "Document";
private static String getLikeForm(String dataSourceName, String repositoryName, String cspaceInstanceId) {
return result;
}
- final String servicesResource = "/cspace-services/"; // HACK - this is configured in war
+ final String servicesResource = "/cspace-services/"; // HACK - this is configured in war, get this from tomcat instead
final int servicesResourceLen = servicesResource.length();
String httpMethod = request.getHttpMethod();
String uriPath = request.getUri().getPath();
result = resEntity + "/*/" + IndexClient.SERVICE_NAME + "/" + indexId;
} else if (indexId != null) {
// e.g., intakes/index/fulltext
- result = resEntity + IndexClient.SERVICE_NAME + "/" + indexId;
+ result = resEntity + "/" + IndexClient.SERVICE_NAME + "/" + indexId;
} else {
// e.g., intakes
result = resEntity;
uriPath = uriPath.replace(pathParamValue, "*");
}
if ((pathParamName.toLowerCase().indexOf("predicate") > -1)) {
- //replace csids with wildcard
+ //replace predicates with wildcard
uriPath = uriPath.replace(pathParamValue, "*");
}
if (pathParamName.toLowerCase().indexOf("specifier") > -1) {
+ ")", "*");
}
if ((pathParamName.toLowerCase().indexOf("ms") > -1)) {
- //replace csids with wildcard
+ //replace ms with wildcard
uriPath = uriPath.replace(pathParamValue, "*");
}
+ if ((pathParamName.toLowerCase().indexOf("indexid") > -1)) {
+ //replace indexid with wildcard
+ uriPath = uriPath.replace(pathParamValue, "*");
+ }
}
// FIXME: REM
String pathSegment = null;
while (strTok.hasMoreTokens() == true) {
pathSegment = strTok.nextToken();
- if (pathSegment.equals("*") == true) {
+ if (pathSegment.equals("*") == true || pathSegment.equals("index") == true) {
//
- // leave the loop if we hit a wildcard character
+ // leave the loop if we hit a wildcard character or the "index" subresource
//
break;
}
+++ /dev/null
-package org.collectionspace.services.nuxeo.client.java;
-
-import java.io.Serializable;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-
-import org.collectionspace.services.common.context.ServiceContext;
-import org.collectionspace.services.common.document.DocumentHandler;
-import org.collectionspace.services.nuxeo.util.ReindexFulltextRoot;
-import org.collectionspace.services.nuxeo.util.ReindexFulltextRoot.ReindexInfo;
-import org.nuxeo.ecm.core.api.IterableQueryResult;
-import org.nuxeo.ecm.core.api.NuxeoException;
-import org.nuxeo.ecm.core.api.NuxeoPrincipal;
-import org.nuxeo.ecm.core.query.QueryFilter;
-import org.nuxeo.ecm.core.query.sql.NXQL;
-import org.nuxeo.ecm.core.storage.StorageException;
-import org.nuxeo.runtime.transaction.TransactionHelper;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/*
- * Use the inherited reindexFulltext() method to reindex the Nuxeo full-text index.
- */
-public class CSReindexFulltextRoot extends ReindexFulltextRoot {
-
- /** The logger. */
- private final Logger logger = LoggerFactory.getLogger(CSReindexFulltextRoot.class);
- protected String repoQuery;
-
- public CSReindexFulltextRoot(CoreSessionInterface repoSession, String repoQuery) {
- this.coreSession = repoSession.getCoreSession();
- this.repoQuery = repoQuery;
- }
-
-
- @Override
- protected List<ReindexInfo> getInfos() throws StorageException {
- getLowLevelSession();
- List<ReindexInfo> infos = new ArrayList<ReindexInfo>();
-// String query = "SELECT ecm:uuid, ecm:primaryType FROM Document"
-// + " WHERE ecm:isProxy = 0"
-// + " AND ecm:currentLifeCycleState <> 'deleted'"
-// + " ORDER BY ecm:uuid";
- IterableQueryResult it = session.queryAndFetch(this.repoQuery, NXQL.NXQL,
- QueryFilter.EMPTY);
- try {
- for (Map<String, Serializable> map : it) {
- Serializable id = map.get(NXQL.ECM_UUID);
- String type = (String) map.get(NXQL.ECM_PRIMARYTYPE);
- infos.add(new ReindexInfo(id, type));
- }
- } finally {
- it.close();
- }
- return infos;
- }
-
-}
import javax.ws.rs.core.MultivaluedMap;
import org.apache.commons.lang.StringUtils;
-
import org.collectionspace.services.client.Profiler;
import org.collectionspace.services.client.CollectionSpaceClient;
import org.collectionspace.services.client.IQueryManager;
import org.collectionspace.services.lifecycle.TransitionDef;
import org.collectionspace.services.lifecycle.TransitionDefList;
import org.collectionspace.services.lifecycle.TransitionList;
-
import org.nuxeo.ecm.core.NXCore;
import org.nuxeo.ecm.core.api.ClientException;
import org.nuxeo.ecm.core.api.DocumentModel;
import org.nuxeo.ecm.core.api.DocumentModelList;
import org.nuxeo.ecm.core.api.model.PropertyException;
import org.nuxeo.ecm.core.lifecycle.LifeCycleService;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
return result;
}
+ @Override
+ public String getDocumentsToIndexQuery(String indexId, String csid) throws DocumentException, Exception {
+ String result = null;
+
+ ServiceContext<PoxPayloadIn,PoxPayloadOut> ctx = this.getServiceContext();
+ String selectClause = "SELECT ecm:uuid, ecm:primaryType FROM ";
+ String docFilterWhereClause = this.getDocumentFilter().getWhereClause();
+ //
+ // The where clause could be a combination of the document filter's where clause plus a CSID qualifier
+ //
+ String whereClause = (csid == null) ? null : String.format("ecm:name = '%s'", csid); // AND ecm:currentLifeCycleState <> 'deleted'"
+ if (whereClause != null && !whereClause.trim().isEmpty()) {
+ // Due to an apparent bug/issue in how Nuxeo translates the NXQL query string
+ // into SQL, we need to parenthesize our 'where' clause
+ if (docFilterWhereClause != null && !docFilterWhereClause.trim().isEmpty()) {
+ whereClause = whereClause + IQueryManager.SEARCH_QUALIFIER_AND + "(" + docFilterWhereClause + ")";
+ }
+ } else {
+ whereClause = docFilterWhereClause;
+ }
+ String orderByClause = "ecm:uuid";
+
+ try {
+ QueryContext queryContext = new QueryContext(ctx, selectClause, whereClause, orderByClause);
+ result = NuxeoUtils.buildNXQLQuery(ctx, queryContext);
+ } catch (DocumentException de) {
+ throw de;
+ } catch (Exception x) {
+ throw x;
+ }
+
+ return result;
+ }
+
/**
* Creates the CMIS query from the service context. Each document handler is
* responsible for returning (can override) a valid CMIS query using the information in the
import javax.ws.rs.core.MultivaluedMap;
import org.collectionspace.services.lifecycle.TransitionDef;
+import org.collectionspace.services.nuxeo.util.CSReindexFulltextRoot;
import org.collectionspace.services.nuxeo.util.NuxeoUtils;
import org.collectionspace.services.client.CollectionSpaceClient;
import org.collectionspace.services.client.IQueryManager;
@Override
- public boolean reindex(DocumentHandler handler, String csid, String indexid) throws DocumentNotFoundException, DocumentException
+ public boolean reindex(DocumentHandler handler, String indexid) throws DocumentNotFoundException, DocumentException
{
- boolean result = true;
- ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = handler.getServiceContext();
- return result;
+ return reindex(handler, null, indexid);
}
@Override
- public boolean reindex(DocumentHandler handler, String indexid) throws DocumentNotFoundException, DocumentException
+ public boolean reindex(DocumentHandler handler, String csid, String indexid) throws DocumentNotFoundException, DocumentException
{
boolean result = true;
CoreSessionInterface repoSession = null;
ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = handler.getServiceContext();
try {
+ String queryString = handler.getDocumentsToIndexQuery(indexid, csid);
repoSession = getRepositorySession(ctx);
- try {
- } catch (ClientException ce) {
- }
+ CSReindexFulltextRoot indexer = new CSReindexFulltextRoot(repoSession);
+ indexer.reindexFulltext(0, 0, queryString);
//
// Set repository session to handle the document
//
--- /dev/null
+package org.collectionspace.services.nuxeo.util;
+
+import org.collectionspace.services.nuxeo.client.java.CoreSessionInterface;
+import org.collectionspace.services.nuxeo.util.ReindexFulltextRoot;
+import org.nuxeo.ecm.core.storage.StorageException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/*
+ * Use the inherited reindexFulltext() method to reindex the Nuxeo full-text index.
+ */
+public class CSReindexFulltextRoot extends ReindexFulltextRoot {
+
+ /** The logger. */
+ private final Logger logger = LoggerFactory.getLogger(CSReindexFulltextRoot.class);
+
+ public CSReindexFulltextRoot(CoreSessionInterface repoSession) {
+ this.coreSession = repoSession.getCoreSession();
+ }
+
+ public String reindexFulltext(int batchSize, int batch, String query) throws StorageException {
+ return super.reindexFulltext(batchSize, batch, query);
+ }
+}
* @throws Exception if supplied values in the query are invalid.
*/
static public final String buildNXQLQuery(ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx, QueryContext queryContext) throws Exception {
- StringBuilder query = new StringBuilder("SELECT * FROM ");
+ StringBuilder query = new StringBuilder(queryContext.getSelectClause());
// Since we have a tenant qualification in the WHERE clause, we do not need
// tenant-specific doc types
// query.append(NuxeoUtils.getTenantQualifiedDocType(queryContext)); // Nuxeo doctype must be tenant qualified.
* @return an NXQL query
*/
static public final String buildNXQLQuery(List<String> docTypes, QueryContext queryContext) throws Exception {
- StringBuilder query = new StringBuilder("SELECT * FROM ");
+ StringBuilder query = new StringBuilder(queryContext.getSelectClause());
boolean fFirst = true;
for (String docType : docTypes) {
if (fFirst) {
@GET
public String get(@QueryParam("batchSize") int batchSize, @QueryParam("batch") int batch) throws StorageException {
coreSession = SessionFactory.getSession(request);
- return reindexFulltext(batchSize, batch);
+ return reindexFulltext(batchSize, batch, null);
}
/**
* @return when done, ok + the total number of docs
* @throws StorageException
*/
- public String reindexFulltext(int batchSize, int batch) throws StorageException {
+ public String reindexFulltext(int batchSize, int batch, String query) throws StorageException {
Principal principal = coreSession.getPrincipal();
if (!(principal instanceof NuxeoPrincipal)) {
return "unauthorized";
if (batchSize <= 0) {
batchSize = DEFAULT_BATCH_SIZE;
}
- List<ReindexInfo> infos = getInfos();
+
+ //
+ // A default query that gets ALL the documents
+ //
+ if (query == null) {
+ query = "SELECT ecm:uuid, ecm:primaryType FROM Document"
+ + " WHERE ecm:isProxy = 0"
+ + " AND ecm:currentLifeCycleState <> 'deleted'"
+ + " ORDER BY ecm:uuid";
+ }
+
+ List<ReindexInfo> infos = getInfos(query);
int size = infos.size();
int numBatches = (size + batchSize - 1) / batchSize;
if (batch < 0 || batch > numBatches) {
}
}
- protected List<ReindexInfo> getInfos() throws StorageException {
+ protected List<ReindexInfo> getInfos(String query) throws StorageException {
getLowLevelSession();
List<ReindexInfo> infos = new ArrayList<ReindexInfo>();
- String query = "SELECT ecm:uuid, ecm:primaryType FROM Document"
- + " WHERE ecm:isProxy = 0"
- + " AND ecm:currentLifeCycleState <> 'deleted'"
- + " ORDER BY ecm:uuid";
IterableQueryResult it = session.queryAndFetch(query, NXQL.NXQL,
QueryFilter.EMPTY);
try {
import org.collectionspace.services.common.document.DocumentFilter;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.security.SecurityUtils;
+import org.collectionspace.services.common.query.nuxeo.QueryManagerNuxeoImpl;
import org.collectionspace.services.config.service.ServiceBindingType;
import org.collectionspace.services.config.service.ServiceObjectType;
}
// This should be "Document" but CMIS is gagging on that right now.
- ctx.getQueryParams().add(IQueryManager.SELECT_DOC_TYPE_FIELD, "CollectionSpaceDocument");
+ ctx.getQueryParams().add(IQueryManager.SELECT_DOC_TYPE_FIELD, QueryManagerNuxeoImpl.COLLECTIONSPACE_DOCUMENT_TYPE);
// Now we have to issue the search
- // findDocs qill build a QueryContext, which wants to see a docType for our context
- ctx.setDocumentType("Document");
+ // findDocs will build a QueryContext, which wants to see a docType for our context
+ ctx.setDocumentType(QueryManagerNuxeoImpl.NUXEO_DOCUMENT_TYPE);
DocumentWrapper<DocumentModelList> docListWrapper =
nuxeoRepoClient.findDocs(ctx, this, repoSession, docTypes );
// Now we gather the info for each document into the list and return