/*
* Copyright (c) 2005-2016 Vincent Vandenschrick. All rights reserved.
*
* This file is part of the Jspresso framework.
*
* Jspresso 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 3 of the License, or
* (at your option) any later version.
*
* Jspresso 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 Jspresso. If not, see <http://www.gnu.org/licenses/>.
*/
package org.jspresso.framework.model.component.query;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.Format;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import org.jspresso.framework.model.component.IComponentFactory;
import org.jspresso.framework.model.descriptor.EDateType;
import org.jspresso.framework.model.descriptor.IComponentDescriptor;
import org.jspresso.framework.model.descriptor.IDatePropertyDescriptor;
import org.jspresso.framework.model.descriptor.IDecimalPropertyDescriptor;
import org.jspresso.framework.model.descriptor.IIntegerPropertyDescriptor;
import org.jspresso.framework.model.descriptor.IPercentPropertyDescriptor;
import org.jspresso.framework.model.descriptor.IPropertyDescriptor;
import org.jspresso.framework.model.descriptor.ITimePropertyDescriptor;
import org.jspresso.framework.model.descriptor.query.ComparableQueryStructureDescriptor;
import org.jspresso.framework.util.i18n.ITranslationProvider;
/**
* A simple query structure which holds a comparator, and inf value and a sup
* value.
*
* @author Vincent Vandenschrick
*/
public class ComparableQueryStructure extends QueryComponent {
private static final long serialVersionUID = 7831817429580706837L;
private final IPropertyDescriptor sourceDescriptor;
private ITranslationProvider translationProvider;
private Locale locale;
/**
* Constructs a new {@code ComparableQueryStructure} instance.
*
* @param componentDescriptor
* the query componentDescriptor
* @param componentFactory
* the component factory
* @param propertyDescriptor
* the property descriptor
*/
public ComparableQueryStructure(IComponentDescriptor<?> componentDescriptor, IComponentFactory componentFactory,
IPropertyDescriptor propertyDescriptor) {
super(componentDescriptor, componentFactory);
this.sourceDescriptor = propertyDescriptor;
setComparator(ComparableQueryStructureDescriptor.EQ);
PropertyChangeListener toStringListener = new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
firePropertyChange(ComparableQueryStructureDescriptor.TO_STRING, null, getToString());
}
};
addPropertyChangeListener(ComparableQueryStructureDescriptor.COMPARATOR, toStringListener);
addPropertyChangeListener(ComparableQueryStructureDescriptor.INF_VALUE, toStringListener);
addPropertyChangeListener(ComparableQueryStructureDescriptor.SUP_VALUE, toStringListener);
}
/**
* Gets the comparator.
*
* @return the comparator.
*/
public String getComparator() {
return (String) get(ComparableQueryStructureDescriptor.COMPARATOR);
}
/**
* Sets the comparator.
*
* @param comparator
* the comparator to set.
*/
public void setComparator(String comparator) {
boolean oldInfValueUsed = isInfValueUsed();
boolean oldSupValueUsed = isSupValueUsed();
put(ComparableQueryStructureDescriptor.COMPARATOR, comparator);
if (!isSupValueUsed()) {
setSupValue(null);
}
if (!isInfValueUsed()) {
setInfValue(null);
}
firePropertyChange(ComparableQueryStructureDescriptor.INF_VALUE_USED, oldInfValueUsed, isInfValueUsed());
firePropertyChange(ComparableQueryStructureDescriptor.SUP_VALUE_USED, oldSupValueUsed, isSupValueUsed());
}
/**
* Gets the infValue.
*
* @return the infValue.
*/
public Object getInfValue() {
return get(ComparableQueryStructureDescriptor.INF_VALUE);
}
/**
* Sets the infValue.
*
* @param infValue
* the infValue to set.
*/
public void setInfValue(Object infValue) {
put(ComparableQueryStructureDescriptor.INF_VALUE, infValue);
}
/**
* Gets the supValue.
*
* @return the supValue.
*/
public Object getSupValue() {
return get(ComparableQueryStructureDescriptor.SUP_VALUE);
}
/**
* Sets the supValue.
*
* @param supValue
* the supValue to set.
*/
public void setSupValue(Object supValue) {
put(ComparableQueryStructureDescriptor.SUP_VALUE, supValue);
}
/**
* Whether the comparable query structure actually holds a restriction.
*
* @return {@code true} if the comparable query structure actually holds a restriction.
*/
@Override
public boolean isRestricting() {
return getComparator() != null && (getInfValue() != null || getSupValue() != null)
|| ComparableQueryStructureDescriptor.NU.equals(getComparator()) || ComparableQueryStructureDescriptor.NN
.equals(getComparator());
}
/**
* Whether the value passed as parameter matches the query structure.
*
* @param value
* the value to test.
* @return {@code true} if the value passed as parameter matches the query structure.
*/
public boolean matches(Comparable<Object> value) {
if (isRestricting()) {
if (value == null) {
return false;
}
String comparator = getComparator();
Object infValue = getInfValue();
Object supValue = getSupValue();
Object compareValue = infValue;
if (compareValue == null) {
compareValue = supValue;
}
switch (comparator) {
case ComparableQueryStructureDescriptor.EQ:
return value.compareTo(compareValue) == 0;
case ComparableQueryStructureDescriptor.GT:
return value.compareTo(compareValue) > 0;
case ComparableQueryStructureDescriptor.GE:
return value.compareTo(compareValue) >= 0;
case ComparableQueryStructureDescriptor.LT:
return value.compareTo(compareValue) < 0;
case ComparableQueryStructureDescriptor.LE:
return value.compareTo(compareValue) <= 0;
case ComparableQueryStructureDescriptor.NU:
return compareValue == null;
case ComparableQueryStructureDescriptor.NN:
return compareValue != null;
case ComparableQueryStructureDescriptor.BE:
if (infValue != null && supValue != null) {
return value.compareTo(infValue) >= 0 && value.compareTo(supValue) <= 0;
} else if (infValue != null) {
return value.compareTo(infValue) >= 0;
} else {
return value.compareTo(supValue) <= 0;
}
default:
break;
}
}
return true;
}
/**
* Computes the toString().
*
* @return the toString().
*/
public String getToString() {
if (isRestricting()) {
String comparator = getComparator();
switch (comparator) {
case ComparableQueryStructureDescriptor.NU:
return "#";
case ComparableQueryStructureDescriptor.NN:
return "!#";
default:
Format format = getFormat();
StringBuilder buf = new StringBuilder();
Object infValue = getInfValue();
Object supValue = getSupValue();
Object compareValue = infValue;
if (compareValue == null) {
compareValue = supValue;
}
String formattedCompareValue = formatValue(compareValue, format);
switch (comparator) {
case ComparableQueryStructureDescriptor.EQ:
buf.append("= ").append(formattedCompareValue);
break;
case ComparableQueryStructureDescriptor.GT:
buf.append("> ").append(formattedCompareValue);
break;
case ComparableQueryStructureDescriptor.GE:
buf.append(">= ").append(formattedCompareValue);
break;
case ComparableQueryStructureDescriptor.LT:
buf.append("< ").append(formattedCompareValue);
break;
case ComparableQueryStructureDescriptor.LE:
buf.append("<= ").append(formattedCompareValue);
break;
case ComparableQueryStructureDescriptor.BE:
if (infValue != null && supValue != null) {
buf.append(">= ").append(formatValue(infValue, format)).append(", <= ").append(
formatValue(supValue, format));
} else if (infValue != null) {
buf.append(">= ").append(formatValue(infValue, format));
} else if (supValue != null) {
buf.append("<= ").append(formatValue(supValue, format));
}
break;
default:
break;
}
return buf.toString();
}
}
return "";
}
private String formatValue(Object value, Format format) {
String formattedCompareValue;
try {
formattedCompareValue = format != null ? format.format(value) : value.toString();
} catch (IllegalArgumentException e) {
formattedCompareValue = value.toString();
}
return formattedCompareValue;
}
/**
* Gets format dependening on property descriptor type.
*
* @return The format.
*/
public Format getFormat() {
Format format = null;
IPropertyDescriptor sd = getSourceDescriptor();
if (sd instanceof IDatePropertyDescriptor) {
if (((IDatePropertyDescriptor) sd).getType() == EDateType.DATE_TIME) {
if (((IDatePropertyDescriptor) sd).isMillisecondsAware()) {
format = new SimpleDateFormat(
getTranslationProvider().getDatePattern(getLocale()) + " " + getTranslationProvider()
.getLongTimePattern(getLocale()));
} else if (((IDatePropertyDescriptor) sd).isSecondsAware()) {
format = new SimpleDateFormat(
getTranslationProvider().getDatePattern(getLocale()) + " " + getTranslationProvider()
.getTimePattern(getLocale()));
} else {
format = new SimpleDateFormat(
getTranslationProvider().getDatePattern(getLocale()) + " " + getTranslationProvider()
.getShortTimePattern(getLocale()));
}
} else {
format = new SimpleDateFormat(getTranslationProvider().getDatePattern(getLocale()));
}
} else if (sd instanceof ITimePropertyDescriptor) {
if (((ITimePropertyDescriptor) sd).isSecondsAware()) {
format = new SimpleDateFormat(getTranslationProvider().getTimePattern(getLocale()));
} else {
format = new SimpleDateFormat(getTranslationProvider().getShortTimePattern(getLocale()));
}
} else if (sd instanceof IIntegerPropertyDescriptor) {
format = NumberFormat.getIntegerInstance(locale);
} else if (sd instanceof IDecimalPropertyDescriptor) {
if (sd instanceof IPercentPropertyDescriptor) {
format = NumberFormat.getPercentInstance(locale);
} else {
format = NumberFormat.getNumberInstance(locale);
}
((NumberFormat) format).setMaximumFractionDigits(((IDecimalPropertyDescriptor) sd).getMaxFractionDigit());
((NumberFormat) format).setMinimumFractionDigits(((IDecimalPropertyDescriptor) sd).getMaxFractionDigit());
}
return format;
}
/**
* Gets the translationProvider.
*
* @return the translationProvider.
*/
protected ITranslationProvider getTranslationProvider() {
return translationProvider;
}
/**
* Sets the translationProvider.
*
* @param translationProvider
* the translationProvider to set.
*/
public void setTranslationProvider(ITranslationProvider translationProvider) {
this.translationProvider = translationProvider;
}
/**
* Gets the locale.
*
* @return the locale.
*/
protected Locale getLocale() {
return locale;
}
/**
* Sets the locale.
*
* @param locale
* the locale to set.
*/
public void setLocale(Locale locale) {
this.locale = locale;
}
/**
* Gets the sourceDescriptor.
*
* @return the sourceDescriptor.
*/
public IPropertyDescriptor getSourceDescriptor() {
return sourceDescriptor;
}
/**
* Is sup value used boolean.
*
* @return the boolean
*/
public boolean isSupValueUsed() {
return ComparableQueryStructureDescriptor.BE.equals(getComparator());
}
/**
* Is inf value used boolean.
*
* @return the boolean
*/
public boolean isInfValueUsed() {
return getComparator() != null;
}
}