Skip to content

Commit

Permalink
backend: endpoint for creating a filtered view
Browse files Browse the repository at this point in the history
MAJOR DocumentFilter(s) refactoring

#372
  • Loading branch information
teosarca committed May 13, 2017
1 parent 34ff643 commit 8101630
Show file tree
Hide file tree
Showing 36 changed files with 1,258 additions and 289 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package de.metas.ui.web.document.filter;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import javax.annotation.concurrent.Immutable;
Expand All @@ -11,6 +12,7 @@
import com.google.common.collect.ImmutableList;

import de.metas.ui.web.document.filter.DocumentFilterParam.Operator;
import lombok.NonNull;

/*
* #%L
Expand Down Expand Up @@ -47,14 +49,25 @@ public static DocumentFilter singleParameterFilter(final String filterId, final
return builder()
.setFilterId(filterId)
.addParameter(DocumentFilterParam.builder()
.setJoinAnd(true)
.setFieldName(fieldName)
.setOperator(operator)
.setValue(value)
.build())
.build();
}

public static DocumentFilter inArrayFilter(final String filterId, final String fieldName, final Collection<Integer> values)
{
return builder()
.setFilterId(filterId)
.addParameter(DocumentFilterParam.builder()
.setFieldName(fieldName)
.setOperator(Operator.IN_ARRAY)
.setValue(ImmutableList.copyOf(values))
.build())
.build();
}

private final String filterId;
private final List<DocumentFilterParam> parameters;

Expand Down Expand Up @@ -88,6 +101,15 @@ public List<DocumentFilterParam> getParameters()
return parameters;
}

public DocumentFilterParam getParameter(@NonNull final String fieldName)
{
return parameters
.stream()
.filter(param -> fieldName.equals(param.getFieldName()))
.findFirst()
.orElseThrow(() -> new IllegalArgumentException("Parameter " + fieldName + " not found in " + this));
}

public static final class Builder
{
private String filterId;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
package de.metas.ui.web.document.filter;

import java.util.Collection;
import java.util.List;
import java.util.function.Function;

import org.adempiere.util.Check;

import com.google.common.base.MoreObjects;
import com.google.common.collect.ImmutableList;

import lombok.NonNull;

/*
* #%L
Expand Down Expand Up @@ -32,7 +39,7 @@ public static final Builder builder()
{
return new Builder();
}

public static final DocumentFilterParam ofSqlWhereClause(final boolean joinAnd, final String sqlWhereClause)
{
return new DocumentFilterParam(joinAnd, sqlWhereClause);
Expand All @@ -54,7 +61,7 @@ public static enum Operator
LESS_OR_EQUAL, //
BETWEEN, //
;

public boolean isRangeOperator()
{
return this == BETWEEN;
Expand Down Expand Up @@ -106,7 +113,7 @@ public String toString()
{
return MoreObjects.toStringHelper(this)
.omitNullValues()
.add("join", joinAnd ? "AND" : "OR")
.add("joinAnd", joinAnd)
.add("fieldName", fieldName)
.add("operator", operator)
.add("value", value)
Expand Down Expand Up @@ -145,6 +152,60 @@ public Object getValue()
return value;
}

public Collection<?> getValueAsCollection()
{
if (value == null)
{
throw new IllegalStateException("Cannot convert null value to Collection<?>");
}
else if (value instanceof Collection)
{
return (Collection<?>)value;
}
else
{
throw new IllegalStateException("Cannot convert value to Collection<?>: " + value);
}
}

public <T> List<T> getValueAsList(@NonNull final Function<Object, T> itemConverter)
{
final Collection<?> valueAsCollection = getValueAsCollection();
if (valueAsCollection == null)
{
throw new IllegalStateException("Cannot convert null value to List<Integer>");
}

if(valueAsCollection.isEmpty())
{
return ImmutableList.of();
}

return valueAsCollection.stream()
.map(itemConverter)
.collect(ImmutableList.toImmutableList());

}

public List<Integer> getValueAsIntList()
{
return getValueAsList(itemObj -> {
if (itemObj == null)
{
// pass-through, even though it will produce an exception when the list will be converted to immutable list
return null;
}
else if (itemObj instanceof Number)
{
return ((Number)itemObj).intValue();
}
else
{
return Integer.parseInt(itemObj.toString());
}
});
}

public Object getValueTo()
{
return valueTo;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package de.metas.ui.web.document.filter.sql;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.adempiere.db.DBConstants;
import org.compiere.util.DB;

import com.google.common.base.MoreObjects;

import de.metas.printing.esb.base.util.Check;
import de.metas.ui.web.document.filter.DocumentFilter;
import de.metas.ui.web.document.filter.DocumentFilterParam;
Expand Down Expand Up @@ -42,55 +40,38 @@
*/

