r1001 - trunk/echobase-services/src/main/java/fr/ifremer/echobase/services/service
Author: tchemit Date: 2014-04-02 10:06:04 +0200 (Wed, 02 Apr 2014) New Revision: 1001 Url: http://forge.codelutin.com/projects/echobase/repository/revisions/1001 Log: fixes #4872 (add filter value to test nullity on fields) Modified: trunk/echobase-services/src/main/java/fr/ifremer/echobase/services/service/DbEditorService.java Modified: trunk/echobase-services/src/main/java/fr/ifremer/echobase/services/service/DbEditorService.java =================================================================== --- trunk/echobase-services/src/main/java/fr/ifremer/echobase/services/service/DbEditorService.java 2014-04-02 07:03:59 UTC (rev 1000) +++ trunk/echobase-services/src/main/java/fr/ifremer/echobase/services/service/DbEditorService.java 2014-04-02 08:06:04 UTC (rev 1001) @@ -80,6 +80,13 @@ /** Logger. */ private static final Log log = LogFactory.getLog(DbEditorService.class); + /** + * To replace the eq (ne) to nu (nn) operand. + * + * @since 2.6 + */ + private static final String NULL_FILTER_VALUE = "$NULL"; + @Inject private UserDbPersistenceService persistenceService; @@ -138,7 +145,7 @@ String hql = dao.newFromClause("e"); if (pager != null && pager.canFilter()) { - String filterHql = getFilterHql(tableMeta, pager, paramsList); + String filterHql = pagerToHql(tableMeta, pager, paramsList); hql += " WHERE " + filterHql; } @@ -310,6 +317,230 @@ return decoratorService.getDecorator(getLocale(), type, null); } + + protected String pagerToHql(TableMeta<EchoBaseUserEntityEnum> tableMeta, + TopiaPagerBean pager, + List<Object> params) { + Preconditions.checkNotNull(pager); + Preconditions.checkState(pager.canFilter()); + + String filterHql = null; + + List<String> strFilterRules = Lists.newLinkedList(); + + for (FilterRule rule : pager.getRules()) { + + Map<String, Object> filterParams = Maps.newHashMap(); + + String ruleFilter = ruleFilterToHql(tableMeta, rule, filterParams); + + if (ruleFilter != null) { + + // register new rule + strFilterRules.add("(" + ruleFilter + ")"); + + // register params + for (Map.Entry<String, Object> entry : filterParams.entrySet()) { + params.add(entry.getKey()); + params.add(entry.getValue()); + } + } + } + + if (CollectionUtils.isNotEmpty(strFilterRules)) { + + // add a rule group operator + FilterRuleGroupOperator groupOp = + pager.getGroupOp(); + filterHql = StringUtils.join(strFilterRules, groupOp.name()); + } + + return filterHql; + } + + protected String ruleFilterToHql(TableMeta<EchoBaseUserEntityEnum> tableMeta, + FilterRule rule, + Map<String, Object> filterParams) { + + long timestamp = System.currentTimeMillis(); + int index = 0; + + String ruleFilter; + String field = rule.getField(); + + ColumnMeta columnMeta = tableMeta.getColumns(field); + Preconditions.checkNotNull(columnMeta, + "no property named " + columnMeta); + + FilterRuleOperator op = rule.getOp(); + String data = rule.getData(); + String paramName = field + "_" + timestamp + (index++); + String propertyName = "e." + field; + Object realData = data; + + if (!columnMeta.isNumber() && NULL_FILTER_VALUE.equals(data)) { + if (op == FilterRuleOperator.eq) { + + // use null op + op = FilterRuleOperator.nu; + if (log.isInfoEnabled()) { + log.info("Use *is null* operand (column " + columnMeta.getName() + ")"); + } + + } else if (op == FilterRuleOperator.ne) { + + // use not null op + op = FilterRuleOperator.nn; + if (log.isInfoEnabled()) { + log.info("Use *is not null* operand (column " + columnMeta.getName() + ")"); + } + } + } + + if (columnMeta.isFK()) { + + if (op == FilterRuleOperator.nu || op == FilterRuleOperator.nn) { + + // is null or is not null is a simple case + + ruleFilter = op.toHql(propertyName, + propertyName, + data, + filterParams); + } else { + // must do a select in using the decoration pattern + JXPathDecorator<?> decorator = + (JXPathDecorator<?>) getDecorator(columnMeta.getType()); + + if (decorator.getNbToken() == 1) { + + String fName = "f_" + timestamp + (index); + + // simple case one token + String token = fName + "." + decorator.getProperty(0); + + String subQuery = op.toHql(paramName, + token, + data, + filterParams); + + ruleFilter = propertyName + " IN ( FROM " + + columnMeta.getType().getName() + " " + + fName + " WHERE " + subQuery + ")"; + } else { + + // more than one property, headace time... + List<String> ruleFilters = Lists.newArrayList(); + for (String decoratorToken : decorator.getTokens()) { + String fName = "f_" + timestamp + (index++); + + // simple case one token + String token = fName + "." + decoratorToken; + + String subQuery = op.toHql(paramName, + token, + data, + filterParams); + + ruleFilters.add(propertyName + " IN ( FROM " + + columnMeta.getType().getName() + " " + + fName + " WHERE " + subQuery + ")"); + } + + String middleOp = "OR"; + switch (op) { + // With negate operand, we must match all !(a or b) = !a and !b + case ne: + case nc: + case en: + case bn: + middleOp = "AND"; + break; + } + ruleFilter = "( " + Joiner.on(" " + middleOp + " ").join(ruleFilters) + " )"; + } + } + + } else { + + if (columnMeta.isNumber()) { + + if (op == FilterRuleOperator.cn || + op == FilterRuleOperator.nc || + op == FilterRuleOperator.bw || + op == FilterRuleOperator.bn || + op == FilterRuleOperator.ew || + op == FilterRuleOperator.en) { + + // string operation + + propertyName = "str(" + propertyName + ")"; + } else { + + // real number operation + try { + realData = convertNumber(columnMeta, data); + } catch (Exception e) { + if (log.isErrorEnabled()) { + log.error("Could not convert column (" + columnMeta.getName() + ") to number: " + data, e); + } + realData = null; + } + } + } else if (columnMeta.isDate()) { + propertyName = "str(" + propertyName + ")"; + } + + if (realData == null) { + + // null rule filter + ruleFilter = null; + } else { + ruleFilter = op.toHql(paramName, + propertyName, + realData, + filterParams); + } + } + + return ruleFilter; + } + + protected Number convertNumber(ColumnMeta columnMeta, String data) { + Number number; + if (columnMeta.getType() == byte.class || + columnMeta.getType() == Byte.class) { + number = Byte.valueOf(data); + } else if (columnMeta.getType() == short.class || + columnMeta.getType() == Short.class) { + number = Short.valueOf(data); + } else if (columnMeta.getType() == int.class || + columnMeta.getType() == Integer.class) { + number = Integer.valueOf(data); + } else if (columnMeta.getType() == long.class || + columnMeta.getType() == Long.class) { + number = Integer.valueOf(data); + } else if (columnMeta.getType() == float.class || + columnMeta.getType() == Float.class) { + number = Float.valueOf(data); + } else if (columnMeta.getType() == double.class || + columnMeta.getType() == Double.class) { + number = Double.valueOf(data); + } else if (columnMeta.getType() == BigInteger.class) { + number = new BigInteger(data); + } else if (columnMeta.getType() == BigDecimal.class) { + number = new BigDecimal(data); + } else { + throw new IllegalStateException( + "Can't convert column (" + columnMeta.getName() + ") of type: " + columnMeta.getType()); + } + return number; + } + + /** + * @deprecated since 2.6, no more used + */ + @Deprecated protected String getFilterHql(TableMeta<EchoBaseUserEntityEnum> tableMeta, TopiaPagerBean pager, List<Object> params) {
participants (1)
-
tchemit@users.forge.codelutin.com