From: Richard Millet Date: Fri, 1 Apr 2011 17:01:23 +0000 (+0000) Subject: CSPACE-3760: Moved implementation of getDocFromCsid() method into NuxeoUtils.java... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=8ecd66ea3ebad86bd2a44a028f4b7f19655c7c52;p=tmp%2Fjakarta-migration.git CSPACE-3760: Moved implementation of getDocFromCsid() method into NuxeoUtils.java. So now this method is available to via the RepositoryJavaClientImpl as well as NuxeoUtils.java. --- diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java index daf3348ab..5518747bc 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/client/java/RepositoryJavaClientImpl.java @@ -71,10 +71,6 @@ public class RepositoryJavaClientImpl implements RepositoryClient(docList); } catch (IllegalArgumentException iae) { @@ -599,25 +585,13 @@ public class RepositoryJavaClientImpl implements RepositoryClient result = null; RepositoryInstance repoSession = getRepositorySession(); - DocumentModelList docModelList = null; - // - // Set of query context using the current service context, but change the document type - // to be the base Nuxeo document type so we can look for the document across service workspaces - // - QueryContext queryContext = new QueryContext(ctx, getByNameWhereClause(csid)); - queryContext.setDocType(NuxeoUtils.BASE_DOCUMENT_TYPE); - // - // Since we're doing a query, we get back a list so we need to make sure there is only - // a single result since CSID values are supposed to be unique. - String query = buildNXQLQuery(queryContext); - docModelList = repoSession.query(query); - long resultSize = docModelList.totalSize(); - if (resultSize == 1) { - result = new DocumentWrapperImpl(docModelList.get(0)); - } else if (resultSize > 1) { - throw new DocumentException("Found more than 1 document with CSID = " + csid); + try { + result = NuxeoUtils.getDocFromCsid(repoSession, ctx, csid); + } finally { + if (repoSession != null) { + releaseRepositorySession(repoSession); + } } - return result; } @@ -645,7 +619,7 @@ public class RepositoryJavaClientImpl implements RepositoryClient docTypes, QueryContext queryContext) { - StringBuilder query = new StringBuilder("SELECT * FROM "); - boolean fFirst = true; - for (String docType : docTypes) { - if (fFirst) { - fFirst = false; - } else { - query.append(","); - } - query.append(docType); - } - appendNXQLWhere(query, queryContext); - // FIXME add 'order by' clause here, if appropriate - return query.toString(); - } /** * Gets the repository session. diff --git a/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java b/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java index 6c371f832..6086456f3 100644 --- a/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java +++ b/services/common/src/main/java/org/collectionspace/services/nuxeo/util/NuxeoUtils.java @@ -23,10 +23,22 @@ import java.io.IOException; import java.io.File; import java.io.Serializable; +import java.util.List; import java.util.Map; import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.regex.PatternSyntaxException; + +import org.collectionspace.services.client.IQueryManager; +import org.collectionspace.services.client.PoxPayloadIn; +import org.collectionspace.services.client.PoxPayloadOut; import org.collectionspace.services.common.context.ServiceContext; import org.collectionspace.services.common.document.DocumentException; +import org.collectionspace.services.common.document.DocumentWrapper; +import org.collectionspace.services.common.document.DocumentWrapperImpl; +import org.collectionspace.services.common.query.QueryContext; +import org.collectionspace.services.nuxeo.client.java.DocumentModelHandler; import org.dom4j.Document; import org.dom4j.io.SAXReader; @@ -67,7 +79,12 @@ public class NuxeoUtils { private static Logger logger = LoggerFactory.getLogger(NuxeoUtils.class); // // Base document type in Nuxeo is "Document" + // public static final String BASE_DOCUMENT_TYPE = "Document"; + + // Regular expressions pattern for identifying valid ORDER BY clauses. + // FIXME: Currently supports only USASCII word characters in field names. + private static final String ORDER_BY_CLAUSE_REGEX = "\\w+(_\\w+)?:\\w+( ASC| DESC)?(, \\w+(_\\w+)?:\\w+( ASC| DESC)?)*"; public static void exportDocModel(DocumentModel src) { DocumentReader reader = null; @@ -231,6 +248,164 @@ public class NuxeoUtils { return result; } + + static public String getByNameWhereClause(String csid) { + String result = null; + + if (csid != null) { + result = "ecm:name = " + "\'" + csid + "\'"; + } + + return result; + } + + /** + * Append a WHERE clause to the NXQL query. + * + * @param query The NXQL query to which the WHERE clause will be appended. + * @param queryContext The query context, which provides the WHERE clause to append. + */ + static private final void appendNXQLWhere(StringBuilder query, QueryContext queryContext) { + // + // Restrict search to a specific Nuxeo domain + // TODO This is a slow method for tenant-filter + // We should make this a property that is indexed. + // +// query.append(" WHERE ecm:path STARTSWITH '/" + queryContext.domain + "'"); + + // + // Restrict search to the current tenant ID. Is the domain path filter (above) still needed? + // + query.append(/*IQueryManager.SEARCH_QUALIFIER_AND +*/ " WHERE " + DocumentModelHandler.COLLECTIONSPACE_CORE_SCHEMA + ":" + + DocumentModelHandler.COLLECTIONSPACE_CORE_TENANTID + + " = " + queryContext.getTenantId()); + // + // Finally, append the incoming where clause + // + String whereClause = queryContext.getWhereClause(); + 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 + query.append(IQueryManager.SEARCH_QUALIFIER_AND + "(" + whereClause + ")"); + } + // + // Please lookup this use in Nuxeo support and document here + // + query.append(IQueryManager.SEARCH_QUALIFIER_AND + "ecm:isProxy = 0"); + } + + /** + * Append an ORDER BY clause to the NXQL query. + * + * @param query the NXQL query to which the ORDER BY clause will be appended. + * @param queryContext the query context, which provides the ORDER BY clause to append. + * + * @throws DocumentException if the supplied value of the orderBy clause is not valid. + * + */ + static private final void appendNXQLOrderBy(StringBuilder query, QueryContext queryContext) + throws Exception { + String orderByClause = queryContext.getOrderByClause(); + if (orderByClause != null && ! orderByClause.trim().isEmpty()) { + if (isValidOrderByClause(orderByClause)) { + query.append(" ORDER BY "); + query.append(orderByClause); + } else { + throw new DocumentException("Invalid format in sort request '" + orderByClause + + "': must be schema_name:fieldName followed by optional sort order (' ASC' or ' DESC')."); + } + } + } + + /** + * Identifies whether the ORDER BY clause is valid. + * + * @param orderByClause the ORDER BY clause. + * + * @return true if the ORDER BY clause is valid; + * false if it is not. + */ + static private final boolean isValidOrderByClause(String orderByClause) { + boolean isValidClause = false; + try { + Pattern orderByPattern = Pattern.compile(ORDER_BY_CLAUSE_REGEX); + Matcher orderByMatcher = orderByPattern.matcher(orderByClause); + if (orderByMatcher.matches()) { + isValidClause = true; + } + } catch (PatternSyntaxException pe) { + logger.warn("ORDER BY clause regex pattern '" + ORDER_BY_CLAUSE_REGEX + + "' could not be compiled: " + pe.getMessage()); + // If reached, method will return a value of false. + } + return isValidClause; + } + + + /** + * Builds an NXQL SELECT query for a single document type. + * + * @param queryContext The query context + * @return an NXQL query + * @throws Exception if supplied values in the query are invalid. + */ + static public final String buildNXQLQuery(QueryContext queryContext) throws Exception { + StringBuilder query = new StringBuilder("SELECT * FROM "); + query.append(queryContext.getDocType()); + appendNXQLWhere(query, queryContext); + appendNXQLOrderBy(query, queryContext); + return query.toString(); + } + + /** + * Builds an NXQL SELECT query across multiple document types. + * + * @param docTypes a list of document types to be queried + * @param queryContext the query context + * @return an NXQL query + */ + static public final String buildNXQLQuery(List docTypes, QueryContext queryContext) { + StringBuilder query = new StringBuilder("SELECT * FROM "); + boolean fFirst = true; + for (String docType : docTypes) { + if (fFirst) { + fFirst = false; + } else { + query.append(","); + } + query.append(docType); + } + appendNXQLWhere(query, queryContext); + // FIXME add 'order by' clause here, if appropriate + return query.toString(); + } + + static public DocumentWrapper getDocFromCsid(RepositoryInstance repoSession, + ServiceContext ctx, + String csid) throws Exception { + DocumentWrapper result = null; + + DocumentModelList docModelList = null; + // + // Set of query context using the current service context, but change the document type + // to be the base Nuxeo document type so we can look for the document across service workspaces + // + QueryContext queryContext = new QueryContext(ctx, getByNameWhereClause(csid)); + queryContext.setDocType(NuxeoUtils.BASE_DOCUMENT_TYPE); + // + // Since we're doing a query, we get back a list so we need to make sure there is only + // a single result since CSID values are supposed to be unique. + String query = buildNXQLQuery(queryContext); + docModelList = repoSession.query(query); + long resultSize = docModelList.totalSize(); + if (resultSize == 1) { + result = new DocumentWrapperImpl(docModelList.get(0)); + } else if (resultSize > 1) { + throw new DocumentException("Found more than 1 document with CSID = " + csid); + } + + return result; + } public static void printDocumentModel(DocumentModel docModel) throws Exception { String[] schemas = docModel.getDeclaredSchemas();