Package org.eclipse.php.internal.debug.ui

Source Code of org.eclipse.php.internal.debug.ui.PHPDebugUIPlugin$FirstSelectionDebugLaunchListener

/*******************************************************************************
* Copyright (c) 2009, 2011 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.ui;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.eclipse.core.internal.runtime.AdapterManager;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IWorkspaceRoot;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.*;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.*;
import org.eclipse.debug.core.model.IDebugTarget;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;
import org.eclipse.debug.internal.ui.viewers.model.InternalTreeModelViewer;
import org.eclipse.debug.internal.ui.views.launch.LaunchView;
import org.eclipse.debug.ui.DebugUITools;
import org.eclipse.debug.ui.IDebugModelPresentation;
import org.eclipse.debug.ui.IDebugUIConstants;
import org.eclipse.equinox.security.storage.ISecurePreferences;
import org.eclipse.equinox.security.storage.SecurePreferencesFactory;
import org.eclipse.jface.dialogs.ErrorDialog;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.TreePath;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.php.internal.debug.core.IPHPDebugConstants;
import org.eclipse.php.internal.debug.core.PHPDebugPlugin;
import org.eclipse.php.internal.debug.core.launching.PHPLaunch;
import org.eclipse.php.internal.debug.core.launching.PHPLaunchUtilities;
import org.eclipse.php.internal.debug.core.model.IPHPDebugTarget;
import org.eclipse.php.internal.debug.ui.actions.EvaluationContextManager;
import org.eclipse.php.internal.debug.ui.views.DebugBrowserView;
import org.eclipse.php.internal.debug.ui.views.DebugOutputView;
import org.eclipse.php.internal.debug.ui.views.variables.PHPDebugElementAdapterFactory;
import org.eclipse.php.internal.ui.util.ImageDescriptorRegistry;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.ui.*;
import org.eclipse.ui.console.IConsoleConstants;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.BundleContext;

/**
* The main plugin class to be used in the desktop.
*/
public class PHPDebugUIPlugin extends AbstractUIPlugin {

  // The shared instance.
  private static PHPDebugUIPlugin plugin;

  private ImageDescriptorRegistry fImageDescriptorRegistry;

  public static final String ID = "org.eclipse.php.debug.ui"; //$NON-NLS-1$
  public static final int INTERNAL_ERROR = 10001;
  private ShowViewListener showViewListener;
  private TerminateDebugLaunchListener finishDebugLaunchListener;
  private FirstSelectionDebugLaunchListener firstSelectionDebugLaunchListener;

  private IDebugModelPresentation fUtilPresentation;

  /**
   * The constructor.
   */
  public PHPDebugUIPlugin() {
    plugin = this;
  }

  /**
   * This method is called upon plug-in activation
   */
  @SuppressWarnings("unchecked")
  public void start(BundleContext context) throws Exception {
    super.start(context);
    showViewListener = new ShowViewListener();
    DebugPlugin.getDefault().addDebugEventListener(showViewListener);

    // Install the TerminateDebugLaunchListener, which is responsible of
    // asking
    // the user to return to the PHP perspective when all the debug sessions
    // where terminated.
    finishDebugLaunchListener = new TerminateDebugLaunchListener();
    DebugPlugin.getDefault().getLaunchManager()
        .addLaunchListener(finishDebugLaunchListener);

    // Install the FirstSelectionDebugLaunchListener, which is responsible
    // of selecting the
    // new launch in the LaunchView.
    firstSelectionDebugLaunchListener = new FirstSelectionDebugLaunchListener();
    DebugPlugin.getDefault().getLaunchManager()
        .addLaunchListener(firstSelectionDebugLaunchListener);

    // Register the PHPDebugElementAdapterFactory.
    // To make sure we are the first adapter factory for the IVariable
    // class, we insert the
    // factory before any other factory.
    AdapterManager manager = (AdapterManager) Platform.getAdapterManager();
    List list = (List) manager.getFactories()
        .get(IVariable.class.getName());
    PHPDebugElementAdapterFactory propertiesFactory = new PHPDebugElementAdapterFactory();
    manager.registerAdapters(propertiesFactory, IVariable.class);
    // In case the list had some factories, make sure our factory is the
    // first in the list.
    if (list != null && list.size() > 1) {
      list.remove(propertiesFactory);
      list.add(0, propertiesFactory);
    }
    // Perform a clean on the secured storage, which might contain SSH
    // tunnels passwords that no longer being used by any of the defined
    // launch configurations.
    cleanSecuredStorage();
    EvaluationContextManager.startup();
  }

