Package org.fusesource.ide.launcher.ui.launch

Source Code of org.fusesource.ide.launcher.ui.launch.ExecutePomActionSupport

/*******************************************************************************
* Copyright (c) 2013 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is 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
*
* Contributors:
*     Red Hat, Inc. - initial API and implementation
******************************************************************************/

package org.fusesource.ide.launcher.ui.launch;

import java.lang.reflect.Method;
import java.util.ArrayList;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
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.IExecutableExtension;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.debug.core.ILaunchManager;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.debug.ui.ILaunchShortcut;
import org.eclipse.debug.ui.RefreshTab;
import org.eclipse.jdt.core.IClasspathEntry;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.launching.IJavaLaunchConfigurationConstants;
import org.eclipse.jdt.launching.JavaRuntime;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.m2e.actions.MavenLaunchConstants;
import org.eclipse.m2e.core.MavenPlugin;
import org.eclipse.m2e.core.internal.IMavenConstants;
import org.eclipse.m2e.core.project.IMavenProjectFacade;
import org.eclipse.m2e.core.project.IMavenProjectRegistry;
import org.eclipse.m2e.core.project.ResolverConfiguration;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.ISelectionService;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ElementListSelectionDialog;
import org.fusesource.ide.commons.util.Strings;
import org.fusesource.ide.launcher.run.util.CamelContextLaunchConfigConstants;
import org.fusesource.ide.launcher.run.util.MavenLaunchUtils;
import org.fusesource.ide.launcher.ui.Activator;

public class ExecutePomActionSupport implements ILaunchShortcut, IExecutableExtension {

  private final String launchConfigurationId;
  private final String launchConfigTypeId;

  private final String defaultMavenGoals;

  private String goalName;
  private boolean showDialog = false;
  private ExecutePomActionPostProcessor postProcessor;

  public ExecutePomActionSupport(String launchConfigurationId,
      String launchConfigTypeId, String defaultMavenGoals) {
    this.launchConfigurationId = launchConfigurationId;
    this.launchConfigTypeId = launchConfigTypeId;
    this.defaultMavenGoals = defaultMavenGoals;
    this.goalName = defaultMavenGoals;
  }

  @Override
  public void setInitializationData(IConfigurationElement config,
      String propertyName, Object data) {
    if ("WITH_DIALOG".equals(data)) {
      this.showDialog = true;
    } else {
      this.goalName = (String) data;
    }
  }

  @Override
  public void launch(IEditorPart editor, String mode) {
    if (editor != null) {
      IEditorInput editorInput = editor.getEditorInput();
      if (editorInput instanceof IFileEditorInput) {
        launchCamelContext(((IFileEditorInput) editorInput).getFile(), mode);
      }
    }
  }

  public void setPostProcessor(ExecutePomActionPostProcessor postProcessor) {
    this.postProcessor = postProcessor;
  }

  /**
   * @return the postProcessor
   */
  public ExecutePomActionPostProcessor getPostProcessor() {
    return this.postProcessor;
  }

  @Override
  public void launch(ISelection selection, String mode) {
    if (selection instanceof IStructuredSelection) {
      IStructuredSelection structuredSelection = (IStructuredSelection) selection;
      Object object = structuredSelection.getFirstElement();

      if (object instanceof IFile) {
        launchCamelContext((IFile)object, mode);
      }
    }
  }

