Loading...

torque-dev@db.apache.org

[Prev] Thread [Next]  |  [Prev] Date [Next]

Re: Criterions which do not reference a column Thomas Vandahl Wed Apr 11 03:00:53 2012

On 06.04.12 12:00, Thomas Vandahl wrote:
> Not necessarily. Generifying Criterion could help to clean up the
> interface quite a bit. I need to look into the code to come up with a
> good example. Stay tuned... :-)

My proposal for the generified Criterion class is attached. Probably it
would be useful to have some better restrictions to the generic types (I
just derived L from Column to see the effects on the code in SqlBuilder)
and/or a common generified container for the left and right sides of the
criterion. AFAICS, the influence on other code is not big.

This would need some more thoughts, but from hat I see, I could be worth
a try.

Bye, Thomas.

package org.apache.torque.criteria;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.torque.Column;

/**
 * Describes one or more where clause parts in the Criteria.
 * Either the parts list is not null and represents this criterion
 * or the column, value, comparison and ignoreStringCase columns
 * are not null and represent this criterion.
 */
public class Criterion<L extends Column, R> implements Serializable
{
    /** Serial version. */
    private static final long serialVersionUID = 7157097965404611710L;

    /** Constant for the operator " AND ". */
    public static final String AND = " AND ";

    /** Constant for the operator " OR ". */
    public static final String OR = " OR ";

    /** Value of the CO. */
    private R value;

    /** Comparison value. */
    private SqlEnum comparison;

    /** Column. */
    private L column;

    /** Flag to ignore case in comparison */
    private boolean ignoreCase = false;

    /**
     * The criterion objects which form a composite criterion.
     * Either this list is not null and represents this criterion
     * or the column, value, comparison and ignoreStringCase columns
     * are not null and represent this criterion.
     */
    private List<Criterion<?, ?>> parts;

    /**
     * The operator (AND, OR...) how the composite criterions
     * are connected.
     */
    private String conjunction;


    /**
     * Create a new instance.
     *
     * @param column the column description, not null.
     * @param val An Object with the value for the Criteria, may be null.
     * @param comp A String with the comparison value, not null.
     *
     * @throws NullPointerException if column is null.
     */
    public Criterion(L column, R val, SqlEnum comp)
    {
        this.value = val;
        setComparison(comp);
        setColumn(column);
    }

    /**
     * Create a new instance, using equals as comparison.
     *
     * @param tableColumn the column description.
     * @param val An Object with the value for the Criteria.
     */
    public Criterion(L column, R val)
    {
        this(column, val, Criteria.EQUAL);
    }

    /**
     * Creates a shallow copy of the given Criterion.
     *
     * @param toCopy the Criterion to copy from, not null.
     */
    public Criterion(Criterion<L, R> toCopy)
    {
        this.column = toCopy.column;
        this.comparison = toCopy.comparison;
        this.value = toCopy.value;
        this.ignoreCase = toCopy.ignoreCase;
        this.parts = toCopy.parts;
        this.conjunction = toCopy.conjunction;
    }

    /**
     * Sets the column.
     *
     * @param column the column, not null.
     *
     * @throws NullPointerException if column is null.
     */
    private void setColumn(L column)
    {
        if (column == null)
        {
            throw new NullPointerException("column must not be null");
        }
        this.column = column;
    }

    /**
     * Get the column.
     *
     * @return the column.
     */
    public L getColumn()
    {
        return this.column;
    }

    /**
     * Sets the comparison.
     *
     * @param comparison the comparison, not null.
     *
     * @throws NullPointerException if comparison is null.
     */
    private void setComparison(SqlEnum comparison)
    {
        if (comparison == null)
        {
            throw new NullPointerException("comparison must not be null");
        }
        this.comparison = comparison;
    }

    /**
     * Get the comparison.
     *
     * @return A String with the comparison.
     */
    public SqlEnum getComparison()
    {
        return this.comparison;
    }

    /**
     * Get the value.
     *
     * @return An Object with the value.
     */
    public R getValue()
    {
        return this.value;
    }

    /**
     * Set the value of the criterion.
     *
     * @param value the new value.
     */
    public void setValue(R value)
    {
        this.value = value;
    }

    /**
     * Sets ignore case.
     *
     * @param b True if case should be ignored.
     * @return A modified Criteria object.
     */
    public Criterion<L, R> setIgnoreCase(boolean b)
    {
        ignoreCase = b;
        return this;
    }

    /**
     * Is ignore case on or off?
     *
     * @return True if case is ignored.
     */
    public boolean isIgnoreCase()
    {
        return ignoreCase;
    }