  /**
   * This method is called when the plug-in is stopped
   */
  public void stop(BundleContext context) throws Exception {
    super.stop(context);
    if (showViewListener != null) {
      DebugPlugin.getDefault().removeDebugEventListener(showViewListener);
    }

    // Uninstall the debug event listener.
    if (finishDebugLaunchListener != null) {
      DebugPlugin.getDefault().getLaunchManager()
          .removeLaunchListener(finishDebugLaunchListener);
    }
    // Uninstall the debug event listener.
    if (firstSelectionDebugLaunchListener != null) {
      DebugPlugin.getDefault().getLaunchManager()
          .removeLaunchListener(firstSelectionDebugLaunchListener);
    }

    plugin = null;
  }

  /**
   * Returns the shared instance.
   */
  public static PHPDebugUIPlugin getDefault() {
    return plugin;
  }

  /**
   * Returns the PHP debug ID.
   */
  public static String getID() {
    return ID;
  }

  /**
   * Returns an image descriptor for the image file at the given plug-in
   * relative path.
   *
   * @param path
   *            the path
   * @return the image descriptor
   */
  public static ImageDescriptor getImageDescriptor(String path) {
    return AbstractUIPlugin.imageDescriptorFromPlugin(
        "org.eclipse.php.debug.ui", path); //$NON-NLS-1$
  }

  /**
   * Returns the image descriptor registry used for this plugin.
   */
  public static ImageDescriptorRegistry getImageDescriptorRegistry() {
    if (getDefault().fImageDescriptorRegistry == null) {
      getDefault().fImageDescriptorRegistry = new ImageDescriptorRegistry();
    }
    return getDefault().fImageDescriptorRegistry;
  }

  /**
   * Returns the active workbench window
   *
   * @return the active workbench window
   */
  public static IWorkbenchWindow getActiveWorkbenchWindow() {
    return getDefault().getWorkbench().getActiveWorkbenchWindow();
  }

  public static IWorkbenchPage getActivePage() {
    IWorkbenchWindow w = getActiveWorkbenchWindow();
    if (w != null) {
      return w.getActivePage();
    }
    return null;
  }

  /**
   * Returns the active workbench shell or <code>null</code> if none
   *
   * @return the active workbench shell or <code>null</code> if none
   */
  public static Shell getActiveWorkbenchShell() {
    IWorkbenchWindow window = getActiveWorkbenchWindow();
    if (window != null) {
      return window.getShell();
    }
    return null;
  }

  public static Display getStandardDisplay() {
    Display display;
    display = Display.getCurrent();
    if (display == null)
      display = Display.getDefault();
    return display;
  }

  public static void showView(String viewID) {
    IWorkbenchWindow window = getDefault().getWorkbench()
        .getActiveWorkbenchWindow();
    if (window != null) {
      IWorkbenchPage page = window.getActivePage();
      IPerspectiveDescriptor descriptor = page.getPerspective();
      if (descriptor.getId().indexOf("php") != -1) { //$NON-NLS-1$
        if (page != null) {
          IViewPart part = page.findView(viewID);
          if (part == null) {
            try {
              page.showView(viewID);
            } catch (PartInitException e) {
              ErrorDialog.openError(window.getShell(),
                  PHPDebugUIMessages.ShowView_errorTitle,
                  e.getMessage(), e.getStatus());
            }
          } else {
            // page.bringToTop(part);
          }
        }
      }
    }
  }

  public static void log(IStatus status) {
    getDefault().getLog().log(status);
  }

  public static void log(Throwable e) {
    log(new Status(IStatus.ERROR, ID, INTERNAL_ERROR,
        "PHP ui plugin internal error", e)); //$NON-NLS-1$
  }

  public static IProject getProject(String projectName) {
    IWorkspaceRoot workspaceRoot = ResourcesPlugin.getWorkspace().getRoot();
    IProject[] projects = workspaceRoot.getProjects();
    IProject project = null;
    for (IProject element : projects) {
      if (element.getName().equals(projectName)) {
        project = element;
        break;
      }
    }
    return project;
  }

