Package org.eclipse.php.internal.debug.core.launching

Source Code of org.eclipse.php.internal.debug.core.launching.PHPExecutableLaunchDelegate

/*******************************************************************************
* Copyright (c) 2009 IBM Corporation and others.
* 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
*
* Contributors:
*     IBM Corporation - initial API and implementation
*     Zend Technologies
*******************************************************************************/
package org.eclipse.php.internal.debug.core.launching;

import java.io.File;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.*;
import org.eclipse.debug.core.*;
import org.eclipse.debug.core.model.IProcess;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.debug.ui.CommonTab;
import org.eclipse.debug.ui.RefreshTab;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.php.debug.core.debugger.parameters.IDebugParametersInitializer;
import org.eclipse.php.debug.core.debugger.parameters.IDebugParametersKeys;
import org.eclipse.php.internal.debug.core.IPHPDebugConstants;
import org.eclipse.php.internal.debug.core.Logger;
import org.eclipse.php.internal.debug.core.PHPDebugCoreMessages;
import org.eclipse.php.internal.debug.core.PHPDebugPlugin;
import org.eclipse.php.internal.debug.core.phpIni.PHPINIUtil;
import org.eclipse.php.internal.debug.core.preferences.PHPProjectPreferences;
import org.eclipse.php.internal.debug.core.preferences.PHPexeItem;
import org.eclipse.php.internal.debug.core.preferences.PHPexes;
import org.eclipse.php.internal.debug.core.zend.communication.DebuggerCommunicationDaemon;
import org.eclipse.php.internal.debug.core.zend.debugger.DebugParametersInitializersRegistry;
import org.eclipse.php.internal.debug.core.zend.debugger.PHPExecutableDebuggerInitializer;
import org.eclipse.php.internal.debug.core.zend.debugger.PHPSessionLaunchMapper;
import org.eclipse.php.internal.debug.core.zend.debugger.ProcessCrashDetector;
import org.eclipse.php.internal.debug.daemon.DaemonPlugin;
import org.eclipse.swt.widgets.Display;

import com.ibm.icu.text.MessageFormat;

public class PHPExecutableLaunchDelegate extends LaunchConfigurationDelegate {

  public static final String SAVE_AUTOMATICALLY = "save_automatically"; //$NON-NLS-1$

  protected Map<String, String> envVariables = null;

  /**
   * Override the extended getLaunch to create a PHPLaunch.
   */
  public ILaunch getLaunch(ILaunchConfiguration configuration, String mode)
      throws CoreException {
    return new PHPLaunch(configuration, mode, null);
  }

  public void debugPHPExecutable(ILaunch launch, String phpExe,
      String fileToDebug) throws DebugException {
    try {
      launch.setAttribute(IDebugParametersKeys.EXECUTABLE_LAUNCH,
          Boolean.toString(true));

      IDebugParametersInitializer parametersInitializer = DebugParametersInitializersRegistry
          .getBestMatchDebugParametersInitializer(launch);
      PHPExecutableDebuggerInitializer debuggerInitializer = new PHPExecutableDebuggerInitializer(
          launch);

      String phpExeString = new File(phpExe).getAbsolutePath();
      String fileName = new File(fileToDebug).getAbsolutePath();
      String query = PHPLaunchUtilities.generateQuery(launch,
          parametersInitializer);
      String iniFileLocation = launch
          .getAttribute(IDebugParametersKeys.PHP_INI_LOCATION);
      String workingDir = new File(fileToDebug).getParentFile()
          .getAbsolutePath();

      debuggerInitializer.initializeDebug(phpExeString, fileName,
          workingDir, query, envVariables, iniFileLocation);

    } catch (java.io.IOException e1) {
      Logger.logException(
          "PHPDebugTarget: Debugger didn't find file to debug.", e1); //$NON-NLS-1$
      String errorMessage = PHPDebugCoreMessages.DebuggerFileNotFound_1;
      throw new DebugException(new Status(IStatus.ERROR,
          PHPDebugPlugin.getID(), IPHPDebugConstants.INTERNAL_ERROR,
          errorMessage, e1));
    }
  }

