<run controlFile="location/location-hierarchy.xml" testGroup="HierarchicLocation" />\r
<run controlFile="organization/organization-hierarchy.xml" testGroup="HierarchicOrganization" />\r
<run controlFile="batch/batch.xml" />\r
+ <run controlFile="report/report.xml" />\r
<run controlFile="vocabulary/vocabulary.xml" testGroup="TestOrder" />\r
\r
</xmlReplayMaster>\r
final static String SEARCH_TYPE_KEYWORDS_KW = "kw";\r
final static String SEARCH_TYPE_PARTIALTERM = "pt";\r
final static String SEARCH_TYPE_DOCTYPE = "doctype";\r
+ final static String SEARCH_TYPE_INVCOATION_MODE = "mode";\r
final static String SEARCH_TYPE_INVOCATION = "inv";\r
final static String SEARCH_QUALIFIER_AND = SEARCH_TERM_SEPARATOR + "AND" + SEARCH_TERM_SEPARATOR;\r
final static String SEARCH_QUALIFIER_OR = SEARCH_TERM_SEPARATOR + "OR" + SEARCH_TERM_SEPARATOR;\r
*/\r
public String createWhereClauseForPartialMatch(String field, String partialTerm);\r
\r
+ /**\r
+ * Creates a filtering where clause from docType, for invocables.\r
+ * \r
+ * @param schema the schema name for this invocable type\r
+ * @param docType the docType\r
+ * \r
+ * @return the string\r
+ */\r
+ public String createWhereClauseForInvocableByDocType(String schema, String docType);\r
+ \r
+ /**\r
+ * Creates a filtering where clause from invocation mode, for invocables.\r
+ * \r
+ * @param schema the schema name for this invocable type\r
+ * @param mode the mode\r
+ * \r
+ * @return the string\r
+ */\r
+ public String createWhereClauseForInvocableByMode(String schema, String mode);\r
+ \r
}\r
--- /dev/null
+package org.collectionspace.services.common.invocable;\r
+\r
+import org.collectionspace.services.jaxb.InvocableJAXBSchema;\r
+\r
+public class InvocableUtils {\r
+\r
+ /**\r
+ * Returns the standard property name for an invocable schema, given\r
+ * and invocation mode string.\r
+ * @param schema If not null, the returned property name will be qualified with\r
+ * this schema name.\r
+ * @param invocationMode one of Invocable.INVOCATION_MODE_*\r
+ * @return\r
+ */\r
+ public static String getPropertyNameForInvocationMode(String schema, String invocationMode) {\r
+ String modeProperty = null;\r
+ if(Invocable.INVOCATION_MODE_SINGLE.equalsIgnoreCase(invocationMode)) {\r
+ modeProperty = InvocableJAXBSchema.SUPPORTS_SINGLE_DOC;\r
+ } else if(Invocable.INVOCATION_MODE_LIST.equalsIgnoreCase(invocationMode)) {\r
+ modeProperty = InvocableJAXBSchema.SUPPORTS_DOC_LIST;\r
+ } else if(Invocable.INVOCATION_MODE_GROUP.equalsIgnoreCase(invocationMode)) {\r
+ modeProperty = InvocableJAXBSchema.SUPPORTS_GROUP;\r
+ } else if(Invocable.INVOCATION_MODE_NO_CONTEXT.equalsIgnoreCase(invocationMode)) {\r
+ modeProperty = InvocableJAXBSchema.SUPPORTS_NO_CONTEXT;\r
+ } else {\r
+ throw new IllegalArgumentException("QueryManagerNuxeoImpl: unknown Invocation Mode: "\r
+ +invocationMode);\r
+ }\r
+ return (schema!=null)? (schema+":"+modeProperty):modeProperty;\r
+ }\r
+\r
+}\r
return queryManager.createWhereClauseForPartialMatch(field, partialTerm);\r
}\r
\r
+ /**\r
+ * Creates a filtering where clause from docType, for invocables.\r
+ * \r
+ * @param schema the schema name for this invocable type\r
+ * @param docType the docType\r
+ * \r
+ * @return the string\r
+ */\r
+ static public String createWhereClauseForInvocableByDocType(String schema, String docType) {\r
+ return queryManager.createWhereClauseForInvocableByDocType(schema, docType);\r
+ }\r
+ \r
+ /**\r
+ * Creates a filtering where clause from invocation mode, for invocables.\r
+ * \r
+ * @param schema the schema name for this invocable type\r
+ * @param mode the mode\r
+ * \r
+ * @return the string\r
+ */\r
+ static public String createWhereClauseForInvocableByMode(String schema, String mode) {\r
+ return queryManager.createWhereClauseForInvocableByMode(schema, mode);\r
+ }\r
+ \r
}\r
import org.nuxeo.ecm.core.api.repository.RepositoryInstance;\r
import org.nuxeo.ecm.core.client.NuxeoClient;\r
\r
+import org.collectionspace.services.jaxb.InvocableJAXBSchema;\r
import org.collectionspace.services.nuxeo.client.java.NuxeoConnector;\r
-import org.collectionspace.services.nuxeo.client.java.RepositoryJavaClientImpl;\r
import org.collectionspace.services.client.IQueryManager;\r
+import org.collectionspace.services.common.invocable.Invocable;\r
+import org.collectionspace.services.common.invocable.InvocableUtils;\r
import org.collectionspace.services.common.storage.DatabaseProductType;\r
import org.collectionspace.services.common.storage.JDBCTools;\r
\r
private static Pattern nonWordChars = Pattern.compile("[^\\p{L}\\p{M}\\p{N}_']");\r
private static Pattern unescapedDblQuotes = Pattern.compile("(?<!\\\\)\"");\r
private static Pattern unescapedSingleQuote = Pattern.compile("(?<!\\\\)'");\r
+ private static Pattern kwdSearchProblemChars = Pattern.compile("[\\:\\(\\)]");\r
+ private static Pattern kwdSearchHyphen = Pattern.compile(" - ");\r
\r
private static String getLikeForm() {\r
if(SEARCH_LIKE_FORM == null) {\r
// and escaping single quotes. Can return a boolean for anything stripped,\r
// which triggers the back-up search. We can think about whether stripping\r
// short words not in a quoted phrase should trigger the backup.\r
- fullTextWhereClause.append(unescapedSingleQuote.matcher(trimmed).replaceAll("\\\\'"));\r
+ trimmed = unescapedSingleQuote.matcher(trimmed).replaceAll("\\\\'");\r
// If there are non-word chars in the phrase, we need to match the\r
// phrase exactly against the fulltext table for this object\r
//if(nonWordChars.matcher(trimmed).matches()) {\r
//}\r
+ // Replace problem chars with spaces. Patches CSPACE-4147, CSPACE-4106 \r
+ trimmed = kwdSearchProblemChars.matcher(trimmed).replaceAll(" ");\r
+ trimmed = kwdSearchHyphen.matcher(trimmed).replaceAll(" ");\r
+\r
+ fullTextWhereClause.append(trimmed);\r
if (logger.isTraceEnabled() == true) {\r
logger.trace("Current built whereClause is: " + fullTextWhereClause.toString());\r
}\r
return ptClause;\r
}\r
\r
-\r
+ /**\r
+ * Creates a filtering where clause from docType, for invocables.\r
+ * \r
+ * @param docType the docType\r
+ * \r
+ * @return the string\r
+ */\r
+ public String createWhereClauseForInvocableByDocType(String schema, String docType) {\r
+ String trimmed = (docType == null)?"":docType.trim(); \r
+ if (trimmed.isEmpty()) {\r
+ throw new RuntimeException("No docType specified.");\r
+ }\r
+ if (schema==null || schema.isEmpty()) {\r
+ throw new RuntimeException("No match schema specified.");\r
+ }\r
+ String wClause = schema+":"+InvocableJAXBSchema.FOR_DOC_TYPE + " = '" + trimmed + "'";\r
+ return wClause;\r
+ }\r
+ \r
+ /**\r
+ * Creates a filtering where clause from invocation mode, for invocables.\r
+ * \r
+ * @param mode the mode\r
+ * \r
+ * @return the string\r
+ */\r
+ public String createWhereClauseForInvocableByMode(String schema, String mode) {\r
+ String trimmed = (mode == null)?"":mode.trim(); \r
+ if (trimmed.isEmpty()) {\r
+ throw new RuntimeException("No docType specified.");\r
+ }\r
+ if (schema==null || schema.isEmpty()) {\r
+ throw new RuntimeException("No match schema specified.");\r
+ }\r
+ String wClause = \r
+ InvocableUtils.getPropertyNameForInvocationMode(schema, trimmed)\r
+ + " != 0";\r
+ return wClause;\r
+ }\r
+ \r
\r
/**\r
* @param input\r
package org.collectionspace.services.client;
//import org.collectionspace.services.common.context.ServiceContext;
+import javax.ws.rs.QueryParam;
+
import org.collectionspace.services.report.ReportsCommonList;
import org.jboss.resteasy.client.ClientResponse;
return getProxy().readList();
}
+ /**
+ * @return
+ * @see org.collectionspace.services.client.ReportProxy#getReport()
+ */
+ public ClientResponse<ReportsCommonList> readListFiltered(
+ String docType, String mode) {
+ return getProxy().readListFiltered(docType, mode);
+ }
+
}
@Produces({"application/xml"})
ClientResponse<ReportsCommonList> readList();
+ @GET
+ @Produces({"application/xml"})
+ ClientResponse<ReportsCommonList> readListFiltered(
+ @QueryParam(IQueryManager.SEARCH_TYPE_DOCTYPE) String docType,
+ @QueryParam(IQueryManager.SEARCH_TYPE_INVCOATION_MODE) String mode);
+
@Override
@GET
@Produces({"application/xml"})
// Instance variables specific to this test.
/** The known resource id. */
private String knownResourceId = null;
+
+ private String testDocType = "Acquisition";
/* (non-Javadoc)
* @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance()
invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+ List<ReportsCommonList.ReportListItem> items =
+ list.getReportListItem();
// Optionally output additional data about list members for debugging.
boolean iterateThroughList = false;
if (iterateThroughList && logger.isDebugEnabled()) {
- List<ReportsCommonList.ReportListItem> items =
- list.getReportListItem();
int i = 0;
for (ReportsCommonList.ReportListItem item : items) {
logger.debug(testName + ": list-item[" + i + "] csid="
i++;
}
}
+ }
+ @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
+ dependsOnMethods = {"readList"})
+ public void readListFiltered(String testName) throws Exception {
+ if (logger.isDebugEnabled()) {
+ logger.debug(testBanner(testName, CLASS_NAME));
+ }
+ // Perform setup.
+ setupReadList();
+
+ // Submit the request to the service and store the response.
+ ReportClient client = new ReportClient();
+ ClientResponse<ReportsCommonList> res = client.readListFiltered(
+ testDocType, "single");
+ ReportsCommonList list = res.getEntity();
+ int statusCode = res.getStatus();
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+ List<ReportsCommonList.ReportListItem> items =
+ list.getReportListItem();
+ // We must find the basic one we created
+ boolean fFoundBaseItem = false;
+ for (ReportsCommonList.ReportListItem item : items) {
+ if(knownResourceId.equalsIgnoreCase(item.getCsid())) {
+ fFoundBaseItem = true;
+ break;
+ }
+ }
+ if(!fFoundBaseItem)
+ Assert.fail("readListFiltered failed to return base item");
+
+ // Now filter for something else, and ensure it is NOT returned
+ res = client.readListFiltered("Intake", "single");
+ list = res.getEntity();
+ statusCode = res.getStatus();
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+ items = list.getReportListItem();
+ // We must NOT find the basic one we created
+ for (ReportsCommonList.ReportListItem item : items) {
+ Assert.assertNotSame(item.getCsid(), knownResourceId,
+ "readListFiltered(\"Intake\", \"single\") incorrectly returned base item");
+ }
+
+ // Now filter for something else, and ensure it is NOT returned
+ res = client.readListFiltered(testDocType, "group");
+ list = res.getEntity();
+ statusCode = res.getStatus();
+
+ // Check the status code of the response: does it match
+ // the expected response(s)?
+ if (logger.isDebugEnabled()) {
+ logger.debug(testName + ": status = " + statusCode);
+ }
+ Assert.assertTrue(REQUEST_TYPE.isValidStatusCode(statusCode),
+ invalidStatusCodeMessage(REQUEST_TYPE, statusCode));
+ Assert.assertEquals(statusCode, EXPECTED_STATUS_CODE);
+
+ items = list.getReportListItem();
+ // We must NOT find the basic one we created
+ for (ReportsCommonList.ReportListItem item : items) {
+ Assert.assertNotSame(item.getCsid(), knownResourceId,
+ "readListFiltered(\""+testDocType+"\", \"group\") incorrectly returned base item");
+ }
}
// ---------------------------------------------------------------
*/
@Override
@Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
- dependsOnMethods = {"read"})
+ dependsOnMethods = {"read", "readListFiltered"})
public void update(String testName) throws Exception {
if (logger.isDebugEnabled()) {
*/
@Override
@Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class,
- dependsOnMethods = {"create", "readList", "testSubmitRequest", "update", "readWorkflow"})
+ dependsOnMethods = {"create", "readListFiltered", "testSubmitRequest", "update", "readWorkflow"})
public void delete(String testName) throws Exception {
if (logger.isDebugEnabled()) {
*/
private PoxPayloadOut createReportInstance(String identifier) {
return createReportInstance(
- "name-" + identifier,
- "persAuthTermCountsTest.jasper",
+ "Acquisition Summary",
+ testDocType, true, false, false, true,
+ "acq_basic.jasper",
"application/pdf");
}
* @return the multipart output
*/
private PoxPayloadOut createReportInstance(String name,
+ String forDocType,
+ boolean supportsSingle, boolean supportsList,
+ boolean supportsGroup, boolean supportsNoContext,
String filename,
String outputMIME) {
ReportsCommon reportCommon = new ReportsCommon();
reportCommon.setName(name);
+ reportCommon.setForDocType(forDocType);
+ reportCommon.setSupportsSingleDoc(supportsSingle);
+ reportCommon.setSupportsDocList(supportsList);
+ reportCommon.setSupportsGroup(supportsGroup);
+ reportCommon.setSupportsNoContext(supportsNoContext);
reportCommon.setFilename(filename);
reportCommon.setOutputMIME(outputMIME);
reportCommon.setNotes(getUTF8DataFragment()); // For UTF-8 tests
import org.collectionspace.services.jaxb.AbstractCommonList;
import org.collectionspace.services.jaxb.InvocableJAXBSchema;
import org.collectionspace.services.ReportJAXBSchema;
+import org.collectionspace.services.client.IQueryManager;
import org.collectionspace.services.client.PoxPayloadIn;
import org.collectionspace.services.client.PoxPayloadOut;
import org.collectionspace.services.client.ReportClient;
import org.collectionspace.services.common.config.ConfigReader;
import org.collectionspace.services.common.context.ServiceContext;
import org.collectionspace.services.common.document.BadRequestException;
+import org.collectionspace.services.common.document.DocumentFilter;
import org.collectionspace.services.common.document.DocumentHandler;
import org.collectionspace.services.common.document.DocumentNotFoundException;
import org.collectionspace.services.common.document.DocumentWrapper;
import org.collectionspace.services.common.invocable.InvocationContext;
import org.collectionspace.services.common.invocable.InvocationResults;
import org.collectionspace.services.common.invocable.Invocable.InvocationError;
+import org.collectionspace.services.common.query.QueryManager;
import org.collectionspace.services.common.security.UnauthorizedException;
import org.jboss.resteasy.spi.ResteasyProviderFactory;
import org.nuxeo.ecm.core.api.DocumentModel;
try {
ServiceContext<PoxPayloadIn, PoxPayloadOut> ctx = createServiceContext(queryParams);
DocumentHandler handler = createDocumentHandler(ctx);
+ String docType = queryParams.getFirst(IQueryManager.SEARCH_TYPE_DOCTYPE);
+ String mode = queryParams.getFirst(IQueryManager.SEARCH_TYPE_INVCOATION_MODE);
+ String whereClause = null;
+ DocumentFilter documentFilter = null;
+ String common_part =ctx.getCommonPartLabel();
+ if (docType != null && !docType.isEmpty()) {
+ whereClause = QueryManager.createWhereClauseForInvocableByDocType(
+ common_part, docType);
+ documentFilter = handler.getDocumentFilter();
+ documentFilter.appendWhereClause(whereClause, IQueryManager.SEARCH_QUALIFIER_AND);
+ }
+ if (mode != null && !mode.isEmpty()) {
+ whereClause = QueryManager.createWhereClauseForInvocableByMode(
+ common_part, mode);
+ documentFilter = handler.getDocumentFilter();
+ documentFilter.appendWhereClause(whereClause, IQueryManager.SEARCH_QUALIFIER_AND);
+ }
+ if (whereClause !=null && logger.isDebugEnabled()) {
+ logger.debug("The WHERE clause is: " + documentFilter.getWhereClause());
+ }
getRepositoryClient(ctx).getFiltered(ctx, handler);
AbstractCommonList list = (AbstractCommonList) handler.getCommonPartList();
return list;