net.smartlab.web.DataAccessObject Maven / Gradle / Ivy
/*
* The SmartWeb Framework
* Copyright (C) 2004-2006
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* For further informations on the SmartWeb Framework please visit
*
* http://smartweb.sourceforge.net
*/
package net.smartlab.web;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Locale;
import java.util.StringTokenizer;
import net.smartlab.web.bean.ConversionException;
import net.smartlab.web.bean.ConverterManager;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
/**
* This interface should be implemented by classes which provide some form of
* persistence.
*
* @author rlogiacco,gperrone
* @uml.dependency supplier="net.smartlab.web.DAOException"
*/
public interface DataAccessObject {
/**
* Retrieves from the persistence tier the object which primary key equals
* the one specified.
*
* @param key the primary key used to search the instance into the
* persistence tier.
* @return an object representing the datas stored in the persistence tier
* associated with the specified key.
* @throws DAOException if an error occur while accessing the persistence
* tier.
* @throws UndefinedKeyException if the specified primary key is not present
* on the persistence tier.
*/
public Object findByKey(Serializable key) throws DAOException;
/**
* Permanently deletes an instance from the persistence tier.
*
* @param object the instance representing the informations to be deleted
* from the store.
* @throws DAOException if an error occur while accessing the persistence
* tier.
*/
public void remove(Object object) throws DAOException;
/**
* Ensures the persistence tier representation of the object is consistent
* with the in memory representation. If the object doesn't exist yet into
* the persistence tier it must be added and a new primary key assigned to
* the object.
*
* @param object the object to be persisted.
* @throws DAOException if an error occur while accessing the persistence
* tier
*/
public void update(Object object) throws DAOException;
/**
* Returns a collection of objects representing all the persistence tier
* informations matching the specified search criterias.
*
* @param info the criterias to be used to search the persistence tier.
* @return a collection of matching entities.
* @throws DAOException if an error occur while accessing the persistence
* tier
*/
public Collection list(SearchInfo info) throws DAOException;
/**
* Instances of this class represents a set of criterias to be used in
* persistence tier searches. This class is providen as a support class used
* to define search criterias using request parameters and should not be
* used in place of Hibernate's Criteria
or Query
* as it doesn't provide the same customizability or features.
*
* @author rlogiacco
*/
public static class SearchInfo implements Serializable {
private static final long serialVersionUID = 1038393869915276007L;
private static final Log logger = LogFactory.getLog(SearchInfo.class);
/**
* Entity properties to be filtered.
*
* @uml.property name="filters"
*/
private Collection filters = new ArrayList();
/**
* Property to be used for ordering.
*
* @uml.property name="order"
*/
private String order = null;
/**
* The ordering direction.
*
* @uml.property name="descendant"
*/
private boolean descendant = false;
/**
* The filtering style.
*
* @uml.property name="union"
*/
private boolean union = false;
/**
* The locale used to convert filters.
*/
private Locale locale = Locale.getDefault();
/**
* Identifies a greater
expression condition.
*/
public final static int EQUALS = 1;
/**
* Identifies an equals
expression condition.
*/
public final static int GREATER = 2;
/**
* Identifies a greater
expression condition.
*/
public final static int GREATER_EQUALS = 3;
/**
* Identifies a greater equals
expression condition.
*/
public final static int LESSER = 4;
/**
* Identifies a lesser
expression condition.
*/
public final static int LESSER_EQUALS = 5;
/**
* Identifies a lesser equal
expression condition.
*/
public final static int NOT_EQUALS = -1;
/**
* Identifies a like
expression condition.
*/
public final static int LIKE = 6;
/**
* Identifies an ilike
expression condition.
*/
public final static int ILIKE = 7;
/**
* Identifies a between
expression condition.
*/
public final static int BETWEEN = 8;
/**
* Identifies an is null
expression condition.
*/
public final static int NULL = 9;
/**
* Identifies an is not null
expression condition.
*/
public final static int NOT_NULL = -9;
/**
* Identifies an in
expression condition.
*/
public final static int IN = 11;
/**
* Identifies a not in
expression condition.
*/
public final static int NOT_IN = -11;
/**
* @return returns the ordering direction.
* @uml.property name="descendant"
*/
public boolean isDescendant() {
return descendant;
}
/**
* @return returns the filters.
* @uml.property name="filters"
*/
public Collection getFilters() {
return filters;
}
/**
* @param filters the filters to set.
* @uml.property name="filters"
*/
public void setFilters(Collection filters) {
this.filters = filters;
}
/**
* @param filters the filters to set.
*/
public void setFilters(String[] filters) {
if (filters != null) {
for (int i = 0; i < filters.length; i++) {
this.addFilter(filters[i]);
}
}
}
/**
* Adds a filter.
*
* @param filter the filter to add.
*/
public void addFilter(String filter) {
try {
for (int i = 0; i < filter.length(); i++) {
switch (filter.charAt(i)) {
// Not equals / Not in
case '!':
if (filter.charAt(i + 1) == '|') {
filters.add(new Filter(filter.substring(0, i), NOT_IN, filter.substring(i + 2)));
} else {
filters.add(new Filter(filter.substring(0, i), NOT_EQUALS, filter.substring(i + 1)));
}
return;
// Equal
case '=':
filters.add(new Filter(filter.substring(0, i), EQUALS, filter.substring(i + 1)));
return;
// Greater
case '>':
// Greater equal
if (filter.charAt(i + 1) == '=') {
filters
.add(new Filter(filter.substring(0, i), GREATER_EQUALS, filter.substring(i + 2)));
} else {
filters.add(new Filter(filter.substring(0, i), GREATER, filter.substring(i + 1)));
}
return;
// Lesser
case '<':
// Lesser equal
if (filter.charAt(i + 1) == '=') {
filters.add(new Filter(filter.substring(0, i), LESSER_EQUALS, filter.substring(i + 2)));
} else {
filters.add(new Filter(filter.substring(0, i), LESSER, filter.substring(i + 1)));
}
return;
// Between / In
case '|':
if (filter.charAt(i + 1) == '|') {
filters.add(new Filter(filter.substring(0, i), IN, filter.substring(i + 2)));
} else {
filters.add(new Filter(filter.substring(0, i), BETWEEN, filter.substring(i + 1)));
}
return;
// Like / ILike
case '%':
if (filter.charAt(i + 1) == '%') {
// ILike
filters.add(new Filter(filter.substring(0, i), ILIKE, filter.substring(i + 2)));
return;
} else {
// Like
filters.add(new Filter(filter.substring(0, i), LIKE, filter.substring(i + 1)));
return;
}
case '\\':
i++;
continue;
}
}
} catch (SkipFilterException sfe) {
logger.debug("skipping filter `" + filter + "`");
}
}
/**
* Adds a filter.
*
* @param property the property to filter on.
* @param condition the expression condition to apply on the property.
* @param values a comma separated list of values to evaluate against
* the condition.
*/
public void addFilter(String property, int condition, String values) {
try {
filters.add(new Filter(property, condition, values));
} catch (SkipFilterException sfe) {
logger.debug("skipping filter on `" + property + "` with condition " + condition + " and values `"
+ values + "`");
}
}
/**
* Adds a filter.
*
* @param property the property to filter on.
* @param condition the expression condition to apply on the property.
* @param value a value to evaluate against the condition.
* @throws ConversionException
*/
public void addFilter(String property, int condition, Object value) throws ConversionException {
try {
filters.add(new Filter(property, condition, (String)ConverterManager.getDefault().convert(String.class, value, locale)));
} catch (SkipFilterException sfe) {
logger.debug("skipping filter on `" + property + "` with condition " + condition + " and value `"
+ value + "`");
}
}
/**
* Adds a filter.
*
* @param property the property to filter on.
* @param condition the expression condition to apply on the property.
* @param values an array of values to evaluate against the condition.
*/
public void addFilter(String property, int condition, String[] values) {
try {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < values.length; i++) {
buffer.append(values[i]);
buffer.append(',');
}
filters.add(new Filter(property, condition, buffer.toString()));
} catch (SkipFilterException sfe) {
logger.debug("skipping filter on `" + property + "` with condition " + condition + " and values `"
+ values + "`");
}
}
/**
* Adds a filter.
*
* @param property the property to filter on.
* @param condition the expression condition to apply on the property.
* @param values an array of values to evaluate against the condition.
* @throws ConversionException
*/
public void addFilter(String property, int condition, Object[] values) throws ConversionException {
try {
StringBuffer buffer = new StringBuffer();
for (int i = 0; i < values.length; i++) {
buffer.append(ConverterManager.getDefault().convert(String.class, values[i], locale));
buffer.append(',');
}
filters.add(new Filter(property, condition, buffer.toString()));
} catch (SkipFilterException sfe) {
logger.debug("skipping filter on `" + property + "` with condition " + condition + " and values `"
+ values + "`");
}
}
/**
* @return returns the order.
* @uml.property name="order"
*/
public String getOrder() {
return order;
}
/**
* Sets the property used to order the collection. By default the
* ordering is set to descendant
unless an !
* (exclamation mark)
is prefixed indicating an
* ascendant
order must be used.
*
* @param order the property used to order the collection, optionally
* prefixed by ! (exclamation mark)
to
* invert the sorting direction.
* @uml.property name="order"
*/
public void setOrder(String order) {
if (order != null && order.length() > 0) {
if (order.charAt(0) == '!') {
this.order = order.substring(1);
this.descendant = true;
} else {
this.order = order;
this.descendant = false;
}
} else {
this.order = null;
}
}
/**
* TODO documentation
*
* @param style
*/
public void setUnion(String style) {
if (style != null && style.length() > 0) {
if (style.equalsIgnoreCase("OR") || style.equalsIgnoreCase("true") || style.equalsIgnoreCase("yes") || style.equalsIgnoreCase("y")) {
this.union = true;
} else {
this.union = false;
}
}
}
/**
* TODO documentation
*
* @return
* @since 1.2.12
* @uml.property name="union"
*/
public void setUnion(boolean union) {
this.union = union;
}
/**
* TODO documentation
*
* @return
* @uml.property name="union"
*/
public boolean isUnion() {
return union;
}
/**
* Sets the locale used to convert filters.
*
* @param locale the locale to set.
*/
public void setLocale(Locale locale) {
this.locale = locale;
}
/**
* Returns the locale used to convert filters.
*
* @return the locale used to convert filters.
*/
public Locale getLocale() {
return locale;
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return new ToStringBuilder(this).append(this.filters).append(this.order).append(this.descendant).append(
this.union).append(this.locale).toString();
}
/**
* Represents a filtering condition to be applied while performing
* searches.
*
* @author rlogiacco
*/
protected class Filter {
/**
* The column.
*
* @uml.property name="column"
*/
private String property;
/**
* The condition.
*
* @uml.property name="condition"
*/
private int condition;
/**
* The values array.
*
* @uml.property name="values"
*/
private String[] values;
/**
* Creates a filter with a column, a condition and a comma separated
* list of values to check against.
*
* @param property the property to filter on.
* @param condition the condition to apply.
* @param values a comma separated list of values to check against.
* @throws SkipFilterException if the filter must be skipped invalid
*/
private Filter(String property, int condition, String values) throws SkipFilterException {
if (values == null) {
throw new SkipFilterException();
}
this.property = property;
this.condition = condition;
StringTokenizer tokenizer = new StringTokenizer(values, ",", false);
this.values = new String[tokenizer.countTokens()];
for (int i = 0; tokenizer.hasMoreTokens(); i++) {
this.values[i] = tokenizer.nextToken();
if (this.values[i].indexOf('\\') > -1) {
StringBuffer buffer = new StringBuffer();
for (int j = 0; j < this.values[i].length(); j++) {
char c = this.values[i].charAt(j);
switch (c) {
case '\\':
if (this.values[i].length() > j + 1 && this.values[i].charAt(j + 1) == '\\') {
buffer.append(c);
j++;
}
break;
default:
buffer.append(c);
}
}
this.values[i] = buffer.toString();
}
}
if (this.values.length == 1 && this.values[0].equals("NULL")
&& (condition == EQUALS || condition == NOT_EQUALS)) {
if (condition == EQUALS) {
this.condition = NULL;
} else if (condition == NOT_EQUALS) {
this.condition = NOT_NULL;
}
this.values = null;
} else if (this.values.length == 0) {
throw new SkipFilterException();
}
logger.trace("adding filter on `" + property + "` with condition " + condition + " and values `" + values
+ "`");
}
/**
* @deprecated this was a misleading name.
* @see getProperty()
*/
protected String getColumn() {
return property;
}
/**
* Returns the property.
*
* @return the property.
* @uml.property name="property"
* @since 1.2.12
*/
protected String getProperty() {
return property;
}
/**
* Returns the condition.
*
* @return the condition.
* @uml.property name="condition"
*/
protected int getCondition() {
return condition;
}
/**
* Returns the values.
*
* @return the values array.
* @uml.property name="values"
*/
protected String[] getValues() {
return values;
}
/**
* Returns the n-th value in the list where the specified index is 0
* based.
*
* @param index the 0 based index of the value to retrieve.
* @return the n-th value in the values list.
*/
protected String getValue(int index) {
return values[index];
}
/**
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object object) {
if (!(object instanceof Filter)) {
return false;
}
Filter filter = (Filter)object;
return new EqualsBuilder().append(this.property, filter.property).append(this.condition, filter.condition)
.append(this.values, filter.values).isEquals();
}
/**
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
return new HashCodeBuilder(-27848275, 353473951).append(this.property).append(this.condition).append(
this.values).toHashCode();
}
/**
* @see java.lang.Object#toString()
*/
public String toString() {
return new ToStringBuilder(this).append(this.property).append(this.condition).append(this.values)
.toString();
}
}
private static class SkipFilterException extends Exception {
private static final long serialVersionUID = 5576925342229697415L;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy