com.netxforge.netxstudio.screens.nf3.Retention.java Source code

Java tutorial

Introduction

Here is the source code for com.netxforge.netxstudio.screens.nf3.Retention.java

Source

/*******************************************************************************
 * Copyright (c) 3 jan. 2013 NetXForge.
 * 
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 * 
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details. You should have received a copy of the GNU General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>
 * 
 * Contributors: Christophe Bouhier - initial API and implementation and/or
 * initial documentation
 *******************************************************************************/
package com.netxforge.netxstudio.screens.nf3;

import org.eclipse.core.databinding.observable.list.IListChangeListener;
import org.eclipse.core.databinding.observable.list.IObservableList;
import org.eclipse.core.databinding.observable.list.ListChangeEvent;
import org.eclipse.core.databinding.property.value.IValueProperty;
import org.eclipse.emf.cdo.eresource.CDOResource;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.databinding.EMFDataBindingContext;
import org.eclipse.emf.databinding.IEMFValueProperty;
import org.eclipse.emf.databinding.edit.EMFEditProperties;
import org.eclipse.emf.databinding.edit.IEMFEditListProperty;
import org.eclipse.emf.databinding.edit.IEMFEditValueProperty;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.DeleteCommand;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.databinding.swt.ISWTObservableValue;
import org.eclipse.jface.databinding.swt.SWTObservables;
import org.eclipse.jface.databinding.viewers.ViewerProperties;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.events.IHyperlinkListener;
import org.eclipse.ui.forms.widgets.ColumnLayout;
import org.eclipse.ui.forms.widgets.Form;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.ImageHyperlink;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.wb.swt.ResourceManager;

import com.google.inject.Inject;
import com.netxforge.base.NonModelUtils;
import com.netxforge.base.cdo.ICDOData;
import com.netxforge.netxstudio.data.actions.ServerRequest;
import com.netxforge.netxstudio.data.fixtures.Fixtures;
import com.netxforge.netxstudio.data.fixtures.IFixtures;
import com.netxforge.netxstudio.library.Expression;
import com.netxforge.netxstudio.library.LibraryFactory;
import com.netxforge.netxstudio.library.LibraryPackage;
import com.netxforge.netxstudio.metrics.MetricRetentionPeriod;
import com.netxforge.netxstudio.metrics.MetricRetentionRule;
import com.netxforge.netxstudio.metrics.MetricRetentionRules;
import com.netxforge.netxstudio.metrics.MetricsFactory;
import com.netxforge.netxstudio.metrics.MetricsPackage;
import com.netxforge.netxstudio.screens.AbstractScreen;
import com.netxforge.netxstudio.screens.ch9.NewEditExpression;
import com.netxforge.screens.editing.base.IDataServiceInjection;
import com.netxforge.screens.editing.base.ScreenUtil;

/**
 * Data retention UI screen.
 * 
 * @author Christophe Bouhier
 * 
 */
public class Retention extends AbstractScreen implements IDataServiceInjection {

    private final FormToolkit toolkit = new FormToolkit(Display.getCurrent());
    private Resource retentionRulesResource;
    private MetricRetentionRules rules = null;
    private Form frmDataRetention;

    @Inject
    private ServerRequest serverActions;

    @Inject
    private IFixtures fixtures;

    private Composite cmpRules;
    private EMFDataBindingContext context;
    private Section sctnRules;
    private Section sctnCustomRules;
    private Composite cmpCustomRules;

    /**
     * Create the composite.
     * 
     * @param parent
     * @param style
     */
    public Retention(Composite parent, int style) {
        super(parent, style);
        addDisposeListener(new DisposeListener() {
            public void widgetDisposed(DisposeEvent e) {
                toolkit.dispose();
            }
        });
        toolkit.adapt(this);
        toolkit.paintBordersFor(this);
    }

