fr.esrf.icat.manager.core.part.DataPart.java Source code

Java tutorial

Introduction

Here is the source code for fr.esrf.icat.manager.core.part.DataPart.java

Source

package fr.esrf.icat.manager.core.part;

/*
 * #%L
 * icat-manager :: core
 * %%
 * Copyright (C) 2014 ESRF - The European Synchrotron
 * %%
 * 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.
 * #L%
 */

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.Path;
import org.eclipse.e4.ui.di.PersistState;
import org.eclipse.e4.ui.model.application.ui.basic.MPart;
import org.eclipse.e4.ui.workbench.modeling.ESelectionService;
import org.eclipse.e4.ui.workbench.swt.modeling.EMenuService;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TableViewerColumn;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.BusyIndicator;
import org.eclipse.swt.custom.CCombo;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.layout.RowData;
import org.eclipse.swt.layout.RowLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.Text;
import org.osgi.framework.Bundle;
import org.osgi.framework.FrameworkUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import fr.esrf.icat.client.ICATClientException;
import fr.esrf.icat.client.wrapper.WrappedEntityBean;
import fr.esrf.icat.manager.core.ICATDataService;
import fr.esrf.icat.manager.core.icatserver.DataColumnEditingSupport;
import fr.esrf.icat.manager.core.icatserver.DataColumnLabelProvider;
import fr.esrf.icat.manager.core.icatserver.EntityContentProvider;
import fr.esrf.icat.manager.core.icatserver.ICATEntity;

@SuppressWarnings("restriction")
public class DataPart {

    public static final String ICAT_MANAGER_MAINSTACK = "icat-manager.core.partstack.mainstack";
    public static final String DATA_PART_ELEMENT_HEADER = "icat-manager.core.part.data";
    public static final String DATA_PART_DESCRIPTOR = "icat-manager.core.partdescriptor.datapart";
    public static final String IN_PLACE_EDITING_PROPERTY_KEY = "inPlaceEditing";

    private final static Logger LOG = LoggerFactory.getLogger(DataPart.class);

    private final static File configfile = new File(System.getProperty("user.home"), ".icat_column_orders");

    private final static Properties columnProps;

    private final static Image IMAGE_UP;
    private final static Image IMAGE_DOWN;
    private final static Image IMAGE_NEXT;
    private final static Image IMAGE_PREVIOUS;
    private final static Image IMAGE_FIRST;
    private final static Image IMAGE_CLEAR;

    static {
        Bundle bundle = FrameworkUtil.getBundle(DataPart.class);
        URL url = FileLocator.find(bundle, new Path("icons/arrow_up.png"), null);
        IMAGE_UP = ImageDescriptor.createFromURL(url).createImage();
        url = FileLocator.find(bundle, new Path("icons/arrow_down.png"), null);
        IMAGE_DOWN = ImageDescriptor.createFromURL(url).createImage();
        url = FileLocator.find(bundle, new Path("icons/next.gif"), null);
        IMAGE_NEXT = ImageDescriptor.createFromURL(url).createImage();
        url = FileLocator.find(bundle, new Path("icons/prev.gif"), null);
        IMAGE_PREVIOUS = ImageDescriptor.createFromURL(url).createImage();
        url = FileLocator.find(bundle, new Path("icons/first.png"), null);
        IMAGE_FIRST = ImageDescriptor.createFromURL(url).createImage();
        url = FileLocator.find(bundle, new Path("icons/clear_co.gif"), null);
        IMAGE_CLEAR = ImageDescriptor.createFromURL(url).createImage();
        columnProps = new Properties();
        LOG.debug("Reading column order file at: " + configfile.getAbsolutePath());
        if (configfile.exists()) {
            FileInputStream inStream = null;
            try {
                inStream = new FileInputStream(configfile);
                columnProps.load(inStream);
            } catch (IOException e) {
                LOG.error("Error reading column file " + configfile.getAbsolutePath(), e);
            } finally {
                if (inStream != null) {
                    try {
                        inStream.close();
                    } catch (Exception e) {
                        LOG.warn("Error closing file " + configfile.getAbsolutePath(), e);
                    }
                }
            }
        }

    }

    private TableViewer viewer;
    private ICATEntity entity;
    private Label paginationLabel;
    private EntityContentProvider contentProvider;
    private Button previousBtn;
    private Button nextBtn;
    private Button firstBtn;
    private Text filterText;
    private Button clearFilter;
    private ISelectionChangedListener selectionListener;

