| /** |
| * |
| * 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.qi4j.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.qi4j.api.util.Dates; |
| import org.qi4j.api.value.ValueBuilder; |
| import org.qi4j.api.value.ValueBuilderFactory; |
| import org.qi4j.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; |
| } |
| } |