From b2c53fc04bcec0ca5a1bc948faccc7489c88c78b Mon Sep 17 00:00:00 2001 From: felmer <felmer> Date: Mon, 28 Sep 2009 09:07:07 +0000 Subject: [PATCH] LMS-1186 standard functions implemented, FilterUtils class refactored SVN: 12724 --- .../framework/EntityPropertyColDef.java | 8 +- .../application/ui/filter/FilterToolbar.java | 13 +-- .../ui/grid/AbstractBrowserGrid.java | 2 +- .../web/client/dto/CustomFilterInfo.java | 15 --- .../client/web/server/calculator/Row.java | 61 ++++++++++++ .../web/server/calculator/RowCalculator.java | 94 +++++++++++++++++++ .../server/calculator/StandardFunctions.java | 75 +++++++++++++++ .../client/web/server/util/FilterUtils.java | 57 +---------- 8 files changed, 243 insertions(+), 82 deletions(-) create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/Row.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/RowCalculator.java create mode 100644 openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/StandardFunctions.java diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/EntityPropertyColDef.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/EntityPropertyColDef.java index 3c4a1c8a8cc..3996522528d 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/EntityPropertyColDef.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/columns/framework/EntityPropertyColDef.java @@ -34,6 +34,10 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.dto.PropertyType; public class EntityPropertyColDef<T extends IEntityPropertiesHolder> extends AbstractColumnDefinition<T> implements IsSerializable { + private static final Double DOUBLE_MIN_VALUE = new Double(-Double.MAX_VALUE); + + private static final Integer INTEGER_MIN_VALUE = new Integer(Integer.MIN_VALUE); + private static final int PROPERTY_COLUMN_WIDTH = 120; private static final String PROPERTY_PREFIX = "property-"; @@ -114,9 +118,9 @@ public class EntityPropertyColDef<T extends IEntityPropertiesHolder> extends switch (dataType) { case INTEGER: - return valueAsString == null ? new Integer(Integer.MIN_VALUE) : new Integer(valueAsString); + return valueAsString == null ? INTEGER_MIN_VALUE : new Integer(valueAsString); case REAL: - return valueAsString == null ? new Double(-Double.MAX_VALUE) : new Double(valueAsString); + return valueAsString == null ? DOUBLE_MIN_VALUE : new Double(valueAsString); default: return super.getComparableValue(rowModel); } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/filter/FilterToolbar.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/filter/FilterToolbar.java index 5e952fa9d4c..f70ed4577c5 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/filter/FilterToolbar.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/filter/FilterToolbar.java @@ -1,6 +1,5 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.filter; -import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; @@ -25,13 +24,11 @@ import ch.systemsx.cisd.openbis.generic.client.web.client.ICommonClientServiceAs import ch.systemsx.cisd.openbis.generic.client.web.client.application.Dict; import ch.systemsx.cisd.openbis.generic.client.web.client.application.IViewContext; import ch.systemsx.cisd.openbis.generic.client.web.client.application.framework.IDatabaseModificationObserver; -import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IColumnDefinitionProvider; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.IDisplayTypeIDProvider; import ch.systemsx.cisd.openbis.generic.client.web.client.application.ui.grid.PagingColumnFilter; import ch.systemsx.cisd.openbis.generic.client.web.client.application.util.IDelegatedAction; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomFilterInfo; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ParameterWithValue; -import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.DatabaseModificationKind; import ch.systemsx.cisd.openbis.generic.shared.basic.dto.Filter; @@ -49,20 +46,16 @@ public class FilterToolbar<T> extends ToolBar implements IDatabaseModificationOb private final FilterSelectionWidget filterSelectionWidget; - private final IColumnDefinitionProvider<T> columnDefinitionProvider; - private final IDelegatedAction delegatedAction; private final TextToolItem applyTool; public FilterToolbar(IViewContext<ICommonClientServiceAsync> viewContext, String gridId, IDisplayTypeIDProvider displayTypeIDProvider, - final List<PagingColumnFilter<T>> filterWidgets, IDelegatedAction delegatedAction, - final IColumnDefinitionProvider<T> columnDefinitionProvider) + final List<PagingColumnFilter<T>> filterWidgets, IDelegatedAction delegatedAction) { this.columnFilters = filterWidgets; this.delegatedAction = delegatedAction; - this.columnDefinitionProvider = columnDefinitionProvider; add(new LabelToolItem(viewContext.getMessage(Dict.FILTER) + ": ")); filterSelectionWidget = new FilterSelectionWidget(viewContext, gridId, displayTypeIDProvider); @@ -114,10 +107,6 @@ public class FilterToolbar<T> extends ToolBar implements IDatabaseModificationOb } else { CustomFilterInfo<T> info = new CustomFilterInfo<T>(); - List<IColumnDefinition<T>> columnDefinitions = - columnDefinitionProvider.getColumnDefinitions(new ArrayList<String>( - selected.getColumns())); - info.setColumns(columnDefinitions); info.setExpression(selected.getExpression()); Set<ParameterWithValue> parameters = new HashSet<ParameterWithValue>(); for (Component field : filterContainer.getItems()) diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java index 19e841c9205..3eeb4d961fc 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/application/ui/grid/AbstractBrowserGrid.java @@ -226,7 +226,7 @@ public abstract class AbstractBrowserGrid<T/* Entity */, M extends BaseEntityMod pagingToolbar.bind(pagingLoader); this.filterToolbar = new FilterToolbar<T>(viewContext, gridId, this, filterWidgets, - createApplyFiltersDelagator(), this); + createApplyFiltersDelagator()); final LayoutContainer bottomToolbars = createBottomToolbars(filterToolbar, pagingToolbar); this.contentPanel = createEmptyContentPanel(); contentPanel.add(grid); diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomFilterInfo.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomFilterInfo.java index d46f95ed98f..d52611da5de 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomFilterInfo.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/client/dto/CustomFilterInfo.java @@ -16,13 +16,10 @@ package ch.systemsx.cisd.openbis.generic.client.web.client.dto; -import java.util.List; import java.util.Set; import com.google.gwt.user.client.rpc.IsSerializable; -import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition; - /** * Stores information about selected custom filter. * @@ -35,8 +32,6 @@ public class CustomFilterInfo<T> implements IsSerializable private Set<ParameterWithValue> parameters; - private List<IColumnDefinition<T>> columns; - public CustomFilterInfo() { } @@ -61,14 +56,4 @@ public class CustomFilterInfo<T> implements IsSerializable this.parameters = parameters; } - public List<IColumnDefinition<T>> getColumns() - { - return columns; - } - - public void setColumns(List<IColumnDefinition<T>> columns) - { - this.columns = columns; - } - } diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/Row.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/Row.java new file mode 100644 index 00000000000..01de1b7e8a2 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/Row.java @@ -0,0 +1,61 @@ +/* + * Copyright 2009 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.systemsx.cisd.openbis.generic.client.web.server.calculator; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition; + +/** + * Row object used in jython expressions to access column values. + * <p> + * All public methods of this class are part of the Filter/Calculated Column API. + * + * @author Franz-Josef Elmer + */ +public final class Row<T> +{ + private final Map<String, IColumnDefinition<T>> map = new HashMap<String, IColumnDefinition<T>>(); + + private T row; + + public Row(Set<IColumnDefinition<T>> availableColumns) + { + for (IColumnDefinition<T> columnDefinition : availableColumns) + { + map.put(columnDefinition.getIdentifier(), columnDefinition); + } + } + + void setRowData(T row) + { + this.row = row; + } + + public Object col(String columnID) + { + IColumnDefinition<T> columnDefinition = map.get(columnID); + if (columnDefinition == null) + { + throw new IllegalArgumentException("Undefined column: " + columnID); + } + return columnDefinition.getComparableValue(row); + } + +} \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/RowCalculator.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/RowCalculator.java new file mode 100644 index 00000000000..be19c31a857 --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/RowCalculator.java @@ -0,0 +1,94 @@ +/* + * Copyright 2009 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.systemsx.cisd.openbis.generic.client.web.server.calculator; + +import java.math.BigInteger; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import ch.systemsx.cisd.common.evaluator.Evaluator; +import ch.systemsx.cisd.common.evaluator.EvaluatorException; +import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ParameterWithValue; +import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition; + +/** + * + * + * @author Franz-Josef Elmer + */ +public class RowCalculator<T> +{ + private static final String INITIAL_SCRIPT = + "from " + StandardFunctions.class.getCanonicalName() + " import *"; + + private final Evaluator evaluator; + + private final Row<T> row; + + public RowCalculator(Set<IColumnDefinition<T>> availableColumns, String expression, + Set<ParameterWithValue> parameters) + { + evaluator = new Evaluator(substitudeParameters(expression, parameters), Math.class, + INITIAL_SCRIPT); + row = new Row<T>(availableColumns); + evaluator.set("row", row); + } + + public void setRowData(T rowData) + { + row.setRowData(rowData); + } + + public boolean evalToBoolean() throws EvaluatorException + { + return evaluator.evalToBoolean(); + } + + public int evalToInt() throws EvaluatorException + { + return evaluator.evalToInt(); + } + + public BigInteger evalToBigInt() throws EvaluatorException + { + return evaluator.evalToBigInt(); + } + + public double evalToDouble() throws EvaluatorException + { + return evaluator.evalToDouble(); + } + + public String evalAsString() throws EvaluatorException + { + return evaluator.evalAsString(); + } + + private String substitudeParameters(String originalExpression, Set<ParameterWithValue> parameters) + { + String expression = originalExpression; + for (ParameterWithValue pw : parameters) + { + String substParameter = "${" + pw.getParameter() + "}"; + String quotedParameter = Pattern.quote(substParameter); + String quotedReplacement = Matcher.quoteReplacement(pw.getValue()); + expression = expression.replaceAll(quotedParameter, quotedReplacement); + } + return expression; + } +} diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/StandardFunctions.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/StandardFunctions.java new file mode 100644 index 00000000000..1866f57fbff --- /dev/null +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/calculator/StandardFunctions.java @@ -0,0 +1,75 @@ +/* + * Copyright 2009 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.systemsx.cisd.openbis.generic.client.web.server.calculator; + +/** + * Set of standard functions used in jython expressions. + * <p> + * All public methods of this class are part of the Filter/Calculated Column API. + * + * @author Franz-Josef Elmer + */ +public final class StandardFunctions +{ + private static final Double DOUBLE_DEFAULT_VALUE = new Double(-Double.MAX_VALUE); + private static final Integer INTEGER_DEFAULT_VALUE = new Integer(Integer.MIN_VALUE); + + public static Integer toInteger(Object value) + { + return toInteger(value, INTEGER_DEFAULT_VALUE); + } + + public static Integer toInteger(Object value, Integer defaultValue) + { + if (value instanceof Number) + { + Number number = (Number) value; + return number.intValue(); + } + return isBlank(value) ? defaultValue : new Integer(value.toString()); + } + + public static Double toFloat(Object value) + { + return toFloat(value, DOUBLE_DEFAULT_VALUE); + } + + public static Double toFloat(Object value, Double defaultValue) + { + if (value instanceof Number) + { + Number number = (Number) value; + return number.doubleValue(); + } + return isBlank(value) ? defaultValue : new Double(value.toString()); + } + + public static Object ifThenElse(Boolean condition, Object thenValue, Object elseValue) + { + return condition != null && condition.booleanValue() ? thenValue : elseValue; + } + + private static boolean isBlank(Object value) + { + return value == null || value.toString().trim().length() == 0; + } + + private StandardFunctions() + { + } + +} \ No newline at end of file diff --git a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/FilterUtils.java b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/FilterUtils.java index 32f3742a80b..004d30b756b 100644 --- a/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/FilterUtils.java +++ b/openbis/source/java/ch/systemsx/cisd/openbis/generic/client/web/server/util/FilterUtils.java @@ -16,16 +16,12 @@ package ch.systemsx.cisd.openbis.generic.client.web.server.util; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import ch.systemsx.cisd.common.evaluator.Evaluator; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.CustomFilterInfo; import ch.systemsx.cisd.openbis.generic.client.web.client.dto.ParameterWithValue; +import ch.systemsx.cisd.openbis.generic.client.web.server.calculator.RowCalculator; import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition; /** @@ -35,37 +31,6 @@ import ch.systemsx.cisd.openbis.generic.shared.basic.IColumnDefinition; */ public class FilterUtils { - public static final class Row<T> - { - private final Map<String, IColumnDefinition<T>> map = new HashMap<String, IColumnDefinition<T>>(); - - private T row; - - public Row(Set<IColumnDefinition<T>> availableColumns) - { - for (IColumnDefinition<T> columnDefinition : availableColumns) - { - map.put(columnDefinition.getIdentifier(), columnDefinition); - } - System.out.println(map); - } - - void setRowData(T row) - { - this.row = row; - } - - public Object get(String columnID) - { - IColumnDefinition<T> columnDefinition = map.get(columnID); - if (columnDefinition == null) - { - throw new IllegalArgumentException("Undefined column: " + columnID); - } - return columnDefinition.getComparableValue(row); - } - } - /** * Applies the filter described by <code>customFilterInfo</code> to * <code>allRows<code> and adds the result to the @@ -76,28 +41,16 @@ public class FilterUtils List<T> filterdRows) { String expression = customFilterInfo.getExpression(); - for (ParameterWithValue pw : customFilterInfo.getParameters()) - { - expression = substituteParameter(expression, pw.getParameter(), pw.getValue()); - } - Evaluator e = new Evaluator(expression, Math.class, null); - Row<T> row = new Row<T>(availableColumns); - e.set("row", row); + Set<ParameterWithValue> parameters = customFilterInfo.getParameters(); + RowCalculator<T> calculator = new RowCalculator<T>(availableColumns, expression, parameters); for (T rowData : allRows) { - row.setRowData(rowData); - if (e.evalToBoolean()) + calculator.setRowData(rowData); + if (calculator.evalToBoolean()) { filterdRows.add(rowData); } } } - private static String substituteParameter(String expression, String p, String value) - { - String substParameter = "${" + p + "}"; - String quotedParameter = Pattern.quote(substParameter); - String quotedReplacement = Matcher.quoteReplacement(value); - return expression.replaceAll(quotedParameter, quotedReplacement); - } } -- GitLab