/******************************************************************************* * 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.preferences; import java.util.*; import java.util.Map.Entry; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; import org.eclipse.php.debug.daemon.communication.ICommunicationDaemon; import org.eclipse.php.internal.debug.core.Logger; import org.eclipse.php.internal.debug.core.PHPDebugPlugin; import org.eclipse.php.internal.debug.core.debugger.AbstractDebuggerConfiguration; import org.eclipse.php.internal.debug.core.debugger.IDebuggerConfiguration; import org.eclipse.php.internal.debug.core.debugger.NoneDebuggerConfiguration; import org.eclipse.php.internal.debug.core.zend.communication.DebuggerCommunicationDaemon; import org.eclipse.php.internal.debug.daemon.communication.DaemonsRegistry; import org.eclipse.ui.IPluginContribution; import org.eclipse.ui.activities.WorkbenchActivityHelper; /** * A registry class for all the PHP debuggers. This registry class supplies the * IDs and the names of all the registered PHP debuggers. The basic PDT supports * Zend's debugger and XDebug debugger. * * @author Shalom Gibly * @since PDT 1.0 */ public class PHPDebuggersRegistry { public static final String NONE_DEBUGGER_ID = "org.eclipse.php.debug.core.noneDebugger"; //$NON-NLS-1$ private static final String EXTENSION_POINT_NAME = "phpDebuggers"; //$NON-NLS-1$ private static final String DEBUGGER_TAG = "phpDebugger"; //$NON-NLS-1$ private static final String NAME_ATTRIBUTE = "name"; //$NON-NLS-1$ private static final String ID_ATTRIBUTE = "id"; //$NON-NLS-1$ private static final String CONFIGURATION_CLASS_ATTRIBUTE = "debuggerConfiguration"; //$NON-NLS-1$ // Zend's debugger is the default for the PDT, however, this can be changed // by calling the setDefaultDebuggerId() method. private static String DEFAULT_DEBUGGER_ID = DebuggerCommunicationDaemon.ZEND_DEBUGGER_ID; private static final String NONE_DEBUGGER_NAME = "<none>"; //$NON-NLS-1$ private static PHPDebuggersRegistry instance; private HashMap<String, String> debuggers = new HashMap<String, String>(); private HashMap<String, AbstractDebuggerConfiguration> configurations = new HashMap<String, AbstractDebuggerConfiguration>(); private AbstractDebuggerConfiguration noneDebuggerConfiguration = new NoneDebuggerConfiguration(); private PHPDebuggersRegistry() { loadDebuggers(); } private static PHPDebuggersRegistry getInstance() { if (instance == null) { instance = new PHPDebuggersRegistry(); } return instance; } /** * Returns an unmodifiable Set of the registered debuggers ids. * * @return An unmodifiable Set of the registered debuggers ids. */ public static Set<String> getDebuggersIds() { return Collections.unmodifiableSet(getInstance().debuggers.keySet()); } /** * Returns the debugger configuration for the given debugger id. * * @param debuggerId * @return An AbstractDebuggerConfiguration, or null if no such debugger id * exists. */ public static AbstractDebuggerConfiguration getDebuggerConfiguration(String debuggerId) { if (NONE_DEBUGGER_ID.equals(debuggerId)) return getInstance().noneDebuggerConfiguration; return getInstance().configurations.get(debuggerId); } /** * <p> * Returns all debuggers configurations. * </p> * <p> * NOTE: 'none' mock debugger configuration is not returned by this method. * </p> * * @return An array of all the loaded AbstractDebuggerConfiguration. */ public static AbstractDebuggerConfiguration[] getDebuggersConfigurations() { Collection<AbstractDebuggerConfiguration> values = getInstance().configurations.values(); AbstractDebuggerConfiguration[] configurations = new AbstractDebuggerConfiguration[values.size()]; return values.toArray(configurations); } /** * Returns the default debugger ID. * * @return The default debugger ID. */ public static String getDefaultDebuggerId() { return DEFAULT_DEBUGGER_ID; } /** * Set the default debugger ID. * * @param id * The debugger id (must exist in the registered ids) * @throws IllegalArgumentException * If the given id is not registered as part of the supported * ids. * @see #getDefaultDebuggerId() * @see #getDebuggersIds() */ public static void setDefaultDebuggerId(String id) throws IllegalArgumentException { if (getInstance().debuggers.containsKey(id)) { DEFAULT_DEBUGGER_ID = id; } else { throw new IllegalArgumentException("No such debugger id was registered: " + id); //$NON-NLS-1$ } } /** * Returns the debugger name according to the given debugger id. * * @param debuggerID * @return The debugger name */ public static String getDebuggerName(String debuggerID) { return getInstance().debuggers.get(debuggerID); } public static boolean isNoneDebugger(String debuggerID) { return NONE_DEBUGGER_ID.equals(debuggerID); } // Load the debuggers into the map. // Do this only once. private void loadDebuggers() { final IExtensionRegistry registry = Platform.getExtensionRegistry(); final IConfigurationElement[] elements = registry.getConfigurationElementsFor(PHPDebugPlugin.getID(), EXTENSION_POINT_NAME); // We use the following HashMap in order to accumulate non PDT debugger // configurations. // that are extension to point: org.eclipse.php.debug.core.phpDebuggers HashMap<String, AbstractDebuggerConfiguration> nonPDTConfigurations = new HashMap<String, AbstractDebuggerConfiguration>(); for (final IConfigurationElement element : elements) { if (DEBUGGER_TAG.equals(element.getName())) { final String name = element.getAttribute(NAME_ATTRIBUTE); final String id = element.getAttribute(ID_ATTRIBUTE); boolean isPDT = element.getNamespaceIdentifier().startsWith("org.eclipse.php"); //$NON-NLS-1$ boolean filter = WorkbenchActivityHelper.filterItem(new IPluginContribution() { public String getLocalId() { return id; } public String getPluginId() { return element.getNamespaceIdentifier(); } }); if (filter) { continue; } debuggers.put(id, name); try { AbstractDebuggerConfiguration configuration = (AbstractDebuggerConfiguration) element .createExecutableExtension(CONFIGURATION_CLASS_ATTRIBUTE); configuration.setDebuggerId(id); configuration.setName(name); try { List<ICommunicationDaemon> daemons = DaemonsRegistry.getDaemons(); // find the daemon that fits this configuration (match // by debugger-id) for (ICommunicationDaemon daemon : daemons) { if (daemon.isDebuggerDaemon() && id.equals(daemon.getDebuggerID())) { configuration.setCommunicationDaemon(daemon); // Attach // the // daemon // reference // to // the // configuration. break; } } } catch (Exception e) { configuration.setPort(-1); } configurations.put(id, configuration); if (!isPDT) { nonPDTConfigurations.put(id, configuration); } } catch (CoreException e) { Logger.logException(e); } } } // Override any PDT debugger settings with any extension of debugger // configuration. for (Entry<String, AbstractDebuggerConfiguration> entry : nonPDTConfigurations.entrySet()) { AbstractDebuggerConfiguration configuration = entry.getValue(); configurations.put(entry.getKey(), configuration); debuggers.put(configuration.getDebuggerId(), configuration.getName()); } debuggers.put(NONE_DEBUGGER_ID, NONE_DEBUGGER_NAME); } }