Package org.cloudfoundry.ide.eclipse.server.ui.internal.editor

Source Code of org.cloudfoundry.ide.eclipse.server.ui.internal.editor.ApplicationMasterPart

/*******************************************************************************
* Copyright (c) 2012, 2014 Pivotal Software, Inc.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of 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.
*  Contributors:
*     Pivotal Software, Inc. - initial API and implementation
*     Steven Hung, IBM - add accessibility for managing service binding
********************************************************************************/
package org.cloudfoundry.ide.eclipse.server.ui.internal.editor;

import java.util.List;

import org.cloudfoundry.client.lib.domain.CloudApplication;
import org.cloudfoundry.client.lib.domain.CloudService;
import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryBrandingExtensionPoint;
import org.cloudfoundry.ide.eclipse.server.core.internal.CloudFoundryServer;
import org.cloudfoundry.ide.eclipse.server.core.internal.client.CloudFoundryApplicationModule;
import org.cloudfoundry.ide.eclipse.server.core.internal.client.TunnelBehaviour;
import org.cloudfoundry.ide.eclipse.server.core.internal.debug.CloudFoundryProperties;
import org.cloudfoundry.ide.eclipse.server.ui.internal.CloudFoundryImages;
import org.cloudfoundry.ide.eclipse.server.ui.internal.Messages;
import org.cloudfoundry.ide.eclipse.server.ui.internal.actions.DeleteServicesAction;
import org.cloudfoundry.ide.eclipse.server.ui.internal.actions.RefreshApplicationEditorAction;
import org.cloudfoundry.ide.eclipse.server.ui.internal.actions.ServiceToApplicationsBindingAction;
import org.cloudfoundry.ide.eclipse.server.ui.internal.wizards.CloudFoundryServiceWizard;
import org.cloudfoundry.ide.eclipse.server.ui.internal.wizards.CloudRoutesWizard;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.ToolBarManager;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.util.LocalSelectionTransfer;
import org.eclipse.jface.viewers.DecorationOverlayIcon;
import org.eclipse.jface.viewers.IDecoration;
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.Viewer;
import org.eclipse.jface.wizard.IWizard;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSourceAdapter;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridLayout;
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.Menu;
import org.eclipse.ui.forms.IManagedForm;
import org.eclipse.ui.forms.SectionPart;
import org.eclipse.ui.forms.widgets.FormToolkit;
import org.eclipse.ui.forms.widgets.Section;
import org.eclipse.ui.progress.UIJob;
import org.eclipse.wst.server.core.IModule;
import org.eclipse.wst.server.ui.internal.ImageResource;
import org.eclipse.wst.server.ui.internal.ServerLabelProvider;
import org.eclipse.wst.server.ui.internal.view.servers.RemoveModuleAction;
import org.eclipse.wst.server.ui.internal.view.servers.ServersViewDropAdapter;
import org.eclipse.wst.server.ui.internal.wizard.ModifyModulesWizard;

/**
* @author Terry Denney
* @author Leo Dos Santos
* @author Steffen Pingel
* @author Christian Dupuis
*/
@SuppressWarnings("restriction")
public class ApplicationMasterPart extends SectionPart {

  private TableViewer applicationsViewer;

  private final CloudFoundryServer cloudServer;

  private IModule currentModule;

  private final CloudFoundryApplicationsEditorPage editorPage;

  private TableViewer servicesViewer;

  private FormToolkit toolkit;

  private boolean provideServices;

  private Section servicesSection;

  public ApplicationMasterPart(CloudFoundryApplicationsEditorPage editorPage, IManagedForm managedForm,
      Composite parent, CloudFoundryServer cloudServer) {
    super(parent, managedForm.getToolkit(), Section.TITLE_BAR | Section.DESCRIPTION);
    this.editorPage = editorPage;
    this.cloudServer = cloudServer;
    this.toolkit = managedForm.getToolkit();
    this.provideServices = CloudFoundryBrandingExtensionPoint.getProvideServices(editorPage.getServer()
        .getServerType().getId());
  }

  /**
   * Creates the content of the master part inside the form part. This method
   * is called when the master/details block is created.
   */
  public void createContents() {
    createApplicationsSection();

    if (provideServices) {
      createServicesSection();
    }

    createRoutesDomainsSection();
  }

