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]
