package au.com.vaadinutils.jasper.filter;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import org.joda.time.DateTime;
import com.vaadin.server.ErrorMessage;
import com.vaadin.ui.Accordion;
import com.vaadin.ui.TabSheet.Tab;
import com.vaadin.ui.VerticalLayout;
import au.com.vaadinutils.jasper.parameter.ReportParameter;
import au.com.vaadinutils.jasper.parameter.ReportParameterDateTimeRange;
import au.com.vaadinutils.jasper.parameter.ReportParameterEnum;
import au.com.vaadinutils.jasper.parameter.ReportParameterString;
/**
* This class is used to build report filter UI by defining how report
* parameters are to be displayed.
*
* The builder also validates that all report parameters have been used and that
* those used are defined by the report.
*
* @author bsutton
*
*/
public class ReportFilterUIBuilder implements ReportFilterFieldBuilder, ReportFilterDateFieldBuilder
{
private Set<ReportParameter<?>> rparams = new LinkedHashSet<ReportParameter<?>>();
ReportParameter<?> lastAdded = null;
public ReportFilterUIBuilder()
{
}
@Override
public ReportFilterFieldBuilder addTextField(String label, String parameterName)
{
ReportParameterString param = new ReportParameterString(label, parameterName);
addField(param);
return this;
}
@Override
public ReportFilterDateFieldBuilder addDateField(String label, String startParameterName, String endParameterName)
{
ReportParameterDateTimeRange param = new ReportParameterDateTimeRange(label, startParameterName,
endParameterName);
addField(param);
return this;
}
@Override
public <T extends Enum<?>> ReportFilterFieldBuilder addEnumField(String label, String paramName, Class<T> enumClass,
T defaultValue)
{
@SuppressWarnings({ "unchecked", "rawtypes" })
ReportParameterEnum<?> param = new ReportParameterEnum(label, defaultValue, paramName, enumClass);
addField(param);
return this;
}
@Override
public ReportFilterFieldBuilder addField(ReportParameter<?> param)
{
rparams.add(param);
lastAdded = param;
return this;
}
@Override
public ReportFilterDateFieldBuilder setDateRange(DateTime startDate, DateTime endDate)
{
@SuppressWarnings("unchecked")
ReportParameter<Date> param = (ReportParameter<Date>) lastAdded;
param.setStartDate(startDate.toDate());
param.setEndDate(endDate.toDate());
return this;
}
@Override
public List<ExpanderComponent> buildLayout(Boolean hideDateFields)
{
List<ExpanderComponent> components = new LinkedList<ExpanderComponent>();
boolean hasExpandingComponents = false;
Accordion accordian = null;
if (hasFilters())
{
for (ReportParameter<?> rparam : rparams)
{
if (rparam.showFilter())
{
// check if we should hide date fields, used for the
// scheduler
if (!hideDateFields || !rparam.isDateField())
{
if (rparam.shouldExpand())
{
if (accordian == null)
{
accordian = new Accordion();
accordian.setSizeFull();
}
final Tab tab = accordian.addTab(rparam.getComponent(), rparam.getLabel(""));
rparam.addValidateListener(new ValidateListener()
{
@Override
public void setComponentError(ErrorMessage componentError)
{
tab.setComponentError(componentError);
}
});
rparam.validate();
}
else
{
components.add(new ExpanderComponent(rparam.getComponent(), rparam.shouldExpand()));
}
}
}
}
}
if (accordian != null)
{
hasExpandingComponents = true;
components.add(new ExpanderComponent(accordian, true));
}
if (!hasExpandingComponents)
{
// there are no expanding components, so add an empty expanding
// component so the fields will group together at the top
components.add(new ExpanderComponent(new VerticalLayout(), true));
}
// add 15px high layout to pack up the bottom of the layout, otherwise
// on
// some sets of filters the last component is hidden
VerticalLayout spacer = new VerticalLayout();
spacer.setHeight("15");
components.add(new ExpanderComponent(spacer, false));
return components;
}
public Collection<ReportParameter<?>> getReportParameters()
{
return rparams;
}
/**
* Return true if the builder has any filters defined.
*/
public boolean hasFilters()
{
boolean ret = false;
for (ReportParameter<?> param : rparams)
{
if (param.showFilter())
{
ret = true;
break;
}
}
return ret;
}
}