  public TableViewer getApplicationsViewer() {
    return applicationsViewer;
  }

  public IModule getCurrentModule() {
    return currentModule;
  }

  private void updateSections() {
    if (provideServices) {
      List<CloudService> services = editorPage.getServices();
      servicesViewer.setInput((services != null) ? services.toArray() : null);
      if (servicesSection != null && !servicesSection.isExpanded()) {
        // If collapsed, expand (e.g. section is collapsed and user adds
        // a new service)
        servicesSection.setExpanded(true);
      }
    }
  }

  public void refreshUI() {

    IStatus status = cloudServer.refreshCloudModules();

    applicationsViewer.setInput(cloudServer.getServerOriginal().getModules());
    // Update the sections regardless of any errors in the modules, as some
    // modules may have no errors
    updateSections();

    if (editorPage != null && !editorPage.isDisposed()) {
      if (!status.isOK()) {
        editorPage.setErrorMessage(status.getMessage());
      }
      else {
        editorPage.setErrorMessage(null);
      }
    }

  }

  private class ApplicationViewersDropAdapter extends ServersViewDropAdapter {

    public ApplicationViewersDropAdapter(Viewer viewer) {
      super(viewer);
    }

    @Override
    protected Object getCurrentTarget() {
      return editorPage.getServer().getOriginal();
    }

    @Override
    protected Object determineTarget(DropTargetEvent event) {
      return editorPage.getServer();
    }

    @Override
    public boolean performDrop(final Object data) {
      final String jobName = "Deploying application"; //$NON-NLS-1$
      UIJob job = new UIJob(jobName) {

        @Override
        public IStatus runInUIThread(IProgressMonitor monitor) {

          if (data instanceof IStructuredSelection) {
            Object modObj = ((IStructuredSelection) data).getFirstElement();
            IProject prj = null;
            if (modObj instanceof IProject) {
              prj = (IProject) modObj;
            }
            else if (modObj instanceof IJavaProject) {
              prj = ((IJavaProject) modObj).getProject();
            }

            if (prj != null) {

              final CloudFoundryServer cloudServer = (CloudFoundryServer) editorPage.getServer()
                  .getOriginal().loadAdapter(CloudFoundryServer.class, monitor);

              if (cloudServer != null) {

                final String moduleName = prj.getName();

                // First of all, should make sure there is no
                // CloundApplicationModule
                // with the same name of the selected project,
                // otherwise it will cause
                // the CloundApplicationModule with the same
                // name and its related remote
                // application in CF to be deleted.
                if (cloudServer.getBehaviour().existCloudApplicationModule(moduleName)) {
                  Display.getDefault().asyncExec(new Runnable() {

                    public void run() {
                      MessageDialog.openError(
                          editorPage.getSite().getShell(),
                          Messages.ApplicationMasterPart_ERROR_DEPLOY_FAIL_TITLE,
                          NLS.bind(
                              Messages.ApplicationMasterPart_ERROR_DEPLOY_FAIL_BODY,
                              moduleName));
                    }

                  });
                  return Status.CANCEL_STATUS;
                }

                // Make sure parent performs the drop first to
                // create the IModule. Unsupported modules will
                // not proceed result in IModule creation
                // therefore checks on the IProject are not
                // necessary
                ApplicationViewersDropAdapter.super.performDrop(data);

                // Now do a publish AFTER the IModule is
                // created. If no IModule is created (either
                // user cancels or project
                // is not supported), the publish operation will
                // do nothing.
                Job job = new Job(jobName) {

                  @Override
                  protected IStatus run(IProgressMonitor monitor) {
                    cloudServer.getBehaviour().publishAdd(moduleName, monitor);
                    return Status.OK_STATUS;
                  }

                };
                job.setPriority(Job.INTERACTIVE);
                job.schedule();
                return Status.OK_STATUS;
              }
            }
          }
          return Status.CANCEL_STATUS;
        }
      };
      job.schedule();

      return true;
    }
  }