    /**
     * Returns the parts of which this criterion consists.
     *
     * @return an unmodifiable list of the clauses,
     *         or null if this criterion is not a composite criterion.
     */
    public List<Criterion<?, ?>> getParts()
    {
        if (parts == null)
        {
            return null;
        }
        return Collections.unmodifiableList(parts);
    }

    /**
     * Returns the conjunction for the parts of this criterion
     *
     * @return the conjunction, or null if this criterion is not a
     *         composite criterion.
     */
    public String getConjunction()
    {
        return conjunction;
    }

    /**
     * Returns whether this criterion is a composite criterion.
     *
     * @return true if this criterion is a composite criterion,
     *         false if it represents a single condition.
     */
    public boolean isComposite()
    {
        return parts != null;
    }

    /**
     * Replaces this criterion's condition with
     * (this criterion's condition AND criterion).
     *
     * @param criterion the criterion to and with this criterion,
     *        not null.
     */
    public Criterion<L, R> and(Criterion<?, ?> criterion)
    {
        addCompositeCriterion(criterion, AND);
        return this;
    }

    /**
     * Replaces this criterion's condition with
     * (this criterion's condition OR criterion).
     *
     * @param criterion the criterion to and with this criterion,
     *        not null.
     */
    public Criterion<L, R> or(Criterion<?, ?> criterion)
    {
        addCompositeCriterion(criterion, OR);
        return this;
    }

    /**
     * Add a composite criterion to this criterion.
     *
     * @param criterion the criterion to add, not null.
     * @param conjunction the conjunction by which to add the criterion,
     *        not null.
     *
     * @throws NullPointerException if criterion is null.
     */
    private void addCompositeCriterion(
            Criterion<?, ?> criterion,
            String conjunction)
    {
        if (criterion == null)
        {
            throw new NullPointerException("criterion must not be null");
        }
        if (isComposite() && this.conjunction.equals(conjunction))
        {
            parts.add(criterion);
        }
        else
        {
            Criterion<L, R> copy = new Criterion<L, R>(this);
            parts = new ArrayList<Criterion<?, ?>>();
            parts.add(copy);
            parts.add(criterion);
            this.conjunction = conjunction;
            this.column = null;
            this.comparison = null;
            this.value = null;
            this.ignoreCase = false;
        }
    }

    /**
     * Appends a debug String representation of the Criterion
     * onto the String builder.
     */
    public void appendTo(StringBuilder sb)
    {
        if (isComposite())
        {
            boolean first = true;
            for (Criterion<?, ?> part : parts)
            {
                if (!first)
                {
                    sb.append(conjunction);
                }
                if (part.isComposite())
                {
                    sb.append('(');
                }
                part.appendTo(sb);
                if (part.isComposite())
                {
                      sb.append(')');
                }
                first = false;
            }
        }
        else
        {
            if (Criteria.CUSTOM == comparison)
            {
                if (value != null && !"".equals(value))
                {
                    sb.append((String) value);
                }
            }
            else
            {
                String field = column.getSqlExpression();
                sb.append(field).append(comparison).append(value);
            }
        }
    }

    /**
     * Build a string representation of the Criterion for debug purposes.
     *
     * @return A String with the representation of the Criterion.
     */
    public String toString()
    {
        StringBuilder builder = new StringBuilder();
        appendTo(builder);
        return builder.toString();
    }

    /**
     * This method checks another Criteria.Criterion to see if they contain
     * the same attributes.
     */
    public boolean equals(Object obj)
    {
        if (this == obj)
        {
            return true;
        }
        if ((obj == null) || !(obj instanceof Criterion))
        {
            return false;
        }
        if (obj.getClass() != this.getClass())
        {
            return false;
        }

        Criterion criterion = (Criterion) obj;
        EqualsBuilder equalsBuilder = new EqualsBuilder();
        equalsBuilder.append(criterion.column, this.column);
        equalsBuilder.append(criterion.comparison, this.comparison);
        equalsBuilder.append(criterion.value, this.value);
        equalsBuilder.append(criterion.ignoreCase, this.ignoreCase);
        equalsBuilder.append(criterion.parts, this.parts);
        equalsBuilder.append(criterion.conjunction, this.conjunction);
        return equalsBuilder.isEquals();
    }

    /**
     * Returns a hash code value for the object.
     */
    public int hashCode()
    {
        HashCodeBuilder hashCodeBuilder = new HashCodeBuilder();
        hashCodeBuilder.append(this.column);
        hashCodeBuilder.append(this.comparison);
        hashCodeBuilder.append(this.value);
        hashCodeBuilder.append(this.ignoreCase);
        hashCodeBuilder.append(this.parts);
        hashCodeBuilder.append(this.conjunction);
        return hashCodeBuilder.toHashCode();
    }
}


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]