Search in sources :

Example 1 with ParameterInfo

use of com.haulmont.cuba.core.global.filter.ParameterInfo in project cuba by cuba-platform.

the class AbstractCollectionDatasource method createDataQuery.

protected DataLoadContextQuery createDataQuery(DataLoadContext context, Map<String, Object> params) {
    DataLoadContextQuery q = null;
    if (query != null && queryParameters != null) {
        Map<String, Object> parameters = getQueryParameters(params);
        for (ParameterInfo info : queryParameters) {
            if (ParameterInfo.Type.DATASOURCE.equals(info.getType())) {
                Object value = parameters.get(info.getFlatName());
                if (value == null) {
                    String[] pathElements = info.getPath().split("\\.");
                    if (pathElements.length == 1) {
                        // nothing selected in 'master' datasource, so return null here to clear the 'detail' datasource
                        return null;
                    } else {
                        // The parameter with null value is the path to the datasource item property,
                        // e.g. :ds$User.group.id.
                        // If the 'master' datasource item is not null then do not clear the 'detail' datasource,
                        // a null query parameter value should be processed
                        String dsName = pathElements[0];
                        final Datasource datasource = dsContext.get(dsName);
                        if (datasource == null) {
                            throw new DevelopmentException("Datasource '" + dsName + "' not found in dsContext", "datasource", dsName);
                        }
                        if (datasource.getState() != State.VALID || datasource.getItem() == null)
                            return null;
                    }
                }
            }
        }
        String queryString = getJPQLQuery(getTemplateParams(params));
        q = context.setQueryString(queryString);
        // Pass only parameters used in the resulting query
        QueryParser parser = QueryTransformerFactory.createParser(queryString);
        Set<String> paramNames = parser.getParamNames();
        for (Map.Entry<String, Object> entry : parameters.entrySet()) {
            if (paramNames.contains(entry.getKey()))
                q.setParameter(entry.getKey(), entry.getValue());
        }
    } else if (!(context instanceof ValueLoadContext)) {
        Collection<MetaProperty> properties = metadata.getTools().getNamePatternProperties(metaClass);
        if (!properties.isEmpty()) {
            StringBuilder orderBy = new StringBuilder();
            for (MetaProperty metaProperty : properties) {
                if (metaProperty != null && metaProperty.getAnnotatedElement().getAnnotation(com.haulmont.chile.core.annotations.MetaProperty.class) == null)
                    orderBy.append("e.").append(metaProperty.getName()).append(", ");
            }
            if (orderBy.length() > 0) {
                orderBy.delete(orderBy.length() - 2, orderBy.length());
                orderBy.insert(0, " order by ");
            }
            q = context.setQueryString("select e from " + metaClass.getName() + " e" + orderBy.toString());
        } else
            q = context.setQueryString("select e from " + metaClass.getName() + " e");
    }
    if (q instanceof LoadContext.Query) {
        ((LoadContext.Query) q).setCacheable(isCacheable());
    }
    return q;
}
Also used : ParameterInfo(com.haulmont.cuba.core.global.filter.ParameterInfo)

Example 2 with ParameterInfo

use of com.haulmont.cuba.core.global.filter.ParameterInfo in project cuba by cuba-platform.

the class AbstractCollectionDatasource method getJPQLQuery.

protected String getJPQLQuery(Map<String, Object> parameterValues) {
    String query;
    if (filter == null)
        query = this.query;
    else
        query = filter.processQuery(this.query, parameterValues);
    for (ParameterInfo info : queryParameters) {
        final String paramName = info.getName();
        final String jpaParamName = info.getFlatName();
        // not ending with "."
        Pattern p = Pattern.compile(paramName.replace("$", "\\$") + "([^\\.]|$)");
        Matcher m = p.matcher(query);
        StringBuffer sb = new StringBuffer();
        while (m.find()) {
            m.appendReplacement(sb, jpaParamName + "$1");
        }
        m.appendTail(sb);
        query = sb.toString();
        Object value = parameterValues.get(paramName);
        if (value != null) {
            parameterValues.put(jpaParamName, value);
        }
    }
    query = query.replace(":" + ParametersHelper.CASE_INSENSITIVE_MARKER, ":");
    query = TemplateHelper.processTemplate(query, parameterValues);
    return query;
}
Also used : Pattern(java.util.regex.Pattern) Matcher(java.util.regex.Matcher) ParameterInfo(com.haulmont.cuba.core.global.filter.ParameterInfo)