  private void createApplicationsSection() {
    Section section = getSection();
    section.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(section);
    section.setText(Messages.COMMONTXT_APPLICATIONS);
    section.setDescription(Messages.ApplicationMasterPart_TEXT_APP_DESCRIP);

    Composite client = toolkit.createComposite(section);
    client.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(client);
    section.setClient(client);

    Composite headerComposite = toolkit.createComposite(section, SWT.NONE);
    RowLayout rowLayout = new RowLayout();
    rowLayout.marginTop = 0;
    rowLayout.marginBottom = 0;
    headerComposite.setLayout(rowLayout);
    headerComposite.setBackground(null);

    ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
    toolBarManager.createControl(headerComposite);

    applicationsViewer = new TableViewer(toolkit.createTable(client, SWT.NONE));
    applicationsViewer.setContentProvider(new TreeContentProvider());
    applicationsViewer.setLabelProvider(new ServerLabelProvider() {
      @Override
      public Image getImage(Object element) {
        Image image = super.getImage(element);

        if (element instanceof IModule) {
          IModule module = (IModule) element;
          CloudFoundryApplicationModule appModule = editorPage.getCloudServer()
              .getExistingCloudModule(module);
          if (appModule != null && appModule.getErrorMessage() != null) {
            return CloudFoundryImages.getImage(new DecorationOverlayIcon(image,
                CloudFoundryImages.OVERLAY_ERROR, IDecoration.BOTTOM_LEFT));
          }
        }

        return image;
      }

      @Override
      public String getText(Object element) {
        // This is the WTP module name (usually, it's the workspace
        // project name)
        String moduleName = super.getText(element);

        // However, the user has the option to specify a different name
        // when pushing an app, which is used as the cf app name. If
        // they are different, and the
        // corresponding workspace project is accessible, show both.
        // Otherwise, show the cf app name.

        if (element instanceof IModule) {

          IModule module = (IModule) element;

          // Find the corresponding Cloud Foundry-aware application
          // Module.
          CloudFoundryApplicationModule appModule = cloudServer.getExistingCloudModule((IModule) element);

          if (appModule != null) {
            String cfAppName = appModule.getDeployedApplicationName();

            if (cfAppName != null) {

              // Be sure not to show a null WTP module name,
              // although
              // that should not be encountered
              if (moduleName != null
                  && !cfAppName.equals(moduleName)
                  && CloudFoundryProperties.isModuleProjectAccessible.testProperty(
                      new IModule[] { module }, cloudServer)) {
                moduleName = cfAppName + " (" + moduleName + ")"; //$NON-NLS-1$ //$NON-NLS-2$
              }
              else {
                moduleName = cfAppName;
              }
            }
          }
        }

        return moduleName;
      }

    });
    applicationsViewer.setInput(new CloudApplication[0]);
    applicationsViewer.setSorter(new CloudFoundryViewerSorter());

    applicationsViewer.addSelectionChangedListener(new ISelectionChangedListener() {

      public void selectionChanged(SelectionChangedEvent event) {
        IStructuredSelection selection = (IStructuredSelection) event.getSelection();
        IModule module = (IModule) selection.getFirstElement();

        if (currentModule != module) {
          currentModule = module;
          getManagedForm().fireSelectionChanged(ApplicationMasterPart.this, selection);
        }
      }
    });
    GridDataFactory.fillDefaults().grab(true, true).hint(250, SWT.DEFAULT).applyTo(applicationsViewer.getControl());

    int ops = DND.DROP_COPY | DND.DROP_LINK | DND.DROP_DEFAULT;
    Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
    ApplicationViewersDropAdapter listener = new ApplicationViewersDropAdapter(applicationsViewer);
    applicationsViewer.addDropSupport(ops, transfers, listener);

    // create context menu
    MenuManager menuManager = new MenuManager();
    menuManager.setRemoveAllWhenShown(true);
    menuManager.addMenuListener(new IMenuListener() {

      public void menuAboutToShow(IMenuManager manager) {
        fillApplicationsContextMenu(manager);
      }
    });

    Menu menu = menuManager.createContextMenu(applicationsViewer.getControl());
    applicationsViewer.getControl().setMenu(menu);
    editorPage.getSite().registerContextMenu(menuManager, applicationsViewer);

    Action addRemoveApplicationAction = new Action(Messages.ApplicationMasterPart_TEXT_ADD_REMOVE,
        ImageResource.getImageDescriptor(ImageResource.IMG_ETOOL_MODIFY_MODULES)) {
      @Override
      public void run() {
        ModifyModulesWizard wizard = new ModifyModulesWizard(cloudServer.getServerOriginal());
        WizardDialog dialog = new WizardDialog(getSection().getShell(), wizard);
        dialog.open();
      }
    };
    toolBarManager.add(addRemoveApplicationAction);

    // Fix for STS-2996. Moved from CloudFoundryApplicationsEditorPage
    toolBarManager.add(new RefreshApplicationEditorAction(editorPage));
    toolBarManager.update(true);
    section.setTextClient(headerComposite);

    getManagedForm().getToolkit().paintBordersFor(client);
  }

