blob: ad0289d84d00dfcc7f7acafd618fdc198dcbac5a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2017 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.ui.internal.handlers;
import java.util.Collections;
import java.util.Map;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.ui.commands.AbstractHandler;
import org.eclipse.ui.commands.ExecutionException;
import org.eclipse.ui.commands.IHandler;
import org.eclipse.ui.internal.WorkbenchPlugin;
/**
* <p>
* A proxy for a handler that has been defined in XML. This delays the class
* loading until the handler is really asked for information (besides the
* priority or the command identifier). Asking a proxy for anything but the
* attributes defined publicly in this class will cause the proxy to instantiate
* the proxied handler.
* </p>
*
* @since 3.0
*/
public final class LegacyHandlerProxy extends AbstractHandler {
/**
* The name of the configuration element attribute which contains the
* information necessary to instantiate the real handler.
*/
private static final String HANDLER_ATTRIBUTE_NAME = "handler"; //$NON-NLS-1$
/**
* The configuration element from which the handler can be created. This value
* will exist until the element is converted into a real class -- at which point
* this value will be set to <code>null</code>.
*/
private IConfigurationElement configurationElement;
/**
* The real handler. This value is <code>null</code> until the proxy is forced
* to load the real handler. At this point, the configuration element is
* converted, nulled out, and this handler gains a reference.
*/
private IHandler handler;
/**
* Constructs a new instance of <code>HandlerProxy</code> with all the
* information it needs to try to avoid loading until it is needed.
*
* @param newConfigurationElement The configuration element from which the real
* class can be loaded at run-time.
*/
public LegacyHandlerProxy(final IConfigurationElement newConfigurationElement) {
configurationElement = newConfigurationElement;
handler = null;
}
/**
* Passes the dipose on to the proxied handler, if it has been loaded.
*/
@Override
public void dispose() {
if (handler != null) {
handler.dispose();
}
}
/**
* @see IHandler#execute(Map)
*/
@Override
public Object execute(Map parameters) throws ExecutionException {
if (loadHandler()) {
return handler.execute(parameters);
}
return null;
}
/**
* @see IHandler#getAttributeValuesByName()
*/
@Override
public Map getAttributeValuesByName() {
if (loadHandler()) {
return handler.getAttributeValuesByName();
}
return Collections.EMPTY_MAP;
}
/**
* Loads the handler, if possible. If the handler is loaded, then the member
* variables are updated accordingly.
*
* @return <code>true</code> if the handler is now non-null; <code>false</code>
* otherwise.
*/
private boolean loadHandler() {
if (handler == null) {
// Load the handler.
try {
handler = (IHandler) configurationElement.createExecutableExtension(HANDLER_ATTRIBUTE_NAME);
configurationElement = null;
return true;
} catch (final CoreException e) {
/*
* TODO If it can't be instantiated, should future attempts to instantiate be
* blocked?
*/
final String message = "The proxied handler for '" //$NON-NLS-1$
+ configurationElement.getAttribute(HANDLER_ATTRIBUTE_NAME) + "' could not be loaded"; //$NON-NLS-1$
IStatus status = new Status(IStatus.ERROR, WorkbenchPlugin.PI_WORKBENCH, 0, message, e);
WorkbenchPlugin.log(message, status);
return false;
}
}
return true;
}
@Override
public String toString() {
final StringBuilder buffer = new StringBuilder();
buffer.append("LegacyProxy("); //$NON-NLS-1$
if (handler == null) {
final String className = configurationElement.getAttribute(HANDLER_ATTRIBUTE_NAME);
buffer.append(className);
} else {
buffer.append(handler);
}
buffer.append(')');
return buffer.toString();
}
}