blob: b984e016324a00c6b001323a8b97c204a2ab7154 [file] [log] [blame]
/**
*
* Copyright 2009-2011 Rickard Öberg AB
*
* Licensed 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.
*/
package org.apache.zest.library.rest.common.table;
import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Map;
import org.apache.zest.api.util.Dates;
import org.apache.zest.api.value.ValueBuilder;
import org.apache.zest.api.value.ValueBuilderFactory;
import org.apache.zest.functional.Function;
import static java.util.Collections.reverseOrder;
/**
* JAVADOC
*/
public class TableBuilder
{
protected ValueBuilderFactory vbf;
private Map<String, TableBuilderFactory.Column> columns;
private TableQuery tableQuery;
protected ValueBuilder<Table> tableBuilder;
protected ValueBuilder<Row> rowBuilder;
public TableBuilder(ValueBuilderFactory vbf)
{
this.vbf = vbf;
tableBuilder = vbf.newValueBuilder(Table.class);
}
public TableBuilder(ValueBuilderFactory vbf, Map<String, TableBuilderFactory.Column> columns, TableQuery tableQuery)
{
this.vbf = vbf;
this.columns = columns;
this.tableQuery = tableQuery;
tableBuilder = vbf.newValueBuilder(Table.class);
if (tableQuery.select().equals("*"))
{
for (TableBuilderFactory.Column column : columns.values())
{
column(column.getId(), column.getLabel(), column.getType());
}
} else
{
for (String columnName : tableQuery.select().split("[, ]"))
{
TableBuilderFactory.Column column = columns.get(columnName.trim());
if (column != null)
column(column.getId(), column.getLabel(), column.getType());
}
}
}
public TableBuilder column(String id, String label, String type)
{
ValueBuilder<Column> builder = vbf.newValueBuilder(Column.class);
builder.prototype().id().set(id);
if (tableQuery != null && tableQuery.label() != null)
{
// TODO Fix label selection
}
builder.prototype().label().set(label);
builder.prototype().columnType().set(type);
tableBuilder.prototype().cols().get().add(builder.newInstance());
return this;
}
public TableBuilder rows(Iterable<?> rowObjects)
{
boolean no_format = false;
boolean no_values = false;
if (tableQuery != null && tableQuery.options() != null)
{
if (tableQuery.options().contains("no_format"))
no_format = true;
if (tableQuery != null && tableQuery.options().contains("no_values"))
no_values = true;
}
for (Object rowObject : rowObjects)
{
row();
for (Column column : tableBuilder.prototype().cols().get())
{
Object v = null;
String f = null;
Function valueFunction = columns.get( column.id().get()).getValueFunction();
if (!no_values && valueFunction != null)
v = valueFunction.map(rowObject);
Function formattedFunction = columns.get( column.id().get()).getFormattedFunction();
if (!no_format && formattedFunction != null)
f = (String) formattedFunction.map(rowObject);
else if (v != null)
{
if ( column.columnType().get().equals( Table.DATETIME))
f = Dates.toUtcString( (Date) v );
else if ( column.columnType().get().equals( Table.DATE))
f = new SimpleDateFormat( "yyyy-MM-dd").format((Date) v);
else if ( column.columnType().get().equals( Table.TIME_OF_DAY))
f = new SimpleDateFormat( "HH:mm:ss").format((Date) v);
else
f = v.toString();
}
cell(v, f);
}
endRow();
}
return this;
}
public TableBuilder row()
{
if (rowBuilder != null)
endRow();
rowBuilder = vbf.newValueBuilder(Row.class);
return this;
}
public TableBuilder endRow()
{
tableBuilder.prototype().rows().get().add(rowBuilder.newInstance());
rowBuilder = null;
return this;
}
public TableBuilder cell(Object v, String f)
{
ValueBuilder<Cell> cellBuilder = vbf.newValueBuilder(Cell.class);
cellBuilder.prototype().v().set(v);
cellBuilder.prototype().f().set(f);
rowBuilder.prototype().c().get().add(cellBuilder.newInstance());
return this;
}
public TableBuilder orderBy()
{
if (tableQuery.orderBy() != null)
{
// Sort table
// Find sort column index
String[] orderBy = tableQuery.orderBy().split(" ");
boolean descending = orderBy.length == 2 && orderBy[1].equals("desc");
int sortIndex = -1;
List<Column> columns = tableBuilder.prototype().cols().get();
for (int i = 0; i < columns.size(); i++)
{
Column column = columns.get(i);
if ( column.id().get().equals(orderBy[0]))
{
sortIndex = i;
break;
}
}
if (sortIndex != -1)
{
final int idx = sortIndex;
Comparator<Row> comparator = new Comparator<Row>()
{
@Override
public int compare(Row o1, Row o2)
{
Object o = o1.c().get().get(idx).v().get();
if (o != null && o instanceof Comparable)
{
Comparable c1 = (Comparable) o;
Comparable c2 = (Comparable) o2.c().get().get(idx).v().get();
return c1.compareTo(c2);
} else
{
String f1 = o1.c().get().get(idx).f().get();
String f2 = o2.c().get().get(idx).f().get();
return f1.compareTo(f2);
}
}
};
if (descending)
{
// Flip it
comparator = reverseOrder(comparator);
}
Collections.sort(tableBuilder.prototype().rows().get(), comparator);
}
}
return this;
}
// public TableBuilder orderBy()
// {
// if (tableQuery.orderBy() != null)
// {
// // Sort table
// // Find sort column index
// int sortIndex = -1;
// List<ColumnValue> columnValues = tableBuilder.prototype().cols().get();
// for (int i = 0; i < columnValues.size(); i++)
// {
// ColumnValue columnValue = columnValues.get(i);
// if (columnValue.id().equals(tableQuery.orderBy()))
// {
// sortIndex = i;
// break;
// }
//
// }
//
// if (sortIndex != -1)
// {
// final int idx = sortIndex;
// Comparator<RowValue> comparator = new Comparator<RowValue>()
// {
// public int compare(RowValue o1, RowValue o2)
// {
// Object o = o1.c().get().get(idx).v().get();
//
// if (o != null && o instanceof Comparable)
// {
// Comparable c1 = (Comparable) o;
// Comparable c2 = (Comparable) o2.c().get().get(idx).v().get();
// return c1.compareTo(c2);
// } else
// {
// String f1 = o1.c().get().get(idx).f().get();
// String f2 = o2.c().get().get(idx).f().get();
// return f1.compareTo(f2);
// }
// }
// };
//
// Collections.sort(tableBuilder.prototype().rows().get(), comparator);
// }
// }
//
// return this;
// }
public TableBuilder paging()
{
// Paging
int start = 0;
int end = tableBuilder.prototype().rows().get().size();
if (tableQuery.offset() != null)
start = Integer.parseInt(tableQuery.offset());
if (tableQuery.limit() != null)
end = Math.min(end, start + Integer.parseInt(tableQuery.limit()));
if (!(start == 0 && end == tableBuilder.prototype().rows().get().size()))
tableBuilder.prototype().rows().set(tableBuilder.prototype().rows().get().subList(start, end));
return this;
}
public Table newTable()
{
if (rowBuilder != null)
endRow();
return tableBuilder.newInstance();
}
public void abortRow()
{
rowBuilder = null;
}
}