  private void createRoutesDomainsSection() {

    Section routeSection = toolkit.createSection(getSection().getParent(), Section.TITLE_BAR | Section.DESCRIPTION
        | Section.TWISTIE);
    routeSection.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(routeSection);
    routeSection.setText(Messages.ApplicationMasterPart_TEXT_ROUTES);
    routeSection.setExpanded(true);

    routeSection.clientVerticalSpacing = 0;

    Composite client = toolkit.createComposite(routeSection);
    client.setLayout(new GridLayout(1, false));
    GridDataFactory.fillDefaults().grab(true, true).applyTo(client);
    routeSection.setClient(client);

    Button button = toolkit.createButton(client, Messages.ApplicationMasterPart_TEXT_REMOVE_BUTTON, SWT.PUSH);
    GridDataFactory.fillDefaults().align(SWT.LEFT, SWT.CENTER).applyTo(button);

    button.addSelectionListener(new SelectionAdapter() {
      public void widgetSelected(SelectionEvent e) {
        UIJob uiJob = new UIJob(Messages.ApplicationMasterPart_JOB_REMOVE_ROUTE) {

          public IStatus runInUIThread(IProgressMonitor monitor) {
            CloudRoutesWizard wizard = new CloudRoutesWizard(cloudServer);

            WizardDialog dialog = new WizardDialog(editorPage.getEditorSite().getShell(), wizard);
            dialog.open();
            return Status.OK_STATUS;
          }

        };
        uiJob.setSystem(true);
        uiJob.setPriority(Job.INTERACTIVE);
        uiJob.schedule();
      }
    });

  }

