From: Aron Roberts Date: Mon, 3 Jan 2011 23:11:08 +0000 (+0000) Subject: CSPACE-3069: List results from services calls may now be sorted on two or more fields... X-Git-Url: https://git.aero2k.de/?a=commitdiff_plain;h=92eabc26a876f55ddb84e89d9df2672d33584853;p=tmp%2Fjakarta-migration.git CSPACE-3069: List results from services calls may now be sorted on two or more fields; previously sorting was restricted to a single field. --- 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 93ddb4f5e..cc6ba105b 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 @@ -73,9 +73,8 @@ public class RepositoryJavaClientImpl implements RepositoryClient { // private String foo = Profiler.createLogger(); // Regular expressions pattern for identifying valid ORDER BY clauses. - // FIXME: Currently supports ordering on only one field. // FIXME: Currently supports only USASCII word characters in field names. - final String ORDER_BY_CLAUSE_REGEX = "\\w+(_\\w+)?:\\w+( ASC| DESC)?"; + final String ORDER_BY_CLAUSE_REGEX = "\\w+(_\\w+)?:\\w+( ASC| DESC)?(, \\w+(_\\w+)?:\\w+( ASC| DESC)?)*"; /** * Instantiates a new repository java client impl. diff --git a/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementSortByTest.java b/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementSortByTest.java index 34e9114ba..7ccb94382 100644 --- a/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementSortByTest.java +++ b/services/movement/client/src/test/java/org/collectionspace/services/client/test/MovementSortByTest.java @@ -63,11 +63,12 @@ public class MovementSortByTest extends BaseServiceTest { private final Logger logger = LoggerFactory.getLogger(CLASS_NAME); // Instance variables specific to this test. - final String DELIMITER_SCHEMA_AND_FIELD = ":"; - final String KEYWORD_DESCENDING_SEARCH = "DESC"; - final String SERVICE_PATH_COMPONENT = "movements"; - final String TEST_SPECIFIC_KEYWORD = "msotebstpfscn"; + private final String DELIMITER_SCHEMA_AND_FIELD = ":"; + private final String KEYWORD_DESCENDING_SEARCH = "DESC"; + private final String SERVICE_PATH_COMPONENT = "movements"; + private final String TEST_SPECIFIC_KEYWORD = "msotebstpfscn"; private List movementIdsCreated = new ArrayList(); + private final String SORT_FIELD_SEPARATOR = ", "; /* (non-Javadoc) * @see org.collectionspace.services.client.test.BaseServiceTest#getClientInstance() @@ -315,12 +316,130 @@ public class MovementSortByTest extends BaseServiceTest { // Verify that the value of the specified field in the current record // is less than or equal to its value in the previous record. if (i > 0 && values.get(i) != null && values.get(i - 1) != null) { - Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) <= 1); + Assert.assertTrue(comparator.compare(values.get(i), values.get(i - 1)) <= 0); } i++; } } + /* + * Tests whether a list of records, sorted by two different fields in + * ascending order, is returned in the expected order. + */ + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"createList"}) + public void sortByTwoFieldsAscending(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + + String firstSortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE); + String secondSortFieldName = qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE); + if (logger.isDebugEnabled()) { + logger.debug("Sorting on field names=" + firstSortFieldName + " and " + secondSortFieldName); + } + String sortExpression = firstSortFieldName + SORT_FIELD_SEPARATOR + secondSortFieldName; + MovementsCommonList list = readSortedList(sortExpression); + List items = + list.getMovementListItem(); + + ArrayList firstFieldValues = new ArrayList(); + ArrayList secondFieldValues = new ArrayList(); + Collator usEnglishCollator = Collator.getInstance(Locale.US); + Comparator comparator = String.CASE_INSENSITIVE_ORDER; + int i = 0; + for (MovementsCommonList.MovementListItem item : items) { + // Because movementNote is not currently a summary field + // (returned in summary list items), we will need to verify + // sort order by retrieving full records, using the + // IDs provided in the summary list items. amd then retriving + // the value of that field from each of those records. + MovementsCommon movement = read(item.getCsid()); + firstFieldValues.add(i, movement.getMovementNote()); + secondFieldValues.add(i, movement.getLocationDate()); + if (logger.isDebugEnabled()) { + logger.debug("list-item[" + i + "] movementNote=" + firstFieldValues.get(i)); + logger.debug("list-item[" + i + "] locationDate=" + secondFieldValues.get(i)); + } + // Verify that the value of the specified field in the current record + // is less than or greater than its value in the previous record. + if (i > 0 && firstFieldValues.get(i) != null && firstFieldValues.get(i - 1) != null) { + Assert.assertTrue(usEnglishCollator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) >= 0); + // If the value of the first sort field in the current record is identical to + // its value in the previous record, verify that the value of the second sort + // field is equal to or greater than its value in the previous record, + // using a locale-specific collator. + if (usEnglishCollator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) == 0) { + if (i > 0 && secondFieldValues.get(i) != null && secondFieldValues.get(i - 1) != null) { + Assert.assertTrue(comparator.compare(secondFieldValues.get(i), secondFieldValues.get(i - 1)) >= 0); + } + } + } + i++; + } + } + + /* + * Tests whether a list of records, sorted by one different fields in + * descending order and a second field in ascending order, is returned in the expected order. + */ + @Test(dataProvider = "testName", dataProviderClass = AbstractServiceTestImpl.class, + dependsOnMethods = {"createList"}) + public void sortByOneFieldAscendingOneFieldsDescending(String testName) throws Exception { + + if (logger.isDebugEnabled()) { + logger.debug(testBanner(testName, CLASS_NAME)); + } + + String firstSortFieldName = + asDescendingSort(qualifySortFieldName(MovementJAXBSchema.LOCATION_DATE)); + String secondSortFieldName = qualifySortFieldName(MovementJAXBSchema.MOVEMENT_NOTE); + if (logger.isDebugEnabled()) { + logger.debug("Sorting on field names=" + firstSortFieldName + " and " + secondSortFieldName); + } + String sortExpression = firstSortFieldName + SORT_FIELD_SEPARATOR + secondSortFieldName; + MovementsCommonList list = readSortedList(sortExpression); + List items = + list.getMovementListItem(); + + ArrayList firstFieldValues = new ArrayList(); + ArrayList secondFieldValues = new ArrayList(); + Collator usEnglishCollator = Collator.getInstance(Locale.US); + Comparator comparator = String.CASE_INSENSITIVE_ORDER; + int i = 0; + for (MovementsCommonList.MovementListItem item : items) { + // Because movementNote is not currently a summary field + // (returned in summary list items), we will need to verify + // sort order by retrieving full records, using the + // IDs provided in the summary list items. amd then retriving + // the value of that field from each of those records. + MovementsCommon movement = read(item.getCsid()); + firstFieldValues.add(i, movement.getLocationDate()); + secondFieldValues.add(i, movement.getMovementNote()); + if (logger.isDebugEnabled()) { + logger.debug("list-item[" + i + "] locationDate=" + firstFieldValues.get(i)); + logger.debug("list-item[" + i + "] movementNote=" + secondFieldValues.get(i)); + } + // Verify that the value of the specified field in the current record + // is less than or greater than its value in the previous record. + if (i > 0 && firstFieldValues.get(i) != null && firstFieldValues.get(i - 1) != null) { + Assert.assertTrue(comparator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) <= 0); + // If the value of the first sort field in the current record is identical to + // its value in the previous record, verify that the value of the second sort + // field is equal to or greater than its value in the previous record, + // using a locale-specific collator. + if (comparator.compare(firstFieldValues.get(i), firstFieldValues.get(i - 1)) == 0) { + if (i > 0 && secondFieldValues.get(i) != null && secondFieldValues.get(i - 1) != null) { + Assert.assertTrue(usEnglishCollator.compare(secondFieldValues.get(i), secondFieldValues.get(i - 1)) >= 0); + } + } + } + i++; + } + } + + /* * Tests whether a request to sort by an empty field name is handled * as expected: the query parameter is simply ignored, and a list @@ -512,10 +631,15 @@ public class MovementSortByTest extends BaseServiceTest { final String TEST_RECORD_SPECIFIC_STRING = CLASS_NAME + " " + TEST_SPECIFIC_KEYWORD; return new Object[][]{ {1, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T00:00:05Z"}, - {4, "Bat fling off wall. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"}, - {2, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T08:00:00Z"}, - {5, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2010-08-31T00:00:00Z"}, - {3, "Bat flies off ball. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"} + {10, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2010-08-31T00:00:00Z"}, + {3, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"}, + {7, "Bat fling off wall. " + TEST_RECORD_SPECIFIC_STRING, "2010-08-30T00:00:00Z"}, + {4, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-01-29T08:00:00Z"}, + {5, "Aardvarks and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}, + {2, "Aardvark and plumeria. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}, + {9, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}, // Identical to next record + {8, "Zounds! " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"}, + {6, "Bat flies off ball. " + TEST_RECORD_SPECIFIC_STRING, "2009-05-29T00:00:00Z"} }; }