/**
* Helper class to build SQL where clauses from {@link DocumentFilter}s.
* Default {@link SqlDocumentFilterConverter}.
*
* It simply converts the filters to SQL using a given {@link SqlEntityBinding} to map filter parameters.
*
* @author metas-dev <dev@metasfresh.com>
*
*/
public class SqlDocumentFiltersBuilder
/* package */final class SqlDefaultDocumentFilterConverter implements SqlDocumentFilterConverter
{
public static final SqlDocumentFiltersBuilder newInstance(final SqlEntityBinding entityBinding)
static SqlDefaultDocumentFilterConverter newInstance(final SqlEntityBinding entityBinding)
{
return new SqlDocumentFiltersBuilder(entityBinding);
return new SqlDefaultDocumentFilterConverter(entityBinding);
}

private final SqlEntityBinding entityBinding;
private final List<DocumentFilter> filters = new ArrayList<>();

private SqlDocumentFiltersBuilder(@NonNull final SqlEntityBinding entityBinding)
private SqlDefaultDocumentFilterConverter(final @NonNull SqlEntityBinding entityBinding)
{
this.entityBinding = entityBinding;
}

public String buildSqlWhereClause(final List<Object> sqlParams)
@Override
public String toString()
{
if (filters.isEmpty())
{
return "";
}

final StringBuilder sqlWhereClauseBuilder = new StringBuilder();

for (final DocumentFilter filter : filters)
{
final String sqlFilter = buildSqlWhereClause(sqlParams, filter);
if (Check.isEmpty(sqlFilter, true))
{
continue;
}

if (sqlWhereClauseBuilder.length() > 0)
{
sqlWhereClauseBuilder.append("\n AND ");
}
sqlWhereClauseBuilder.append(DB.TO_COMMENT(filter.getFilterId())).append("(").append(sqlFilter).append(")");
}

return sqlWhereClauseBuilder.toString();
return MoreObjects.toStringHelper(this)
.add("entityBinding", entityBinding)
.toString();
}

/** Build document filter where clause */
private String buildSqlWhereClause(final List<Object> sqlParams, final DocumentFilter filter)
@Override
public String getSql(final List<Object> sqlParams, final DocumentFilter filter)
{
final StringBuilder sql = new StringBuilder();

Expand Down Expand Up @@ -148,7 +129,7 @@ private String buildSqlWhereClause(final List<Object> sqlParams, final DocumentF
}
case IN_ARRAY:
{
final List<Object> sqlValuesList = convertToSqlValuesList(filterParam.getValue(), fieldBinding);
final List<Object> sqlValuesList = filterParam.getValueAsList(itemObj -> convertToSqlValue(itemObj, fieldBinding));
return buildSqlWhereClause_InArray(columnSql, sqlValuesList, sqlParams);
}
case GREATER:
Expand Down Expand Up @@ -221,24 +202,6 @@ private Object convertToSqlValue(final Object value, final SqlEntityFieldBinding
return sqlValue;
}

private List<Object> convertToSqlValuesList(final Object valuesAsObj, final SqlEntityFieldBinding fieldBinding)
{
final Stream<?> valuesStream;
if (valuesAsObj instanceof Collection)
{
Collection<?> valuesCollection = (Collection<?>)valuesAsObj;
valuesStream = valuesCollection.stream();
}
else
{
throw new IllegalArgumentException("Value type not supported: " + valuesAsObj);
}

return valuesStream
.map(value -> convertToSqlValue(value, fieldBinding))
.collect(Collectors.toCollection(ArrayList::new));
}

private static final String buildSqlWhereClause_Equals(final String sqlColumnExpr, final Object sqlValue, final boolean negate, final List<Object> sqlParams)
{
if (sqlValue == null)
Expand Down Expand Up @@ -330,7 +293,7 @@ private static final String buildSqlWhereClause_Between(final String sqlColumnEx
.toString();
}

public String replaceTableNameWithTableAlias(final String sql)
private String replaceTableNameWithTableAlias(final String sql)
{
if (sql == null || sql.isEmpty())
{
Expand All @@ -341,14 +304,4 @@ public String replaceTableNameWithTableAlias(final String sql)
return sqlFixed;
}

public SqlDocumentFiltersBuilder addFilters(final List<DocumentFilter> filters)
{
if (filters == null || filters.isEmpty())
{
return this;
}

this.filters.addAll(filters);
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package de.metas.ui.web.document.filter.sql;

import java.util.List;

import org.compiere.util.DB;

import de.metas.printing.esb.base.util.Check;
import de.metas.ui.web.document.filter.DocumentFilter;

/*
* #%L
* metasfresh-webui-api
* %%
* Copyright (C) 2017 metas GmbH
* %%
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as
* published by the Free Software Foundation, either version 2 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program. If not, see
* <http://www.gnu.org/licenses/gpl-2.0.html>.
* #L%
*/

/**
* Converts and {@link DocumentFilter} to SQL.
*
* To create and manipulate {@link SqlDocumentFilterConverter}s please use {@link SqlDocumentFilterConverters}.
*
* @author metas-dev <dev@metasfresh.com>
*
*/
public interface SqlDocumentFilterConverter
{
/**
* Converts given <code>filter</code> to SQL and returns it.
* In case the produced SQL requires parameters, those parameters will be added to <code>sqlParamsOut</code> parameter.
*
* @param sqlParamsOut
* @param filter
* @return SQL
*/
String getSql(List<Object> sqlParamsOut, DocumentFilter filter);

default String getSql(final List<Object> sqlParamsOut, final List<DocumentFilter> filters)
{
if (filters.isEmpty())
{
return "";
}

final StringBuilder sqlWhereClauseBuilder = new StringBuilder();

for (final DocumentFilter filter : filters)
{
final String sqlFilter = getSql(sqlParamsOut, filter);
if (Check.isEmpty(sqlFilter, true))
{
continue;
}

if (sqlWhereClauseBuilder.length() > 0)
{
sqlWhereClauseBuilder.append("\n AND ");
}
sqlWhereClauseBuilder.append(DB.TO_COMMENT(filter.getFilterId())).append("(").append(sqlFilter).append(")");
}

return sqlWhereClauseBuilder.toString();
}
}
Loading

0 comments on commit 8101630

Please sign in to comment.