org.csstudio.diirt.util.preferences.DataSourcesPreferencePage.java Source code

Java tutorial

Introduction

Here is the source code for org.csstudio.diirt.util.preferences.DataSourcesPreferencePage.java

Source

/**
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * Copyright (C) 2016 European Spallation Source ERIC.
 * 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
 */
package org.csstudio.diirt.util.preferences;

import static org.csstudio.diirt.util.core.preferences.DIIRTPreferences.PREF_CONFIGURATION_DIRECTORY;
import static org.csstudio.diirt.util.core.preferences.pojo.ChannelAccess.CA_DIR;
import static org.csstudio.diirt.util.core.preferences.pojo.ChannelAccess.CA_FILE;
import static org.csstudio.diirt.util.core.preferences.pojo.DataSources.DATASOURCES_DIR;
import static org.csstudio.diirt.util.core.preferences.pojo.DataSources.DATASOURCES_FILE;
import static org.csstudio.diirt.util.core.preferences.pojo.DataSources.PREF_DEFAULT;
import static org.csstudio.diirt.util.core.preferences.pojo.DataSources.PREF_DELIMITER;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;

import org.apache.commons.lang3.StringUtils;
import org.csstudio.diirt.util.core.preferences.DIIRTPreferences;
import org.csstudio.diirt.util.core.preferences.pojo.CompositeDataSource.DataSourceProtocol;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.preference.ComboFieldEditor;
import org.eclipse.jface.preference.DirectoryFieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.StringFieldEditor;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.program.Program;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Group;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.wb.swt.SWTResourceManager;

/**
 * @author Claudio Rosati, European Spallation Source ERIC
 * @version 1.0.0 3 Nov 2016
 */
public class DataSourcesPreferencePage extends BasePreferencePage {

    public static final String[][] AVAILABLE_DATA_SOURCES = { { "None", DataSourceProtocol.none.name() },
            { "Channel Access", DataSourceProtocol.ca.name() }, { "File", DataSourceProtocol.file.name() },
            { "Local", DataSourceProtocol.loc.name() }, { "PV Access", DataSourceProtocol.pva.name() },
            { "Simulation", DataSourceProtocol.sim.name() }, { "System", DataSourceProtocol.sys.name() }, };

    private static String lastPath = System.getProperty("user.home");

    private Composite cdsInnerGroup;
    private Group cdsOuterGroup;
    private DirectoryFieldEditor directoryEditor;
    private ComboFieldEditor defaultDataSourceEditor;
    private StringFieldEditor delimiterEditor;
    private Image fileImage = null;
    private Image folderImage = null;
    private TreeViewer treeViewer;
    private Image xmlImage = null;

    /**
     * Create the preference page.
     */
    public DataSourcesPreferencePage() {
        setDescription(Messages.DSPP_description);
        setTitle(Messages.DSPP_title);
    }

