protected void applyQueryFilters( final MultivaluedMap<String, String> p, final CriteriaBuilder builder) { final MultivaluedMap<String, String> params = new MultivaluedMapImpl(); params.putAll(p); builder.distinct(); builder.limit(DEFAULT_LIMIT); // not sure why we remove this, but that's what the old query filter code did, I presume there's // a reason :) params.remove("_dc"); if (params.containsKey("limit")) { builder.limit(Integer.valueOf(params.getFirst("limit"))); params.remove("limit"); } if (params.containsKey("offset")) { builder.offset(Integer.valueOf(params.getFirst("offset"))); params.remove("offset"); } // Is this necessary anymore? setLimitOffset() comments implies it's for Ext-JS. if (params.containsKey("start")) { builder.offset(Integer.valueOf(params.getFirst("start"))); params.remove("start"); } if (params.containsKey("orderBy")) { builder.orderBy(params.getFirst("orderBy")); params.remove("orderBy"); if (params.containsKey("order")) { if ("desc".equalsIgnoreCase(params.getFirst("order"))) { builder.desc(); } else { builder.asc(); } params.remove("order"); } } final String query = removeParameter(params, "query"); if (query != null) builder.sql(query); final String matchType; final String match = removeParameter(params, "match"); if (match == null) { matchType = "all"; } else { matchType = match; } builder.match(matchType); final Class<?> criteriaClass = builder.toCriteria().getCriteriaClass(); final BeanWrapper wrapper = getBeanWrapperForClass(criteriaClass); final String comparatorParam = removeParameter(params, "comparator", "eq").toLowerCase(); final Criteria currentCriteria = builder.toCriteria(); for (final String key : params.keySet()) { for (final String paramValue : params.get(key)) { // NOSONAR // NOSONAR the interface of MultivaluedMap.class declares List<String> as return value, // the actual implementation com.sun.jersey.core.util.MultivaluedMapImpl returns a String, // so this is fine in some way ... if ("null".equalsIgnoreCase(paramValue)) { builder.isNull(key); } else if ("notnull".equalsIgnoreCase(paramValue)) { builder.isNotNull(key); } else { Object value; Class<?> type = Object.class; try { type = currentCriteria.getType(key); } catch (final IntrospectionException e) { LOG.debug("Unable to determine type for key {}", key); } if (type == null) { type = Object.class; } LOG.warn("comparator = {}, key = {}, propertyType = {}", comparatorParam, key, type); if (comparatorParam.equals("contains") || comparatorParam.equals("iplike") || comparatorParam.equals("ilike") || comparatorParam.equals("like")) { value = paramValue; } else { LOG.debug("convertIfNecessary({}, {})", key, paramValue); try { value = wrapper.convertIfNecessary(paramValue, type); } catch (final Throwable t) { LOG.debug("failed to introspect (key = {}, value = {})", key, paramValue, t); value = paramValue; } } try { final Method m = builder.getClass().getMethod(comparatorParam, String.class, Object.class); m.invoke(builder, new Object[] {key, value}); } catch (final Throwable t) { LOG.warn( "Unable to find method for comparator: {}, key: {}, value: {}", comparatorParam, key, value, t); } } } } }