  @SuppressWarnings("deprecation")
  private void launchCamelContext(IFile file, String mode) {
    if (file == null) {
      return;
    }

    IContainer basedir = findPomXmlBasedir(file.getParent());

    ILaunchConfiguration launchConfiguration;
    try {
      launchConfiguration = getLaunchConfiguration(basedir, mode);
      if (launchConfiguration == null) {
        launchConfiguration = createLaunchConfiguration(basedir,
            defaultMavenGoals);
        if (launchConfiguration == null) {
          return;
        }
      }
    } catch (InvalidConfigurationException e) {
      return;
    }

    boolean isWARPackaging = false;
    try {
      isWARPackaging = MavenLaunchUtils.isPackagingTypeWAR(basedir.getFile(Path.fromOSString("pom.xml")));
    } catch (CoreException ex) {
      Activator.getLogger().error(ex);
    }
   
    ILaunchConfigurationWorkingCopy lc = null;
    try {
      lc = launchConfiguration.getWorkingCopy();
    } catch (CoreException ex) {
      Activator.getLogger().error(ex);
      MessageDialog.openError(getShell(), "Unable to launch...", "An error occured when trying to launch the project. Message: " + ex.getMessage());
      return;
    }
    boolean openDialog = showDialog;
    if (!openDialog) {
      try {
        // if no goals specified
        String goals = lc.getAttribute(MavenLaunchConstants.ATTR_GOALS, (String) null);
        if (Strings.isBlank(goals)) {
          goals = isWARPackaging ? CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_WAR : CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_JAR;
        } else {
          if (goals.indexOf(CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_ALL) != -1) {
            // replace
            goals = goals.replaceAll(CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_ALL, isWARPackaging ? CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_WAR : CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_JAR);
          } else {
            // add
            goals = isWARPackaging ? CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_WAR : CamelContextLaunchConfigConstants.DEFAULT_MAVEN_GOALS_JAR;
          }
        }
        // no rider file selection
        if (Strings.isBlank(lc.getAttribute(CamelContextLaunchConfigConstants.ATTR_FILE, ""))) {
          lc.setAttribute(CamelContextLaunchConfigConstants.ATTR_FILE, file.getLocation().toOSString());
        }
        openDialog = Strings.isBlank(goals) || Strings.isBlank(lc.getAttribute(CamelContextLaunchConfigConstants.ATTR_FILE, ""));
        lc.setAttribute(MavenLaunchConstants.ATTR_GOALS, goals);
      } catch (CoreException ex) {
        Activator.getLogger().error("Error getting the maven goals from the configuration.", ex);
      }
    }

    if (openDialog) {
      String category = "org.fusesource.ide.launcher.ui.runCamelLaunchGroup";
      if (mode == ILaunchManager.DEBUG_MODE) {
        category = "org.fusesource.ide.launcher.ui.debugCamelLaunchGroup";
      }
      if (DebugUITools.openLaunchConfigurationPropertiesDialog(getShell(), lc, category, null) == Window.CANCEL) {
        return;
      }
    }
   
    try {
      final ILaunch launch = lc.launch(mode, new NullProgressMonitor());
      if (postProcessor != null) {

        // TODO would be nice to avoid the thread here but I guess there's no other way?
        Thread t = new Thread(new Runnable() {
          @Override
          public void run() {
            while (!launch.isTerminated()) {
              try {
                Thread.sleep(100);
              } catch (InterruptedException e) {
              }
            }

            IProcess[] processes = launch.getProcesses();
            boolean failed = false;
            for (IProcess process : processes) {
              try {
                if (process.getExitValue() != 0) {
                  failed = true;
                  break;
                }
              } catch (DebugException e) {
                Activator.getLogger().error("Failed to get exit code of build process", e);
              }
            }
            // only invoke post processor on sucess
            if (!failed) {
              postProcessor.executeOnSuccess();
            } else {
              postProcessor.executeOnFailure();
            }
          }
        });
        t.setDaemon(false);
        t.start();
      }
    } catch (CoreException ex) {
      DebugUITools.launch(lc, mode);
    }
  }

  private Shell getShell() {
    return PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
  }

  private IContainer findPomXmlBasedir(IContainer dir) {
    if (dir == null) {
      return null;
    }

    try {
      // loop upwards through the parents as long as we do not cross the
      // project boundary
      while (dir.exists() && dir.getProject() != null
          && dir.getProject() != dir) {
        // see if pom.xml exists
        if (dir.getType() == IResource.FOLDER) {
          IFolder folder = (IFolder) dir;
          if (folder.findMember(IMavenConstants.POM_FILE_NAME) != null) {
            return folder;
          }
        } else if (dir.getType() == IResource.FILE) {
          if (((IFile) dir).getName().equals(
              IMavenConstants.POM_FILE_NAME)) {
            return dir.getParent();
          }
        }
        dir = dir.getParent();
      }
    } catch (Exception e) {
      return dir;
    }
    return dir;
  }