    private void buildUI() {
        setLayout(new FillLayout(SWT.HORIZONTAL));

        frmDataRetention = toolkit.createForm(this);
        frmDataRetention.setSeparatorVisible(true);
        toolkit.paintBordersFor(frmDataRetention);
        frmDataRetention.setText(this.getScreenName());
        ColumnLayout columnLayout = new ColumnLayout();
        columnLayout.maxNumColumns = 1;
        frmDataRetention.getBody().setLayout(columnLayout);

        // buildRunRetentionRulesSection();

        sctnRules = toolkit.createSection(frmDataRetention.getBody(), Section.TITLE_BAR);
        toolkit.paintBordersFor(sctnRules);
        sctnRules.setText("Data retention rules");

        final ToolBarManager createSectionToolbar = createSectionToolbar(sctnRules);

        // final ImageDescriptor resetDescriptor = ResourceManager
        // .getPluginImageDescriptor(
        // "com.netxforge.netxstudio.screens.editing",
        // "/icons/full/obj16/add_obj.gif");

        createSectionToolbar.add(new ResetFixedRulesAction("Reset"));

        createSectionToolbar.update(true);

        cmpRules = toolkit.createComposite(sctnRules, SWT.NONE);
        toolkit.paintBordersFor(cmpRules);
        sctnRules.setClient(cmpRules);

        // 1 Name,3. Combo with period 4. Expression.
        cmpRules.setLayout(new GridLayout(3, false));

        FormText ftMetricDataRetentionInstruction = toolkit.createFormText(cmpRules, false);
        GridData gd_ftMetricDataRetentionInstruction = new GridData(SWT.FILL, SWT.CENTER, true, false, 4, 1);
        gd_ftMetricDataRetentionInstruction.heightHint = 23;
        ftMetricDataRetentionInstruction.setLayoutData(gd_ftMetricDataRetentionInstruction);
        toolkit.paintBordersFor(ftMetricDataRetentionInstruction);
        ftMetricDataRetentionInstruction.setText(
                "<form><p>Settings for data retention, keep value data for:</p>\n<p/></form>", true, false);

        sctnCustomRules = toolkit.createSection(frmDataRetention.getBody(), Section.TITLE_BAR);
        toolkit.paintBordersFor(sctnCustomRules);
        sctnCustomRules.setText("Custom data retention rules");

        final ToolBarManager customRulesToolBar = createSectionToolbar(sctnCustomRules);

        final ImageDescriptor addDescriptor = ResourceManager.getPluginImageDescriptor(
                "com.netxforge.netxstudio.screens.editing", "/icons/full/obj16/add_obj.gif");

        customRulesToolBar.add(new NewRetentionRuleAction("", addDescriptor));
        customRulesToolBar.update(true);

        cmpCustomRules = toolkit.createComposite(sctnCustomRules, SWT.NONE);
        toolkit.paintBordersFor(sctnCustomRules);
        sctnCustomRules.setClient(cmpCustomRules);

        // 1 Name, 2 Interval 3. Combo with period 4. Expression. 5. Delete
        // rule.
        cmpCustomRules.setLayout(new GridLayout(5, false));

    }

    // CB 17-07 2012, Decided not to allow this operation in this screen.
    // It would start a server side job, without showing feedback, the job can
    // be scheduled instead.
    @SuppressWarnings("unused")
    private void buildRunRetentionRulesSection() {
        Section sctnControl = toolkit.createSection(frmDataRetention.getBody(), Section.TITLE_BAR);
        sctnControl.setText("Control");
        toolkit.paintBordersFor(sctnControl);

        Composite composite = toolkit.createComposite(sctnControl, SWT.NONE);
        toolkit.paintBordersFor(composite);
        sctnControl.setClient(composite);
        composite.setLayout(new GridLayout(1, false));

        ImageHyperlink mghprlnkInvokeDataRetention = toolkit.createImageHyperlink(composite, SWT.NONE);
        mghprlnkInvokeDataRetention.addHyperlinkListener(new IHyperlinkListener() {
            public void linkActivated(HyperlinkEvent e) {
                try {
                    serverActions.setCDOServer(getCDOEditingService().getServer());
                    // TODO, We get the workflow run ID back, which
                    // could be used
                    // to link back to the screen showing the running
                    // workflows.
                    String result = serverActions.callRetentionAction();
                    MessageDialog.openInformation(Retention.this.getShell(), "Data retention action invoked",
                            "Clear data invoked on the server");

                } catch (Exception e1) {
                    e1.printStackTrace();
                    MessageDialog.openError(Retention.this.getShell(), "Data retention action failed:",
                            "Remote service is not available");

                }

            }

            public void linkEntered(HyperlinkEvent e) {
            }

            public void linkExited(HyperlinkEvent e) {
            }
        });
        toolkit.paintBordersFor(mghprlnkInvokeDataRetention);
        mghprlnkInvokeDataRetention.setText("Invoke data retention rules now");
    }

