| /** |
| * |
| * Copyright (c) 2011, 2017 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany) |
| * |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation |
| */ |
| package org.eclipse.osbp.xtext.datamart.common; |
| |
| import java.util.ArrayList; |
| import java.util.List; |
| import java.util.Locale; |
| import java.util.Map; |
| import java.util.concurrent.CopyOnWriteArrayList; |
| |
| import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent; |
| import org.eclipse.osbp.runtime.common.event.EventDispatcherEvent.EventDispatcherDataTag; |
| import org.eclipse.osbp.runtime.common.event.IDualData; |
| import org.eclipse.osbp.ui.api.datamart.DatamartFilter; |
| import org.eclipse.osbp.ui.api.datamart.IDataMart; |
| import org.eclipse.osbp.ui.api.datamart.IDatamartBetweenInput; |
| import org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator; |
| import org.eclipse.osbp.ui.api.datamart.IDatamartSelectable; |
| import org.eclipse.osbp.ui.api.layout.IViewLayoutManager; |
| import org.eclipse.osbp.ui.api.metadata.IDSLMetadataService; |
| import org.eclipse.osbp.ui.api.user.IUser; |
| import org.eclipse.osbp.xtext.i18n.I18NKeyGenerator; |
| |
| import com.vaadin.data.Property.ValueChangeEvent; |
| import com.vaadin.data.Property.ValueChangeListener; |
| import com.vaadin.ui.Component; |
| import com.vaadin.ui.TextField; |
| |
| // creates a filtermap from selected and multiselected components. |
| /** |
| * The Class DatamartFilterGenerator. |
| */ |
| // For cubes the class creates permutated slices over all filter aspects |
| @SuppressWarnings("serial") |
| public class DatamartFilterGenerator implements IDatamartFilterGenerator, ValueChangeListener, IUser.UserLocaleListener { |
| |
| /** The dsl metadata service. */ |
| private transient IDSLMetadataService dslMetadataService; |
| |
| /** The datamart. */ |
| private transient IDataMart datamart; |
| |
| /** The listeners. */ |
| private transient List<FilterChangeListener> listeners = new CopyOnWriteArrayList<>(); |
| |
| /** avoid concurrent modification of vadin multiselect list **/ |
| private boolean concurrentModificationLock = false; |
| private ValueChangeEvent concurrentEvent; |
| private boolean concurrentEventOccured = false; |
| |
| /** |
| * Instantiates a new datamart filter generator. |
| * |
| * @param datamart the datamart |
| * @param dslMetadataService the dsl metadata service |
| */ |
| public DatamartFilterGenerator(IDataMart datamart, IDSLMetadataService dslMetadataService) { |
| this.datamart = datamart; |
| this.dslMetadataService = dslMetadataService; |
| if(this.datamart != null && datamart.getUser() != null) { |
| this.datamart.getUser().addUserLocaleListener(this); |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator#addFilterChangeListener(org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator.FilterChangeListener) |
| */ |
| @Override |
| public void addFilterChangeListener(FilterChangeListener listener) { |
| listeners.add(listener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator#removeChangeListener(org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator.FilterChangeListener) |
| */ |
| @Override |
| public void removeFilterChangeListener(FilterChangeListener listener) { |
| listeners.remove(listener); |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator#selectItem(java.lang.String, java.lang.String) |
| */ |
| @Override |
| public void selectItem(String filterID, String selection) { |
| if (selection != null && datamart != null) { |
| String sel = selection.replace("_", " "); |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| for (DatamartFilter filter : filters) { |
| if(filter.getType() != DatamartFilter.FilterType.BY_ID && filter.getName().equals(filterID)) { |
| for(IDualData item : filter.getData()) { |
| if(item.getSelectionValue().equals(sel)) { |
| filter.getSelector().select(item); |
| return; |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator#selectItem(java.util.Map) |
| */ |
| @Override |
| public boolean selectItem(EventDispatcherEvent event, boolean byId) { |
| boolean mustRefresh = false; |
| for(DatamartFilter filter : datamart.getFilters()) { |
| switch (filter.getType()) { |
| case BY_ID: |
| if(byId && event.getData().containsKey(EventDispatcherDataTag.ID)) { |
| Object id = event.getData().get(EventDispatcherDataTag.ID); |
| filter.setSql(""); |
| if(event.getTopic().endsWith(filter.getName())) { |
| if(id instanceof Integer) { |
| filter.setSql(((Integer)id).toString()); |
| } else if (id instanceof String) { |
| filter.setSql("'"+(String)id+"'"); |
| } |
| |
| } else { |
| filter.setSql(""); |
| } |
| mustRefresh = true; |
| } |
| break; |
| case SINGLE: |
| if(filter.canSelectData(event.getData(), false, false)) { |
| filter.getSelector().select(filter.getSelectedData().get(0)); |
| return false; |
| } |
| break; |
| case MULTIPLE: |
| if(filter.canSelectData(event.getData(), true, false)) { |
| concurrentModificationLock = true; |
| filter.getSelector().select(filter.getSelectedData()); |
| concurrentModificationLock = false; |
| if(concurrentEventOccured) { |
| valueChange(concurrentEvent); |
| } |
| return false; |
| } |
| break; |
| case SINGLEHIERARCHY: |
| case SINGLESLICER: |
| case EXCEPT: |
| if(filter.canSelectData(event.getData(), false, true)) { |
| filter.getSelector().select(filter.getSelectedData().get(0)); |
| return false; |
| } |
| break; |
| case MULTIPLEHIERARCHY: |
| case MULTIPLESLICER: |
| if(filter.canSelectData(event.getData(), true, true)) { |
| concurrentModificationLock = true; |
| filter.getSelector().select(filter.getSelectedData()); |
| concurrentModificationLock = false; |
| if(concurrentEventOccured) { |
| valueChange(concurrentEvent); |
| } |
| return false; |
| } |
| break; |
| } |
| } |
| return mustRefresh; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator#resetItem(java.lang.String) |
| */ |
| @Override |
| public void resetItem(String filterID) { |
| if (datamart != null) { |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| for (DatamartFilter filter : filters) { |
| if(filter.getType() != DatamartFilter.FilterType.BY_ID) { |
| filter.getSelector().select(filter.getSelector().getFirstItem()); |
| return; |
| } |
| } |
| } |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator#createUIFilters(org.eclipse.osbp.ui.api.layout.IViewLayoutManager) |
| */ |
| @Override |
| public boolean createUIFilters(IViewLayoutManager layoutManager) { |
| boolean hasFilters = false; |
| if(datamart != null) { |
| datamart.renderFilters(); |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| hasFilters = true; |
| for (DatamartFilter filter : filters) { |
| switch (filter.getType()) { |
| case BY_ID: |
| break; |
| case SINGLE: |
| case SINGLEHIERARCHY: |
| filter.setSelector(new DatamartSingleSelect(false, false, filter.getData())); |
| layoutManager.getTopArea().addComponent((Component)filter.getSelector()); |
| break; |
| case SINGLESLICER: |
| filter.setSelector(new DatamartSingleSelect(false, true, filter.getData())); |
| layoutManager.getTopArea().addComponent((Component)filter.getSelector()); |
| break; |
| case EXCEPT: |
| filter.setSelector(new DatamartSingleSelect(true, false, filter.getData())); |
| layoutManager.getTopArea().addComponent((Component)filter.getSelector()); |
| break; |
| case MULTIPLE: |
| case MULTIPLEHIERARCHY: |
| filter.setSelector(new DatamartMultiSelect(IDatamartFilterGenerator.MULTISELECTION_ROWS, false, false, filter.getData())); |
| layoutManager.getSideArea().addComponent((Component)filter.getSelector()); |
| break; |
| case MULTIPLESLICER: |
| filter.setSelector(new DatamartMultiSelect(IDatamartFilterGenerator.MULTISELECTION_ROWS, false, true, filter.getData())); |
| layoutManager.getSideArea().addComponent((Component)filter.getSelector()); |
| break; |
| case BETWEEN: |
| filter.setBetweenInputComponent(new DatamartBetweenText()); |
| layoutManager.getTopArea().addComponent((Component) filter.getBetweenInputComponent()); |
| break; |
| case BETWEEN_DATE: |
| filter.setBetweenInputComponent(new DatamartBetweenDate(filter.format, filter.resolution)); |
| layoutManager.getTopArea().addComponent((Component) filter.getBetweenInputComponent()); |
| break; |
| } |
| if(filter.getType() != DatamartFilter.FilterType.BY_ID) { |
| if (DatamartFilter.FilterType.BETWEEN == filter.getType() || DatamartFilter.FilterType.BETWEEN_DATE == filter.getType()){ |
| filter.getBetweenInputComponent().addValueChangeListener(this); |
| } else { |
| filter.getSelector().addValueChangeListener(this); |
| } |
| } |
| } |
| } |
| localeChanged(datamart.getUser().getLocale()); |
| getSelections(); |
| } |
| return hasFilters; |
| } |
| |
| public boolean createUIFilters(IViewLayoutManager layoutManager, DatamartUiFilterFactory filterFactory) { |
| boolean hasFilters = false; |
| if(datamart != null) { |
| datamart.renderFilters(); |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| hasFilters = true; |
| for (DatamartFilter filter : filters) { |
| switch (filter.getType()) { |
| case BY_ID: |
| break; |
| case SINGLE: |
| case SINGLEHIERARCHY: |
| case SINGLESLICER: |
| case EXCEPT: |
| filter.setSelector((IDatamartSelectable)filterFactory.getUiFilter(filter)); |
| layoutManager.getTopArea().addComponent((Component)filter.getSelector()); |
| break; |
| case MULTIPLE: |
| case MULTIPLEHIERARCHY: |
| case MULTIPLESLICER: |
| filter.setSelector((IDatamartSelectable)filterFactory.getUiFilter(filter)); |
| layoutManager.getSideArea().addComponent((Component)filter.getSelector()); |
| break; |
| case BETWEEN: |
| case BETWEEN_DATE: |
| filter.setBetweenInputComponent((IDatamartBetweenInput)filterFactory.getUiFilter(filter)); |
| layoutManager.getTopArea().addComponent((Component) filter.getBetweenInputComponent()); |
| break; |
| } |
| if(filter.getType() != DatamartFilter.FilterType.BY_ID) { |
| if (DatamartFilter.FilterType.BETWEEN == filter.getType() || DatamartFilter.FilterType.BETWEEN_DATE == filter.getType()){ |
| filter.getBetweenInputComponent().addValueChangeListener(this); |
| } else { |
| filter.getSelector().addValueChangeListener(this); |
| } |
| } |
| } |
| } |
| localeChanged(datamart.getUser().getLocale()); |
| getSelections(); |
| } |
| return hasFilters; |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.datamart.IDatamartFilterGenerator#updateFilter() |
| */ |
| @Override |
| public void updateFilter() { |
| if(datamart != null) { |
| datamart.renderFilters(); |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| for (DatamartFilter filter : filters) { |
| if(filter.getType() != DatamartFilter.FilterType.BY_ID) { |
| filter.getSelector().update(filter.getData()); |
| } |
| } |
| } |
| } |
| } |
| |
| /** |
| * Gets the selections. |
| * |
| * @return the selections |
| */ |
| private boolean getSelections() { |
| boolean allFiltersSet = true; |
| if(datamart != null) { |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| for (DatamartFilter filter : filters) { |
| filter.clearSelectedData(); |
| switch (filter.getType()) { |
| case BY_ID: |
| break; |
| case SINGLE: |
| case SINGLEHIERARCHY: |
| case EXCEPT: |
| case SINGLESLICER: |
| if(filter.getSelector().getValue() != null) { |
| filter.addSelectedItem((IDualData)filter.getSelector().getValue()); |
| } else { |
| filter.clearSelectedData(); |
| allFiltersSet = false; |
| } |
| break; |
| case MULTIPLE: |
| case MULTIPLEHIERARCHY: |
| case MULTIPLESLICER: |
| filter.setSelectedData(filter.getSelector().getSelectedItems()); |
| if(filter.getSelector().getSelectedItems().isEmpty()) { |
| allFiltersSet = false; |
| } |
| break; |
| } |
| } |
| } |
| } |
| return allFiltersSet; |
| } |
| |
| /** |
| * Strip MDX characters. |
| * |
| * @param filterName the filter name |
| * @return the string |
| */ |
| private String stripMDXCharacters(String filterName) { |
| return filterName.replace("[", "").replace("]", ""); |
| } |
| |
| /** |
| * Gets the translatable key. |
| * |
| * @param filterName the filter name |
| * @return the translatable key |
| */ |
| private String getTranslatableKey(String filterName) { |
| return I18NKeyGenerator.key(stripHierarchy(filterName)); |
| } |
| |
| /** |
| * Strip hierarchy. |
| * |
| * @param filterName the filter name |
| * @return the string |
| */ |
| private String stripHierarchy(String filterName) { |
| String result = filterName; |
| String[] parts = stripMDXCharacters(filterName).split("\\."); |
| int len = parts.length; |
| if (len > 0) { |
| result = parts[len - 1]; |
| } |
| return result.replace(".", " "); |
| } |
| |
| /* (non-Javadoc) |
| * @see com.vaadin.data.Property.ValueChangeListener#valueChange(com.vaadin.data.Property.ValueChangeEvent) |
| */ |
| @Override |
| public void valueChange(ValueChangeEvent event) { |
| if(!concurrentModificationLock) { |
| concurrentEventOccured = false; |
| // compute selections |
| if(getSelections()) { |
| // get the filter that changed |
| DatamartFilter changedFilter = null; |
| if(datamart != null) { |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| for (DatamartFilter filter : filters) { |
| if(event != null) { |
| if (filter.getType() == DatamartFilter.FilterType.BETWEEN || filter.getType() == DatamartFilter.FilterType.BETWEEN_DATE) { |
| if (!filter.getBetweenInputComponent().getFrom().isEmpty() && filter.getBetweenInputComponent().getUntilInput().equals(event.getProperty())){ |
| changedFilter = filter; |
| break; |
| } |
| } else if (filter.getType() != DatamartFilter.FilterType.BY_ID && filter.getSelector().equals(event.getProperty())) { |
| changedFilter = filter; |
| break; |
| } |
| } |
| } |
| } |
| } |
| // notify the listeners of the changed filter |
| for(FilterChangeListener listener:listeners) { |
| listener.filterChanged(changedFilter); |
| } |
| } |
| } else { |
| concurrentEventOccured = true; |
| concurrentEvent = event; |
| } |
| } |
| |
| /* (non-Javadoc) |
| * @see org.eclipse.osbp.ui.api.user.IUser.UserLocaleListener#localeChanged(java.util.Locale) |
| */ |
| @Override |
| public void localeChanged(final Locale locale) { |
| if(datamart != null) { |
| ArrayList<DatamartFilter> filters = datamart.getFilters(); |
| if (filters != null) { |
| for (DatamartFilter filter : filters) { |
| if(filter.getSelector() != null || filter.getBetweenInputComponent() != null) { |
| if (IDatamartFilterGenerator.SHOW_CAPTION) { |
| if (DatamartFilter.FilterType.BETWEEN == filter.getType() || DatamartFilter.FilterType.BETWEEN_DATE == filter.getType()) { |
| filter.getBetweenInputComponent().setCaption(dslMetadataService.translate(locale.toLanguageTag(), getTranslatableKey(filter.getName()))); |
| } else { |
| filter.getSelector().setCaption(dslMetadataService.translate(locale.toLanguageTag(), getTranslatableKey(filter.getName()))); |
| } |
| } |
| if (DatamartFilter.FilterType.BETWEEN == filter.getType() || DatamartFilter.FilterType.BETWEEN_DATE == filter.getType()) { |
| filter.getBetweenInputComponent().setDescription(dslMetadataService.translate(locale.toLanguageTag(), getTranslatableKey(filter.getName()))); |
| } else { |
| filter.getSelector().setDescription(dslMetadataService.translate(locale.toLanguageTag(), getTranslatableKey(filter.getName()))); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |