/* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * 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.dashbuilder.dataset.impl; import java.util.List; import org.dashbuilder.dataset.DataSetLookup; import org.dashbuilder.dataset.DataSetLookupBuilder; import org.dashbuilder.dataset.DataSetOp; import org.dashbuilder.dataset.date.DayOfWeek; import org.dashbuilder.dataset.date.Month; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.DataSetFilter; import org.dashbuilder.dataset.group.AggregateFunctionType; import org.dashbuilder.dataset.group.ColumnGroup; import org.dashbuilder.dataset.group.DataSetGroup; import org.dashbuilder.dataset.group.DateIntervalType; import org.dashbuilder.dataset.group.GroupFunction; import org.dashbuilder.dataset.group.GroupStrategy; import org.dashbuilder.dataset.sort.ColumnSort; import org.dashbuilder.dataset.sort.DataSetSort; import org.dashbuilder.dataset.sort.SortOrder; public abstract class AbstractDataSetLookupBuilder<T> implements DataSetLookupBuilder<T> { private static final String SYMBOL_UNDERSCORE = "_"; private DataSetLookup dataSetLookup = new DataSetLookup(); protected DataSetOp getCurrentOp() { List<DataSetOp> dataSetOps = dataSetLookup.getOperationList(); if (dataSetOps.isEmpty()) return null; return dataSetOps.get(dataSetOps.size() - 1); } public T dataset(String uuid) { dataSetLookup.setDataSetUUID(uuid); return (T) this; } public T rowOffset(int offset) { dataSetLookup.setRowOffset(offset); return (T) this; } public T rowNumber(int rows) { dataSetLookup.setNumberOfRows(rows); return (T) this; } public T group(String columnId) { return group(columnId, columnId); } public T group(String columnId, String newColumnId) { DataSetGroup gOp = new DataSetGroup(); gOp.setColumnGroup(new ColumnGroup(columnId, newColumnId)); dataSetLookup.addOperation(gOp); return (T) this; } public T join() { DataSetGroup gOp = (DataSetGroup) getCurrentOp(); if (gOp == null || gOp.getColumnGroup() == null) { throw new RuntimeException("group() must be called first."); } gOp.setJoin(true); return (T) this; } public T asc() { DataSetGroup gOp = (DataSetGroup) getCurrentOp(); if (gOp == null || gOp.getColumnGroup() == null) { throw new RuntimeException("group() must be called first."); } ColumnGroup columnGroup = gOp.getColumnGroup(); columnGroup.setAscendingOrder(true); return (T) this; } public T desc() { DataSetGroup gOp = (DataSetGroup) getCurrentOp(); if (gOp == null || gOp.getColumnGroup() == null) { throw new RuntimeException("group() must be called first."); } ColumnGroup columnGroup = gOp.getColumnGroup(); columnGroup.setAscendingOrder(false); return (T) this; } public T dynamic(int maxIntervals, boolean emptyAllowed) { return groupStrategy(GroupStrategy.DYNAMIC, maxIntervals, null, emptyAllowed); } public T dynamic(int maxIntervals, DateIntervalType intervalSize, boolean emptyAllowed) { return groupStrategy(GroupStrategy.DYNAMIC, maxIntervals, intervalSize.toString(), emptyAllowed); } public T dynamic(DateIntervalType intervalSize, boolean emptyAllowed) { return groupStrategy(GroupStrategy.DYNAMIC, -1, intervalSize.toString(), emptyAllowed); } public T fixed(DateIntervalType intervalSize, boolean emptyAllowed) { if (!DateIntervalType.FIXED_INTERVALS_SUPPORTED.contains(intervalSize)) { throw new IllegalArgumentException("Fixed group size '" + intervalSize + "' not supported."); } return groupStrategy(GroupStrategy.FIXED, -1, intervalSize.toString(), emptyAllowed); } public T firstDay(DayOfWeek dayOfWeek) { DataSetGroup gOp = (DataSetGroup) getCurrentOp(); if (gOp == null || gOp.getColumnGroup() == null) { throw new RuntimeException("group() must be called first."); } ColumnGroup columnGroup = gOp.getColumnGroup(); if (!GroupStrategy.FIXED.equals(columnGroup.getStrategy())) { throw new RuntimeException("A fixed group is required."); } if (!DateIntervalType.DAY_OF_WEEK.equals(DateIntervalType.getByName(columnGroup.getIntervalSize()))) { throw new RuntimeException("A fixed DAY_OF_WEEK date group is required."); } columnGroup.setFirstDayOfWeek(dayOfWeek); return (T) this; } public T firstMonth(Month month) { DataSetGroup gOp = (DataSetGroup) getCurrentOp(); if (gOp == null || gOp.getColumnGroup() == null) { throw new RuntimeException("group() must be called first."); } ColumnGroup columnGroup = gOp.getColumnGroup(); if (!GroupStrategy.FIXED.equals(columnGroup.getStrategy())) { throw new RuntimeException("A fixed group is required."); } if (!DateIntervalType.MONTH.equals(DateIntervalType.getByName(columnGroup.getIntervalSize()))) { throw new RuntimeException("A fixed MONTH date group is required."); } columnGroup.setFirstMonthOfYear(month); return (T) this; } private T groupStrategy(GroupStrategy strategy, int maxIntervals, String intervalSize, boolean emptyAllowed) { DataSetGroup gOp = (DataSetGroup) getCurrentOp(); if (gOp == null || gOp.getColumnGroup() == null) { throw new RuntimeException("group() must be called first."); } ColumnGroup cg = gOp.getColumnGroup(); cg.setStrategy(strategy); cg.setMaxIntervals(maxIntervals); cg.setIntervalSize(intervalSize); cg.setEmptyIntervalsAllowed(emptyAllowed); return (T) this; } public T select(String... intervalNames) { DataSetOp op = getCurrentOp(); if (op == null || !(op instanceof DataSetGroup)) { dataSetLookup.addOperation(new DataSetGroup()); } DataSetGroup gOp = (DataSetGroup) getCurrentOp(); gOp.addSelectedIntervalNames(intervalNames); return (T) this; } public T filter(ColumnFilter... filters) { return filter(null, filters); } public T filter(String columnId, ColumnFilter... filters) { DataSetOp op = getCurrentOp(); if (op == null || !(op instanceof DataSetFilter)) { dataSetLookup.addOperation(new DataSetFilter()); } DataSetFilter fOp = (DataSetFilter) getCurrentOp(); for (ColumnFilter filter : filters) { if (columnId != null) filter.setColumnId(columnId); fOp.addFilterColumn(filter); } return (T) this; } public T sort(String columnId, String order) { return sort(columnId, SortOrder.getByName(order)); } public T sort(String columnId, SortOrder order) { DataSetOp op = getCurrentOp(); if (op == null || !(op instanceof DataSetSort)) { dataSetLookup.addOperation(new DataSetSort()); } DataSetSort sOp = (DataSetSort) getCurrentOp(); sOp.addSortColumn(new ColumnSort(columnId, order)); return (T) this; } public T column(String columnId) { return this.column(columnId, null, columnId); } public T column(String columnId, String newColumnId) { return this.column(columnId, null, newColumnId); } public T column(String columnId, AggregateFunctionType function) { String newColumnId = buildColumnId(columnId, function); return this.column(columnId, function, newColumnId); } public T column(AggregateFunctionType function, String newColumnId) { return this.column(null, function, newColumnId); } public T column(String columnId, AggregateFunctionType function, String newColumnId) { DataSetOp op = getCurrentOp(); if (op == null || !(op instanceof DataSetGroup)) { dataSetLookup.addOperation(new DataSetGroup()); } DataSetGroup gOp = (DataSetGroup) getCurrentOp(); gOp.addGroupFunction(new GroupFunction(columnId, newColumnId, function)); return (T) this; } public DataSetLookup buildLookup() { return dataSetLookup; } /** * <p>Builds a column identifier when applying an aggregate function to the column, but no id is specified.</p> * <p>It follows the nomenclature: <code>sourceId_function</code>.</p> * * @param sourceId The source column identifier. * @param function The aggregate function. * @return A new column identifier. */ protected String buildColumnId(String sourceId, AggregateFunctionType function) { if (sourceId == null || sourceId.trim().length() == 0) { return function.name().toLowerCase(); } else { return sourceId + SYMBOL_UNDERSCORE + function.name().toLowerCase(); } } }