nl.strohalm.cyclos.utils.hibernate.HibernateCustomFieldHandler.java Source code

Java tutorial

Introduction

Here is the source code for nl.strohalm.cyclos.utils.hibernate.HibernateCustomFieldHandler.java

Source

/*
This file is part of Cyclos (www.cyclos.org).
A project of the Social Trade Organisation (www.socialtrade.org).
    
Cyclos 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.
    
Cyclos 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 Cyclos; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    
 */
package nl.strohalm.cyclos.utils.hibernate;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;

import nl.strohalm.cyclos.dao.FetchDAO;
import nl.strohalm.cyclos.dao.customizations.CustomFieldPossibleValueDAO;
import nl.strohalm.cyclos.entities.customization.fields.CustomField;
import nl.strohalm.cyclos.entities.customization.fields.CustomFieldPossibleValue;
import nl.strohalm.cyclos.entities.customization.fields.CustomFieldValue;
import nl.strohalm.cyclos.utils.StringHelper;
import nl.strohalm.cyclos.utils.access.LoggedUser;
import nl.strohalm.cyclos.utils.conversion.IdConverter;

import org.apache.commons.lang.StringUtils;

/**
 * Helper class used to handle custom fields
 * @author luis
 */
public class HibernateCustomFieldHandler {
    private FetchDAO fetchDao;
    private CustomFieldPossibleValueDAO customFieldPossibleValueDao;

    /**
     * Appends the custom field values on a query. Should be invoked when building the where part of the query
     * @param hql The current HQL buffer
     * @param values The custom field values used to filter
     */
    public void appendConditions(final StringBuilder hql, final Map<String, Object> namedParameters,
            final Collection<? extends CustomFieldValue> values) {
        if (values == null || values.isEmpty()) {
            return;
        }
        for (final CustomFieldValue fieldValue : values) {
            CustomField field = fieldValue.getField();
            if (field == null) {
                continue;
            }
            field = fetchDao.fetch(field);
            String value = fieldValue.getValue();
            // Remove any manually entered '%'
            value = StringUtils.trimToNull(StringUtils.replace(value, "%", ""));
            if (value == null) {
                continue;
            }
            final String alias = alias(field);
            final String fieldParam = "field_" + alias;
            final String valueParam = "value_" + alias;

            hql.append(" and ").append(alias).append(".field = :").append(fieldParam);
            namedParameters.put(fieldParam, field);

            if (LoggedUser.hasUser() && !LoggedUser.isAdministrator()) {
                if (field.getNature() == CustomField.Nature.MEMBER) {
                    // Exclude hidden fields
                    hql.append(" and ").append(alias).append(".hidden <> true");
                }
            }
            // Check the field type
            switch (field.getType()) {
            case STRING:
                if (StringUtils.isNotEmpty(field.getPattern())) {
                    // Remove the mask and consider the value as matching exactly
                    value = StringHelper.removeMask(field.getPattern(), value, false);
                    hql.append(" and ").append(alias).append(".stringValue like :").append(valueParam);
                    namedParameters.put(valueParam, value);
                } else {
                    // Use a like expression
                    hql.append(" and ").append(alias).append(".stringValue like :").append(valueParam);
                    namedParameters.put(valueParam, StringUtils.trimToEmpty(value) + "%");
                }
                break;
            case BOOLEAN:
                if (Boolean.parseBoolean(value)) {
                    hql.append(" and ").append(alias).append(".stringValue = :" + valueParam);
                } else {
                    hql.append(" and ").append(alias).append(".stringValue <> :" + valueParam);
                }
                namedParameters.put(valueParam, "true");
                break;
            case ENUMERATED:
                boolean byName = true;
                if (StringUtils.containsOnly(value, "0123456789,")) {
                    // Try by id
                    try {
                        final Collection<CustomFieldPossibleValue> possibleValues = new ArrayList<CustomFieldPossibleValue>();
                        final String[] possibleValueIds = StringUtils.split(value, ',');
                        for (final String idAsString : possibleValueIds) {
                            final CustomFieldPossibleValue possibleValue = customFieldPossibleValueDao
                                    .load(Long.valueOf(idAsString));
                            if (!possibleValue.getField().equals(field)) {
                                throw new Exception();
                            }
                            possibleValues.add(possibleValue);
                        }
                        byName = false;
                        hql.append(" and ").append(alias).append(".possibleValue in (:").append(valueParam)
                                .append(')');
                        namedParameters.put(valueParam, possibleValues);
                    } catch (final Exception e) {
                        // Possible value not found by id - next try by name
                    }
                }
                if (byName) {
                    hql.append(" and ").append(alias).append(".possibleValue.value = :").append(valueParam);
                    namedParameters.put(valueParam, value);
                }
                break;
            case MEMBER:
                Long memberId = null;
                if (fieldValue.getMemberValue() != null) {
                    memberId = fieldValue.getMemberValue().getId();
                } else {
                    memberId = IdConverter.instance().valueOf(value);
                }
                if (memberId != null) {
                    hql.append(" and ").append(alias).append(".memberValue.id = :").append(valueParam);
                    namedParameters.put(valueParam, memberId);
                }
                break;
            default:
                hql.append(" and ").append(alias).append(".stringValue = :").append(valueParam);
                namedParameters.put(valueParam, value);
                break;
            }
        }
    }

    /**
     * Appends the inner joins for each custom field. Should be invoked when building the from part of the query.
     * @param hql The current HQL buffer
     * @param fieldValuesPath The path on the query for the custom fields value collection
     * @param values The custom field values used to filter
     */
    public void appendJoins(final StringBuilder hql, final String fieldValuesPath,
            final Collection<? extends CustomFieldValue> values) {
        if (values == null || values.isEmpty()) {
            return;
        }
        for (final CustomFieldValue fieldValue : values) {
            CustomField field = fieldValue.getField();
            if (field == null) {
                continue;
            }
            String value = fieldValue.getValue();
            // Remove any manually entered '%'
            value = StringUtils.trimToNull(StringUtils.replace(value, "%", ""));
            if (value == null) {
                continue;
            }
            field = fetchDao.fetch(field);
            hql.append(" inner join ").append(fieldValuesPath).append(' ').append(alias(field));
        }
    }

    public void setCustomFieldPossibleValueDao(final CustomFieldPossibleValueDAO customFieldPossibleValueDao) {
        this.customFieldPossibleValueDao = customFieldPossibleValueDao;
    }

    public void setFetchDao(final FetchDAO fetchDao) {
        this.fetchDao = fetchDao;
    }

    private String alias(final CustomField field) {
        return "fv_" + field.getId();
    }
}