com.webbfontaine.valuewebb.search.custom.UserCriterion.java Source code

Java tutorial

Introduction

Here is the source code for com.webbfontaine.valuewebb.search.custom.UserCriterion.java

Source

package com.webbfontaine.valuewebb.search.custom;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.SimpleExpression;
import org.jboss.seam.log.Log;
import org.jboss.seam.log.Logging;

import javax.faces.model.SelectItem;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;

import static com.webbfontaine.valuewebb.search.custom.StringConditions.*;
import static com.webbfontaine.valuewebb.search.custom.UserCriterionType.*;

/**
 * Copyrights 2002-2011 Webb Fontaine
 * This software is the proprietary information of Webb Fontaine.
 * Its use is subject to License terms.
 * User: nigiyan
 * Date: 6/23/11
 */

// todo: need to implement pattern/converter assignment depends on type
// todo: think about impl for auto init type by key name as well as ref name and values - key is dot-delimited field name, e.g. TtGen.idfNum, or Pd.TtGen.idfNum

/**
 * Represents single criterion for user selection
 */
public class UserCriterion {
    private String fullKey;
    private String name;
    private String condition;
    private UserCriterionType type;
    private Object value;
    private List<String> possibleConditions = new ArrayList<String>();
    private List<SelectItem> possibleValues;
    private Integer diff;

    private static final Log LOGGER = Logging.getLog(UserCriterion.class);

    /**
     * @param fullKey entity field's full name to be identified in by search provider's Criteria class, e.g. pd.ttGen.ctyOrig, unitF
     */
    public void setFullKey(String fullKey) {
        this.fullKey = fullKey;
    }

    public String getFullKey() {
        return fullKey;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCondition() {
        return condition;
    }

    public void setCondition(String condition) {
        this.condition = condition;
    }

    public UserCriterionType getType() {
        return type;
    }

    public void setType(UserCriterionType type) {
        this.type = type;

        initPossibleConditions();
    }

    public Object getValue() {
        return value;
    }

    public void setValue(Object value) {
        this.value = value;
    }

    public List<SelectItem> getPossibleValues() {
        return possibleValues;
    }

    public void setPossibleValues(List<SelectItem> possibleValues) {
        this.possibleValues = possibleValues;
    }

    public Integer getDiff() {
        return diff;
    }

    public void setDiff(Integer diff) {
        this.diff = diff;
    }

    private void initPossibleConditions() {
        setBasicConditions();

        switch (type) {
        case REF:
            //already added in setBasicConditions()
            break;
        case STRING:
            possibleConditions.addAll(Arrays.asList(CONTAINS, NOT_CONTAIN, STARTS_WITH, ENDS_WITH));
            break;
        case DATE:
            possibleConditions.addAll(Arrays.asList(GT, GE, LT, LE));
            break;
        case BIG_DECIMAL:
            possibleConditions.addAll(Arrays.asList(GT, GE, LT, LE, IN_A_RANGE));
            break;
        case LONG:
            possibleConditions.addAll(Arrays.asList(GT, GE, LT, LE));
            break;
        case BOOLEAN:
            possibleConditions.clear();
            possibleConditions.addAll(Arrays.asList(EQ));
            break;
        default:
            LOGGER.error("Development forgot to add case for: {}", type);
        }
        if (possibleConditions.isEmpty()) {
            throw new RuntimeException("Possible conditions not initialized");
        } else {
            condition = possibleConditions.get(0);
        }
    }

    private void setBasicConditions() {
        possibleConditions.clear();
        possibleConditions.addAll(Arrays.asList(EQ, NE));
    }

    public boolean isTypeString() {
        return type == STRING;
    }

    public boolean isTypeDate() {
        return type == DATE;
    }

    public boolean isTypeRef() {
        return type == REF;
    }

    public boolean isTypeBigDecimal() {
        return type == BIG_DECIMAL;
    }

    public boolean isTypeLong() {
        return type == LONG;
    }

    public boolean isTypeBoolean() {
        return type == BOOLEAN;
    }

    public List<SelectItem> getUserConditions() {
        List<SelectItem> items = new ArrayList<SelectItem>();

        for (String s : possibleConditions) {
            items.add(new SelectItem(s));
        }
        return items;
    }

    /**
     * @return real search criterion
     * @throws Exception thrown during transforming UserCriterion into real search criterion, exception message might be shown to user
     */
    public Criterion transform() throws Exception {
        Criterion criterion = getCriterion();

        makeCaseInsensitive(criterion);

        return criterion;
    }

    public Criterion getCriterion() throws Exception {
        if (condition.equals(EQ)) {
            if (value == null || value.toString().trim().length() == 0) {
                return Restrictions.isNull(fullKey);
            } else {
                return Restrictions.eq(fullKey, value);
            }
        }

        if (condition.equals(NE)) {
            if (value == null || value.toString().trim().length() == 0) {
                return Restrictions.isNotNull(fullKey);
            } else {
                return Restrictions.ne(fullKey, value);
            }
        }

        if (condition.equals(GT)) {
            assertNonNullity(value);
            return Restrictions.gt(fullKey, value);
        }

        if (condition.equals(GE)) {
            assertNonNullity(value);
            return Restrictions.ge(fullKey, value);
        }

        if (condition.equals(LT)) {
            assertNonNullity(value);
            return Restrictions.lt(fullKey, value);
        }

        if (condition.equals(LE)) {
            assertNonNullity(value);
            return Restrictions.le(fullKey, value);
        }

        if (condition.equals(IN_A_RANGE)) {
            assertNonNullity(value);
            assertNonNullity(diff);
            return getPercentRange();
        }

        if (condition.equals(ENDS_WITH)) {
            return Restrictions.like(fullKey, "%" + StringUtils.trim(value.toString()));
        }

        if (condition.equals(STARTS_WITH)) {
            return Restrictions.like(fullKey, StringUtils.trim(value.toString()) + "%");
        }

        if (condition.equals(CONTAINS)) {
            return Restrictions.like(fullKey, "%" + StringUtils.trim(value.toString()) + '%');
        }

        if (condition.equals(NOT_CONTAIN)) {
            return Restrictions.not(Restrictions.like(fullKey, "%" + StringUtils.trim(value.toString()) + '%'));
        }

        LOGGER.error(
                "Undefined User Criteria [key:{0}, value:{1}, condition:{3}] couldn't be transformed to search criterion",
                fullKey, value, condition);

        throw new RuntimeException("Undefined User Criteria: " + name);
    }

    private void makeCaseInsensitive(Criterion criterion) {
        SimpleExpression simpleExpression;
        if (type == STRING && criterion instanceof SimpleExpression) {
            simpleExpression = (SimpleExpression) criterion;
            if (StringUtils.trimToNull((String) value) != null) {
                simpleExpression.ignoreCase();
            }
        }
    }

    private void assertNonNullity(Object value) throws Exception {
        if (value == null) {
            throw new Exception("Invalid search attrubutes in " + name);
        }
    }

    private Criterion getPercentRange() {
        BigDecimal bdValue = new BigDecimal(value.toString());

        BigDecimal range = bdValue.multiply(new BigDecimal(diff).divide(new BigDecimal(100)));

        BigDecimal bdValueFrom = bdValue.subtract(range);
        BigDecimal bdValueTo = bdValue.add(range);
        return Restrictions.and(Restrictions.ge(fullKey, bdValueFrom), Restrictions.le(fullKey, bdValueTo));
    }

    public static final UserCriteriaComparator USER_CRITERIA_COMPARATOR = new UserCriteriaComparator();

    private static class UserCriteriaComparator implements Comparator<SelectItem> {
        @Override
        public int compare(SelectItem o1, SelectItem o2) {
            return o1.getLabel().compareTo(o2.getLabel());
        }
    }

}