  public void launch(ILaunchConfiguration configuration, String mode,
      ILaunch launch, IProgressMonitor monitor) throws CoreException {
    // Check that the debug daemon is functional
    // DEBUGGER - Make sure that the active debugger id is indeed Zend's
    // debugger
    if (!DaemonPlugin.getDefault().validateCommunicationDaemons(
        DebuggerCommunicationDaemon.ZEND_DEBUGGER_ID)) {
      monitor.setCanceled(true);
      monitor.done();
      return;
    }
    // Check for previous launches.
    if (!PHPLaunchUtilities.notifyPreviousLaunches(launch)) {
      monitor.setCanceled(true);
      monitor.done();
      return;
    }
    PHPLaunchUtilities.showDebugView();
    IProgressMonitor subMonitor; // the total of monitor is 100
    if (monitor.isCanceled()) {
      return;
    }

    String phpExeString = configuration.getAttribute(
        IPHPDebugConstants.ATTR_EXECUTABLE_LOCATION, (String) null);
    String phpIniPath = configuration.getAttribute(
        IPHPDebugConstants.ATTR_INI_LOCATION, (String) null);
    String fileName = configuration.getAttribute(
        IPHPDebugConstants.ATTR_FILE_FULL_PATH, (String) null);
    boolean runWithDebugInfo = configuration.getAttribute(
        IPHPDebugConstants.RUN_WITH_DEBUG_INFO, true);

    IProject project = null;
    String file = configuration.getAttribute(IPHPDebugConstants.ATTR_FILE,
        (String) null);
    if (file != null) {
      IResource resource = ResourcesPlugin.getWorkspace().getRoot()
          .findMember(file);
      if (resource != null) {
        project = resource.getProject();
      } else {
        String projectName = configuration.getAttribute(
            IPHPDebugConstants.ATTR_PROJECT_NAME, (String) null);
        if (projectName != null) {
          IProject resolved = ResourcesPlugin.getWorkspace()
              .getRoot().getProject(projectName);
          if (resolved != null && resolved.isAccessible()) {
            project = resolved;
          }
        }
      }
    }

    if (monitor.isCanceled()) {
      return;
    }

    if (fileName == null || fileName.equals("")) { //$NON-NLS-1$
      displayErrorMessage(PHPDebugCoreMessages.PHPExecutableLaunchDelegate_0);
      return;
    }

    if (phpExeString == null) {
      displayErrorMessage(PHPDebugCoreMessages.PHPExecutableLaunchDelegate_4);
      return;
    }

    subMonitor = new SubProgressMonitor(monitor, 10); // 10 of 100

    // Locate the php.ini by using the attribute. If the attribute was null,
    // try to locate an php.ini that exists next to the executable.
    File phpIni = (phpIniPath != null && new File(phpIniPath).exists()) ? new File(
        phpIniPath) : PHPINIUtil.findPHPIni(phpExeString);
    File tempIni = PHPINIUtil.prepareBeforeDebug(phpIni, phpExeString,
        project);
    launch.setAttribute(IDebugParametersKeys.PHP_INI_LOCATION,
        tempIni.getAbsolutePath());

    if (mode.equals(ILaunchManager.DEBUG_MODE) || runWithDebugInfo == true) {
      boolean stopAtFirstLine = configuration.getAttribute(
          IDebugParametersKeys.FIRST_LINE_BREAKPOINT,
          PHPProjectPreferences.getStopAtFirstLine(project));
      int requestPort = PHPDebugPlugin
          .getDebugPort(DebuggerCommunicationDaemon.ZEND_DEBUGGER_ID);

      ILaunchConfigurationWorkingCopy wc;
      if (configuration.isWorkingCopy()) {
        wc = (ILaunchConfigurationWorkingCopy) configuration;
      } else {
        wc = configuration.getWorkingCopy();
      }

      // Set Project Name
      if (project != null) {
        wc.setAttribute(IPHPDebugConstants.PHP_Project, project
            .getFullPath().toString());
      }

      // Set transfer encoding:
      wc.setAttribute(IDebugParametersKeys.TRANSFER_ENCODING,
          PHPProjectPreferences.getTransferEncoding(project));
      wc.setAttribute(IDebugParametersKeys.OUTPUT_ENCODING,
          PHPProjectPreferences.getOutputEncoding(project));
      wc.setAttribute(IDebugParametersKeys.PHP_DEBUG_TYPE,
          IDebugParametersKeys.PHP_EXE_SCRIPT_DEBUG);
      wc.doSave();

      if (monitor.isCanceled()) {
        return;
      }

      // Generate a session id for this launch and put it in the map
      int sessionID = DebugSessionIdGenerator.generateSessionID();
      PHPSessionLaunchMapper.put(sessionID, launch);

      // Define all needed debug attributes:
      launch.setAttribute(IDebugParametersKeys.PORT,
          Integer.toString(requestPort));
      launch.setAttribute(IDebugParametersKeys.FIRST_LINE_BREAKPOINT,
          Boolean.toString(stopAtFirstLine));
      launch.setAttribute(IDebugParametersKeys.SESSION_ID,
          Integer.toString(sessionID));

      // Trigger the debug session by initiating a debug requset to the
      // php.exe
      debugPHPExecutable(launch, phpExeString, fileName);

    } else {
      // resolve location
      IPath phpExe = new Path(phpExeString);

      String[] envp = DebugPlugin.getDefault().getLaunchManager()
          .getEnvironment(configuration);
      File phpExeFile = new File(phpExeString);
      String phpIniLocation = launch
          .getAttribute(IDebugParametersKeys.PHP_INI_LOCATION);

      // Determine PHP configuration file location:
      String phpConfigDir = phpExeFile.getParent();
      if (phpIniLocation != null && !phpIniLocation.equals("")) { //$NON-NLS-1$
        phpConfigDir = new File(phpIniLocation).getParent();
      }

      // Detect PHP SAPI type:
      String sapiType = null;
      String phpV = null;
      PHPexeItem[] items = PHPexes.getInstance().getAllItems();
      for (PHPexeItem item : items) {
        if (item.getExecutable().equals(phpExeFile)) {
          sapiType = item.getSapiType();
          phpV = item.getVersion();
          break;
        }
      }

      String[] args = PHPLaunchUtilities.getProgramArguments(launch
          .getLaunchConfiguration());
      String[] cmdLine = PHPLaunchUtilities.getCommandLine(
          launch.getLaunchConfiguration(), phpExeString,
          phpConfigDir, fileName,
          PHPexeItem.SAPI_CLI.equals(sapiType) ? args : null, phpV);

      // Set library search path:
      String libPath = PHPLaunchUtilities
          .getLibrarySearchPathEnv(phpExeFile.getParentFile());
      if (libPath != null) {
        String[] envpNew = new String[envp == null ? 1
            : envp.length + 1];
        if (envp != null) {
          System.arraycopy(envp, 0, envpNew, 0, envp.length);
        }
        envpNew[envpNew.length - 1] = libPath;
        envp = envpNew;
      }

      if (monitor.isCanceled()) {
        return;
      }

      File workingDir = new File(fileName).getParentFile();
      Process p = workingDir.exists() ? DebugPlugin.exec(cmdLine,
          workingDir, envp) : DebugPlugin.exec(cmdLine, null, envp);

      // Attach a crash detector
      new Thread(new ProcessCrashDetector(launch, p)).start();

      IProcess process = null;

      // add process type to process attributes
      Map<String, String> processAttributes = new HashMap<String, String>();
      String programName = phpExe.lastSegment();
      String extension = phpExe.getFileExtension();

      if (extension != null) {
        programName = programName.substring(0, programName.length()
            - (extension.length() + 1));
      }

      programName = programName.toLowerCase();
      processAttributes.put(IProcess.ATTR_PROCESS_TYPE, programName);

      if (p != null) {
        subMonitor = new SubProgressMonitor(monitor, 80); // 10+80 of
                                  // 100;
        subMonitor
            .beginTask(
                MessageFormat
                    .format("start launch", new Object[] { configuration.getName() }), IProgressMonitor.UNKNOWN); //$NON-NLS-1$
        process = DebugPlugin.newProcess(launch, p,
            phpExe.toOSString(), processAttributes);
        if (process == null) {
          p.destroy();
          throw new CoreException(new Status(IStatus.ERROR,
              PHPDebugPlugin.getID(), 0, null, null));
        }
        subMonitor.done();
      }
      process.setAttribute(IProcess.ATTR_CMDLINE, fileName);

      if (CommonTab.isLaunchInBackground(configuration)) {
        // refresh resources after process finishes
        /*
         * if (RefreshTab.getRefreshScope(configuration) != null) {
         * BackgroundResourceRefresher refresher = new
         * BackgroundResourceRefresher(configuration, process);
         * refresher.startBackgroundRefresh(); }
         */
      } else {
        // wait for process to exit
        while (!process.isTerminated()) {
          try {
            if (monitor.isCanceled()) {
              process.terminate();
              break;
            }
            Thread.sleep(50);
          } catch (InterruptedException e) {
          }
        }

        // refresh resources
        subMonitor = new SubProgressMonitor(monitor, 10); // 10+80+10 of
                                  // 100;
        RefreshTab.refreshResources(configuration, subMonitor);
      }
    }
  }

  private void displayErrorMessage(final String message) {
    final Display display = Display.getDefault();
    display.asyncExec(new Runnable() {
      public void run() {
        MessageDialog.openError(display.getActiveShell(),
            PHPDebugCoreMessages.Debugger_LaunchError_title,
            message);
      }
    });
  }

  protected boolean saveBeforeLaunch(ILaunchConfiguration configuration,
      String mode, IProgressMonitor monitor) throws CoreException {
    String filePath = configuration.getAttribute(
        IPHPDebugConstants.ATTR_FILE, ""); //$NON-NLS-1$
    if ("".equals(filePath)) { //$NON-NLS-1$
      return super.saveBeforeLaunch(configuration, mode, monitor);
    }
    return super.saveBeforeLaunch(configuration, mode, monitor);
  }

}
TOP

Related Classes of org.eclipse.php.internal.debug.core.launching.PHPExecutableLaunchDelegate

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.