gov.redhawk.ide.spd.internal.ui.editor.ImplementationsSection.java Source code

Java tutorial

Introduction

Here is the source code for gov.redhawk.ide.spd.internal.ui.editor.ImplementationsSection.java

Source

/*******************************************************************************
 * This file is protected by Copyright. 
 * Please refer to the COPYRIGHT file distributed with this source distribution.
 *
 * This file is part of REDHAWK IDE.
 *
 * 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 gov.redhawk.ide.spd.internal.ui.editor;

import gov.redhawk.ide.codegen.CodegenPackage;
import gov.redhawk.ide.codegen.CodegenUtil;
import gov.redhawk.ide.codegen.ICodeGeneratorDescriptor;
import gov.redhawk.ide.codegen.ImplementationSettings;
import gov.redhawk.ide.codegen.RedhawkCodegenActivator;
import gov.redhawk.ide.codegen.WaveDevSettings;
import gov.redhawk.ide.codegen.ui.action.CleanUpGeneratorRunnable;
import gov.redhawk.ide.codegen.util.ProjectCreator;
import gov.redhawk.ide.codegen.util.PropertyUtil;
import gov.redhawk.ide.spd.internal.ui.editor.provider.ImplementationSectionImplementationItemProvider;
import gov.redhawk.ide.spd.internal.ui.editor.provider.ImplementationSectionSoftPkgItemProvider;
import gov.redhawk.ide.spd.internal.ui.editor.provider.ImplementationSectionUsesDeviceItemProvider;
import gov.redhawk.ide.spd.internal.ui.editor.provider.SpdItemProviderAdapterFactoryAdapter;
import gov.redhawk.ide.spd.internal.ui.editor.wizard.ImplementationWizard;
import gov.redhawk.model.sca.util.ModelUtil;
import gov.redhawk.sca.ui.parts.FormFilteredTree;
import gov.redhawk.ui.actions.SortAction;
import gov.redhawk.ui.editor.TreeSection;
import gov.redhawk.ui.parts.TreePart;
import gov.redhawk.ui.util.SCAEditorUtil;

import java.util.List;

import mil.jpeojtrs.sca.spd.Dependency;
import mil.jpeojtrs.sca.spd.Implementation;
import mil.jpeojtrs.sca.spd.PropertyRef;
import mil.jpeojtrs.sca.spd.SoftPkg;
import mil.jpeojtrs.sca.spd.SoftPkgRef;
import mil.jpeojtrs.sca.spd.SpdPackage;
import mil.jpeojtrs.sca.spd.UsesDevice;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.resources.WorkspaceJob;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.SubMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.command.Command;
import org.eclipse.emf.common.command.CompoundCommand;
import org.eclipse.emf.common.notify.AdapterFactory;
import org.eclipse.emf.common.util.EMap;
import org.eclipse.emf.ecore.provider.EcoreItemProviderAdapterFactory;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.edit.command.AddCommand;
import org.eclipse.emf.edit.command.RemoveCommand;
import org.eclipse.emf.edit.command.SetCommand;
import org.eclipse.emf.edit.domain.EditingDomain;
import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
import org.eclipse.emf.edit.provider.ReflectiveItemProviderAdapterFactory;
import org.eclipse.emf.edit.provider.resource.ResourceItemProviderAdapterFactory;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.util.IPropertyChangeListener;
import org.eclipse.jface.util.PropertyChangeEvent;
import org.eclipse.jface.viewers.DecoratingLabelProvider;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.StructuredViewer;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.graphics.Cursor;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.PatternFilter;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;

/**
 * 
 */
public class ImplementationsSection extends TreeSection implements IPropertyChangeListener {

    private static final int BUTTON_REMOVE = 1;

    private static final int BUTTON_ADD = 0;

    private FormFilteredTree fFilteredTree;

    private TreeViewer fExtensionTree;

    private SortAction fSortAction;

    private ComposedAdapterFactory adapterFactory;

    private Resource spdResource;

    private boolean editable;