  /*
   * Clean the secure storage from any SSH Tunnel definitions that are no
   * longer used by any of the launch configuration definitions.
   */
  private void cleanSecuredStorage() {
    Job cleanStorageJob = new Job(PHPDebugUIMessages.PHPDebugUIPlugin_2) {
      protected IStatus run(IProgressMonitor monitor) {
        try {
          // First, collect all the tunnel definitions in the launch
          // configurations.
          HashMap<String, List<String>> hostToUsers = new HashMap<String, List<String>>();
          ILaunchManager launchManager = DebugPlugin.getDefault()
              .getLaunchManager();
          ILaunchConfigurationType configurationType = launchManager
              .getLaunchConfigurationType(IPHPDebugConstants.PHPServerLaunchType);
          ILaunchConfiguration[] configs = launchManager
              .getLaunchConfigurations(configurationType);
          for (ILaunchConfiguration configuration : configs) {
            addTunnelConfiguration(configuration, hostToUsers);
          }
          // Then, check with the secure-storage node and remove
          // anything that should not be there.
          ISecurePreferences root = SecurePreferencesFactory
              .getDefault();
          ISecurePreferences node = root
              .node(IPHPDebugConstants.SSH_TUNNEL_SECURE_PREF_NODE);
          String[] listedHosts = node.childrenNames();
          // For each host that we have in the secured storage, check
          // that it's existing in the launch configurations and that
          // it contains
          // only the user names that are defined.
          // In any other case, remove the item from the storage (a
          // host node, or a user node).
          for (String host : listedHosts) {
            if (!hostToUsers.containsKey(host)) {
              ISecurePreferences hostNode = node.node(host);
              hostNode.removeNode();
            } else {
              if (node.nodeExists(host)) {
                ISecurePreferences hostNode = node.node(host);
                // holds the user names field in the secure
                // preference
                String[] usersKeys = hostNode.keys();
                List<String> usersList = hostToUsers.get(host);
                for (String userNode : usersKeys) {
                  if (!usersList.contains(userNode)) {
                    hostNode.remove(userNode);
                  }
                }
              }
            }
          }
        } catch (Exception e) {
          Logger.logException(
              "Error while cleaning up the php debug tunnels credentials from the secured storage", //$NON-NLS-1$
              e);
        }
        return Status.OK_STATUS;
      }
    };
    cleanStorageJob.setSystem(true);
    cleanStorageJob.setPriority(Job.LONG);
    // No rush. We can schedule it to run a few seconds after the loading.
    cleanStorageJob.schedule(30000L);
  }

  /*
   * Potentially, add a tunnel configuration that exists in the given launch
   * configuration. If non exists, nothing is added.
   */
  private void addTunnelConfiguration(ILaunchConfiguration configuration,
      HashMap<String, List<String>> hostToUsers) throws CoreException {
    boolean isUsingTunnel = configuration.getAttribute(
        IPHPDebugConstants.USE_SSH_TUNNEL, false);
    if (isUsingTunnel) {
      String userName = configuration.getAttribute(
          IPHPDebugConstants.SSH_TUNNEL_USER_NAME, ""); //$NON-NLS-1$
      if (userName.length() > 0) {
        String debugHost = PHPLaunchUtilities
            .getDebugHost(configuration);
        List<String> users = hostToUsers.get(debugHost);
        if (users == null) {
          users = new ArrayList<String>(3);
          hostToUsers.put(debugHost, users);
        }
        users.add(userName);
      }
    }
  }

  private static class ShowViewListener implements IDebugEventSetListener {
    public void handleDebugEvents(DebugEvent[] events) {
      if (events != null) {
        int size = events.length;
        for (int i = 0; i < size; i++) {
          DebugEvent event = events[i];
          if (event.getKind() == DebugEvent.CREATE) {
            Object obj = events[i].getSource();

            if (!(obj instanceof IPHPDebugTarget))
              continue;
            if (PHPDebugPlugin.getOpenDebugViewsOption()) {
              Job job = new org.eclipse.ui.progress.UIJob(
                  PHPDebugUIMessages.PHPDebugUIPlugin_0) {
                public IStatus runInUIThread(
                    IProgressMonitor monitor) {
                  showView(DebugBrowserView.ID_PHPBrowserOutput);
                  showView(DebugOutputView.ID_PHPDebugOutput);
                  showView(IConsoleConstants.ID_CONSOLE_VIEW);
                  return Status.OK_STATUS;
                }
              };
              job.schedule();
            }
          }
          if (event.getKind() == DebugEvent.MODEL_SPECIFIC) {
            Object obj = events[i].getSource();

            if (!(obj instanceof IPHPDebugTarget))
              continue;
            final Object data = events[i].getData();
            if (data instanceof IStatus) {
              Job job = new org.eclipse.ui.progress.UIJob(
                  PHPDebugUIMessages.PHPDebugUIPlugin_0) {
                public IStatus runInUIThread(
                    IProgressMonitor monitor) {
                  IStatus status = (IStatus) data;
                  Shell shell = getActiveWorkbenchShell();
                  ErrorDialog.openError(shell, null, null,
                      status);
                  return Status.OK_STATUS;
                }
              };
              job.schedule();
            }

          }
        }
      }
    }
  };