  private void createServicesSection() {
    servicesSection = toolkit.createSection(getSection().getParent(), Section.TITLE_BAR | Section.DESCRIPTION
        | Section.TWISTIE);
    servicesSection.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(servicesSection);
    servicesSection.setText(Messages.COMMONTXT_SERVICES);
    servicesSection.setExpanded(true);
    servicesSection.setDescription(Messages.ApplicationMasterPart_TEXT_SERVICES_DESCRIP);
    // NOTE:Comment out as keeping section collapsed by default causes zero
    // height tables if no services are provided
    // servicesSection.addExpansionListener(new ExpansionAdapter() {
    //
    // @Override
    // public void expansionStateChanged(ExpansionEvent e) {
    // userExpanded = true;
    // }
    // });

    Composite client = toolkit.createComposite(servicesSection);
    client.setLayout(new GridLayout());
    GridDataFactory.fillDefaults().grab(true, true).applyTo(client);
    servicesSection.setClient(client);

    Composite headerComposite = toolkit.createComposite(servicesSection, SWT.NONE);
    RowLayout rowLayout = new RowLayout();
    rowLayout.marginTop = 0;
    rowLayout.marginBottom = 0;
    headerComposite.setLayout(rowLayout);
    headerComposite.setBackground(null);

    ToolBarManager toolBarManager = new ToolBarManager(SWT.FLAT);
    toolBarManager.createControl(headerComposite);

    servicesViewer = new TableViewer(toolkit.createTable(client, SWT.MULTI));
    new ServiceViewerConfigurator().configureViewer(servicesViewer);

    servicesViewer.setContentProvider(new TreeContentProvider());
    servicesViewer.setLabelProvider(new ServicesTreeLabelProvider(servicesViewer) {

      protected Image getColumnImage(CloudService service, ServiceViewColumn column) {
        if (column == ServiceViewColumn.Tunnel) {
          TunnelBehaviour handler = new TunnelBehaviour(cloudServer);
          if (handler.hasCaldecottTunnel(service.getName())) {
            return CloudFoundryImages.getImage(CloudFoundryImages.CONNECT);
          }
        }
        return null;
      }

    });
    servicesViewer.setSorter(new ServiceViewerSorter(servicesViewer) {

      @Override
      protected int compare(CloudService service1, CloudService service2, ServiceViewColumn sortColumn) {
        if (sortColumn == ServiceViewColumn.Tunnel) {
          TunnelBehaviour handler = new TunnelBehaviour(cloudServer);
          if (handler.hasCaldecottTunnel(service1.getName())) {
            return -1;
          }
          else if (handler.hasCaldecottTunnel(service2.getName())) {
            return 1;
          }
          else {
            return 0;
          }
        }
        return super.compare(service1, service2, sortColumn);
      }

    });

    servicesViewer.setInput(new CloudService[0]);

    GridDataFactory.fillDefaults().grab(true, true).applyTo(servicesViewer.getControl());

    Action addServiceAction = new Action(Messages.COMMONTXT_ADD_SERVICE, CloudFoundryImages.NEW_SERVICE) {
      @Override
      public void run() {
        IWizard wizard = new CloudFoundryServiceWizard(cloudServer);
        WizardDialog dialog = new WizardDialog(getSection().getShell(), wizard);
        dialog.setBlockOnOpen(true);
        dialog.open();
      }
    };
    toolBarManager.add(addServiceAction);
    toolBarManager.update(true);
    servicesSection.setTextClient(headerComposite);

    // create context menu
    MenuManager menuManager = new MenuManager();
    menuManager.setRemoveAllWhenShown(true);
    menuManager.addMenuListener(new IMenuListener() {

      public void menuAboutToShow(IMenuManager manager) {
        fillServicesContextMenu(manager);
      }
    });

    Menu menu = menuManager.createContextMenu(servicesViewer.getControl());
    servicesViewer.getControl().setMenu(menu);
    editorPage.getSite().registerContextMenu(menuManager, servicesViewer);

    // Create drag source on the table
    int ops = DND.DROP_COPY;
    Transfer[] transfers = new Transfer[] { LocalSelectionTransfer.getTransfer() };
    DragSourceAdapter listener = new DragSourceAdapter() {
      @Override
      public void dragSetData(DragSourceEvent event) {
        IStructuredSelection selection = (IStructuredSelection) servicesViewer.getSelection();
        event.data = selection.getFirstElement();
        LocalSelectionTransfer.getTransfer().setSelection(selection);
      }

      @Override
      public void dragStart(DragSourceEvent event) {
        if (event.detail == DND.DROP_NONE || event.detail == DND.DROP_DEFAULT) {
          event.detail = DND.DROP_COPY;
        }
        dragSetData(event);
      }

    };
    servicesViewer.addDragSupport(ops, transfers, listener);

    getManagedForm().getToolkit().paintBordersFor(client);

  }

  private void fillServicesContextMenu(IMenuManager manager) {
    IStructuredSelection selection = (IStructuredSelection) servicesViewer.getSelection();
    if (selection.isEmpty()) {
      return;
    }

    manager.add(new DeleteServicesAction(selection, cloudServer.getBehaviour(), editorPage));
       
    manager.add(new ServiceToApplicationsBindingAction(
        selection,
        cloudServer.getBehaviour(),
        editorPage));   
   
    // FIXNS: Disable Caldecott feature in 1.5.1 until feature is supported
    // in the client-lib
    // List<IAction> caldecottAction = new
    // TunnelActionProvider(cloudServer).getTunnelActions(selection,
    // editorPage);
    // for (IAction action : caldecottAction) {
    // manager.add(action);
    // }
  }

  private void fillApplicationsContextMenu(IMenuManager manager) {
    IStructuredSelection selection = (IStructuredSelection) applicationsViewer.getSelection();
    if (selection.isEmpty()) {
      return;
    }

    IModule module = (IModule) selection.getFirstElement();
    if (module != null) {
      manager.add(new RemoveModuleAction(getSection().getShell(), editorPage.getServer().getOriginal(), module));
    }
  }

}
TOP

Related Classes of org.cloudfoundry.ide.eclipse.server.ui.internal.editor.ApplicationMasterPart

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.