    /**
     * The Constructor.
     * 
     * @param page the page
     * @param parent the parent
     */
    public ImplementationsSection(final ImplementationPage page, final Composite parent) {
        super(page, parent, Section.DESCRIPTION, new String[] { "Add...", "Remove" });
        this.fHandleDefaultButton = false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void selectionChanged(final IStructuredSelection selection) {
        this.getPage().setSelection(selection);
        this.updateButtons(selection);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void createClient(final Section section, final FormToolkit toolkit) {

        final Composite container = this.createClientContainer(section, 2, toolkit);
        final TreePart treePart = this.getTreePart();
        this.createViewerPartControl(container, SWT.MULTI, 2, toolkit);
        this.fExtensionTree = treePart.getTreeViewer();
        this.fExtensionTree.setContentProvider(new AdapterFactoryContentProvider(this.getAdapterFactory()));
        this.fExtensionTree.setLabelProvider(
                new DecoratingLabelProvider(new AdapterFactoryLabelProvider(this.getAdapterFactory()),
                        PlatformUI.getWorkbench().getDecoratorManager().getLabelDecorator()));
        this.fExtensionTree.addSelectionChangedListener(new ISelectionChangedListener() {
            //Try selecting the first element if the event's selection is empty.
            @Override
            public void selectionChanged(final SelectionChangedEvent event) {
                if (event.getSelection().isEmpty()) {
                    ImplementationsSection.this.selectFirstElement();
                }
            }
        });
        toolkit.paintBordersFor(container);
        section.setClient(container);
        section.setDescription("Define implementations within the following section.");
        // See Bug # 160554: Set text before text client
        section.setText("All Implementations");
        this.initialize();
        this.createSectionToolbar(section, toolkit);
        // Create the adapted listener for the filter entry field
        final Text filterText = this.fFilteredTree.getFilterControl();
        if (filterText != null) {
            filterText.addModifyListener(new ModifyListener() {
                @Override
                public void modifyText(final ModifyEvent e) {
                    final StructuredViewer viewer = ImplementationsSection.this.getStructuredViewerPart()
                            .getViewer();
                    final IStructuredSelection ssel = (IStructuredSelection) viewer.getSelection();
                    ImplementationsSection.this.updateButtons((ssel.size() != 1) ? null : ssel); // SUPPRESS CHECKSTYLE AvoidInline
                }
            });
        }

        this.refresh(this.spdResource);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean setFormInput(final Object object) {
        this.fExtensionTree.setSelection(new StructuredSelection(object), true);
        return true;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void dispose() {
        // Explicitly call the dispose method on the extensions tree
        if (this.fFilteredTree != null) {
            this.fFilteredTree.dispose();
        }
        this.adapterFactory.dispose();
        super.dispose();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected TreeViewer createTreeViewer(final Composite parent, final int style) {
        this.fFilteredTree = new FormFilteredTree(parent, style, new PatternFilter());
        parent.setData("filtered", Boolean.TRUE); //$NON-NLS-1$
        return this.fFilteredTree.getViewer();
    }

    /**
     * Gets the adapter factory.
     * 
     * @return the adapter factory
     */
    private AdapterFactory getAdapterFactory() {
        if (this.adapterFactory == null) {
            // Create an adapter factory that yields item providers.
            //
            this.adapterFactory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);

            this.adapterFactory.addAdapterFactory(new ResourceItemProviderAdapterFactory());

            final SpdItemProviderAdapterFactoryAdapter provider = new SpdItemProviderAdapterFactoryAdapter();
            provider.setSoftPkgAdapter(new ImplementationSectionSoftPkgItemProvider(provider));
            provider.setUsesDeviceAdapter(new ImplementationSectionUsesDeviceItemProvider(provider));
            provider.setImplementationAdapter(new ImplementationSectionImplementationItemProvider(provider,
                    this.getPage().getEditor().getMainResource()));
            this.adapterFactory.addAdapterFactory(provider);

            this.adapterFactory.addAdapterFactory(new EcoreItemProviderAdapterFactory());
            this.adapterFactory.addAdapterFactory(new ReflectiveItemProviderAdapterFactory());
        }
        return this.adapterFactory;
    }

    /**
     * Initialize.
     */
    private void initialize() {
        this.selectFirstElement();
        final TreePart treePart = this.getTreePart();
        treePart.setButtonEnabled(ImplementationsSection.BUTTON_ADD, true);
        treePart.setButtonEnabled(ImplementationsSection.BUTTON_REMOVE, false);
    }

    /**
     * Select first element.
     */
    private void selectFirstElement() {
        final Tree tree = this.fExtensionTree.getTree();
        final TreeItem[] items = tree.getItems();
        if (items.length == 0) {
            return;
        }
        final TreeItem firstItem = items[0];
        final Object obj = firstItem.getData();
        if (obj != null) {
            this.fExtensionTree.setSelection(new StructuredSelection(obj));
        }
    }

    /**
     * Creates the section toolbar.
     * 
     * @param section the section
     * @param toolkit the toolkit
     */
    private void createSectionToolbar(final Section section, final FormToolkit toolkit) {
        final ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
        final ToolBar toolbar = toolBarManager.createControl(section);
        final Cursor handCursor = new Cursor(Display.getCurrent(), SWT.CURSOR_HAND);
        toolbar.setCursor(handCursor);
        // Cursor needs to be explicitly disposed
        toolbar.addDisposeListener(new DisposeListener() {
            @Override
            public void widgetDisposed(final DisposeEvent e) {
                if (!handCursor.isDisposed()) {
                    handCursor.dispose();
                }
            }
        });
        // Add sort action to the tool bar
        this.fSortAction = new SortAction(this.fExtensionTree, "Sort the properties alpabetically.", null, null,
                this);
        toolBarManager.add(this.fSortAction);

        toolBarManager.update(true);

        section.setTextClient(toolbar);
    }

    /**
     * Update buttons.
     * 
     * @param item the item
     */
    private void updateButtons(final Object item) {
        final boolean sorted = this.fSortAction != null && this.fSortAction.isChecked();
        if (sorted) {
            return;
        }

        final boolean filtered = this.fFilteredTree.isFiltered();
        boolean addEnabled = true;
        boolean removeEnabled = false;

        if (item != null && this.editable) {
            removeEnabled = true;
        }
        if (filtered || !this.editable) {
            // Fix for bug 194529 and bug 194828
            addEnabled = false;
        }
        this.getTreePart().setButtonEnabled(ImplementationsSection.BUTTON_ADD, addEnabled);
        this.getTreePart().setButtonEnabled(ImplementationsSection.BUTTON_REMOVE, removeEnabled);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void buttonSelected(final int index) {
        switch (index) {
        case BUTTON_ADD:
            this.handleNew();
            break;
        case BUTTON_REMOVE:
            this.handleDelete();
            break;
        default:
            break;
        }
    }

    /**
     * Deletes the implementation from the model.
     * 
     * @param impl the implementation to remove
     */
    private void deleteImplementation(final Implementation impl) {
        final SoftPkg softpkg = this.getSoftPkg();
        final CompoundCommand command = new CompoundCommand("Remove Implementation");
        command.append(RemoveCommand.create(this.getEditingDomain(), softpkg,
                SpdPackage.Literals.SOFT_PKG__IMPLEMENTATION, impl));
        final ImplementationSettings implSettings = CodegenUtil.getImplementationSettings(impl);
        if (implSettings != null) {
            command.append(RemoveCommand.create(this.getEditingDomain(), this.getWaveDevSettings(),
                    CodegenPackage.Literals.WAVE_DEV_SETTINGS__IMPL_SETTINGS, implSettings.eContainer()));

            final IResource resource = ModelUtil.getResource(softpkg);
            final IProject project = resource.getProject();
            final IResource spdFile = ModelUtil.getResource(implSettings);
            IFolder dir = null;
            if (!"".equals(implSettings.getOutputDir()) && (implSettings.getOutputDir() != null)) {
                dir = spdFile.getProject().getFolder(implSettings.getOutputDir());
            }
            final IFolder outputDir = dir;
            if (outputDir != null && outputDir.exists()) {
                final Shell shell = this.getPage().getEditorSite().getShell();
                final boolean remove = MessageDialog.openQuestion(shell, "Remove Implementation Directory",
                        "Would you like to remove the implementation directory(" + implSettings.getOutputDir()
                                + ") also?");
                if (remove) {

                    PropertyUtil.setLastGenerated(CodegenUtil.loadWaveDevSettings(softpkg), implSettings, null);

                    final WorkspaceJob job = new WorkspaceJob("Removing Implementation Directory") {

                        @Override
                        @SuppressWarnings("deprecation")
                        public IStatus runInWorkspace(final IProgressMonitor monitor) throws CoreException {
                            final SubMonitor subMonitor = SubMonitor.convert(monitor,
                                    "Deleting Implementation " + implSettings.getName(), 90);
                            try {
                                outputDir.delete(true, subMonitor.newChild(10)); // SUPPRESS CHECKSTYLE MagicNumber

                                final String codegenId = implSettings.getGeneratorId();

                                final ICodeGeneratorDescriptor codeGenDesc = RedhawkCodegenActivator
                                        .getCodeGeneratorsRegistry().findCodegen(codegenId);

                                final CleanUpGeneratorRunnable cleanup = new CleanUpGeneratorRunnable(codeGenDesc,
                                        project);
                                cleanup.run(subMonitor.newChild(90)); // SUPPRESS CHECKSTYLE MagicNumber

                                return Status.OK_STATUS;
                            } finally {
                                subMonitor.done();
                            }
                        }

                    };
                    job.setPriority(Job.LONG);
                    job.setUser(true);
                    job.setSystem(false);
                    job.setRule(ResourcesPlugin.getWorkspace().getRuleFactory().buildRule());
                    job.schedule();
                }
            }
            this.execute(command);
        } else {
            this.execute(RemoveCommand.create(this.getEditingDomain(), softpkg,
                    SpdPackage.Literals.SOFT_PKG__IMPLEMENTATION, impl));
        }

    }

    private SoftPkg getSoftPkg() {
        if (this.spdResource != null) {
            return SoftPkg.Util.getSoftPkg(this.spdResource);
        }
        return null;
    }

    /**
     * Deletes the PropertyRef from the model.
     */
    private void deletePropertyRef(final PropertyRef obj) {
        if (obj.eContainer() instanceof Dependency) {
            this.execute(SetCommand.create(this.getEditingDomain(), obj.eContainer(),
                    SpdPackage.Literals.DEPENDENCY__PROPERTY_REF, null));
        } else if (obj.eContainer() instanceof UsesDevice) {
            this.execute(RemoveCommand.create(this.getEditingDomain(), obj.eContainer(),
                    SpdPackage.Literals.USES_DEVICE__PROPERTY_REF, obj));
        }
    }

    /**
     * Removes the selected SoftPkgRef from the model.
     * 
     * @param obj the SoftPkgRef to remove
     */
    private void deleteSoftPkgRef(final SoftPkgRef obj) {
        this.execute(SetCommand.create(this.getEditingDomain(), obj.eContainer(),
                SpdPackage.Literals.DEPENDENCY__SOFT_PKG_REF, null));
    }

    /**
     * Removes the selected UsesDevice from the model.
     * 
     * @param obj the Device to remove
     */
    private void deleteUsesDevice(final UsesDevice obj) {
        this.execute(RemoveCommand.create(this.getEditingDomain(), obj.eContainer(),
                SpdPackage.Literals.IMPLEMENTATION__USES_DEVICE, obj));
    }

    /**
     * Removes the selected Dependency from the model.
     * 
     * @param obj the Dependency to remove
     */
    private void deleteDependency(final Dependency obj) {
        this.execute(RemoveCommand.create(this.getEditingDomain(), obj.eContainer(),
                SpdPackage.Literals.IMPLEMENTATION__DEPENDENCY, obj));
    }

    /**
     * Handle delete.
     */
    private void handleDelete() {
        final List<Object> objs = this.getSelections();

        for (final Object obj : objs) {
            if (obj instanceof Implementation) {
                this.deleteImplementation((Implementation) obj);
            } else if (obj instanceof Dependency) {
                this.deleteDependency((Dependency) obj);
            } else if (obj instanceof UsesDevice) {
                this.deleteUsesDevice((UsesDevice) obj);
            } else if (obj instanceof SoftPkgRef) {
                this.deleteSoftPkgRef((SoftPkgRef) obj);
            } else if (obj instanceof PropertyRef) {
                this.deletePropertyRef((PropertyRef) obj);
            }
        }
    }

    /**
     * Handle new.
     */
    private void handleNew() {
        final ImplementationWizard wizard = new ImplementationWizard(this.getEditingDomain(),
                this.getSoftPkg().getName(), this.getSoftPkg());
        final WizardDialog dialog = new WizardDialog(this.getPage().getSite().getShell(), wizard);
        if (dialog.open() == Window.OK) {
            final Implementation impl = wizard.getImplementation();
            final ImplementationSettings settings = wizard.getSettings();
            final WaveDevSettings waveDevSettings = CodegenUtil.loadWaveDevSettings(this.getSoftPkg());

            ProjectCreator.setupImplementation(this.getSoftPkg(), impl, settings);

            final CompoundCommand command = new CompoundCommand("Add Implementation");
            command.append(AddCommand.create(this.getEditingDomain(), this.getSoftPkg(),
                    SpdPackage.Literals.SOFT_PKG__IMPLEMENTATION, impl));
            command.append(CodegenUtil.createAddImplementationSettingsCommand(this.getEditingDomain(), impl.getId(),
                    settings, waveDevSettings));

            final ICodeGeneratorDescriptor desc = RedhawkCodegenActivator.getCodeGeneratorsRegistry()
                    .findCodegen(settings.getGeneratorId());
            Assert.isNotNull(settings);
            Assert.isNotNull(impl);

            if (CodegenUtil.canPrimary(impl.getProgrammingLanguage().getName())) {
                final EMap<String, ImplementationSettings> settingsMap = waveDevSettings.getImplSettings();
                boolean primary = true;
                for (final Implementation tmpImpl : this.getSoftPkg().getImplementation()) {
                    if (tmpImpl.getProgrammingLanguage().getName()
                            .equals(impl.getProgrammingLanguage().getName())) {
                        final ImplementationSettings set = settingsMap.get(tmpImpl.getId());
                        if (set.isPrimary()) {
                            primary = false; // Don't change the primary if another implementation of the same language is primary
                        }
                    }
                }
                final SetCommand setPrimary = new SetCommand(this.getEditingDomain(), settings,
                        CodegenPackage.Literals.IMPLEMENTATION_SETTINGS__PRIMARY, primary);
                command.append(setPrimary);
            }

            this.getEditingDomain().getCommandStack().execute(command);

            Display.getCurrent().asyncExec(new Runnable() {

                @Override
                public void run() {
                    ImplementationsSection.this.getTreePart().getTreeViewer()
                            .setSelection(new StructuredSelection(impl));
                }
            });

            //         new OpenAssociatedPerspectiveJob(desc).schedule();
        }

    }

    /**
     * Gets the wave dev settings.
     * 
     * @return the wave dev settings
     */
    private WaveDevSettings getWaveDevSettings() {
        return CodegenUtil.loadWaveDevSettings(this.getSoftPkg());
    }

    /**
     * Execute.
     * 
     * @param command the command
     */
    private void execute(final Command command) {
        this.getEditingDomain().getCommandStack().execute(command);
    }

    /**
     * Gets the list of currently selected items.
     * 
     * @return list of selections
     */
    @SuppressWarnings("unchecked")
    private List<Object> getSelections() {
        return ((IStructuredSelection) this.getTreePart().getViewer().getSelection()).toList();
    }

    /**
     * Gets the editing domain.
     * 
     * @return the editing domain
     */
    private EditingDomain getEditingDomain() {
        return this.getPage().getEditor().getEditingDomain();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void propertyChange(final PropertyChangeEvent event) {
        if (this.fSortAction.equals(event.getSource()) && IAction.RESULT.equals(event.getProperty())) {
            final StructuredViewer viewer = this.getStructuredViewerPart().getViewer();
            final IStructuredSelection ssel = (IStructuredSelection) viewer.getSelection();
            this.updateButtons(ssel);
        }
    }

    /**
     * Fire selection.
     */
    protected void fireSelection() {
        final ISelection selection = this.fExtensionTree.getSelection();
        if (selection.isEmpty()) {
            this.selectFirstElement();
        } else {
            this.fExtensionTree.setSelection(this.fExtensionTree.getSelection());
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void refresh(final Resource resource) {
        this.spdResource = resource;
        final SoftPkg spd = this.getSoftPkg();
        if (this.fExtensionTree != null) {
            if (spd != null) {
                this.fExtensionTree.setInput(this.getSoftPkg());
            } else {
                this.fExtensionTree.setInput(null);
            }
            this.fireSelection();
        }

        this.setEditable();

        super.refresh(resource);
    }

    private void setEditable() {
        this.editable = SCAEditorUtil.isEditableResource(this.getPage(), this.spdResource);
        this.getTreePart().setButtonEnabled(ImplementationsSection.BUTTON_ADD, this.editable);
        this.getTreePart().setButtonEnabled(ImplementationsSection.BUTTON_REMOVE, this.editable);
    }
}