eu.geclipse.ui.widgets.GridProjectStructureComposite.java Source code

Java tutorial

Introduction

Here is the source code for eu.geclipse.ui.widgets.GridProjectStructureComposite.java

Source

/*****************************************************************************
 * Copyright (c) 2006, 2007 g-Eclipse Consortium 
 * 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
 *
 * Initial development of the original code was made for the
 * g-Eclipse project founded by European Union
 * project number: FP6-IST-034327  http://www.geclipse.eu/
 *
 * Contributors:
 *    Mathias Stuempert - initial API and implementation
 *****************************************************************************/
package eu.geclipse.ui.widgets;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.CheckStateChangedEvent;
import org.eclipse.jface.viewers.CheckboxTableViewer;
import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.ide.IDE;
import org.osgi.framework.Bundle;

import eu.geclipse.core.ExtensionManager;
import eu.geclipse.core.Extensions;
import eu.geclipse.core.model.GridModel;
import eu.geclipse.core.model.IGridContainer;
import eu.geclipse.core.model.IGridElement;
import eu.geclipse.core.model.IGridProject;
import eu.geclipse.core.model.IGridResource;
import eu.geclipse.core.model.IVirtualOrganization;
import eu.geclipse.ui.internal.Activator;
import eu.geclipse.ui.providers.ArrayTableLabelProvider;

public class GridProjectStructureComposite extends Composite {

    private static final int LABEL_COLUMN = 1;

    protected TableEditor editor;

    private Tree previewTree;

    private TreeItem rootItem;

    private Table table;

    private CheckboxTableViewer viewer;

    private Hashtable<String, Class<?>> creatorTargets;

    private Hashtable<String, Class<?>> elementClasses;