  private ILaunchConfiguration createLaunchConfiguration(IContainer basedir,
      String goal) {
    ILaunchConfiguration config = null;
    try {
      ILaunchManager launchManager = DebugPlugin.getDefault()
          .getLaunchManager();
      /*
      ILaunchConfigurationType launchConfigurationType = launchManager
          .getLaunchConfigurationType(MavenLaunchConstants.LAUNCH_CONFIGURATION_TYPE_ID);
       */
      ILaunchConfigurationType launchConfigurationType = launchManager.getLaunchConfigurationType(launchConfigTypeId);

      String launchSafeGoalName = goal.replace(':', '-');

      ILaunchConfigurationWorkingCopy workingCopy = launchConfigurationType
          .newInstance(
              null, //
              "Executing "
              + launchSafeGoalName
              + " in "
              + basedir.getLocation().toString()
              .replace('/', '-'));
      workingCopy.setAttribute(MavenLaunchConstants.ATTR_POM_DIR, basedir
          .getLocation().toOSString());
      workingCopy.setAttribute(MavenLaunchConstants.ATTR_GOALS, goal);
      workingCopy.setAttribute(IDebugUIConstants.ATTR_PRIVATE, true);
      workingCopy.setAttribute(RefreshTab.ATTR_REFRESH_SCOPE,
          "${project}");
      workingCopy.setAttribute(RefreshTab.ATTR_REFRESH_RECURSIVE, true);
      workingCopy.setAttribute(
          IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
          basedir.getProject().getName());

      appendAttributes(basedir, workingCopy, goal);

      setProjectConfiguration(workingCopy, basedir);

      IPath path = getJREContainerPath(basedir);
      if (path != null) {
        workingCopy
        .setAttribute(
            IJavaLaunchConfigurationConstants.ATTR_JRE_CONTAINER_PATH,
            path.toPortableString());
      }

      // TODO when launching Maven with debugger consider to add the
      // following property
      // -Dmaven.surefire.debug="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 -Xnoagent -Djava.compiler=NONE"

      // CONTEXTLAUNCHING
      workingCopy.setMappedResources(new IResource[] { basedir });
      config = workingCopy.doSave();

      return config;
    } catch (CoreException ex) {
      Activator.getLogger().error("Unable to create launch configuration", ex);
    }
    return null;
  }

  /**
   * Appends attributes to the working copy
   *
   * @throws InvalidConfigurationException if the configuration cannot be used due to missing configuration
   */
  protected void appendAttributes(IContainer basedir,
      ILaunchConfigurationWorkingCopy workingCopy, String goal) {
  }

  private void setProjectConfiguration(
      ILaunchConfigurationWorkingCopy workingCopy, IContainer basedir) {
    IMavenProjectRegistry projectRegistry = MavenPlugin.getMavenProjectRegistry();
    IFile pomFile = basedir
        .getFile(new Path(IMavenConstants.POM_FILE_NAME));
    IMavenProjectFacade projectFacade = projectRegistry.create(pomFile,
        false, new NullProgressMonitor());
    if (projectFacade != null) {
      ResolverConfiguration configuration = projectFacade
          .getResolverConfiguration();

      String activeProfiles = configuration.getActiveProfiles();
      if (activeProfiles != null && activeProfiles.length() > 0) {
        workingCopy.setAttribute(MavenLaunchConstants.ATTR_PROFILES,
            activeProfiles);
      }
    }
  }

  private IPath getJREContainerPath(IContainer basedir) throws CoreException {
    IProject project = basedir.getProject();
    if (project != null && project.hasNature(JavaCore.NATURE_ID)) {
      IJavaProject javaProject = JavaCore.create(project);
      IClasspathEntry[] entries = javaProject.getRawClasspath();
      for (int i = 0; i < entries.length; i++) {
        IClasspathEntry entry = entries[i];
        if (JavaRuntime.JRE_CONTAINER
            .equals(entry.getPath().segment(0))) {
          return entry.getPath();
        }
      }
    }
    return null;
  }

