Skip to content
Snippets Groups Projects
Commit e127a136 authored by pkupczyk's avatar pkupczyk
Browse files

SSDM-2636 : V3 AS API - sort search results by property values

SVN: 35020
parent b67595a9
No related branches found
No related tags found
No related merge requests found
Showing
with 324 additions and 83 deletions
......@@ -14,7 +14,7 @@
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.generic.client.web.server.resultset;
package ch.systemsx.cisd.common.collection;
/*
* The Alphanum Algorithm is an improved sorting algorithm for strings
......
......@@ -14,7 +14,7 @@
* limitations under the License.
*/
package ch.systemsx.cisd.openbis.generic.client.web.server.resultset;
package ch.systemsx.cisd.common.collection;
import java.util.Arrays;
......@@ -22,6 +22,8 @@ import org.testng.AssertJUnit;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import ch.systemsx.cisd.common.collection.AlphanumComparator;
/**
* @author Piotr Buczek
*/
......
......@@ -13,12 +13,16 @@
require.paths["test"] = testPath;
require.paths["test/qunit"] = testPath + "/lib/qunit/js/qunit";
require.paths["test/qunit-report"] = testPath + "/lib/qunit/js/qunit-reporter-junit";
require.paths["test/naturalsort"] = testPath + "/lib/naturalsort/js/naturalSort";
require.urlArgs = 'now=' + Date.now();
require.shim["test/qunit-report"] = {
deps : [ 'test/qunit' ]
};
require.shim["test/naturalsort"] = {
exports : "naturalSort"
};
</script>
<script src="/openbis/resources/api/v3/require.js"></script>
......
/**
*
* Natural Sort algorithm for Javascript - Version 0.7 - Released under MIT license
* Author: Jim Palmer (based on chunking idea from Dave Koelle)
*
* @param a first string to compare
* @param b second string to compare
* @return 1 if a > b, 0 if a == b, -1 if a < b
*
* @see http://www.overset.com/2008/09/01/javascript-natural-sort-algorithm-with-unicode-support/
*/
naturalSort = function(a, b) {
var re = /(^-?[0-9]+(\.?[0-9]*)[df]?e?[0-9]?$|^0x[0-9a-f]+$|[0-9]+)/gi,
sre = /(^[ ]*|[ ]*$)/g,
dre = /(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,
hre = /^0x[0-9a-f]+$/i,
ore = /^0/,
i = function(s) {
return naturalSort.insensitive && ('' + s).toLowerCase() || '' + s;
},
// convert all to strings strip whitespace
x = i(a).replace(sre, '') || '',
y = i(b).replace(sre, '') || '',
// chunk/tokenize
xN = x.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/,'').split('\0'),
yN = y.replace(re, '\0$1\0').replace(/\0$/, '').replace(/^\0/,'').split('\0'),
// numeric, hex or date detection
xD = parseInt(x.match(hre)) || (xN.length != 1 && x.match(dre) && Date.parse(x)),
yD = parseInt(y.match(hre)) || xD && y.match(dre) && Date.parse(y) || null, oFxNcL, oFyNcL;
// first try and sort Hex codes or Dates
if (yD)
if (xD < yD)
return -1;
else if (xD > yD)
return 1;
// natural sorting through split numeric strings and default strings
for (var cLoc = 0, numS = Math.max(xN.length, yN.length); cLoc < numS; cLoc++) {
// find floats not starting with '0', string or 0 if not defined (Clint Priest)
oFxNcL = !(xN[cLoc] || '').match(ore) && parseFloat(xN[cLoc]) || xN[cLoc] || 0;
oFyNcL = !(yN[cLoc] || '').match(ore) && parseFloat(yN[cLoc]) || yN[cLoc] || 0;
// handle numeric vs string comparison - number < string - (Kyle Adams)
if (isNaN(oFxNcL) !== isNaN(oFyNcL)) {
return (isNaN(oFxNcL)) ? 1 : -1;
}
// rely on string comparison if different types - i.e. '02' < 2 != '02' < '2'
else if (typeof oFxNcL !== typeof oFyNcL) {
oFxNcL += '';
oFyNcL += '';
}
if (oFxNcL < oFyNcL)
return -1;
if (oFxNcL > oFyNcL)
return 1;
}
return 0;
};
define([ 'jquery', 'underscore', 'openbis', 'test/common' ], function($, _, openbis, common) {
define([ 'jquery', 'underscore', 'openbis', 'test/common', 'test/naturalsort' ], function($, _, openbis, common, naturalsort) {
return function() {
QUnit.module("Search tests");
......@@ -26,7 +26,7 @@ define([ 'jquery', 'underscore', 'openbis', 'test/common' ], function($, _, open
});
}
var testSearchWithPagingAndSorting = function(c, fSearch, fetchOptions, fieldName) {
var testSearchWithPagingAndSorting = function(c, fSearch, fetchOptions, fieldName, fieldParameters) {
c.start();
fetchOptions.from(null).count(null);
......@@ -40,17 +40,12 @@ define([ 'jquery', 'underscore', 'openbis', 'test/common' ], function($, _, open
c.ok("Sorting by " + fieldName);
var fieldGetterName = "get" + fieldName.substr(0, 1).toUpperCase() + fieldName.substr(1);
objects.sort(function(o1, o2) {
var v1 = o1[fieldName];
var v2 = o2[fieldName];
if (v1 > v2) {
return 1;
} else if (v1 < v2) {
return -1;
} else {
return 0;
}
var v1 = o1[fieldGetterName](fieldParameters);
var v2 = o2[fieldGetterName](fieldParameters);
return naturalsort(v1, v2);
});
var codes = objects.map(function(object) {
......@@ -63,12 +58,12 @@ define([ 'jquery', 'underscore', 'openbis', 'test/common' ], function($, _, open
var secondFromEnd = codes[codes.length - 2];
fetchOptions.from(1).count(1);
fetchOptions.sortBy()[fieldName]();
fetchOptions.sortBy()[fieldName](fieldParameters);
return fSearch(facade).then(function(results) {
c.ok("Got results ASC");
c.assertObjectsWithValues(results.getObjects(), "code", [ secondFromStart ]);
fetchOptions.sortBy()[fieldName]().desc();
fetchOptions.sortBy()[fieldName](fieldParameters).desc();
return fSearch(facade).then(function(results) {
c.ok("Got results DESC");
......@@ -375,6 +370,22 @@ define([ 'jquery', 'underscore', 'openbis', 'test/common' ], function($, _, open
}, fo);
});
QUnit.test("searchDataSets() with sorting by property", function(assert) {
var c = new common(assert);
var criteria = new c.DataSetSearchCriteria();
criteria.withOrOperator();
criteria.withPermId().thatEquals("20130412142543232-197");
criteria.withPermId().thatEquals("20130412142205843-196");
criteria.withPermId().thatEquals("20130412142942295-198");
var fo = c.createDataSetFetchOptions();
testSearchWithPagingAndSorting(c, function(facade) {
return facade.searchDataSets(criteria, fo);
}, fo, "property", "RESOLUTION");
});
QUnit.test("searchDataSets() withoutSample", function(assert) {
var c = new common(assert);
......
......@@ -20,6 +20,7 @@ import java.util.Comparator;
import org.apache.commons.collections.ComparatorUtils;
import ch.systemsx.cisd.common.collection.AlphanumComparator;
import ch.systemsx.cisd.openbis.generic.shared.basic.GridRowModel;
import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition;
import ch.systemsx.cisd.openbis.generic.shared.basic.dto.SortInfo.SortDir;
......
......@@ -198,6 +198,10 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
prototype.setSample = function(sample) {
this.sample = sample;
};
prototype.getProperty = function(propertyName) {
var properties = this.getProperties();
return properties ? properties[propertyName] : null;
};
prototype.getProperties = function() {
if (this.getFetchOptions().hasProperties()) {
return this.properties;
......
......@@ -111,6 +111,10 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
prototype.setHistory = function(history) {
this.history = history;
};
prototype.getProperty = function(propertyName) {
var properties = this.getProperties();
return properties ? properties[propertyName] : null;
};
prototype.getProperties = function() {
if (this.getFetchOptions().hasProperties()) {
return this.properties;
......
......@@ -79,6 +79,10 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
prototype.setModificationDate = function(modificationDate) {
this.modificationDate = modificationDate;
};
prototype.getProperty = function(propertyName) {
var properties = this.getProperties();
return properties ? properties[propertyName] : null;
};
prototype.getProperties = function() {
if (this.getFetchOptions().hasProperties()) {
return this.properties;
......
......@@ -106,6 +106,10 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
prototype.setExperiment = function(experiment) {
this.experiment = experiment;
};
prototype.getProperty = function(propertyName) {
var properties = this.getProperties();
return properties ? properties[propertyName] : null;
};
prototype.getProperties = function() {
if (this.getFetchOptions().hasProperties()) {
return this.properties;
......
......@@ -13,6 +13,7 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
prototype.code = null;
prototype.description = null;
prototype.registrationDate = null;
prototype.modificationDate = null;
prototype.registrator = null;
prototype.samples = null;
prototype.projects = null;
......@@ -47,6 +48,12 @@ define([ "stjs", "util/Exceptions" ], function(stjs, exceptions) {
prototype.setRegistrationDate = function(registrationDate) {
this.registrationDate = registrationDate;
};
prototype.getModificationDate = function() {
return this.modificationDate;
};
prototype.setModificationDate = function(modificationDate) {
this.modificationDate = modificationDate;
};
prototype.getRegistrator = function() {
if (this.getFetchOptions().hasRegistrator()) {
return this.registrator;
......
......@@ -6,7 +6,8 @@ define([ "require", "stjs", "dto/fetchoptions/sort/SortOptions" ], function(requ
var fields = {
CODE : "CODE",
REGISTRATION_DATE : "REGISTRATION_DATE",
MODIFICATION_DATE : "MODIFICATION_DATE"
MODIFICATION_DATE : "MODIFICATION_DATE",
PROPERTY : "PROPERTY"
};
stjs.extend(EntitySortOptions, SortOptions, [ SortOptions ], function(constructor, prototype) {
......@@ -18,6 +19,14 @@ define([ "require", "stjs", "dto/fetchoptions/sort/SortOptions" ], function(requ
prototype.getCode = function() {
return this.getSorting(fields.CODE);
};
prototype.property = function(propertyName) {
return this.getOrCreateSorting(fields.PROPERTY + propertyName);
};
prototype.getProperty = function(propertyName) {
return this.getSorting(fields.PROPERTY + propertyName);
};
prototype.registrationDate = function() {
return this.getOrCreateSorting(fields.REGISTRATION_DATE);
};
......
......@@ -236,6 +236,41 @@ public class SearchMaterialTest extends AbstractTest
testSearch(TEST_USER, criteria, new MaterialPermId("SRM_1", "SELF_REF"), new MaterialPermId("SRM_1A", "SELF_REF"));
}
@Test
public void testSearchWithSortingByPropertyWithFloatValues()
{
String sessionToken = v3api.login(TEST_USER, PASSWORD);
MaterialSearchCriteria criteria = new MaterialSearchCriteria();
criteria.withOrOperator();
criteria.withId().thatEquals(new MaterialPermId("GFP", "CONTROL"));
criteria.withId().thatEquals(new MaterialPermId("SCRAM", "CONTROL"));
criteria.withId().thatEquals(new MaterialPermId("XXXXX-ALL", "CONTROL"));
criteria.withId().thatEquals(new MaterialPermId("X-NO-DESC", "CONTROL"));
criteria.withId().thatEquals(new MaterialPermId("X-NO-SIZE", "CONTROL"));
MaterialFetchOptions fo = new MaterialFetchOptions();
fo.withProperties();
fo.sortBy().property("VOLUME").asc();
List<Material> materials1 = v3api.searchMaterials(sessionToken, criteria, fo).getObjects();
assertEquals(materials1.get(0).getProperties().get("VOLUME"), "2.2");
assertEquals(materials1.get(1).getProperties().get("VOLUME"), "3.0");
assertEquals(materials1.get(2).getProperties().get("VOLUME"), "22.22");
assertEquals(materials1.get(3).getProperties().get("VOLUME"), "99.99");
assertEquals(materials1.get(4).getProperties().get("VOLUME"), "123");
fo.sortBy().property("VOLUME").desc();
List<Material> materials2 = v3api.searchMaterials(sessionToken, criteria, fo).getObjects();
assertEquals(materials2.get(0).getProperties().get("VOLUME"), "123");
assertEquals(materials2.get(1).getProperties().get("VOLUME"), "99.99");
assertEquals(materials2.get(2).getProperties().get("VOLUME"), "22.22");
assertEquals(materials2.get(3).getProperties().get("VOLUME"), "3.0");
assertEquals(materials2.get(4).getProperties().get("VOLUME"), "2.2");
}
@Test
public void testSearchWithAndOperator()
{
......
......@@ -621,6 +621,67 @@ public class SearchSampleTest extends AbstractSampleTest
v3api.logout(sessionToken);
}
@Test
public void testSearchWithSortingByPropertyWithTextValues()
{
SampleSearchCriteria criteria = new SampleSearchCriteria();
criteria.withOrOperator();
criteria.withPermId().thatEquals("200902091219327-1025");
criteria.withPermId().thatEquals("200902091225616-1027");
criteria.withPermId().thatEquals("200902091250077-1026");
String sessionToken = v3api.login(TEST_USER, PASSWORD);
SampleFetchOptions fo = new SampleFetchOptions();
fo.withProperties();
fo.sortBy().property("COMMENT").asc();
List<Sample> samples1 = search(sessionToken, criteria, fo);
assertEquals(samples1.get(0).getProperties().get("COMMENT"), "extremely simple stuff");
assertEquals(samples1.get(1).getProperties().get("COMMENT"), "stuff like others");
assertEquals(samples1.get(2).getProperties().get("COMMENT"), "very advanced stuff");
fo.sortBy().property("COMMENT").desc();
List<Sample> samples2 = search(sessionToken, criteria, fo);
assertEquals(samples2.get(0).getProperties().get("COMMENT"), "very advanced stuff");
assertEquals(samples2.get(1).getProperties().get("COMMENT"), "stuff like others");
assertEquals(samples2.get(2).getProperties().get("COMMENT"), "extremely simple stuff");
v3api.logout(sessionToken);
}
@Test
public void testSearchWithSortingByPropertyWithIntegerValues()
{
SampleSearchCriteria criteria = new SampleSearchCriteria();
criteria.withOrOperator();
criteria.withPermId().thatEquals("200902091219327-1025");
criteria.withPermId().thatEquals("200902091225616-1027");
criteria.withPermId().thatEquals("200902091250077-1026");
criteria.withPermId().thatEquals("200811050946559-981");
String sessionToken = v3api.login(TEST_USER, PASSWORD);
SampleFetchOptions fo = new SampleFetchOptions();
fo.withProperties();
fo.sortBy().property("SIZE").asc();
List<Sample> samples1 = search(sessionToken, criteria, fo);
assertEquals(samples1.get(0).getProperties().get("SIZE"), "123");
assertEquals(samples1.get(1).getProperties().get("SIZE"), "321");
assertEquals(samples1.get(2).getProperties().get("SIZE"), "666");
assertEquals(samples1.get(3).getProperties().get("SIZE"), "4711");
fo.sortBy().property("SIZE").desc();
List<Sample> samples2 = search(sessionToken, criteria, fo);
assertEquals(samples2.get(0).getProperties().get("SIZE"), "4711");
assertEquals(samples2.get(1).getProperties().get("SIZE"), "666");
assertEquals(samples2.get(2).getProperties().get("SIZE"), "321");
assertEquals(samples2.get(3).getProperties().get("SIZE"), "123");
v3api.logout(sessionToken);
}
@Test
public void testSearchWithSortingByRegistrationDate()
{
......@@ -840,76 +901,64 @@ public class SearchSampleTest extends AbstractSampleTest
v3api.logout(sessionToken);
}
private String getCodePropertyPairs(List<Sample> samples, String propertyCode) {
StringBuilder builder = new StringBuilder();
builder.append("SEARCH TEST RESULT: ");
for(Sample sample : samples) {
builder.append(sample.getCode() + ":" + sample.getProperties().get(propertyCode) + " ");
}
return builder.toString();
}
@Test
public void testSearchNumeric()
{
//SIZE: 4711 CODE: 3VCP7
//SIZE: 123 CODE: CP-TEST-1
//SIZE: 321 CODE: CP-TEST-2
//SIZE: 666 CODE: CP-TEST-3
// SIZE: 4711 CODE: 3VCP7
// SIZE: 123 CODE: CP-TEST-1
// SIZE: 321 CODE: CP-TEST-2
// SIZE: 666 CODE: CP-TEST-3
String sessionToken = v3api.login(TEST_USER, PASSWORD);
SampleFetchOptions sortByCodeFO = new SampleFetchOptions();
sortByCodeFO.sortBy().code().asc();
sortByCodeFO.withProperties();
//Greater or Equals - Giving integer as real
// Greater or Equals - Giving integer as real
SampleSearchCriteria criteriaGOE = new SampleSearchCriteria();
criteriaGOE.withNumberProperty("SIZE").thatIsGreaterThanOrEqualTo(321.0);
List<Sample> samplesGOE = search(sessionToken, criteriaGOE, sortByCodeFO);
assertSampleIdentifiersInOrder(samplesGOE, "/CISD/3VCP7", "/CISD/CP-TEST-2", "/CISD/CP-TEST-3");
//Greater - Giving integer as real
// Greater - Giving integer as real
SampleSearchCriteria criteriaG = new SampleSearchCriteria();
criteriaG.withNumberProperty("SIZE").thatIsGreaterThan(321.0);
List<Sample> samplesG = search(sessionToken, criteriaG, sortByCodeFO);
assertSampleIdentifiersInOrder(samplesG, "/CISD/3VCP7", "/CISD/CP-TEST-3");
//Equals As Text - Real
// Equals As Text - Real
SampleSearchCriteria criteriaETxt2 = new SampleSearchCriteria();
criteriaETxt2.withProperty("SIZE").thatEquals("666.0");
List<Sample> samplesETxt2 = search(sessionToken, criteriaETxt2, sortByCodeFO);
assertSampleIdentifiersInOrder(samplesETxt2, "/CISD/CP-TEST-3");
//Equals As Text - Integer
// Equals As Text - Integer
SampleSearchCriteria criteriaETxt = new SampleSearchCriteria();
criteriaETxt.withProperty("SIZE").thatEquals("666");
List<Sample> samplesETxt = search(sessionToken, criteriaETxt, sortByCodeFO);
assertSampleIdentifiersInOrder(samplesETxt, "/CISD/CP-TEST-3");
//Equals
// Equals
SampleSearchCriteria criteriaE = new SampleSearchCriteria();
criteriaE.withNumberProperty("SIZE").thatEquals(666);
List<Sample> samplesE = search(sessionToken, criteriaE, sortByCodeFO);
assertSampleIdentifiersInOrder(samplesE, "/CISD/CP-TEST-3");
//Less
// Less
SampleSearchCriteria criteriaL = new SampleSearchCriteria();
criteriaL.withNumberProperty("SIZE").thatIsLessThan(666);
List<Sample> samplesL = search(sessionToken, criteriaL, sortByCodeFO);
assertSampleIdentifiersInOrder(samplesL, "/CISD/CP-TEST-1", "/CISD/CP-TEST-2");
//Less or Equals
// Less or Equals
SampleSearchCriteria criteriaLOE = new SampleSearchCriteria();
criteriaLOE.withNumberProperty("SIZE").thatIsLessThanOrEqualTo(321);
List<Sample> samplesLOE = search(sessionToken, criteriaLOE, sortByCodeFO);
assertSampleIdentifiersInOrder(samplesLOE, "/CISD/CP-TEST-1", "/CISD/CP-TEST-2");
v3api.logout(sessionToken);
}
private void testSearch(String user, SampleSearchCriteria criteria, String... expectedIdentifiers)
{
String sessionToken = v3api.login(user, PASSWORD);
......@@ -925,12 +974,12 @@ public class SearchSampleTest extends AbstractSampleTest
assertEquals(samples.size(), expectedCount);
v3api.logout(sessionToken);
}
private List<Sample> search(String sessionToken, SampleSearchCriteria criteria, SampleFetchOptions fetchOptions)
{
SearchResult<Sample> searchResult =
v3api.searchSamples(sessionToken, criteria, fetchOptions);
return searchResult.getObjects();
}
}
......@@ -18,16 +18,17 @@ package ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort;
import static ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.CodeComparator.CODE;
import static ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.ModificationDateComparator.MODIFICATION_DATE;
import static ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.PropertyComparator.PROPERTY;
import static ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.RegistrationDateComparator.REGISTRATION_DATE;
import java.util.Comparator;
import java.util.Map;
import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.interfaces.ICodeHolder;
import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.interfaces.IModificationDateHolder;
import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.interfaces.IRegistrationDateHolder;
import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.CodeComparator;
import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.ModificationDateComparator;
import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.PropertyComparator;
import ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator.RegistrationDateComparator;
import ch.systemsx.cisd.base.annotation.JsonObject;
......@@ -50,6 +51,16 @@ public class EntitySortOptions<OBJECT extends ICodeHolder & IRegistrationDateHol
return getSorting(CODE);
}
public SortOrder property(String propertyName)
{
return getOrCreateSorting(PROPERTY + propertyName);
}
public SortOrder getProperty(String propertyName)
{
return getSorting(PROPERTY + propertyName);
}
public SortOrder registrationDate()
{
return getOrCreateSorting(REGISTRATION_DATE);
......@@ -71,11 +82,23 @@ public class EntitySortOptions<OBJECT extends ICodeHolder & IRegistrationDateHol
}
@Override
public void addComparators(Map<String, Comparator<OBJECT>> map)
public Comparator<OBJECT> getComparator(String field)
{
map.put(CODE, new CodeComparator<OBJECT>());
map.put(REGISTRATION_DATE, new RegistrationDateComparator<OBJECT>());
map.put(MODIFICATION_DATE, new ModificationDateComparator<OBJECT>());
if (CODE.equals(field))
{
return new CodeComparator<OBJECT>();
} else if (REGISTRATION_DATE.equals(field))
{
return new RegistrationDateComparator<OBJECT>();
} else if (MODIFICATION_DATE.equals(field))
{
return new ModificationDateComparator<OBJECT>();
} else if (field.startsWith(PROPERTY))
{
return new PropertyComparator<OBJECT>(field.substring(PROPERTY.length()));
} else
{
return null;
}
}
}
......@@ -216,15 +216,18 @@ public class SortAndPage
int index = 0;
for (Sorting sorting : sortings)
{
Comparator aComparator = sortBy.getComparator(sorting.getField());
if (aComparator == null)
if (sorting.getField() != null)
{
throw new IllegalArgumentException("Comparator for field " + sorting.getField() + " not found");
}
Comparator aComparator = sortBy.getComparator(sorting.getField());
if (aComparator == null)
{
throw new IllegalArgumentException("Comparator for field " + sorting.getField() + " not found");
}
comparators[index] = aComparator;
directions[index] = sorting.getOrder().isAsc() ? 1 : -1;
index++;
comparators[index] = aComparator;
directions[index] = sorting.getOrder().isAsc() ? 1 : -1;
index++;
}
}
return new Comparator()
......
......@@ -18,10 +18,8 @@ package ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort;
import java.io.Serializable;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import ch.systemsx.cisd.base.annotation.JsonObject;
......@@ -34,24 +32,11 @@ public abstract class SortOptions<OBJECT> implements Serializable
private static final long serialVersionUID = 1L;
private transient Map<String, Comparator<OBJECT>> comparators;
private List<Sorting> sortings = new LinkedList<>();
protected void addComparators(Map<String, Comparator<OBJECT>> map)
{
}
public final Comparator<OBJECT> getComparator(String field)
public Comparator<OBJECT> getComparator(String field)
{
if (comparators == null)
{
Map<String, Comparator<OBJECT>> map = new HashMap<String, Comparator<OBJECT>>();
addComparators(map);
comparators = map;
}
return comparators.get(field);
return null;
}
protected SortOrder getOrCreateSorting(String field)
......
......@@ -32,7 +32,7 @@ public abstract class AbstractComparator<OBJECT, VALUE extends Comparable<VALUE>
if (value1 != null && value2 != null)
{
return value1.compareTo(value2);
return doCompare(value1, value2);
} else if (value1 != null)
{
return 1;
......@@ -45,6 +45,11 @@ public abstract class AbstractComparator<OBJECT, VALUE extends Comparable<VALUE>
}
}
protected int doCompare(VALUE value1, VALUE value2)
{
return value1.compareTo(value2);
}
protected abstract VALUE getValue(OBJECT o);
}
/*
* Copyright 2015 ETH Zuerich, CISD
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ch.ethz.sis.openbis.generic.shared.api.v3.dto.fetchoptions.sort.comparator;
import ch.systemsx.cisd.common.collection.AlphanumComparator;
/**
* @author pkupczyk
*/
public abstract class AbstractStringComparator<OBJECT> extends AbstractComparator<OBJECT, String>
{
private AlphanumComparator alphanumComparator = new AlphanumComparator();
@Override
protected int doCompare(String value1, String value2)
{
return alphanumComparator.compare(value1, value2);
}
}
......@@ -21,7 +21,7 @@ import ch.ethz.sis.openbis.generic.shared.api.v3.dto.entity.interfaces.ICodeHold
/**
* @author pkupczyk
*/
public class CodeComparator<OBJECT extends ICodeHolder> extends AbstractComparator<OBJECT, String>
public class CodeComparator<OBJECT extends ICodeHolder> extends AbstractStringComparator<OBJECT>
{
public static final String CODE = "CODE";
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment