001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.handlers;
011:
012: import java.util.Collections;
013: import java.util.Map;
014:
015: import org.eclipse.core.runtime.CoreException;
016: import org.eclipse.core.runtime.IConfigurationElement;
017: import org.eclipse.core.runtime.IStatus;
018: import org.eclipse.core.runtime.Status;
019: import org.eclipse.ui.commands.AbstractHandler;
020: import org.eclipse.ui.commands.ExecutionException;
021: import org.eclipse.ui.commands.IHandler;
022: import org.eclipse.ui.internal.WorkbenchPlugin;
023:
024: /**
025: * <p>
026: * A proxy for a handler that has been defined in XML. This delays the class
027: * loading until the handler is really asked for information (besides the
028: * priority or the command identifier). Asking a proxy for anything but the
029: * attributes defined publicly in this class will cause the proxy to instantiate
030: * the proxied handler.
031: * </p>
032: *
033: * @since 3.0
034: */
035: public final class LegacyHandlerProxy extends AbstractHandler {
036:
037: /**
038: * The name of the configuration element attribute which contains the
039: * information necessary to instantiate the real handler.
040: */
041: private static final String HANDLER_ATTRIBUTE_NAME = "handler"; //$NON-NLS-1$
042:
043: /**
044: * The configuration element from which the handler can be created. This
045: * value will exist until the element is converted into a real class -- at
046: * which point this value will be set to <code>null</code>.
047: */
048: private IConfigurationElement configurationElement;
049:
050: /**
051: * The real handler. This value is <code>null</code> until the proxy is
052: * forced to load the real handler. At this point, the configuration element
053: * is converted, nulled out, and this handler gains a reference.
054: */
055: private IHandler handler;
056:
057: /**
058: * Constructs a new instance of <code>HandlerProxy</code> with all the
059: * information it needs to try to avoid loading until it is needed.
060: *
061: * @param newConfigurationElement
062: * The configuration element from which the real class can be
063: * loaded at run-time.
064: */
065: public LegacyHandlerProxy(
066: final IConfigurationElement newConfigurationElement) {
067: configurationElement = newConfigurationElement;
068: handler = null;
069: }
070:
071: /**
072: * Passes the dipose on to the proxied handler, if it has been loaded.
073: */
074: public void dispose() {
075: if (handler != null) {
076: handler.dispose();
077: }
078: }
079:
080: /**
081: * @see IHandler#execute(Map)
082: */
083: public Object execute(Map parameters) throws ExecutionException {
084: if (loadHandler()) {
085: return handler.execute(parameters);
086: }
087:
088: return null;
089: }
090:
091: /**
092: * @see IHandler#getAttributeValuesByName()
093: */
094: public Map getAttributeValuesByName() {
095: if (loadHandler()) {
096: return handler.getAttributeValuesByName();
097: } else {
098: return Collections.EMPTY_MAP;
099: }
100: }
101:
102: /**
103: * Loads the handler, if possible. If the handler is loaded, then the member
104: * variables are updated accordingly.
105: *
106: * @return <code>true</code> if the handler is now non-null;
107: * <code>false</code> otherwise.
108: */
109: private final boolean loadHandler() {
110: if (handler == null) {
111: // Load the handler.
112: try {
113: handler = (IHandler) configurationElement
114: .createExecutableExtension(HANDLER_ATTRIBUTE_NAME);
115: configurationElement = null;
116: return true;
117: } catch (final CoreException e) {
118: /*
119: * TODO If it can't be instantiated, should future attempts to
120: * instantiate be blocked?
121: */
122: final String message = "The proxied handler for '" + configurationElement.getAttribute(HANDLER_ATTRIBUTE_NAME) //$NON-NLS-1$
123: + "' could not be loaded"; //$NON-NLS-1$
124: IStatus status = new Status(IStatus.ERROR,
125: WorkbenchPlugin.PI_WORKBENCH, 0, message, e);
126: WorkbenchPlugin.log(message, status);
127: return false;
128: }
129: }
130:
131: return true;
132: }
133:
134: public final String toString() {
135: final StringBuffer buffer = new StringBuffer();
136:
137: buffer.append("LegacyProxy("); //$NON-NLS-1$
138: if (handler == null) {
139: final String className = configurationElement
140: .getAttribute(HANDLER_ATTRIBUTE_NAME);
141: buffer.append(className);
142: } else {
143: buffer.append(handler);
144: }
145: buffer.append(')');
146:
147: return buffer.toString();
148: }
149: }
|