    @PostConstruct
    public void postConstruct(final Composite parent, final EMenuService menuService, final MPart part,
            final ESelectionService selectionService) {

        final GridLayout pageLayout = new GridLayout();
        pageLayout.marginWidth = 0;
        pageLayout.marginHeight = 0;
        pageLayout.verticalSpacing = 0;
        parent.setLayout(pageLayout);

        Composite top = new Composite(parent, SWT.NONE);
        top.setLayoutData(new GridData(SWT.CENTER, SWT.TOP, true, false));
        final RowLayout barLayout = new RowLayout();
        barLayout.center = true;
        barLayout.pack = true;
        barLayout.spacing = 5;
        top.setLayout(barLayout);

        paginationLabel = new Label(top, SWT.NONE);

        firstBtn = new Button(top, SWT.PUSH);
        firstBtn.setText("First");
        firstBtn.setImage(IMAGE_FIRST);

        previousBtn = new Button(top, SWT.PUSH);
        previousBtn.setText("Previous");
        previousBtn.setImage(IMAGE_PREVIOUS);

        nextBtn = new Button(top, SWT.PUSH);
        nextBtn.setText("Next");
        nextBtn.setImage(IMAGE_NEXT);

        new Label(top, SWT.NONE).setText("Page size:");
        final CCombo pageSizeCombo = new CCombo(top, SWT.DROP_DOWN | SWT.BORDER);
        pageSizeCombo.setLayoutData(new RowData(SWT.DEFAULT, SWT.DEFAULT));
        pageSizeCombo.setItems(new String[] { "50", "100", "150", "200" });
        pageSizeCombo.select(0);
        pageSizeCombo.addVerifyListener(new VerifyListener() {
            @Override
            public void verifyText(VerifyEvent e) {
                e.doit = e.character == SWT.BS || e.character == SWT.DEL || e.text.matches("\\d+");
            }
        });
        new Label(top, SWT.NONE).setText("Filter:");
        filterText = new Text(top, SWT.BORDER);
        filterText.setLayoutData(new RowData(400, SWT.DEFAULT));
        filterText.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
                contentProvider.setFilterString(filterText.getText());
                refresh();
            }
        });

        clearFilter = new Button(top, SWT.PUSH);
        clearFilter.setImage(IMAGE_CLEAR);
        clearFilter.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                filterText.setText("");
                contentProvider.setFilterString(null);
                refresh();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.BORDER);
        contentProvider = new EntityContentProvider();
        viewer.setContentProvider(contentProvider);
        entity = (ICATEntity) part.getTransientData().get(ICATEntity.ENTITY_CONTEXT_KEY);
        final String initialFilter = (String) part.getTransientData().get(ICATEntity.ENTITY_FILTER_KEY);
        if (null != initialFilter) {
            contentProvider.setFilterString(initialFilter);
            filterText.setText(initialFilter);
        }

        pageSizeCombo.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                contentProvider.setPageSize(Integer.parseInt(pageSizeCombo.getText()));
                refresh();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
                String text = pageSizeCombo.getText();
                if (null == text || text.isEmpty()) {
                    pageSizeCombo.select(0);
                    text = pageSizeCombo.getText();
                }
                contentProvider.setPageSize(Integer.parseInt(text));
                refresh();
            }
        });
        firstBtn.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                contentProvider.gotToFirst();
                refresh();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
        previousBtn.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                contentProvider.previousPage();
                refresh();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });
        nextBtn.addSelectionListener(new SelectionListener() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                contentProvider.nextPage();
                refresh();
            }

            @Override
            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        viewer.setData(IN_PLACE_EDITING_PROPERTY_KEY, Boolean.FALSE);
        createColumns(parent);
        final Table table = viewer.getTable();
        table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
        table.setHeaderVisible(true);
        table.setLinesVisible(true);
        viewer.setInput(entity);
        paginationLabel.setText(contentProvider.getPaginationLabelText());
        nextBtn.setEnabled(!contentProvider.isLastPage());
        previousBtn.setEnabled(!contentProvider.isFirstPage());
        // needed to have the selection in the service ...
        selectionListener = new ISelectionChangedListener() {
            @Override
            public void selectionChanged(SelectionChangedEvent event) {
                IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
                selectionService.setSelection(selection.toList());
            }
        };
        viewer.addSelectionChangedListener(selectionListener);
        // context menu
        menuService.registerContextMenu(viewer.getControl(), "icat-manager.core.popupmenu.entity");
        // reset column order if saved
        try {
            final String pState = columnProps.getProperty(getPersistenceID());
            if (pState != null) {
                String[] idxS = pState.split(",");
                if (idxS.length == viewer.getTable().getColumnCount()) {
                    int[] indices = new int[idxS.length];
                    for (int i = 0; i < indices.length; i++) {
                        indices[i] = Integer.parseInt(idxS[i]);
                    }
                    viewer.getTable().setColumnOrder(indices);
                } else {
                    LOG.warn("DataPart viewer has {} columns while the saved state has {}, removing configuration",
                            viewer.getTable().getColumnCount(), idxS.length);
                    columnProps.remove(getPersistenceID());
                }
            }
        } catch (Exception e) {
            LOG.error("Error while setting persisted column back", e);
        }
        // final show
        table.pack();
        refresh();
    }

    private void createColumns(final Composite parent) {
        WrappedEntityBean data = null;
        try {
            data = ICATDataService.getInstance().getClient(entity.getServer()).create(entity.getEntityName());
        } catch (ICATClientException e) {
            LOG.error("Error creating " + entity.getEntityName(), e);
            return;
        }
        List<String> fields = new LinkedList<>();
        fields.addAll(data.getMutableFields());
        //      fields.addAll(data.getAssociationFields());
        fields.addAll(data.getImmutableFields());

        for (final String field : fields) {
            TableViewerColumn column = new TableViewerColumn(viewer, SWT.NONE);
            final TableColumn currentColumn = column.getColumn();
            currentColumn.setText(field);
            currentColumn.setWidth(100);
            currentColumn.setResizable(true);
            currentColumn.setMoveable(true);
            if (field.equals(contentProvider.getSortingField())) {
                switch (contentProvider.getSortingOrder()) {
                case SWT.UP:
                    currentColumn.setImage(IMAGE_UP);
                    break;
                case SWT.DOWN:
                    currentColumn.setImage(IMAGE_DOWN);
                    break;
                default:
                    currentColumn.setImage(null);
                    break;
                }
            } else {
                currentColumn.setImage(null);
            }

            column.getColumn().addSelectionListener(new SelectionListener() {
                @Override
                public void widgetSelected(SelectionEvent e) {
                    final TableColumn col = (TableColumn) e.getSource();
                    final String sortingField = col.getText();
                    DataPart.LOG.debug("Selected column " + sortingField);
                    contentProvider.toggleSortingField(field);
                    for (TableColumn column : viewer.getTable().getColumns()) {
                        if (column.getText().equals(sortingField)) {
                            switch (contentProvider.getSortingOrder()) {
                            case SWT.UP:
                                column.setImage(IMAGE_UP);
                                break;
                            case SWT.DOWN:
                                column.setImage(IMAGE_DOWN);
                                break;
                            default:
                                column.setImage(null);
                                break;
                            }
                        } else {
                            column.setImage(null);
                        }
                    }
                    refresh();
                }

                @Override
                public void widgetDefaultSelected(SelectionEvent e) {
                }

            });

            column.setLabelProvider(new DataColumnLabelProvider(field));
            if (data.isMutable(field)) {
                column.setEditingSupport(
                        new DataColumnEditingSupport(viewer, field, data.getReturnType(field), entity.getServer()));
            }
        }
    }

    public ICATEntity getEntity() {
        return entity;
    }

    public void refresh() {
        BusyIndicator.showWhile(null, new Runnable() {
            @Override
            public void run() {
                try {
                    contentProvider.fetch(entity);
                } catch (ICATClientException e) {
                    MessageDialog.openError(null, "Error", "Error feetching data:\n" + e.getMessage());
                }
                Display.getDefault().asyncExec(new Runnable() {
                    @Override
                    public void run() {
                        viewer.refresh();
                        refreshSelection();
                        paginationLabel.setText(contentProvider.getPaginationLabelText());
                        firstBtn.setEnabled(!contentProvider.isFirstPage());
                        previousBtn.setEnabled(!contentProvider.isFirstPage());
                        nextBtn.setEnabled(!contentProvider.isLastPage());
                        clearFilter.setEnabled(!filterText.getText().isEmpty());
                        // reset to 1st row
                        viewer.getTable().setTopIndex(0);
                        // this has to be called to avoid the label not resizing properly
                        paginationLabel.getParent().getParent().layout();
                    }
                });
            }
        });
    }

    public void toggleInPLaceEditing() {
        final Object value = viewer.getData(IN_PLACE_EDITING_PROPERTY_KEY);
        if (Boolean.FALSE.equals(value)) {
            viewer.setData(IN_PLACE_EDITING_PROPERTY_KEY, Boolean.TRUE);
        } else {
            viewer.setData(IN_PLACE_EDITING_PROPERTY_KEY, Boolean.FALSE);
        }
    }

    public void toggleNameSorting() {
        contentProvider.toggleNameSorting();
        refresh();
    }

    public void toggleKeepCount() {
        contentProvider.toggleKeepCount();
        refresh();
    }

    public void refreshSelection() {
        // needed to refresh potentially modified objects in the selection
        selectionListener.selectionChanged(null);
    }

    public void updateFilter(final String newFilter) {
        contentProvider.setFilterString(newFilter);
        filterText.setText(newFilter);
        refresh();
    }

    @PersistState
    public void saveColumnOrder(final MPart mPart) {
        columnProps.put(getPersistenceID(), StringUtils.join(viewer.getTable().getColumnOrder(), ','));
        //      updateConfig();
    }

    private String getPersistenceID() {
        return entity.getServer().getServerURL() + ":" + entity.getEntityName();
    }

    public static void updateConfig() {
        LOG.debug("Writing column order file at: " + configfile.getAbsolutePath());
        FileOutputStream outStream = null;
        try {
            outStream = new FileOutputStream(configfile);
            columnProps.store(outStream, null);
        } catch (IOException e) {
            LOG.error("Error writing column file " + configfile.getAbsolutePath(), e);
        } finally {
            if (outStream != null) {
                try {
                    outStream.close();
                } catch (Exception e) {
                    LOG.warn("Error closing file " + configfile.getAbsolutePath(), e);
                }
            }
        }
    }
}