/* * 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.displayer.client.widgets.filter; import java.util.ArrayList; import java.util.Date; import java.util.Iterator; import java.util.List; import javax.enterprise.context.Dependent; import javax.enterprise.event.Event; import javax.inject.Inject; import com.google.gwt.user.client.ui.IsWidget; import com.google.gwt.user.client.ui.Widget; import org.dashbuilder.dataset.ColumnType; import org.dashbuilder.dataset.DataSetMetadata; import org.dashbuilder.dataset.filter.ColumnFilter; import org.dashbuilder.dataset.filter.CoreFunctionFilter; import org.dashbuilder.dataset.filter.CoreFunctionType; import org.dashbuilder.dataset.filter.FilterFactory; import org.dashbuilder.dataset.date.TimeFrame; import org.dashbuilder.displayer.client.events.ColumnFilterChangedEvent; import org.dashbuilder.displayer.client.events.ColumnFilterDeletedEvent; import org.jboss.errai.ioc.client.container.SyncBeanManager; import org.uberfire.client.mvp.UberView; import org.uberfire.mvp.Command; @Dependent public class ColumnFilterEditor implements IsWidget { public interface View extends UberView<ColumnFilterEditor> { void clearFunctionSelector(); void addFunctionItem(CoreFunctionType function); void setFunctionSelected(String function); int getSelectedFunctionIndex(); void showFilterConfig(); void clearFilterConfig(); void addFilterConfigWidget(IsWidget widget); String formatDate(Date date); String formatNumber(Number number); } View view = null; SyncBeanManager beanManager = null; ColumnFilter filter = null; DataSetMetadata metadata = null; Event<ColumnFilterChangedEvent> changedEvent = null; Event<ColumnFilterDeletedEvent> deletedEvent = null; @Inject public ColumnFilterEditor(View view, SyncBeanManager beanManager, Event<ColumnFilterChangedEvent> changedEvent, Event<ColumnFilterDeletedEvent> deletedEvent) { this.view = view; this.beanManager = beanManager; this.changedEvent = changedEvent; this.deletedEvent = deletedEvent; this.view.init(this); } public void init(DataSetMetadata metadata, ColumnFilter filter) { this.filter = filter; this.metadata = metadata; initFilterSelector(); initFilterConfig(); } public ColumnFilter getFilter() { return filter; } public View getView() { return view; } @Override public Widget asWidget() { return view.asWidget(); } public void expand() { view.showFilterConfig(); } // View notifications public void onSelectFilterFunction() { int selectedIdx = view.getSelectedFunctionIndex(); if (selectedIdx >= 0) { CoreFunctionFilter coreFilter = getCoreFilter(); CoreFunctionType functionType = getAvailableFunctions(coreFilter).get(selectedIdx); ColumnType columnType = metadata.getColumnType(coreFilter.getColumnId()); List params = FilterFactory.createParameters(columnType, functionType); coreFilter.setType(functionType); coreFilter.setParameters(params); initFilterSelector(); fireFilterChanged(); if (!initFilterConfig().isEmpty()) { view.showFilterConfig(); } } } public void onDeleteFilter() { deletedEvent.fire(new ColumnFilterDeletedEvent(this)); } // Internals protected CoreFunctionFilter getCoreFilter() { try { return (CoreFunctionFilter) filter; } catch (Exception e) { return null; } } protected List<FunctionParameterEditor> createFilterInputControls() { List<FunctionParameterEditor> filterInputControls = new ArrayList<FunctionParameterEditor>(); CoreFunctionFilter coreFilter = getCoreFilter(); if (CoreFunctionType.LIKE_TO.equals(coreFilter.getType())) { FunctionParameterEditor paramInput = createLikeToFunctionWidget(coreFilter); filterInputControls.add(paramInput); } else { for (int i = 0; i < coreFilter.getType().getParametersCount(); i++) { FunctionParameterEditor paramInput = createParamInputWidget(coreFilter, i); filterInputControls.add(paramInput); } } return filterInputControls; } protected void initFilterSelector() { CoreFunctionFilter coreFilter = getCoreFilter(); if (coreFilter != null) { view.clearFunctionSelector(); String currentFunction = formatFilterFunction(coreFilter); view.setFunctionSelected(currentFunction); List<CoreFunctionType> calculateAvailableFunctions = getAvailableFunctions(coreFilter); for (CoreFunctionType functionType : calculateAvailableFunctions) { view.addFunctionItem(functionType); } } } protected List<CoreFunctionType> getAvailableFunctions(CoreFunctionFilter coreFilter) { ColumnType columnType = metadata.getColumnType(coreFilter.getColumnId()); List<CoreFunctionType> functionTypes = CoreFunctionType.getSupportedTypes(columnType); Iterator<CoreFunctionType> it = functionTypes.iterator(); while (it.hasNext()) { CoreFunctionType next = it.next(); if (next.equals(coreFilter.getType())) { it.remove(); } } return functionTypes; } protected List<FunctionParameterEditor> initFilterConfig() { view.clearFilterConfig(); List<FunctionParameterEditor> inputs = createFilterInputControls(); if (!inputs.isEmpty()) { for (IsWidget input : inputs) { view.addFilterConfigWidget(input); } inputs.get(0).setFocus(true); } return inputs; } protected void updateSelectedFilter() { String currentFunction = formatFilterFunction(getCoreFilter()); view.setFunctionSelected(currentFunction); fireFilterChanged(); } protected void fireFilterChanged() { changedEvent.fire(new ColumnFilterChangedEvent(this)); } protected FunctionParameterEditor createParamInputWidget(final CoreFunctionFilter coreFilter, final int paramIndex) { final List paramList = coreFilter.getParameters(); ColumnType columnType = metadata.getColumnType(coreFilter.getColumnId()); CoreFunctionType functionType = coreFilter.getType(); boolean isMultiple = CoreFunctionType.IN.equals(functionType) || CoreFunctionType.NOT_IN.equals(functionType); if (ColumnType.DATE.equals(columnType)) { if (CoreFunctionType.TIME_FRAME.equals(coreFilter.getType())) { return createTimeFrameWidget(paramList, paramIndex); } return createDateInputWidget(paramList, paramIndex); } if (!isMultiple) { if (ColumnType.NUMBER.equals(columnType)) { return createNumberInputWidget(paramList, paramIndex); } return createTextInputWidget(paramList, paramIndex); } else { if (ColumnType.NUMBER.equals(columnType)) { return createMultipleNumberInputWidget(paramList); } return createMultipleTextInputWidget(paramList); } } protected FunctionParameterEditor createDateInputWidget(final List paramList, final int paramIndex) { Date param = (Date) paramList.get(paramIndex); final DateParameterEditor input = beanManager.lookupBean(DateParameterEditor.class).newInstance(); input.setCurrentValue(param); input.setOnChangeCommand(new Command() { public void execute() { paramList.set(paramIndex, input.getCurrentValue()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createNumberInputWidget(final List paramList, final int paramIndex) { final NumberParameterEditor input = beanManager.lookupBean(NumberParameterEditor.class).newInstance(); input.setValue(Double.parseDouble(paramList.get(paramIndex).toString())); input.setOnChangeCommand(new Command() { public void execute() { paramList.set(paramIndex, input.getValue()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createTextInputWidget(final List paramList, final int paramIndex) { final TextParameterEditor input = beanManager.lookupBean(TextParameterEditor.class).newInstance(); input.setValue((String) paramList.get(paramIndex)); input.setOnChangeCommand(new Command() { public void execute() { paramList.set(paramIndex, input.getValue()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createMultipleNumberInputWidget(final List paramList) { final MultipleNumberParameterEditor input = beanManager.lookupBean(MultipleNumberParameterEditor.class).newInstance(); input.setValues(paramList); input.setOnChangeCommand(new Command() { public void execute() { updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createMultipleTextInputWidget(final List paramList) { final MultipleTextParameterEditor input = beanManager.lookupBean(MultipleTextParameterEditor.class).newInstance(); input.setValues(paramList); input.setOnChangeCommand(new Command() { public void execute() { updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createTimeFrameWidget(final List paramList, final int paramIndex) { TimeFrame timeFrame = TimeFrame.parse((String) paramList.get(paramIndex)); final TimeFrameEditor input = beanManager.lookupBean(TimeFrameEditor.class).newInstance(); input.init(timeFrame, new Command() { public void execute() { paramList.set(paramIndex, input.getTimeFrame().toString()); updateSelectedFilter(); } }); return input; } protected FunctionParameterEditor createLikeToFunctionWidget(final CoreFunctionFilter coreFilter) { final LikeToFunctionEditor input = beanManager.lookupBean(LikeToFunctionEditor.class).newInstance(); final List paramList = coreFilter.getParameters(); String pattern = (String) paramList.get(0); boolean caseSensitive = paramList.size() < 2 || Boolean.parseBoolean(paramList.get(1).toString()); input.setCaseSensitive(caseSensitive); input.setPattern(pattern); input.setOnChangeCommand(new Command() { public void execute() { paramList.clear(); paramList.add(input.getPattern()); if (!input.isCaseSensitive()) { // Only add if disabled since case sensitive is enabled by default. paramList.add(input.isCaseSensitive()); } updateSelectedFilter(); } }); return input; } public String formatFilterFunction(CoreFunctionFilter filter) { String columnId = filter.getColumnId(); CoreFunctionType type = filter.getType(); List parameters = filter.getParameters(); StringBuilder out = new StringBuilder(); if (CoreFunctionType.BETWEEN.equals(type)) { out.append(columnId).append(" ["); formatParameters(out, parameters); out.append("]"); } else if (CoreFunctionType.GREATER_THAN.equals(type)) { out.append(columnId).append(" > "); formatParameters(out, parameters); } else if (CoreFunctionType.GREATER_OR_EQUALS_TO.equals(type)) { out.append(columnId).append(" >= "); formatParameters(out, parameters); } else if (CoreFunctionType.LOWER_THAN.equals(type)) { out.append(columnId).append(" < "); formatParameters(out, parameters); } else if (CoreFunctionType.LOWER_OR_EQUALS_TO.equals(type)) { out.append(columnId).append(" <= "); formatParameters(out, parameters); } else if (CoreFunctionType.EQUALS_TO.equals(type)) { out.append(columnId).append(" = "); formatParameters(out, parameters); } else if (CoreFunctionType.NOT_EQUALS_TO.equals(type)) { out.append(columnId).append(" != "); formatParameters(out, parameters); } else if (CoreFunctionType.LIKE_TO.equals(type)) { out.append(columnId).append(" like "); formatParameters(out, parameters); } else if (CoreFunctionType.IS_NULL.equals(type)) { out.append(columnId).append(" = null "); formatParameters(out, parameters); } else if (CoreFunctionType.NOT_NULL.equals(type)) { out.append(columnId).append(" != null "); formatParameters(out, parameters); } else if (CoreFunctionType.TIME_FRAME.equals(type)) { out.append(columnId).append(" = "); formatParameters(out, parameters); } else if (CoreFunctionType.IN.equals(type)) { out.append(columnId).append(" in ("); formatParameters(out, parameters); out.append(")"); } else if (CoreFunctionType.NOT_IN.equals(type)) { out.append(columnId).append(" not in ("); formatParameters(out, parameters); out.append(")"); } return out.toString(); } protected StringBuilder formatParameters(StringBuilder out, List parameters) { for (int i=0; i< parameters.size(); i++) { if (i > 0) out.append(" "); out.append(formatParameter(parameters.get(i))); } return out; } protected String formatParameter(Object p) { if (p == null) { return ""; } if (p instanceof Date) { Date d = (Date) p; return view.formatDate(d); } if (p instanceof Number) { Number n = (Number) p; return view.formatNumber(n); } return p.toString(); } }