stroom.statistics.client.common.presenter.StatisticsCustomMaskListPresenter.java Source code

Java tutorial

Introduction

Here is the source code for stroom.statistics.client.common.presenter.StatisticsCustomMaskListPresenter.java

Source

/*
 * Copyright 2016 Crown Copyright
 *
 * 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 stroom.statistics.client.common.presenter;

import com.google.gwt.cell.client.CheckboxCell;
import com.google.gwt.cell.client.FieldUpdater;
import com.google.gwt.dom.client.NativeEvent;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.resources.client.ClientBundle;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.cellview.client.Column;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.google.web.bindery.event.shared.HandlerRegistration;
import com.gwtplatform.mvp.client.MyPresenterWidget;
import stroom.alert.client.event.ConfirmEvent;
import stroom.alert.client.presenter.ConfirmCallback;
import stroom.data.grid.client.DataGridView;
import stroom.data.grid.client.DataGridViewImpl;
import stroom.data.grid.client.EndColumn;
import stroom.dispatch.client.AsyncCallbackAdaptor;
import stroom.dispatch.client.ClientDispatchAsync;
import stroom.entity.client.event.DirtyEvent;
import stroom.entity.client.event.DirtyEvent.DirtyHandler;
import stroom.entity.client.event.HasDirtyHandlers;
import stroom.entity.client.presenter.HasRead;
import stroom.entity.client.presenter.HasWrite;
import stroom.entity.shared.ResultList;
import stroom.statistics.client.common.presenter.StatisticsCustomMaskListPresenter.MaskHolder;
import stroom.statistics.shared.CustomRollUpMask;
import stroom.statistics.shared.RollUpBitMaskPermGenerationAction;
import stroom.statistics.shared.StatisticField;
import stroom.statistics.shared.StatisticStoreEntity;
import stroom.statistics.shared.StatisticsDataSourceData;
import stroom.statistics.shared.StatisticsDataSourceFieldChangeAction;
import stroom.widget.button.client.GlyphButtonView;
import stroom.widget.button.client.GlyphIcons;
import stroom.widget.button.client.ImageButtonView;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class StatisticsCustomMaskListPresenter extends MyPresenterWidget<DataGridView<MaskHolder>>
        implements HasRead<StatisticStoreEntity>, HasWrite<StatisticStoreEntity>, HasDirtyHandlers {
    public interface Resources extends ClientBundle {
        ImageResource autoGenerate();

        ImageResource autoGenerateDisabled();
    }

    private final GlyphButtonView newButton;
    private final GlyphButtonView removeButton;
    private final ImageButtonView autoGenerateButton;

    private MaskHolder selectedElement;

    private StatisticStoreEntity statisticsDataSource;
    private MaskHolderList maskList = new MaskHolderList();

    private final List<Column<MaskHolder, ?>> columns = new ArrayList<Column<MaskHolder, ?>>();

    private final ClientDispatchAsync dispatcher;

    @SuppressWarnings("unchecked")
    @Inject
    public StatisticsCustomMaskListPresenter(final EventBus eventBus, final Resources resources,
            final ClientDispatchAsync dispatcher) {
        super(eventBus, new DataGridViewImpl<MaskHolder>(true, true));

        newButton = getView().addButton(GlyphIcons.NEW_ITEM);
        newButton.setTitle("New roll-up permutation");

        autoGenerateButton = getView().addButton("Auto-generate roll-up permutations", resources.autoGenerate(),
                resources.autoGenerateDisabled(), true);

        removeButton = getView().addButton(GlyphIcons.REMOVE);
        removeButton.setTitle("Remove roll-up permutation");

        maskList = new MaskHolderList();

        this.dispatcher = dispatcher;
        refreshModel();
    }

    @Override
    protected void onBind() {
        super.onBind();

        registerHandler(newButton.addClickHandler(event -> {
            if ((event.getNativeButton() & NativeEvent.BUTTON_LEFT) != 0) {
                onAdd(event);
            }
        }));

        registerHandler(removeButton.addClickHandler(event -> {
            if ((event.getNativeButton() & NativeEvent.BUTTON_LEFT) != 0) {
                onRemove(event);
            }
        }));

        registerHandler(autoGenerateButton.addClickHandler(event -> {
            if ((event.getNativeButton() & NativeEvent.BUTTON_LEFT) != 0) {
                onAutoGenerate(event);
            }
        }));

        registerHandler(getView().getSelectionModel().addSelectionHandler(event -> enableButtons()));
    }

    private void enableButtons() {
        autoGenerateButton.setEnabled(true);

        if (maskList != null && maskList.size() > 0) {
            selectedElement = getView().getSelectionModel().getSelected();
            final boolean enabled = selectedElement != null;

            removeButton.setEnabled(enabled);

        } else {
            removeButton.setEnabled(false);
        }
    }

    private void addColumns() {
        int fieldPos = 0;
        for (final StatisticField statisticField : statisticsDataSource.getStatisticFields()) {
            addStatFieldColumn(fieldPos++, statisticField.getFieldName());
        }

        final EndColumn<MaskHolder> endColumn = new EndColumn<MaskHolder>();

        getView().addEndColumn(endColumn);

        columns.add(endColumn);
    }

    private void removeAllColumns() {
        for (final Column<MaskHolder, ?> column : columns) {
            getView().removeColumn(column);
        }
    }

    private void addStatFieldColumn(final int fieldPositionNumber, final String fieldname) {
        // Enabled.
        final Column<MaskHolder, Boolean> rolledUpColumn = new Column<MaskHolder, Boolean>(new CheckboxCell()) {
            @Override
            public Boolean getValue(final MaskHolder row) {
                return row.getMask().isTagRolledUp(fieldPositionNumber);
            }
        };

        rolledUpColumn.setFieldUpdater(new FieldUpdater<MaskHolder, Boolean>() {
            @Override
            public void update(final int index, final MaskHolder row, final Boolean value) {
                row.getMask().setRollUpState(fieldPositionNumber, value);

                DirtyEvent.fire(StatisticsCustomMaskListPresenter.this, true);
            }
        });

        getView().addResizableColumn(rolledUpColumn, fieldname, 100);
        columns.add(rolledUpColumn);
    }

    private void onAdd(final ClickEvent event) {
        this.maskList.addMask(new CustomRollUpMask());

        // dataProvider.refresh();
        refreshModel();
        DirtyEvent.fire(StatisticsCustomMaskListPresenter.this, true);
    }

    private void onAutoGenerate(final ClickEvent event) {
        final StatisticsCustomMaskListPresenter thisInstance = this;

        ConfirmEvent.fire(this,
                "Are you sure you want to clear the existing roll-ups and generate all possible permutations for the field list?",
                new ConfirmCallback() {
                    @Override
                    public void onResult(final boolean result) {
                        if (result) {
                            dispatcher.execute(
                                    new RollUpBitMaskPermGenerationAction(
                                            statisticsDataSource.getStatisticFieldCount()),
                                    new AsyncCallbackAdaptor<ResultList<CustomRollUpMask>>() {
                                        @Override
                                        public void onSuccess(final ResultList<CustomRollUpMask> result) {
                                            updateState(new HashSet<CustomRollUpMask>(result.getValues()));
                                            DirtyEvent.fire(thisInstance, true);
                                        }

                                    });
                        }
                    }
                });
    }

    private void onRemove(final ClickEvent event) {
        final List<MaskHolder> list = getView().getSelectionModel().getSelectedItems();
        if (maskList != null && list != null && list.size() > 0) {
            maskList.removeAll(list);

            getView().getSelectionModel().clear();
            // dataProvider.refresh();
            refreshModel();

            DirtyEvent.fire(StatisticsCustomMaskListPresenter.this, true);
        }
    }

    private void refreshFromEntity(final StatisticStoreEntity statisticsDataSource) {
        maskList.clear();
        maskList.addMasks(statisticsDataSource.getCustomRollUpMasks());

        addNoRollUpPerm();

        refreshModel();
    }

    private void addNoRollUpPerm() {
        // add a line with no rollups as a starting point
        if (statisticsDataSource.getCustomRollUpMasks().size() == 0
                && statisticsDataSource.getStatisticFieldCount() > 0) {
            maskList.addMask(new CustomRollUpMask(Collections.<Integer>emptyList()));
        }
    }

    public void refreshModel() {
        getView().setRowData(0, maskList);
        getView().setRowCount(maskList.size(), true);
    }

    @Override
    public void read(final StatisticStoreEntity statisticsDataSource) {
        // initialise the columns and hold the statDataSource on first time
        // or if we are passed a different object
        if (this.statisticsDataSource == null || this.statisticsDataSource != statisticsDataSource) {
            this.statisticsDataSource = statisticsDataSource;

            removeAllColumns();
            addColumns();
        }

        refreshFromEntity(statisticsDataSource);
    }

    @Override
    public void write(final StatisticStoreEntity entity) {
        entity.getStatisticDataSourceDataObject()
                .setCustomRollUpMasks(new HashSet<CustomRollUpMask>(maskList.getMasks()));
    }

    @Override
    public HandlerRegistration addDirtyHandler(final DirtyHandler handler) {
        return addHandlerToSource(DirtyEvent.getType(), handler);
    }

    /**
     * Call this method to inform this that it needs to update its display based
     * on state that has changed on another tab
     *
     * @param customRollUpMasks The rollup masks as updated by another tab
     */
    public void updateState(final Set<CustomRollUpMask> customRollUpMasks) {
        maskList.clear();
        maskList.addMasks(customRollUpMasks);

        addNoRollUpPerm();

        removeAllColumns();
        addColumns();

        refreshModel();
    }

    public void reComputeRollUpBitMask(final StatisticsDataSourceData oldStatisticsDataSourceData,
            final StatisticsDataSourceData newStatisticsDataSourceData) {
        // grab the mask list from this presenter
        oldStatisticsDataSourceData.setCustomRollUpMasks(new HashSet<CustomRollUpMask>(maskList.getMasks()));

        dispatcher.execute(
                new StatisticsDataSourceFieldChangeAction(oldStatisticsDataSourceData, newStatisticsDataSourceData),
                new AsyncCallbackAdaptor<StatisticsDataSourceData>() {
                    @Override
                    public void onSuccess(final StatisticsDataSourceData result) {
                        newStatisticsDataSourceData.setCustomRollUpMasks(result.getCustomRollUpMasks());

                        updateState(result.getCustomRollUpMasks());

                    }

                ;
                });

    }

    /**
     * Wrap the mask with an ID value that can be used for equality checks in
     * the UI, to allow multiple rows with the same check box values
     */
    public static class MaskHolder {
        private final int id;
        private final CustomRollUpMask mask;

        public MaskHolder(final int id, final CustomRollUpMask mask) {
            this.id = id;
            this.mask = mask;
        }

        public int getId() {
            return id;
        }

        public CustomRollUpMask getMask() {
            return mask;
        }

        @Override
        public int hashCode() {
            final int prime = 31;
            int result = 1;
            result = prime * result + id;
            return result;
        }

        @Override
        public boolean equals(final Object obj) {
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            final MaskHolder other = (MaskHolder) obj;
            if (id != other.id)
                return false;
            return true;
        }
    }

    /**
     * Extension of ArrayList that adds an ID value to each
     * {@link CustomRollUpMask} object added to it
     */
    public static class MaskHolderList extends ArrayList<MaskHolder> {
        private static final long serialVersionUID = 4981870664808232963L;

        private int idCounter = 0;

        public boolean addMask(final CustomRollUpMask mask) {
            final MaskHolder holder = new MaskHolder(idCounter++, mask);

            return super.add(holder);
        }

        public boolean addMasks(final Collection<CustomRollUpMask> masks) {
            final List<MaskHolder> list = new ArrayList<MaskHolder>();

            for (final CustomRollUpMask mask : masks) {
                final MaskHolder holder = new MaskHolder(idCounter++, mask);
                list.add(holder);
            }
            return super.addAll(list);
        }

        public List<CustomRollUpMask> getMasks() {
            final List<CustomRollUpMask> list = new ArrayList<CustomRollUpMask>();
            for (final MaskHolder holder : this) {
                list.add(holder.getMask());
            }
            return list;
        }
    }
}