| /** |
| * |
| * 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 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * 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.concurrent.CopyOnWriteArrayList; |
| import java.util.concurrent.LinkedBlockingQueue; |
| import java.util.concurrent.atomic.AtomicBoolean; |
| |
| import org.eclipse.e4.core.contexts.IEclipseContext; |
| 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.DatamartFilter.FilterType; |
| 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 org.slf4j.Logger; |
| |
| import com.vaadin.data.Property.ValueChangeEvent; |
| import com.vaadin.data.Property.ValueChangeListener; |
| import com.vaadin.ui.Component; |
| import com.vaadin.ui.UI; |
| |
| // 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 { |
| private static Logger logger = org.slf4j.LoggerFactory.getLogger(DatamartFilterGenerator.class); |
| |
| /** 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 vaadin **/ |
| private LinkedBlockingQueue<ValueChangeEvent> queue = new LinkedBlockingQueue<>(); |
| private AtomicBoolean active = new AtomicBoolean(false); |
| private transient Thread thread; |
| |
| private boolean showCaption; |
| |
| private int numMultiRows; |
| /** |
| * Instantiates a new datamart filter generator. |
| * |
| * @param datamart the datamart |
| * @param dslMetadataService the dsl metadata service |
| */ |
| public DatamartFilterGenerator(IDataMart datamart, IEclipseContext eclipseContext, boolean showCaption, int numMultiRows) { |
| this.datamart = datamart; |
| this.dslMetadataService = eclipseContext.get(IDSLMetadataService.class); |
| this.showCaption = showCaption; |
| this.numMultiRows = numMultiRows; |
| if(this.datamart != null && datamart.getUser() != null) { |
| this.datamart.getUser().addUserLocaleListener(this); |
| } |
| |
| active.set(true); |
| final UI ui = eclipseContext.get(UI.class); |
| Runnable runnable = () -> { |
| while (active.get()) { |
| try { |
| ValueChangeEvent event; |
| try { |
| event = queue.take(); |
| ui.access(() -> { |
| processValueChange(event); |
| }); |
| } catch (InterruptedException e) { |
| } |
| } catch (Exception e) { |
| logger.error("{}", e); |
| } |
| } |
| }; |
| |
| thread = new Thread(runnable, "DatamartFilterGenerator eventProcessor " + getClass().getName()); |
| thread.setDaemon(true); |
| thread.start(); |
| } |
| |
| /* (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) { |
| if(!listeners.contains(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) { |
| if(listeners.contains(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); |
| if(event.getTopic().endsWith(filter.getShortName())) { |
| 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)) { |
| filter.getSelector().select(filter.getSelectedData()); |
| return false; |
| } |
| break; |
| case SINGLESLICER: |
| case SINGLEHIERARCHY: |
| case SINGLEHIERARCHYCHILDREN: |
| if(filter.canSelectData(event.getData(), false, true)) { |
| filter.getSelector().select(filter.getSelectedData().get(0)); |
| return false; |
| } |
| break; |
| case EXCEPT: |
| case MULTIPLESLICER: |
| case MULTIPLEHIERARCHY: |
| case MULTIPLEHIERARCHYCHILDREN: |
| if(filter.canSelectData(event.getData(), true, true)) { |
| filter.getSelector().select(filter.getSelectedData()); |
| return false; |
| } |
| break; |
| default: |
| 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) { |
| DatamartUiFilterFactory filterFactory = new DatamartUiFilterFactory(); |
| 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 SINGLESLICER: |
| case SINGLEHIERARCHY: |
| case SINGLEHIERARCHYCHILDREN: |
| filter.setSelector((IDatamartSelectable)filterFactory.getUiFilter(filter, numMultiRows)); |
| layoutManager.getTopArea().addComponent((Component)filter.getSelector()); |
| break; |
| case EXCEPT: |
| case MULTIPLE: |
| case MULTIPLESLICER: |
| case MULTIPLEHIERARCHY: |
| case MULTIPLEHIERARCHYCHILDREN: |
| filter.setSelector((IDatamartSelectable)filterFactory.getUiFilter(filter, numMultiRows)); |
| layoutManager.getSideArea().addComponent((Component)filter.getSelector()); |
| break; |
| case BETWEEN: |
| case BETWEEN_DATE: |
| filter.setBetweenInputComponent((IDatamartBetweenInput)filterFactory.getUiFilter(filter, numMultiRows)); |
| 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 SINGLESLICER: |
| case SINGLEHIERARCHY: |
| case SINGLEHIERARCHYCHILDREN: |
| if(filter.getSelector().getValue() != null) { |
| filter.addSelectedItem((IDualData)filter.getSelector().getValue()); |
| } else { |
| filter.clearSelectedData(); |
| allFiltersSet = false; |
| } |
| break; |
| case EXCEPT: |
| filter.setSelectedData(filter.getSelector().getSelectedItems()); |
| break; |
| case MULTIPLE: |
| case MULTIPLESLICER: |
| case MULTIPLEHIERARCHY: |
| case MULTIPLEHIERARCHYCHILDREN: |
| filter.setSelectedData(filter.getSelector().getSelectedItems()); |
| if(filter.getSelector().getSelectedItems().isEmpty()) { |
| allFiltersSet = false; |
| } |
| break; |
| default: |
| 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) { |
| synchronized (queue) { |
| queue.offer(event); |
| } |
| } |
| |
| protected void processValueChange(ValueChangeEvent event) { |
| // 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 (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) { |
| if(changedFilter != null) { |
| listener.filterChanged(changedFilter); |
| } |
| } |
| } |
| } |
| |
| /* (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) { |
| StringBuilder text = new StringBuilder(); |
| if(filter.getType()==FilterType.EXCEPT) { |
| text.append(dslMetadataService.translate(locale.toLanguageTag(), "exceptFor")); |
| text.append(" "); |
| } |
| text.append(dslMetadataService.translate(locale.toLanguageTag(), getTranslatableKey(filter.getName()))); |
| if (showCaption) { |
| if (DatamartFilter.FilterType.BETWEEN == filter.getType() || DatamartFilter.FilterType.BETWEEN_DATE == filter.getType()) { |
| filter.getBetweenInputComponent().setCaption(text.toString()); |
| } else { |
| filter.getSelector().setCaption(text.toString()); |
| } |
| } |
| if (DatamartFilter.FilterType.BETWEEN == filter.getType() || DatamartFilter.FilterType.BETWEEN_DATE == filter.getType()) { |
| filter.getBetweenInputComponent().setDescription(text.toString()); |
| } else { |
| filter.getSelector().setDescription(text.toString()); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| @Override |
| public boolean isPrimaryFilterId(EventDispatcherEvent event) { |
| return event.getTopic().endsWith(datamart.getPrimaryFilterId()); |
| } |
| } |