Example 3 with ParameterInfo

use of com.haulmont.cuba.core.global.filter.ParameterInfo in project cuba by cuba-platform.

the class AbstractCollectionDatasource method getQueryParameters.

protected Map<String, Object> getQueryParameters(Map<String, Object> params) {
    final Map<String, Object> map = new HashMap<>();
    for (ParameterInfo info : queryParameters) {
        String name = info.getFlatName();
        final String path = info.getPath();
        final String[] elements = path.split("\\.");
        switch(info.getType()) {
            case DATASOURCE:
                {
                    String dsName = elements[0];
                    final Datasource datasource = dsContext.get(dsName);
                    if (datasource == null) {
                        throw new DevelopmentException("Datasource '" + dsName + "' not found in dsContext", "datasource", dsName);
                    }
                    if (datasource.getState() == State.VALID) {
                        final Entity item = datasource.getItem();
                        if (elements.length > 1) {
                            String[] valuePath = (String[]) ArrayUtils.subarray(elements, 1, elements.length);
                            String propertyName = InstanceUtils.formatValuePath(valuePath);
                            Object value = InstanceUtils.getValueEx(item, propertyName);
                            map.put(name, value);
                        } else {
                            map.put(name, item);
                        }
                    } else {
                        map.put(name, null);
                    }
                    break;
                }
            case PARAM:
                {
                    Object value;
                    if (dsContext.getFrameContext() == null) {
                        value = null;
                    } else {
                        Map<String, Object> windowParams = dsContext.getFrameContext().getParams();
                        value = windowParams.get(path);
                        if (value == null && elements.length > 1) {
                            Instance instance = (Instance) windowParams.get(elements[0]);
                            if (instance != null) {
                                String[] valuePath = (String[]) ArrayUtils.subarray(elements, 1, elements.length);
                                String propertyName = InstanceUtils.formatValuePath(valuePath);
                                value = InstanceUtils.getValueEx(instance, propertyName);
                            }
                        }
                    }
                    if (value instanceof String && info.isCaseInsensitive()) {
                        value = makeCaseInsensitive((String) value);
                    }
                    map.put(name, value);
                    break;
                }
            case COMPONENT:
                {
                    Object value = null;
                    if (dsContext.getFrameContext() != null) {
                        value = dsContext.getFrameContext().getValue(path);
                        if (value instanceof String && info.isCaseInsensitive()) {
                            value = makeCaseInsensitive((String) value);
                        }
                        if (java.sql.Date.class.equals(info.getJavaClass()) && value != null && value instanceof Date) {
                            value = new java.sql.Date(((Date) value).getTime());
                        }
                        if (refreshOnComponentValueChange) {
                            if (componentValueListener == null)
                                componentValueListener = new ComponentValueListener();
                            try {
                                dsContext.getFrameContext().addValueChangeListener(path, componentValueListener);
                            } catch (Exception e) {
                                Logger log = LoggerFactory.getLogger(AbstractCollectionDatasource.class);
                                log.error("Unable to add value listener: " + e);
                            }
                        }
                    }
                    map.put(name, value);
                    break;
                }
            case SESSION:
                {
                    Object value;
                    value = userSession.getAttribute(path);
                    if (value instanceof String && info.isCaseInsensitive()) {
                        value = makeCaseInsensitive((String) value);
                    }
                    map.put(name, value);
                    break;
                }
            case CUSTOM:
                {
                    Object value = params.get(info.getPath());
                    if (value == null) {
                        // a case when a query contains a parameter like :custom$city.country.id and we passed
                        // just "city" parameter to the datasource refresh() method
                        String[] pathElements = info.getPath().split("\\.");
                        if (pathElements.length > 1) {
                            Object entity = params.get(pathElements[0]);
                            if (entity != null && entity instanceof Instance) {
                                value = InstanceUtils.getValueEx((Instance) entity, Arrays.copyOfRange(pathElements, 1, pathElements.length));
                            }
                        }
                    }
                    if (value instanceof String && info.isCaseInsensitive()) {
                        value = makeCaseInsensitive((String) value);
                    }
                    map.put(name, value);
                    break;
                }
            default:
                {
                    throw new UnsupportedOperationException("Unsupported parameter type: " + info.getType());
                }
        }
    }
    return map;
}
Also used : Entity(com.haulmont.cuba.core.entity.Entity) ParameterInfo(com.haulmont.cuba.core.global.filter.ParameterInfo) Logger(org.slf4j.Logger)

Example 4 with ParameterInfo

use of com.haulmont.cuba.core.global.filter.ParameterInfo in project cuba by cuba-platform.

the class AbstractCollectionDatasource method setQuery.

@Override
public void setQuery(String query, QueryFilter filter) {
    if (Objects.equals(this.query, query) && Objects.equals(this.filter, filter))
        return;
    this.query = query;
    this.filter = filter;
    queryParameters = ParametersHelper.parseQuery(query, filter);
    for (ParameterInfo info : queryParameters) {
        final ParameterInfo.Type type = info.getType();
        if (ParameterInfo.Type.DATASOURCE.equals(type)) {
            final String path = info.getPath();
            final String[] strings = path.split("\\.");
            String source = strings[0];
            final String property;
            if (strings.length > 1) {
                final List<String> list = Arrays.asList(strings);
                final List<String> valuePath = list.subList(1, list.size());
                property = InstanceUtils.formatValuePath(valuePath.toArray(new String[valuePath.size()]));
            } else {
                property = null;
            }
            final Datasource ds = dsContext.get(source);
            if (ds != null) {
                dsContext.registerDependency(this, ds, property);
            } else {
                ((DsContextImplementation) dsContext).addLazyTask(context -> {
                    final String[] strings1 = path.split("\\.");
                    String source1 = strings1[0];
                    final Datasource ds1 = dsContext.get(source1);
                    if (ds1 != null) {
                        dsContext.registerDependency(AbstractCollectionDatasource.this, ds1, property);
                    }
                });
            }
        }
    }
}
Also used : ParameterInfo(com.haulmont.cuba.core.global.filter.ParameterInfo)

Example 5 with ParameterInfo

use of com.haulmont.cuba.core.global.filter.ParameterInfo in project cuba by cuba-platform.

the class AbstractCollectionDatasource method getTemplateParams.

protected Map<String, Object> getTemplateParams(Map<String, Object> customParams) {
    Map<String, Object> templateParams = new HashMap<>();
    String compPerfix = ParameterInfo.Type.COMPONENT.getPrefix() + "$";
    for (ParameterInfo info : queryParameters) {
        if (info.getType() == ParameterInfo.Type.COMPONENT) {
            Object value = dsContext.getFrameContext() == null ? null : dsContext.getFrameContext().getValue(info.getPath());
            templateParams.put(compPerfix + info.getPath(), value);
        }
    }
    String customPerfix = ParameterInfo.Type.CUSTOM.getPrefix() + "$";
    for (Map.Entry<String, Object> entry : customParams.entrySet()) {
        templateParams.put(customPerfix + entry.getKey(), entry.getValue());
    }
    if (dsContext != null) {
        FrameContext windowContext = dsContext.getFrameContext();
        if (windowContext != null) {
            String paramPerfix = ParameterInfo.Type.PARAM.getPrefix() + "$";
            for (Map.Entry<String, Object> entry : windowContext.getParams().entrySet()) {
                templateParams.put(paramPerfix + entry.getKey(), entry.getValue());
            }
        }
    }
    String sessionPrefix = ParameterInfo.Type.SESSION.getPrefix() + "$";
    templateParams.put(sessionPrefix + "userId", userSession.getCurrentOrSubstitutedUser().getId());
    templateParams.put(sessionPrefix + "userLogin", userSession.getCurrentOrSubstitutedUser().getLoginLowerCase());
    for (String name : userSession.getAttributeNames()) {
        templateParams.put(sessionPrefix + name, userSession.getAttribute(name));
    }
    return templateParams;
}
Also used : FrameContext(com.haulmont.cuba.gui.FrameContext) ParameterInfo(com.haulmont.cuba.core.global.filter.ParameterInfo)

Aggregations

ParameterInfo (com.haulmont.cuba.core.global.filter.ParameterInfo)5 Entity (com.haulmont.cuba.core.entity.Entity)1 FrameContext (com.haulmont.cuba.gui.FrameContext)1 Matcher (java.util.regex.Matcher)1 Pattern (java.util.regex.Pattern)1 Logger (org.slf4j.Logger)1