| /******************************************************************************* |
| * Copyright (c) 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Common Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/cpl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.internal.commands; |
| |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.eclipse.core.commands.Category; |
| import org.eclipse.core.commands.Command; |
| import org.eclipse.core.commands.CommandManager; |
| import org.eclipse.core.commands.IHandler; |
| import org.eclipse.core.commands.common.NotDefinedException; |
| import org.eclipse.core.commands.contexts.ContextManager; |
| import org.eclipse.core.runtime.Platform; |
| import org.eclipse.jface.bindings.Binding; |
| import org.eclipse.jface.bindings.BindingManager; |
| import org.eclipse.jface.bindings.BindingManagerEvent; |
| import org.eclipse.jface.bindings.IBindingManagerListener; |
| import org.eclipse.jface.bindings.Scheme; |
| import org.eclipse.jface.bindings.TriggerSequence; |
| import org.eclipse.jface.bindings.keys.KeyBinding; |
| import org.eclipse.jface.bindings.keys.ParseException; |
| import org.eclipse.ui.commands.CommandManagerEvent; |
| import org.eclipse.ui.commands.ICategory; |
| import org.eclipse.ui.commands.ICommand; |
| import org.eclipse.ui.commands.ICommandManager; |
| import org.eclipse.ui.commands.ICommandManagerListener; |
| import org.eclipse.ui.commands.IKeyConfiguration; |
| import org.eclipse.ui.internal.WorkbenchPlugin; |
| import org.eclipse.ui.internal.util.Util; |
| import org.eclipse.ui.keys.KeySequence; |
| |
| /** |
| * Provides support for the old <code>ICommandManager</code> interface. |
| * |
| * @since 3.1 |
| */ |
| public final class CommandManagerWrapper implements ICommandManager, |
| org.eclipse.core.commands.ICommandManagerListener, |
| IBindingManagerListener { |
| |
| /** |
| * Whether commands should print out information about which handlers are |
| * being executed. Change this value if you want console output on command |
| * execution. |
| */ |
| public static boolean DEBUG_COMMAND_EXECUTION = false; |
| |
| /** |
| * Whether commands should print out information about handler changes. |
| * Change this value if you want console output when commands change |
| * handlers. |
| */ |
| public static boolean DEBUG_HANDLERS = false; |
| |
| /** |
| * Which command should print out debugging information. Change this value |
| * if you want to only here when a command with a particular identifier |
| * changes its handler. |
| */ |
| public static String DEBUG_HANDLERS_COMMAND_ID = null; |
| |
| static boolean isKeyConfigurationDefinitionChildOf(String ancestor, |
| String id, Map keyConfigurationDefinitionsById) { |
| Collection visited = new HashSet(); |
| while (id != null && !visited.contains(id)) { |
| KeyConfigurationDefinition keyConfigurationDefinition = (KeyConfigurationDefinition) keyConfigurationDefinitionsById |
| .get(id); |
| visited.add(id); |
| if (keyConfigurationDefinition != null |
| && Util.equals(id = keyConfigurationDefinition |
| .getParentId(), ancestor)) |
| return true; |
| } |
| return false; |
| } |
| |
| static boolean validateKeySequence(KeySequence keySequence) { |
| if (keySequence == null) |
| return false; |
| List keyStrokes = keySequence.getKeyStrokes(); |
| int size = keyStrokes.size(); |
| if (size == 0 || size > 4 || !keySequence.isComplete()) |
| return false; |
| return true; |
| } |
| |
| static void validateKeySequenceBindingDefinitions( |
| Collection keySequenceBindingDefinitions) { |
| Iterator iterator = keySequenceBindingDefinitions.iterator(); |
| while (iterator.hasNext()) { |
| KeySequenceBindingDefinition keySequenceBindingDefinition = (KeySequenceBindingDefinition) iterator |
| .next(); |
| String keyConfigurationId = keySequenceBindingDefinition |
| .getKeyConfigurationId(); |
| KeySequence keySequence = keySequenceBindingDefinition |
| .getKeySequence(); |
| if (keyConfigurationId == null || keySequence == null |
| || !validateKeySequence(keySequence)) |
| iterator.remove(); |
| } |
| } |
| |
| /** |
| * The JFace binding machine that provides binding support for this |
| * workbench mutable command manager. This value will never be |
| * <code>null</code>. |
| * |
| * @since 3.1 |
| */ |
| private final BindingManager bindingManager; |
| |
| /** |
| * The command manager that provides functionality for this workbench |
| * command manager. This value will never be <code>null</code>. |
| * |
| * @since 3.1 |
| */ |
| private final CommandManager commandManager; |
| |
| private List commandManagerListeners; |
| |
| private ICommandRegistry commandRegistry; |
| |
| /** |
| * The context manager that provides functionality for this workbench |
| * command manager. This value will never be <code>null</code>. |
| * |
| * @since 3.1 |
| */ |
| private final ContextManager contextManager; |
| |
| /** |
| * The set of handlers defined in XML. This set is never <code>null</code>. |
| * It may be empty if there are either no handler submissions defined in XML |
| * or if the method <code>readRegistry</code> has not yet been called. |
| */ |
| private final Set definedHandlers = new HashSet(); |
| |
| private IMutableCommandRegistry mutableCommandRegistry; |
| |
| /** |
| * Constructs a new instance of <code>MutableCommandManager</code>. The |
| * registry readers are constructed automatically at this time. |
| * |
| * @param bindingManager |
| * The binding manager providing support for the command manager; |
| * must not be <code>null</code>. |
| * @param commandManager |
| * The command manager providing support for this command |
| * manager; must not be <code>null</code>. |
| * @param contextManager |
| * The context manager to provide context support to this |
| * manager. This value must not be <code>null</code>. |
| */ |
| public CommandManagerWrapper(final BindingManager bindingManager, |
| final CommandManager commandManager, |
| final ContextManager contextManager) { |
| this(new ExtensionCommandRegistry(Platform.getExtensionRegistry()), |
| new PreferenceCommandRegistry(WorkbenchPlugin.getDefault() |
| .getPreferenceStore()), bindingManager, commandManager, |
| contextManager); |
| } |
| |
| /** |
| * Constructs a new instance of <code>MutableCommandManager</code>. The |
| * binding manager and command manager providing support for this manager |
| * are constructed at this time. |
| * |
| * @param commandRegistry |
| * The plug-in registry from which the commands should be read; |
| * must not be <code>null</code>. |
| * @param mutableCommandRegistry |
| * The preference registry from which preferences should be read; |
| * must not be <code>null</code>. |
| * @param bindingManager |
| * The binding manager providing support for the command manager; |
| * must not be <code>null</code>. |
| * @param commandManager |
| * The command manager providing support for this command |
| * manager; must not be <code>null</code>. |
| * @param contextManager |
| * The context manager to provide context support to this |
| * manager. This value must not be <code>null</code>. |
| * |
| */ |
| public CommandManagerWrapper(final ICommandRegistry commandRegistry, |
| final IMutableCommandRegistry mutableCommandRegistry, |
| final BindingManager bindingManager, |
| final CommandManager commandManager, |
| final ContextManager contextManager) { |
| if (contextManager == null) { |
| throw new NullPointerException( |
| "The context manager cannot be null."); //$NON-NLS-1$ |
| } |
| |
| if ((commandRegistry == null) || (mutableCommandRegistry == null)) { |
| throw new NullPointerException("The registries must not be null."); //$NON-NLS-1$ |
| } |
| |
| this.commandRegistry = commandRegistry; |
| this.mutableCommandRegistry = mutableCommandRegistry; |
| this.bindingManager = bindingManager; |
| this.commandManager = commandManager; |
| this.contextManager = contextManager; |
| |
| this.commandRegistry |
| .addCommandRegistryListener(new ICommandRegistryListener() { |
| public void commandRegistryChanged( |
| CommandRegistryEvent commandRegistryEvent) { |
| readRegistry(); |
| } |
| }); |
| this.mutableCommandRegistry |
| .addCommandRegistryListener(new ICommandRegistryListener() { |
| public void commandRegistryChanged( |
| CommandRegistryEvent commandRegistryEvent) { |
| readRegistry(); |
| } |
| }); |
| this.commandManager.addCommandManagerListener(this); |
| this.bindingManager.addBindingManagerListener(this); |
| |
| // Make sure to read in the registry. |
| readRegistry(); |
| } |
| |
| public final void addCommandManagerListener( |
| final ICommandManagerListener commandManagerListener) { |
| if (commandManagerListener == null) { |
| throw new NullPointerException("Cannot add a null listener."); //$NON-NLS-1$ |
| } |
| |
| if (commandManagerListeners == null) { |
| commandManagerListeners = new ArrayList(); |
| } |
| |
| if (!commandManagerListeners.contains(commandManagerListener)) { |
| commandManagerListeners.add(commandManagerListener); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.jface.bindings.IBindingManagerListener#bindingManagerChanged(org.eclipse.jface.bindings.BindingManagerEvent) |
| */ |
| public void bindingManagerChanged(BindingManagerEvent event) { |
| // TODO Fire a command manager event. |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.commands.ICommandManagerListener#commandManagerChanged(org.eclipse.commands.CommandManagerEvent) |
| */ |
| public void commandManagerChanged( |
| org.eclipse.core.commands.CommandManagerEvent commandManagerEvent) { |
| // TODO Fire a command manager event. |
| } |
| |
| private void fireCommandManagerChanged( |
| CommandManagerEvent commandManagerEvent) { |
| if (commandManagerEvent == null) |
| throw new NullPointerException(); |
| if (commandManagerListeners != null) |
| for (int i = 0; i < commandManagerListeners.size(); i++) |
| ((ICommandManagerListener) commandManagerListeners.get(i)) |
| .commandManagerChanged(commandManagerEvent); |
| } |
| |
| public Set getActiveContextIds() { |
| return contextManager.getActiveContextIds(); |
| } |
| |
| public String getActiveKeyConfigurationId() { |
| final Scheme scheme = bindingManager.getActiveScheme(); |
| if (scheme != null) { |
| return scheme.getId(); |
| } |
| |
| /* |
| * TODO This is possibly a breaking change. The id should be non-null, |
| * and presumably, a real scheme id. |
| */ |
| return Util.ZERO_LENGTH_STRING; |
| } |
| |
| public String getActiveLocale() { |
| return bindingManager.getLocale(); |
| } |
| |
| public String getActivePlatform() { |
| return bindingManager.getPlatform(); |
| } |
| |
| public ICategory getCategory(String categoryId) { |
| // TODO Provide access to the categories. |
| //return new CategoryWrapper(commandManager.getCategory(categoryId)); |
| return null; |
| } |
| |
| public ICommand getCommand(String commandId) { |
| final Command command = commandManager.getCommand(commandId); |
| return new CommandWrapper(command, bindingManager); |
| } |
| |
| /** |
| * Returns the plug-in registry for this command manager. |
| * |
| * @return The command registry; never <code>null</code>. |
| */ |
| public ICommandRegistry getCommandRegistry() { |
| return commandRegistry; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.eclipse.ui.commands.ICommandManager#getDefinedCategoryIds() |
| */ |
| public Set getDefinedCategoryIds() { |
| return commandManager.getDefinedCategoryIds(); |
| } |
| |
| public Set getDefinedCommandIds() { |
| return commandManager.getDefinedCommandIds(); |
| } |
| |
| /** |
| * An accessor for those handlers that have been defined in XML. |
| * |
| * @return The handlers defined in XML; never <code>null</code>, but may |
| * be empty. |
| */ |
| public Set getDefinedHandlers() { |
| return definedHandlers; |
| } |
| |
| public Set getDefinedKeyConfigurationIds() { |
| return bindingManager.getDefinedSchemeIds(); |
| } |
| |
| public IKeyConfiguration getKeyConfiguration(String keyConfigurationId) { |
| final Scheme scheme = bindingManager.getScheme(keyConfigurationId); |
| return new SchemeWrapper(scheme, bindingManager); |
| } |
| |
| IMutableCommandRegistry getMutableCommandRegistry() { |
| return mutableCommandRegistry; |
| } |
| |
| public Map getPartialMatches(KeySequence keySequence) { |
| try { |
| final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence |
| .getInstance(keySequence.toString()); |
| final Map partialMatches = bindingManager |
| .getPartialMatches(sequence); |
| final Map returnValue = new HashMap(); |
| final Iterator matchItr = partialMatches.entrySet().iterator(); |
| while (matchItr.hasNext()) { |
| final Map.Entry entry = (Map.Entry) matchItr.next(); |
| final TriggerSequence trigger = (TriggerSequence) entry |
| .getKey(); |
| if (trigger instanceof org.eclipse.jface.bindings.keys.KeySequence) { |
| final org.eclipse.jface.bindings.keys.KeySequence triggerKey = (org.eclipse.jface.bindings.keys.KeySequence) trigger; |
| returnValue.put(KeySequence.getInstance(triggerKey |
| .toString()), entry.getValue()); |
| } |
| } |
| return returnValue; |
| } catch (final ParseException e) { |
| return new HashMap(); |
| } catch (final org.eclipse.ui.keys.ParseException e) { |
| return new HashMap(); |
| } |
| } |
| |
| public String getPerfectMatch(KeySequence keySequence) { |
| try { |
| final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence |
| .getInstance(keySequence.toString()); |
| return bindingManager.getPerfectMatch(sequence); |
| } catch (final ParseException e) { |
| return null; |
| } |
| } |
| |
| public boolean isPartialMatch(KeySequence keySequence) { |
| try { |
| final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence |
| .getInstance(keySequence.toString()); |
| return bindingManager.isPartialMatch(sequence); |
| } catch (final ParseException e) { |
| return false; |
| } |
| } |
| |
| public boolean isPerfectMatch(KeySequence keySequence) { |
| try { |
| final org.eclipse.jface.bindings.keys.KeySequence sequence = org.eclipse.jface.bindings.keys.KeySequence |
| .getInstance(keySequence.toString()); |
| return bindingManager.isPerfectMatch(sequence); |
| } catch (final ParseException e) { |
| return false; |
| } |
| } |
| |
| private void readRegistry() { |
| // Copy in the category definitions. |
| final Collection categoryDefinitions = new ArrayList(); |
| categoryDefinitions.addAll(commandRegistry.getCategoryDefinitions()); |
| categoryDefinitions.addAll(mutableCommandRegistry |
| .getCategoryDefinitions()); |
| final Map categoryDefinitionsById = new HashMap(CategoryDefinition |
| .categoryDefinitionsById(categoryDefinitions, false)); |
| Iterator categoryDefinitionItr = categoryDefinitionsById.values() |
| .iterator(); |
| while (categoryDefinitionItr.hasNext()) { |
| final CategoryDefinition categoryDefinition = (CategoryDefinition) categoryDefinitionItr |
| .next(); |
| final String name = categoryDefinition.getName(); |
| if ((name != null) && (name.length() > 0)) { |
| final String categoryId = categoryDefinition.getId(); |
| final Category category = commandManager |
| .getCategory(categoryId); |
| category.define(categoryDefinition.getName(), |
| categoryDefinition.getDescription()); |
| } |
| } |
| |
| // Copy in the command definitions. |
| Collection commandDefinitions = new ArrayList(); |
| commandDefinitions.addAll(commandRegistry.getCommandDefinitions()); |
| commandDefinitions.addAll(mutableCommandRegistry |
| .getCommandDefinitions()); |
| Map commandDefinitionsById = new HashMap(CommandDefinition |
| .commandDefinitionsById(commandDefinitions, false)); |
| for (Iterator iterator = commandDefinitionsById.values().iterator(); iterator |
| .hasNext();) { |
| CommandDefinition commandDefinition = (CommandDefinition) iterator |
| .next(); |
| String name = commandDefinition.getName(); |
| if (name == null || name.length() == 0) |
| iterator.remove(); |
| } |
| final Iterator commandDefinitionItr = commandDefinitionsById.values() |
| .iterator(); |
| while (commandDefinitionItr.hasNext()) { |
| final CommandDefinition commandDefinition = (CommandDefinition) commandDefinitionItr |
| .next(); |
| final String commandId = commandDefinition.getId(); |
| final Command command = commandManager.getCommand(commandId); |
| command.define(commandDefinition.getName(), commandDefinition |
| .getDescription(), commandManager |
| .getCategory(commandDefinition.getCategoryId())); |
| } |
| |
| // Copy in the key configuration definitions. |
| Collection keyConfigurationDefinitions = new ArrayList(); |
| keyConfigurationDefinitions.addAll(commandRegistry |
| .getKeyConfigurationDefinitions()); |
| keyConfigurationDefinitions.addAll(mutableCommandRegistry |
| .getKeyConfigurationDefinitions()); |
| Map keyConfigurationDefinitionsById = new HashMap( |
| KeyConfigurationDefinition.keyConfigurationDefinitionsById( |
| keyConfigurationDefinitions, false)); |
| for (Iterator iterator = keyConfigurationDefinitionsById.values() |
| .iterator(); iterator.hasNext();) { |
| KeyConfigurationDefinition keyConfigurationDefinition = (KeyConfigurationDefinition) iterator |
| .next(); |
| String name = keyConfigurationDefinition.getName(); |
| if (name == null || name.length() == 0) |
| iterator.remove(); |
| } |
| for (Iterator iterator = keyConfigurationDefinitionsById.keySet() |
| .iterator(); iterator.hasNext();) |
| if (!isKeyConfigurationDefinitionChildOf(null, (String) iterator |
| .next(), keyConfigurationDefinitionsById)) |
| iterator.remove(); |
| final Iterator schemeDefinitionItr = keyConfigurationDefinitionsById |
| .values().iterator(); |
| while (schemeDefinitionItr.hasNext()) { |
| final KeyConfigurationDefinition schemeDefinition = (KeyConfigurationDefinition) schemeDefinitionItr |
| .next(); |
| final String schemeId = schemeDefinition.getId(); |
| final Scheme scheme = bindingManager.getScheme(schemeId); |
| scheme.define(schemeDefinition.getName(), schemeDefinition |
| .getDescription(), schemeDefinition.getParentId()); |
| } |
| |
| // Copy in the handler submissions |
| definedHandlers.clear(); |
| definedHandlers.addAll(commandRegistry.getHandlers()); |
| definedHandlers.addAll(mutableCommandRegistry.getHandlers()); |
| |
| // Set up the active scheme. |
| try { |
| final List activeSchemeDefinitions = new ArrayList(); |
| activeSchemeDefinitions.addAll(commandRegistry |
| .getActiveKeyConfigurationDefinitions()); |
| activeSchemeDefinitions.addAll(mutableCommandRegistry |
| .getActiveKeyConfigurationDefinitions()); |
| if (activeSchemeDefinitions.isEmpty()) { |
| bindingManager |
| .setActiveScheme(bindingManager |
| .getScheme("org.eclipse.ui.defaultAcceleratorConfiguration")); //$NON-NLS-1$ |
| } else { |
| final ActiveKeyConfigurationDefinition definition = (ActiveKeyConfigurationDefinition) activeSchemeDefinitions |
| .get(activeSchemeDefinitions.size() - 1); |
| final String schemeId = definition.getKeyConfigurationId(); |
| bindingManager.setActiveScheme(bindingManager |
| .getScheme(schemeId)); |
| } |
| } catch (final NotDefinedException e) { |
| // Oh, well.... |
| } |
| |
| // Copy in the key bindings. |
| List commandRegistryKeySequenceBindingDefinitions = new ArrayList( |
| commandRegistry.getKeySequenceBindingDefinitions()); |
| validateKeySequenceBindingDefinitions(commandRegistryKeySequenceBindingDefinitions); |
| List mutableCommandRegistryKeySequenceBindingDefinitions = new ArrayList( |
| mutableCommandRegistry.getKeySequenceBindingDefinitions()); |
| validateKeySequenceBindingDefinitions(mutableCommandRegistryKeySequenceBindingDefinitions); |
| final Set bindings = new HashSet(); |
| final Iterator registryBindingItr = commandRegistryKeySequenceBindingDefinitions |
| .iterator(); |
| while (registryBindingItr.hasNext()) { |
| final KeySequenceBindingDefinition definition = (KeySequenceBindingDefinition) registryBindingItr |
| .next(); |
| try { |
| final org.eclipse.jface.bindings.keys.KeySequence keySequence = org.eclipse.jface.bindings.keys.KeySequence |
| .getInstance(definition.getKeySequence().toString()); |
| final String commandId = definition.getCommandId(); |
| final String schemeId = definition.getKeyConfigurationId(); |
| final String contextId = definition.getContextId(); |
| final String locale = definition.getLocale(); |
| final String platform = definition.getPlatform(); |
| bindings.add(new KeyBinding(keySequence, commandId, schemeId, |
| contextId, locale, platform, null, Binding.SYSTEM)); |
| } catch (final ParseException e) { |
| // Ignore this binding. |
| } |
| } |
| final Iterator preferenceBindingItr = mutableCommandRegistryKeySequenceBindingDefinitions |
| .iterator(); |
| while (preferenceBindingItr.hasNext()) { |
| final KeySequenceBindingDefinition definition = (KeySequenceBindingDefinition) preferenceBindingItr |
| .next(); |
| try { |
| final org.eclipse.jface.bindings.keys.KeySequence keySequence = org.eclipse.jface.bindings.keys.KeySequence |
| .getInstance(definition.getKeySequence().toString()); |
| final String commandId = definition.getCommandId(); |
| final String schemeId = definition.getKeyConfigurationId(); |
| final String contextId = definition.getContextId(); |
| final String locale = definition.getLocale(); |
| final String platform = definition.getPlatform(); |
| bindings.add(new KeyBinding(keySequence, commandId, schemeId, |
| contextId, locale, platform, null, Binding.USER)); |
| } catch (final ParseException e) { |
| // Ignore this binding. |
| } |
| } |
| bindingManager.setBindings(bindings); |
| } |
| |
| public void removeCommandManagerListener( |
| ICommandManagerListener commandManagerListener) { |
| if (commandManagerListener == null) |
| throw new NullPointerException(); |
| if (commandManagerListeners != null) |
| commandManagerListeners.remove(commandManagerListener); |
| } |
| |
| public void setActiveContextIds(Map activeContextIds) { |
| contextManager.setActiveContextIds(activeContextIds.keySet()); |
| } |
| |
| public void setActiveKeyConfigurationId(String activeKeyConfigurationId) { |
| try { |
| bindingManager.setActiveScheme(bindingManager |
| .getScheme(activeKeyConfigurationId)); |
| } catch (final NotDefinedException e) { |
| // The key configuration is not defined, so do nothing. |
| } |
| } |
| |
| public void setActiveLocale(String activeLocale) { |
| bindingManager.setLocale(activeLocale); |
| } |
| |
| public void setActivePlatform(String activePlatform) { |
| bindingManager.setPlatform(activePlatform); |
| } |
| |
| /** |
| * Updates the handlers for a block of commands all at once. |
| * |
| * @param handlersByCommandId |
| * The map of command identifier (<code>String</code>) to |
| * handler (<code>IHandler</code>). |
| */ |
| public final void setHandlersByCommandId(final Map handlersByCommandId) { |
| final Iterator entryItr = handlersByCommandId.entrySet().iterator(); |
| while (entryItr.hasNext()) { |
| final Map.Entry entry = (Map.Entry) entryItr.next(); |
| final String commandId = (String) entry.getKey(); |
| |
| // Convert the handler to the right kind of handler. |
| final Object value = entry.getValue(); |
| final IHandler handler; |
| if (value instanceof IHandler) { |
| handler = (IHandler) value; |
| } else { |
| handler = new LegacyHandlerWrapper( |
| (org.eclipse.ui.commands.IHandler) value); |
| } |
| |
| // Set the handler on the command. |
| final Command command = commandManager.getCommand(commandId); |
| command.setHandler(handler); |
| } |
| } |
| } |