  private ILaunchConfiguration getLaunchConfiguration(IContainer basedir,
      String mode) {
    if (goalName != null) {
      return createLaunchConfiguration(basedir, goalName);
    }

    ILaunchManager launchManager = DebugPlugin.getDefault()
        .getLaunchManager();
    ILaunchConfigurationType launchConfigurationType = launchManager
        .getLaunchConfigurationType(launchConfigTypeId);

    // scan existing launch configurations
    IPath basedirLocation = basedir.getLocation();
    if (!showDialog) {
      try {
        // ILaunch[] launches = launchManager.getLaunches();
        // ILaunchConfiguration[] launchConfigurations = null;
        // if(launches.length > 0) {
        // for(int i = 0; i < launches.length; i++ ) {
        // ILaunchConfiguration config =
        // launches[i].getLaunchConfiguration();
        // if(config != null &&
        // launchConfigurationType.equals(config.getType())) {
        // launchConfigurations = new ILaunchConfiguration[] {config};
        // }
        // }
        // }
        // if(launchConfigurations == null) {
        // launchConfigurations =
        // launchManager.getLaunchConfigurations(launchConfigurationType);
        // }

        ILaunchConfiguration[] launchConfigurations = launchManager
            .getLaunchConfigurations(launchConfigurationType);
        ArrayList<ILaunchConfiguration> matchingConfigs = new ArrayList<ILaunchConfiguration>();
        for (ILaunchConfiguration configuration : launchConfigurations) {
          // substitute variables
          String workDir = MavenLaunchUtils.substituteVar(configuration
              .getAttribute(MavenLaunchConstants.ATTR_POM_DIR,
                  (String) null));
          if (workDir == null) {
            continue;
          }
          IPath workPath = new Path(workDir);
          if (basedirLocation.equals(workPath)) {
            matchingConfigs.add(configuration);
          }
        }

        if (matchingConfigs.size() == 1) {
          Activator.getLogger().info("Using existing launch configuration");
          return matchingConfigs.get(0);
        } else if (matchingConfigs.size() > 1) {
          final IDebugModelPresentation labelProvider = DebugUITools
              .newDebugModelPresentation();
          ElementListSelectionDialog dialog = new ElementListSelectionDialog(
              getShell(), //
              new ILabelProvider() {
                @Override
                public Image getImage(Object element) {
                  return labelProvider.getImage(element);
                }

                @Override
                public String getText(Object element) {
                  if (element instanceof ILaunchConfiguration) {
                    ILaunchConfiguration configuration = (ILaunchConfiguration) element;
                    try {
                      return labelProvider
                          .getText(element)
                          + " : "
                          + configuration
                          .getAttribute(
                              MavenLaunchConstants.ATTR_GOALS,
                              "");
                    } catch (CoreException ex) {
                      // ignore
                    }
                  }
                  return labelProvider.getText(element);
                }

                @Override
                public boolean isLabelProperty(Object element,
                    String property) {
                  return labelProvider.isLabelProperty(
                      element, property);
                }

                @Override
                public void addListener(
                    ILabelProviderListener listener) {
                  labelProvider.addListener(listener);
                }

                @Override
                public void removeListener(
                    ILabelProviderListener listener) {
                  labelProvider.removeListener(listener);
                }

                @Override
                public void dispose() {
                  labelProvider.dispose();
                }
              });
          dialog.setElements(matchingConfigs
              .toArray(new ILaunchConfiguration[matchingConfigs
                                                .size()]));
          dialog.setTitle("Select Configuration");
          if (mode.equals(ILaunchManager.DEBUG_MODE)) {
            dialog.setMessage("Select a launch configuration to debug:");
          } else {
            dialog.setMessage("Select a launch configuration to run:");
          }
          dialog.setMultipleSelection(false);
          int result = dialog.open();
          labelProvider.dispose();
          return result == Window.OK ? (ILaunchConfiguration) dialog
              .getFirstResult() : null;
        }

      } catch (CoreException ex) {
        Activator.getLogger().error("Unable to get the launch configuration.", ex);
      }
    }

    Activator.getLogger().info("Creating new launch configuration");

    // need to do it that way as Eclipse 3.6 differs from 3.5 so we need
    // to
    // introspect to find the correct method to call
    String newName = null;
    try {
      Method m = DebugPlugin.getDefault().getLaunchManager().getClass()
          .getMethod("generateLaunchConfigurationName", String.class);
      newName = (String) m.invoke(DebugPlugin.getDefault()
          .getLaunchManager(), basedir.getName());
    } catch (NoSuchMethodError nsm) {
      newName = DebugPlugin.getDefault().getLaunchManager()
          .generateLaunchConfigurationName(basedir.getName());
    } catch (Exception ex) {
      // ignore
    } finally {
      if (newName == null) {
        newName = basedir.getName();
      }
    }

    try {
      ILaunchConfigurationWorkingCopy workingCopy = launchConfigurationType
          .newInstance(null, newName);
      workingCopy.setAttribute(MavenLaunchConstants.ATTR_POM_DIR,
          basedirLocation.toString());
      workingCopy.setAttribute(
          IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME,
          basedir.getProject().getName());

      appendAttributes(basedir, workingCopy, goalName);

      setProjectConfiguration(workingCopy, basedir);

      // set other defaults if needed
      // MavenLaunchMainTab maintab = new MavenLaunchMainTab();
      // maintab.setDefaults(workingCopy);
      // maintab.dispose();

      return workingCopy.doSave();
    } catch (Exception ex) {
      Activator.getLogger().error("Error creating new launch configuration", ex);
    }
    return null;
  }

  /**
   *
   * @return
   */
  protected String getSelectedFilePath() {
    ISelectionService selService = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService();
    ISelection isel = selService.getSelection();
    if (isel != null && isel instanceof StructuredSelection) {
      StructuredSelection ssel = (StructuredSelection)isel;
      Object elem = ssel.getFirstElement();
      if (elem != null && elem instanceof IFile) {
        IFile f = (IFile)elem;
        return f.getLocationURI().toString();
      }
    }
    return null;
  }

  /**
   *
   * @param basedir
   * @return
   */
  protected IFile getPomFile(IContainer basedir) {
    return basedir.getFile(Path.fromOSString("pom.xml"));   
  }
}
TOP

Related Classes of org.fusesource.ide.launcher.ui.launch.ExecutePomActionSupport

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.