    private void launchExpressionScreen(MetricRetentionRule retention) {
        if (retention != null) {
            final NewEditExpression expressionScreen = new NewEditExpression(screenService.getScreenContainer(),
                    SWT.NONE);
            Expression expression = null;
            if (retention.getRetentionExpression() == null) {
                // Auto Create an expression, if null.
                expression = LibraryFactory.eINSTANCE.createExpression();
                expressionScreen.setOperation(ScreenUtil.OPERATION_NEW);
            } else {
                expression = retention.getRetentionExpression();
                expressionScreen.setOperation(ScreenUtil.OPERATION_EDIT);
            }
            expressionScreen.setScreenService(screenService);
            expressionScreen.injectData(expression.eResource(), expression);
            screenService.setActiveScreen(expressionScreen);
        }
    }

    public EMFDataBindingContext initDataBindings_() {

        final EMFDataBindingContext context = new EMFDataBindingContext();

        buildRules(context);

        // Add an observer to refresh the UI when rules are added/removed.
        final IEMFEditListProperty metricRetentionRules = EMFEditProperties.list(editingService.getEditingDomain(),
                MetricsPackage.Literals.METRIC_RETENTION_RULES__METRIC_RETENTION_RULES);

        final IObservableList observe = metricRetentionRules.observe(rules);
        observe.addListChangeListener(new IListChangeListener() {
            public void handleListChange(ListChangeEvent event) {
                // System.out.println("value changed: " + event);
                // rebuild the rules:
                buildRules(context);
                updateUI();
            }

        });

        return context;
    }

    /**
     * @param context
     */
    private void buildRules(EMFDataBindingContext context) {

        // Dispose all children from cmpRules.
        if (cmpRules.getChildren().length > 0) {
            for (Control c : cmpRules.getChildren()) {
                c.dispose();
            }
        }

        if (cmpCustomRules.getChildren().length > 0) {
            for (Control c : cmpCustomRules.getChildren()) {
                c.dispose();
            }
        }

        for (MetricRetentionRule r : rules.getMetricRetentionRules()) {
            int indexOf = rules.getMetricRetentionRules().indexOf(r);
            // All rules above 4 are editable.
            addUIRule(r, context, indexOf > 4);
        }
    }

    private void addUIRule(MetricRetentionRule r, EMFDataBindingContext context, boolean isEditable) {
        final IEMFValueProperty retentionPeriodProperty = EMFEditProperties.value(editingService.getEditingDomain(),
                MetricsPackage.Literals.METRIC_RETENTION_RULE__PERIOD);
        IValueProperty selectionProperty = ViewerProperties.singleSelection();

        if (!isEditable) {
            addUIRule(cmpRules, r, context, retentionPeriodProperty, selectionProperty);
        } else {
            addCustomUIRule(cmpCustomRules, r, context, retentionPeriodProperty, selectionProperty);

        }
    }