    /**
     * Create contents of the preference page.
     *
     * @param parent
     */
    @Override
    public Control createContents(Composite parent) {

        IPreferenceStore store = getPreferenceStore();
        Composite container = new Composite(parent, SWT.NULL);

        container.setLayoutData(new GridData(GridData.FILL_BOTH));
        container.setLayout(new GridLayout());

        directoryEditor = new ConfigurationDirectoryFieldEditor(PREF_CONFIGURATION_DIRECTORY,
                Messages.DSPP_directoryCaption_text, container, store);

        directoryEditor.setChangeButtonText(Messages.DSPP_browseButton_text);
        directoryEditor.getTextControl(container).setEditable(false);
        directoryEditor.getTextControl(container)
                .setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_BACKGROUND));
        directoryEditor.getTextControl(container)
                .setForeground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_FOREGROUND));

        addField(directoryEditor, container, false, () -> store.getString(PREF_CONFIGURATION_DIRECTORY));

        Composite treeComposite = new Composite(container, SWT.NONE);
        GridData gd_treeComposite = new GridData(SWT.FILL, SWT.FILL, true, true, 3, 1);

        gd_treeComposite.heightHint = -14;
        treeComposite.setLayoutData(gd_treeComposite);
        treeComposite.setLayout(new GridLayout());

        treeViewer = new TreeViewer(treeComposite);

        GridData gridData = new GridData(GridData.FILL_BOTH);

        gridData.heightHint = -16;
        treeViewer.getTree().setLayoutData(gridData);
        treeViewer.setLabelProvider(new FileTreeLabelProvider());
        treeViewer.setContentProvider(new FileTreeContentProvider());
        treeViewer.addDoubleClickListener(new IDoubleClickListener() {
            @Override
            public void doubleClick(DoubleClickEvent event) {

                TreeSelection selection = (TreeSelection) event.getSelection();
                File fileSelection = (File) selection.getFirstElement();

                try {
                    if (fileSelection.isFile()) {
                        clearWarning();
                        Program.launch(fileSelection.getCanonicalPath());
                    }
                } catch (IOException ex) {
                    notifyWarning(NLS.bind(Messages.DSPP_resolveMessage, ex.getMessage()));
                }

            }
        });

        cdsOuterGroup = new Group(container, SWT.NONE);

        cdsOuterGroup.setText(Messages.DSPP_cdsGroup_text);
        cdsOuterGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false, 3, 1));
        cdsOuterGroup.setLayout(new GridLayout());

        cdsInnerGroup = new Composite(cdsOuterGroup, SWT.DOUBLE_BUFFERED);

        cdsInnerGroup.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1));
        cdsInnerGroup.setLayout(new GridLayout());

        defaultDataSourceEditor = new ComboFieldEditor(PREF_DEFAULT, Messages.DSPP_defaultDataSourceCaption_text,
                AVAILABLE_DATA_SOURCES, cdsInnerGroup);

        addField(defaultDataSourceEditor, cdsInnerGroup, true, () -> store.getDefaultString(PREF_DEFAULT),
                () -> store.getString(PREF_DEFAULT));

        delimiterEditor = new StringFieldEditor(PREF_DELIMITER, Messages.DSPP_delimiterCaption_text, cdsInnerGroup);

        delimiterEditor.getTextControl(cdsInnerGroup)
                .setLayoutData(new GridData(SWT.FILL, SWT.CENTER, false, false, 1, 1));

        addField(delimiterEditor, cdsInnerGroup, true, () -> store.getDefaultString(PREF_DELIMITER),
                () -> store.getString(PREF_DELIMITER));

        initializeValues(store);

        return container;

    }

    @Override
    protected void contributeButtons(Composite parent) {

        ((GridLayout) parent.getLayout()).numColumns++;

        Button button = new Button(parent, SWT.PUSH);

        button.setText(Messages.DSPP_exportButton_text);
        button.addSelectionListener(new SelectionListener() {

            @Override
            public void widgetSelected(SelectionEvent e) {
                exportConfiguration();
            }

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

        });

    }

    @Override
    protected String initializeValues(IPreferenceStore store) {

        String confDir = super.initializeValues(store);

        lastPath = confDir;

        directoryEditor.setStringValue(confDir);
        directoryEditor.setFilterPath(new File(confDir).getParentFile());

        if (StringUtils.isNotBlank(confDir) && Files.exists(Paths.get(confDir))) {
            treeViewer.setInput(confDir);
        }

        return confDir;

    }

    /**
     * Ask the user for a folder where to save the DIIRT configuration files.
     */
    private void exportConfiguration() {

        DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.SHEET);

        dialog.setText(Messages.DSPP_exportDialog_text);
        dialog.setMessage(Messages.DSPP_exportDialog_message);

        if (lastPath != null) {
            dialog.setFilterPath(lastPath);
        }

        String choice = dialog.open();

        if (choice != null) {

            try {
                choice = DIIRTPreferences.resolvePlatformPath(choice.trim());
            } catch (Exception ex) {
                notifyWarning(NLS.bind(Messages.DSPP_resolveMessage, choice));
                return;
            }

            lastPath = choice;

            Path parentPath = Paths.get(choice);
            Path dsPath = Paths.get(parentPath.toString(), DATASOURCES_DIR);
            Path dsFile = Paths.get(dsPath.toString(), DATASOURCES_FILE);
            Path caPath = Paths.get(dsPath.toString(), CA_DIR);
            Path caFile = Paths.get(caPath.toString(), CA_FILE);
            Path[] content = new Path[] { dsPath, dsFile, caPath, caFile };

            if (Arrays.asList(content).stream().anyMatch(p -> Files.exists(p, LinkOption.NOFOLLOW_LINKS))) {

                boolean overwrite = MessageDialog.openConfirm(getShell(), Messages.DSPP_exportFilesExist_title,
                        NLS.bind(Messages.DSPP_exportFilesExist_message, choice));

                if (!overwrite) {
                    return;
                }

            }

            try {
                DIIRTPreferences.get().toFiles(parentPath.toFile());
                notifyInformation(NLS.bind(Messages.DSPP_exportSuccessful_message, choice));
            } catch (IOException ex) {
                notifyWarning(NLS.bind(Messages.DSPP_exportFailed_message, choice, ex.getMessage()));
            }

        }

    }

    private Image getFileImage() {

        if (fileImage == null) {
            fileImage = AbstractUIPlugin
                    .imageDescriptorFromPlugin("org.csstudio.diirt.util.preferences", "icons/file.png")
                    .createImage();
        }

        return fileImage;

    }

    private Image getFolderImage() {

        if (folderImage == null) {
            folderImage = AbstractUIPlugin
                    .imageDescriptorFromPlugin("org.csstudio.diirt.util.preferences", "icons/open.png")
                    .createImage();
        }

        return folderImage;

    }

    private Image getXMLImage() {

        if (xmlImage == null) {
            xmlImage = AbstractUIPlugin
                    .imageDescriptorFromPlugin("org.csstudio.diirt.util.preferences", "icons/xml.gif")
                    .createImage();
        }

        return xmlImage;

    }

    /**
     * Editor for the configuration directory.
     */
    private class ConfigurationDirectoryFieldEditor extends DirectoryFieldEditor {

        private final IPreferenceStore store;

        protected ConfigurationDirectoryFieldEditor(String name, String labelText, Composite parent,
                IPreferenceStore store) {

            super(name, labelText, parent);

            this.store = store;

        }

        @Override
        protected String changePressed() {

            DirectoryDialog dialog = new DirectoryDialog(getShell(), SWT.SHEET);

            dialog.setText(Messages.DSPP_browseDialog_text);
            dialog.setMessage(Messages.DSPP_browseDialog_message);

            if (lastPath != null) {
                dialog.setFilterPath(lastPath);
            }

            String choice = dialog.open();

            if (choice != null) {

                try {
                    choice = DIIRTPreferences.resolvePlatformPath(choice.trim());
                } catch (Exception ex) {
                    notifyWarning(NLS.bind(Messages.DSPP_resolveMessage, choice));
                    return null;
                }

                lastPath = choice;

                if (verifyAndNotifyWarning(choice)) {
                    DIIRTPreferences.get().fromFiles(new File(choice));
                    DIIRTPreferencesPlugin.copyDataSources(DIIRTPreferences.get(), store);
                    DIIRTPreferencesPlugin.copyChannelAccess(DIIRTPreferences.get(), store);
                    reloadEditorsForAllPages();
                }

                treeViewer.setInput(choice);
                treeViewer.refresh();

            }

            return choice;

        }

    }

    /**
     * This class provides the content for the tree in FileTree.
     */
    private class FileTreeContentProvider implements ITreeContentProvider {

        File root = new File("root");

        @Override
        public void dispose() {
        }

        /**
         * Gets the children of the specified file object.
         *
         * @param file The parent file object.
         * @return The files and sub-directories in this directory.
         */
        @Override
        public Object[] getChildren(Object file) {
            return ((File) file).listFiles(f -> !f.isHidden());
        }

        /**
         * Gets the root element(s) of the tree.
         *
         * @param arg0 The input data (unused).
         * @return The files and sub-directories in the root.
         */
        @Override
        public Object[] getElements(Object arg0) {
            return root.listFiles(f -> !f.isHidden());
        }

        /**
         * Gets the parent of the specified file.
         *
         * @param file The file object.
         * @return The file's parent.
         */
        @Override
        public Object getParent(Object file) {
            return ((File) file).getParentFile();
        }

        /**
         * Returns whether the passed file object has children.
         *
         * @param file The parent file object.
         * @return Whether the parent has children.
         */
        @Override
        public boolean hasChildren(Object file) {

            Object[] obj = getChildren(file);

            return (obj == null) ? false : obj.length > 0;

        }

        /**
         * Called when the input changes.
         *
         * @param viewer The viewer.
         * @param oldValue The old input.
         * @param newValue The new input.
         */
        @Override
        public void inputChanged(Viewer viewer, Object oldValue, Object newValue) {
            try {
                root = new File((String) newValue);
            } catch (Exception e) {
                root = new File(System.getProperty("user.home"));
            }
        }

    } //  class FileTreeContentProvider

    /**
     * This class provides the labels for the file tree.
     */
    private class FileTreeLabelProvider implements ILabelProvider {

        @Override
        public void addListener(ILabelProviderListener listener) {
        }

        @Override
        public void dispose() {
        }

        @Override
        public Image getImage(Object element) {

            if (element == null || !(element instanceof File)) {
                return null;
            } else {

                File file = (File) element;

                if (file.isFile()) {
                    if (file.getName().toLowerCase().endsWith(".xml")) {
                        return getXMLImage();
                    } else {
                        return getFileImage();
                    }
                } else {
                    return getFolderImage();
                }

            }

        }

        /**
         * Gets the text to display for a node in the tree.
         *
         * @param node The node.
         * @return The string representation of the given node.
         */
        @Override
        public String getText(Object node) {

            // Get the name of the file
            String text = ((File) node).getName();

            // If name is blank, get the path
            if (text.length() == 0) {
                text = ((File) node).getPath();
            }

            return text;

        }

        /**
         * Returns whether changes to the specified property on the specified
         * element would affect the label for the element.
         *
         * @param element The element.
         * @param property The property (name).
         * @return boolean
         */
        @Override
        public boolean isLabelProperty(Object element, String property) {
            return false;
        }

        @Override
        public void removeListener(ILabelProviderListener arg0) {
        }

    } //  class FileTreeLabelProvider

}