  /*
   * A class that is responsible of asking the user to return to the PHP
   * perspective when all the debug sessions where terminated.
   */
  private static class TerminateDebugLaunchListener implements
      ILaunchesListener2 {

    /**
     * Handle only the termination events.
     */
    public void launchesTerminated(ILaunch[] launches) {
      boolean isPHPLaunch = false;
      for (ILaunch launch : launches) {
        if (launch instanceof PHPLaunch) {
          isPHPLaunch = true;
          break;
        }
      }
      if (!isPHPLaunch) {
        return;
      }
      // In case we have an active debug launches, we can terminate the
      // event handling because there is no need to switch perspective.
      Display.getDefault().asyncExec(new Runnable() {
        public void run() {
          if (!PHPLaunchUtilities.hasPHPDebugLaunch()) {
            PHPLaunchUtilities.switchToPHPPerspective();
          }
        }
      });
    }

    public void launchesAdded(ILaunch[] launches) {
    }

    public void launchesChanged(ILaunch[] launches) {
    }

    public void launchesRemoved(ILaunch[] launches) {
    }
  }

  /*
   * A class that is responsible of selecting the new launch in the
   * LaunchView.
   */
  private static class FirstSelectionDebugLaunchListener implements
      ILaunchesListener2 {

    public void launchesTerminated(ILaunch[] launches) {
    }

    /**
     * handle only add new launch event
     */
    public void launchesAdded(ILaunch[] launches) {
      if (launches != null && launches.length > 0) {
        final ILaunch[] currentLaunches = launches;
        Display.getDefault().asyncExec(new Runnable() {
          public void run() {
            // get the LaunchView
            IWorkbenchWindow activeWorkbenchWindow = PlatformUI
                .getWorkbench().getActiveWorkbenchWindow();
            if (activeWorkbenchWindow == null) {
              return;
            }
            IWorkbenchPage page = activeWorkbenchWindow
                .getActivePage();
            if (page == null)
              return;
            LaunchView view = (LaunchView) page
                .findView(IDebugUIConstants.ID_DEBUG_VIEW);
            if (view == null)
              return;
            try {
              // build the tree path
              // LaunchManager->Launch->DebugTarget->PHPThread->PHPStackFrame
              IDebugTarget target = currentLaunches[0]
                  .getDebugTarget();
              if (target == null)
                return;
              if (target.getThreads() == null
                  || target.getThreads().length == 0)
                return;
              IThread thread = target.getThreads()[0];
              IStackFrame frame = thread.getTopStackFrame();
              if (frame == null)
                return;
              Object[] segments = new Object[5];
              segments[0] = DebugPlugin.getDefault()
                  .getLaunchManager();
              segments[1] = currentLaunches[0];
              segments[2] = target;
              segments[3] = thread;
              segments[4] = frame;
              TreePath treePath = new TreePath(segments);
              // set the current launch as the LaunchViewer
              // selection.
              ((InternalTreeModelViewer) view.getViewer())
                  .setSelection(new TreeSelection(treePath),
                      true, true);
            } catch (DebugException e) {
            }
          }
        });
      }
    }

    public void launchesChanged(ILaunch[] launches) {
    }

    public void launchesRemoved(ILaunch[] launches) {
    }
  }

  /**
   * Returns a shared utility PHP debug model presentation. Clients should not
   * dispose the presentation.
   *
   * @return a PHP debug model presentation
   */
  public IDebugModelPresentation getModelPresentation() {
    if (fUtilPresentation == null) {
      fUtilPresentation = DebugUITools
          .newDebugModelPresentation(IPHPDebugConstants.ID_PHP_DEBUG_CORE);
    }
    return fUtilPresentation;
  }
}
TOP

Related Classes of org.eclipse.php.internal.debug.ui.PHPDebugUIPlugin$FirstSelectionDebugLaunchListener

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.