    private void addUIRule(final Composite cmpRules, final MetricRetentionRule rule, EMFDataBindingContext context,
            IEMFValueProperty retentionPeriodProperty, IValueProperty cmbSelectionProperty) {

        final Label lblMonthlyValues = toolkit.createLabel(cmpRules, rule.getName(), SWT.NONE);
        lblMonthlyValues.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));

        final ComboViewer cmbViewerTarget = new ComboViewer(cmpRules, SWT.NONE);
        Combo cmbMonthly = cmbViewerTarget.getCombo();
        GridData gd_cmbMonthly = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
        gd_cmbMonthly.widthHint = 150;
        cmbMonthly.setLayoutData(gd_cmbMonthly);
        toolkit.paintBordersFor(cmbMonthly);

        cmbMonthly.setFocus();

        final ImageHyperlink mghprlnkEditRetentionExpression = toolkit.createImageHyperlink(cmpRules, SWT.NONE);
        mghprlnkEditRetentionExpression.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
        mghprlnkEditRetentionExpression.addHyperlinkListener(new HyperlinkAdapter() {
            public void linkActivated(HyperlinkEvent e) {
                launchExpressionScreen(rule);
            }
        });
        toolkit.paintBordersFor(mghprlnkEditRetentionExpression);
        mghprlnkEditRetentionExpression.setText("Edit retention expression");

        cmbViewerTarget.setContentProvider(new ArrayContentProvider());
        cmbViewerTarget.setLabelProvider(new LabelProvider());
        cmbViewerTarget.setInput(MetricRetentionPeriod.values());

        context.bindValue(cmbSelectionProperty.observe(cmbViewerTarget), retentionPeriodProperty.observe(rule));
    }

    private void addCustomUIRule(final Composite cmpRules, final MetricRetentionRule rule,
            EMFDataBindingContext context, IEMFValueProperty retentionPeriodProperty,
            IValueProperty cmbSelectionProperty) {

        // Edit the name of the rule.
        final Text nameText = toolkit.createText(cmpRules, "");
        GridData textLayoutData = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
        textLayoutData.widthHint = 100;
        nameText.setLayoutData(textLayoutData);

        nameText.setFocus();

        final ISWTObservableValue observeTextName = SWTObservables.observeDelayedValue(400,
                SWTObservables.observeText(nameText, SWT.Modify));

        final IEMFEditValueProperty nameProperty = EMFEditProperties.value(editingService.getEditingDomain(),
                MetricsPackage.Literals.METRIC_RETENTION_RULE__NAME);

        context.bindValue(observeTextName, nameProperty.observe(rule));

        // Edit the interval.
        final Text intervalText = toolkit.createText(cmpRules, "");
        final GridData intervalGridData = new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1);
        intervalText.setLayoutData(intervalGridData);

        final ISWTObservableValue observeTextInterval = SWTObservables.observeDelayedValue(400,
                SWTObservables.observeText(intervalText, SWT.Modify));

        final IEMFEditValueProperty intervalModelProperty = EMFEditProperties.value(
                editingService.getEditingDomain(), MetricsPackage.Literals.METRIC_RETENTION_RULE__INTERVAL_HINT);

        context.bindValue(observeTextInterval, intervalModelProperty.observe(rule));

        // Edit the retention period.
        final ComboViewer cmbViewerTarget = new ComboViewer(cmpRules, SWT.NONE);
        final Combo cmbRetentionPeriod = cmbViewerTarget.getCombo();
        final GridData gridDataRetentionPeriod = new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1);
        gridDataRetentionPeriod.widthHint = 150;
        cmbRetentionPeriod.setLayoutData(gridDataRetentionPeriod);
        toolkit.paintBordersFor(cmbRetentionPeriod);

        final ImageHyperlink mghprlnkEditRetentionExpression = toolkit.createImageHyperlink(cmpRules, SWT.NONE);
        mghprlnkEditRetentionExpression.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1));
        mghprlnkEditRetentionExpression.addHyperlinkListener(new HyperlinkAdapter() {
            public void linkActivated(HyperlinkEvent e) {
                launchExpressionScreen(rule);
            }
        });
        toolkit.paintBordersFor(mghprlnkEditRetentionExpression);
        mghprlnkEditRetentionExpression.setText("Edit retention expression");

        final ImageHyperlink removeObjectHyperLink = toolkit.createImageHyperlink(cmpRules, SWT.NONE);
        removeObjectHyperLink.addHyperlinkListener(new HyperlinkAdapter() {
            public void linkActivated(HyperlinkEvent e) {

                final CompoundCommand cc = new CompoundCommand();

                if (rule.eIsSet(MetricsPackage.Literals.METRIC_RETENTION_RULE__RETENTION_EXPRESSION)) {
                    final Expression retentionExpression = rule.getRetentionExpression();
                    final Command deleteExpressionCommand = DeleteCommand.create(editingService.getEditingDomain(),
                            retentionExpression);
                    cc.append(deleteExpressionCommand);
                }
                final Command deleteRuleCommand = DeleteCommand.create(editingService.getEditingDomain(), rule);
                cc.append(deleteRuleCommand);
                editingService.getEditingDomain().getCommandStack().execute(cc);
            }
        });

        final GridData removeObjectGridData = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
        removeObjectGridData.widthHint = 18;
        removeObjectHyperLink.setLayoutData(removeObjectGridData);
        removeObjectHyperLink
                .setImage(ResourceManager.getPluginImage("org.eclipse.ui", "/icons/full/etool16/delete.gif"));
        toolkit.paintBordersFor(removeObjectHyperLink);
        removeObjectHyperLink.setText("");

        cmbViewerTarget.setContentProvider(new ArrayContentProvider());
        cmbViewerTarget.setLabelProvider(new LabelProvider());
        cmbViewerTarget.setInput(MetricRetentionPeriod.values());

        context.bindValue(cmbSelectionProperty.observe(cmbViewerTarget), retentionPeriodProperty.observe(rule));

    }

    public void injectData() {
        buildUI();

        retentionRulesResource = editingService.getData(MetricsPackage.Literals.METRIC_RETENTION_RULES);
        EList<EObject> contents = retentionRulesResource.getContents();
        if (contents.size() == 1) {
            rules = (MetricRetentionRules) contents.get(0);
            context = initDataBindings_();
        }
    }

    public Viewer getViewer() {
        return null;
    }

    public boolean isValid() {
        return true;
    }

    public Form getScreenForm() {
        return this.frmDataRetention;
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.netxforge.netxstudio.screens.AbstractScreenImpl#getScreenName()
     */
    @Override
    public String getScreenName() {
        return "Data Retention";
    }

    /**
     * Add a retention rule Action.
     * 
     * @author Christophe Bouhier
     */
    class NewRetentionRuleAction extends Action {

        public NewRetentionRuleAction(String text) {
            super(text);
        }

        public NewRetentionRuleAction(String text, ImageDescriptor image) {
            super(text, image);
            this.setToolTipText("Add retention rule");
        }

        @Override
        public void run() {

            final MetricRetentionRule rule = MetricsFactory.eINSTANCE.createMetricRetentionRule();
            rule.setIntervalHint(NonModelUtils.MINUTES_IN_AN_HOUR);
            rule.setPeriod(MetricRetentionPeriod.ALWAYS);
            rule.setName("Custom Rule");

            final Expression createExpression = LibraryFactory.eINSTANCE.createExpression();
            createExpression.setName("Custom Retention Rule");
            rule.setRetentionExpression(createExpression);

            final Resource expressionResource = editingService.getData(LibraryPackage.Literals.EXPRESSION);

            addUIRule(rule, context, true);

            final CompoundCommand cc = new CompoundCommand();

            final Command addExpressionCommand = AddCommand.create(editingService.getEditingDomain(),
                    expressionResource, null, createExpression);

            cc.append(addExpressionCommand);

            final Command addRuleCommand = AddCommand.create(editingService.getEditingDomain(), rules,
                    MetricsPackage.Literals.METRIC_RETENTION_RULES__METRIC_RETENTION_RULES, rule);
            cc.append(addRuleCommand);

            editingService.getEditingDomain().getCommandStack().execute(cc);

        }

    }

    /**
     * Reset to the fixed rules {@link Action}.
     * 
     * @see {@link Fixtures}
     * @author Christophe Bouhier
     */
    class ResetFixedRulesAction extends Action {

        public ResetFixedRulesAction(String text) {
            super(text);
        }

        public ResetFixedRulesAction(String text, ImageDescriptor image) {
            super(text, image);
            this.setToolTipText("Reset to default fixed rules");
        }

        @Override
        public void run() {

            boolean openConfirm = MessageDialog.openConfirm(Retention.this.getShell(), "Confirm reset",
                    "Please confirm the reset to the default retention rules.\n This will also clear the custom retention rules. ");

            if (openConfirm) {
                ICDOData cdoData = getCDOEditingService().getCDOData();
                cdoData.getTransaction();
                cdoData.setDoGetResourceFromOwnTransaction(false);
                // Data change, not through an editing domain, so should commit
                // explicitly.
                fixtures.setDataProvider(cdoData);
                fixtures.reloadRetentionRules();

                // Will close our one of transaction.
                cdoData.commitTransactionThenClose();
                cdoData.setDoGetResourceFromOwnTransaction(true);

                // We need to reload the screen here, as it won't be noticed
                // otherwise, and databinding will keep references to
                // old objects.

                if (retentionRulesResource instanceof CDOResource) {
                    ((CDOResource) retentionRulesResource).cdoView().getSession().refresh();
                }

                final EList<EObject> contents = retentionRulesResource.getContents();

                if (contents.size() == 1) {
                    rules = (MetricRetentionRules) contents.get(0);
                    if (context != null) {
                        context.dispose();
                    }
                    context = initDataBindings_();
                }
                updateUI();
            }
        }
    }

    /**
     * layout the form and composites as we have disposed and recreated
     * controls.
     */
    private void updateUI() {
        sctnRules.layout();
        sctnCustomRules.layout();
        frmDataRetention.layout();
    }
}