    public GridProjectStructureComposite(final Composite parent, final int style) {

        super(parent, style);

        GridData gData;

        setLayout(new GridLayout(3, false));
        gData = new GridData(GridData.FILL_BOTH);
        gData.grabExcessHorizontalSpace = true;
        gData.grabExcessVerticalSpace = true;
        setLayoutData(gData);

        Composite previewComp = new Composite(this, SWT.NONE);
        previewComp.setLayout(new GridLayout(1, false));
        gData = new GridData(GridData.FILL_VERTICAL);
        gData.grabExcessVerticalSpace = true;
        previewComp.setLayoutData(gData);

        Label previewLabel = new Label(previewComp, SWT.NONE);
        previewLabel.setText("Preview:");
        gData = new GridData();
        previewLabel.setLayoutData(gData);

        this.previewTree = new Tree(previewComp, SWT.BORDER);
        gData = new GridData(GridData.FILL_VERTICAL);
        gData.grabExcessVerticalSpace = true;
        gData.widthHint = 150;
        this.previewTree.setLayoutData(gData);

        this.rootItem = new TreeItem(this.previewTree, SWT.NONE);
        this.rootItem.setText("My Cloud/Grid Project");
        this.rootItem
                .setImage(PlatformUI.getWorkbench().getSharedImages().getImage(IDE.SharedImages.IMG_OBJ_PROJECT));

        Composite settingsComp = new Composite(this, SWT.NONE);
        settingsComp.setLayout(new GridLayout(1, false));
        gData = new GridData(GridData.FILL_BOTH);
        gData.grabExcessVerticalSpace = true;
        gData.grabExcessHorizontalSpace = true;
        settingsComp.setLayoutData(gData);

        Label settingsLabel = new Label(settingsComp, SWT.NONE);
        settingsLabel.setText("Available Folders:");
        gData = new GridData();
        settingsLabel.setLayoutData(gData);

        this.table = new Table(settingsComp,
                SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.CHECK | SWT.FULL_SELECTION);
        this.table.setHeaderVisible(true);
        gData = new GridData(GridData.FILL_BOTH);
        gData.grabExcessHorizontalSpace = true;
        gData.grabExcessVerticalSpace = true;
        this.table.setLayoutData(gData);

        TableColumn nameColumn = new TableColumn(this.table, SWT.NONE);
        nameColumn.setText("Folder ID");
        nameColumn.setWidth(150);
        TableColumn labelColumn = new TableColumn(this.table, SWT.None);
        labelColumn.setText("Folder Label");
        labelColumn.setWidth(100);

        this.editor = new TableEditor(this.table);
        this.editor.grabHorizontal = true;
        this.editor.minimumWidth = 100;
        this.editor.horizontalAlignment = SWT.LEFT;

        this.table.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                startEditing((TableItem) e.item);
            }
        });

        this.viewer = new CheckboxTableViewer(this.table);
        this.viewer.setContentProvider(new ArrayContentProvider());
        this.viewer.setLabelProvider(new ArrayTableLabelProvider());

        this.viewer.addCheckStateListener(new ICheckStateListener() {
            public void checkStateChanged(final CheckStateChangedEvent e) {
                updateTree();
            }
        });

        Composite buttonComp = new Composite(settingsComp, SWT.NONE);
        GridLayout buttonLayout = new GridLayout(3, false);
        buttonLayout.marginHeight = 0;
        buttonLayout.marginWidth = 0;
        buttonComp.setLayout(buttonLayout);
        buttonComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));

        Button selectAllButton = new Button(buttonComp, SWT.NONE);
        selectAllButton.setText("Select All");
        selectAllButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
        selectAllButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                selectAll();
            }
        });

        Button deselectAllButton = new Button(buttonComp, SWT.NONE);
        deselectAllButton.setText("Deselect All");
        deselectAllButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
        deselectAllButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                deselectAll();
            }
        });

        Button invertButton = new Button(buttonComp, SWT.NONE);
        invertButton.setText("Invert Selection");
        invertButton.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, false, false));
        invertButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(final SelectionEvent e) {
                invertSelection();
            }
        });

        loadProjectFolders();
        initialize();
        updateTree();

    }

    public Hashtable<String, String> getProjectFolders() {

        Hashtable<String, String> result = new Hashtable<String, String>();

        List<String[]> input = (List<String[]>) this.viewer.getInput();
        TableItem[] items = this.table.getItems();

        for (int i = 0; i < items.length; i++) {
            if (items[i].getChecked()) {
                String id = input.get(i)[2];
                String label = items[i].getText(1);
                result.put(id, label);
            }
        }

        return result;

    }

    public void performDefaults() {
        loadProjectFolders();
        updateTree();
    }

    public void setProject(final IProject project) throws CoreException {

        Hashtable<String, String> projectFolders = new Hashtable<String, String>();
        IGridProject gridProject = (IGridProject) GridModel.getRoot().findElement(project);

        IResource[] members = project.members();
        for (IResource resource : members) {
            String name = resource.getName();
            IGridElement element = gridProject.findChild(name);
            if ((element != null) && (element instanceof IGridContainer)) {
                String id = gridProject.getProjectFolderID((IGridContainer) element);
                if (id != null) {
                    projectFolders.put(id, name);
                }
            }
        }

        setProjectFolders(projectFolders);

    }

    public void setProjectFolders(final Hashtable<String, String> projectFolders) {

        List<String[]> input = (List<String[]>) this.viewer.getInput();
        TableItem[] items = this.table.getItems();

        for (int i = 0; i < input.size(); i++) {
            String id = input.get(i)[2];
            String name = projectFolders.get(id);
            if (name != null) {
                items[i].setChecked(true);
                items[i].setText(1, name);
            } else {
                items[i].setChecked(false);
            }
        }

        updateTree();

    }

    protected void selectAll() {
        this.viewer.setAllChecked(true);
        updateTree();
    }

    protected void deselectAll() {
        this.viewer.setAllChecked(false);
        updateTree();
    }

    protected void invertSelection() {
        List<String[]> elements = (List<String[]>) this.viewer.getInput();
        for (String[] element : elements) {
            boolean state = this.viewer.getChecked(element);
            this.viewer.setChecked(element, !state);
        }
        updateTree();
    }

    protected void updateTree() {

        this.rootItem.removeAll();

        Object[] checked = this.viewer.getCheckedElements();
        TableItem[] data = this.table.getItems();
        TreeItem[] treeItems = new TreeItem[checked.length];
        int index = 0;
        for (TableItem row : data) {
            if (row.getChecked()) {
                treeItems[index] = new TreeItem(this.rootItem, SWT.NONE);
                treeItems[index].setText(row.getText(LABEL_COLUMN));
                treeItems[index].setImage(
                        PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER));
                index++;
            }
        }

        for (String name : this.creatorTargets.keySet()) {

            Class<?> creatorTarget = this.creatorTargets.get(name);

            TreeItem parentItem = findParentForTarget(checked, treeItems, creatorTarget, true);
            // IGridWorkflowDescripion extends IGridJobDescription, so both classes fit into the same target.
            // So first let's check exact target (comparing classes), then use isAssignable() 
            if (parentItem == null) {
                parentItem = findParentForTarget(checked, treeItems, creatorTarget, false);
            }

            if (parentItem == null) {
                parentItem = this.rootItem;
            }

            TreeItem leafItem = new TreeItem(parentItem, SWT.NONE);
            leafItem.setText(name);
            leafItem.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FILE));

        }

        this.rootItem.setExpanded(true);
        for (TreeItem child : this.rootItem.getItems()) {
            child.setExpanded(true);
        }

    }

    private TreeItem findParentForTarget(final Object[] checked, final TreeItem[] treeItems,
            final Class<?> creatorTarget, final boolean equalClass) {
        TreeItem parentItem = null;
        for (int i = 0; i < checked.length && parentItem == null; i++) {
            try {
                String elementClassName = ((String[]) checked[i])[3];
                Class<?> elementClass = this.elementClasses.get(elementClassName);

                if (elementClass == null) {
                    elementClass = Class.forName(elementClassName);
                }

                if (equalClass) {
                    if (elementClass.equals(creatorTarget)) {
                        parentItem = treeItems[i];
                    }
                } else {
                    if (elementClass.isAssignableFrom(creatorTarget)) {
                        parentItem = treeItems[i];
                    }
                }
            } catch (ClassNotFoundException cnfExc) {
                Activator.logException(cnfExc);
            }
        }
        return parentItem;
    }

    private void initialize() {

        if (this.creatorTargets == null) {

            this.creatorTargets = new Hashtable<String, Class<?>>();

            ExtensionManager extm = new ExtensionManager();
            List<IConfigurationElement> creators = GridModel.getCreatorRegistry().getConfigurations();

            for (IConfigurationElement creator : creators) {
                IConfigurationElement[] targets = creator
                        .getChildren(Extensions.GRID_ELEMENT_CREATOR_TARGET_ELEMENT);
                if (targets != null) {
                    for (IConfigurationElement target : targets) {
                        String name = target.getAttribute(Extensions.GRID_ELEMENT_CREATOR_TARGET_NAME_ATTRIBUTE);
                        String className = target
                                .getAttribute(Extensions.GRID_ELEMENT_CREATOR_TARGET_CLASS_ATTRIBUTE);
                        String contributor = target.getContributor().getName();
                        Bundle bundle = Platform.getBundle(contributor);
                        if (bundle != null) {
                            try {

                                Class<?> cls = bundle.loadClass(className);
                                if (!IGridResource.class.isAssignableFrom(cls)
                                        && !IVirtualOrganization.class.isAssignableFrom(cls)) {
                                    this.creatorTargets.put(name, cls);
                                }
                            } catch (ClassNotFoundException cnfExc) {
                                Activator.logException(cnfExc);
                            }
                        }
                    }
                }

            }

        }

    }

    private void loadProjectFolders() {

        if (elementClasses == null) {
            this.elementClasses = new Hashtable<String, Class<?>>();
        }

        List<String[]> input = new ArrayList<String[]>();
        List<String[]> checked = new ArrayList<String[]>();
        ExtensionManager extm = new ExtensionManager();
        List<IConfigurationElement> configurationElements = extm
                .getConfigurationElements(Extensions.PROJECT_FOLDER_POINT, Extensions.PROJECT_FOLDER_ELEMENT);

        for (IConfigurationElement element : configurationElements) {
            String id = element.getAttribute(Extensions.PROJECT_FOLDER_ID_ATTRIBUTE);
            String name = element.getAttribute(Extensions.PROJECT_FOLDER_NAME_ATTRIBUTE);
            String label = element.getAttribute(Extensions.PROJECT_FOLDER_LABEL_ATTRIBUTE);
            String cls = element.getAttribute(Extensions.PROJECT_FOLDER_ELEMENTCLASS_ATTRIBUTE);

            try {
                String contributor = element.getContributor().getName();
                Bundle bundle = Platform.getBundle(contributor);

                Class<?> elementClass = bundle.loadClass(cls);
                this.elementClasses.put(cls, elementClass);
            } catch (ClassNotFoundException exception) {
                Activator.logException(exception);
            }

            boolean preset = Boolean.parseBoolean(element.getAttribute(Extensions.PROJECT_FOLDER_PRESET_ATTRIBUTE));
            String[] row = new String[] { name, label, id, cls };
            input.add(row);
            if (preset) {
                checked.add(row);
            }
        }

        this.viewer.setInput(input);
        this.viewer.setCheckedElements(checked.toArray());

    }

    private void startEditing(final TableItem item) {

        Control oldEditor = this.editor.getEditor();
        if (oldEditor != null) {
            oldEditor.dispose();
        }

        if (item != null) {

            Text text = new Text(this.table, SWT.NONE);
            text.setText(item.getText(LABEL_COLUMN));

            text.addModifyListener(new ModifyListener() {
                public void modifyText(final ModifyEvent e) {
                    Text t = (Text) GridProjectStructureComposite.this.editor.getEditor();
                    GridProjectStructureComposite.this.editor.getItem().setText(LABEL_COLUMN, t.getText());
                    updateTree();
                }
            });

            text.selectAll();
            text.setFocus();
            this.editor.setEditor(text, item, LABEL_COLUMN);

        }

    }

}