X-Git-Url: http://git.phpeclipse.com diff --git a/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/extensions/ProcessServiceMembers.java b/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/extensions/ProcessServiceMembers.java new file mode 100644 index 0000000..30ca7f2 --- /dev/null +++ b/archive/net.sourceforge.phpeclipse.quantum.sql/src/com/quantum/extensions/ProcessServiceMembers.java @@ -0,0 +1,281 @@ + +/* + * Created on 16-feb-2004 + * + */ +package com.quantum.extensions; +import java.util.Vector; + +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IConfigurationElement; +import org.eclipse.core.runtime.IExtension; +import org.eclipse.core.runtime.IExtensionPoint; +import org.eclipse.core.runtime.IPluginRegistry; +import org.eclipse.core.runtime.Platform; +import org.eclipse.ui.IViewPart; +import org.eclipse.ui.WorkbenchException; +import org.w3c.dom.Document; + +import com.quantum.view.bookmark.BookmarkView; +import com.quantum.view.tableview.TableView; + +/** + * Extension processing logic for the functions extension-point. + * Extract specific information about each function. Create callback + * function object when required. + * + * @author panic + * + */ +public class ProcessServiceMembers { + + /** + * The fully-qualified name of the functions extension-point for this plug-in. + */ + private static final String EXTENSION_POINT_METADATA = + "com.quantum.Quantum.metadata"; + private static final String EXTENSION_POINT_DATA = + "com.quantum.Quantum.data"; + + /** + * Name of the XML attribute designating a metadata actor label. + */ + private static final String FUNCTION_NAME_ATTRIBUTE = "label"; + + /** + * Name of the XML attribute designating the fully-qualified name + * of the implementation class of a function. + */ + private static final String CLASS_ATTRIBUTE = "class"; + + /** + * Perform initial extension processing for the members of the + * functions extension-point. Make calls to the user interface + * module to add the functions of an extension to the UI functions grid. + * For each function, a virtual proxy callback object is created and handed + * to the user interface module. The proxy class is a nested top-level + * class and is therefore known at compile time. The actual (real) callback + * objects configured into extensions are instantiated and initialized in + * a lazy fashion by the proxy callback objects. + * + * @param grid The UI functions grid exposing the functions configured + * into functions extensions. + * + */ + public static void process(IViewPart view, Vector extensionActions) throws WorkbenchException { + + extensionActions.clear(); + + IPluginRegistry registry = Platform.getPluginRegistry(); + String extPointId; + // We have two different extension points, we choose the needed one based + // on the view that calls this function. + // Our two extension points have the same attributes, so the only change is the name + // If the implementation differed more, we should probably make two different functions + if (view instanceof BookmarkView) + extPointId = EXTENSION_POINT_METADATA; + else if (view instanceof TableView) + extPointId = EXTENSION_POINT_DATA; + else + return; + + IExtensionPoint extensionPoint = + registry.getExtensionPoint(extPointId); + if (extensionPoint == null) { + throw new WorkbenchException( + "unable to resolve extension-point: " + extPointId); + } + IConfigurationElement[] members = + extensionPoint.getConfigurationElements(); + + // For each service: + for (int m = 0; m < members.length; m++) { + IConfigurationElement member = members[m]; + // Get the label of the extender plugin and the ID of the extension. + IExtension extension = member.getDeclaringExtension(); + String pluginLabel = + extension.getDeclaringPluginDescriptor().getLabel(); + if (pluginLabel == null) { + pluginLabel = "[unnamed plugin]"; + } + // Get the name of the operation implemented by the service. + // The operation name is a service attribute in the extension's XML specification. + String functionName = member.getAttribute(FUNCTION_NAME_ATTRIBUTE); + if (functionName == null) { + functionName = "[unnamed function]"; + } + String label = pluginLabel + "/" + functionName; + // Add a row to support this operation to the UI grid. + IQuantumExtension proxy = null; + if (view instanceof BookmarkView) + proxy = (IMetadataExtension) new MetadataFunctionProxy(member); + else if (view instanceof TableView) + proxy = (IDataExtension) new DataFunctionProxy(member); + //grid.addFunction(proxy, functionName, label); + extensionActions.add(new ExtensionAction(view, label, label, proxy)); + } + } + + /** + * Virtual proxy class for function invokation. + * Members of this class support lazy processing by fronting the real + * implementations of arithmetic functions configured into extensions. + */ + private static class MetadataFunctionProxy implements IMetadataExtension { + // The "real" implementation of the function. + private IMetadataExtension delegate = null; + // The configured state of the extension element representing this arithmetic function. + private IConfigurationElement element; + // Whether this function has been invoked before. + // Used for lazy evaluation of the service. + private boolean invoked = false; + + /** + * Construct a virtual proxy to stand in place of an extension function. + * The constructor simply keeps track of an arithmetic function's configured state + * without at this time instantiating the implementation of the function. + * + * @param element The configuration of this arithmetic function. + */ + public MetadataFunctionProxy(IConfigurationElement element) { + this.element = element; + } + + /** + * Compute the function value. + * The proxy computation first instantiates the implementation + * of the function, if this is the first time the function is called, + * and then delegates to that implementation. The instantiation and + * initialization of the delegate implementation uses the standard + * callback object instantiation and initialization methods of Eclipse. + * + * @see com.bolour.sample.eclipse.service.ui.IFunction#compute(long) + */ + public final void run(Document doc) { + try { + getDelegate().run(doc); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Instantiate and initialize the implementation of the function if + * this is the first time the proxy has been called. + * + * @return The implementation delegate (same as the instance variable delegate. + * @throws Exception If the callback object is misconfigured. + */ + private final IMetadataExtension getDelegate() throws Exception { + if (invoked) { + return delegate; + } + invoked = true; + try { + Object callback = + element.createExecutableExtension(CLASS_ATTRIBUTE); + if (!(callback instanceof IMetadataExtension)) { + String message = + "callback class '" + + callback.getClass().getName() + + "' is not an IFunction"; + System.err.println(message); + throw new ClassCastException(message); + } + delegate = (IMetadataExtension) callback; + } catch (CoreException ex) { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + throw ex; + } catch (Error err) { + System.err.println(err.getMessage()); + err.printStackTrace(); + throw err; + } + return delegate; + } + } + /** + * Virtual proxy class for function invokation. + * Members of this class support lazy processing by fronting the real + * implementations of arithmetic functions configured into extensions. + */ + private static class DataFunctionProxy implements IDataExtension { + // The "real" implementation of the function. + private IDataExtension delegate = null; + // The configured state of the extension element representing this arithmetic function. + private IConfigurationElement element; + // Whether this function has been invoked before. + // Used for lazy evaluation of the service. + private boolean invoked = false; + + /** + * Construct a virtual proxy to stand in place of an extension function. + * The constructor simply keeps track of an arithmetic function's configured state + * without at this time instantiating the implementation of the function. + * + * @param element The configuration of this arithmetic function. + */ + public DataFunctionProxy(IConfigurationElement element) { + this.element = element; + } + + /** + * Compute the function value. + * The proxy computation first instantiates the implementation + * of the function, if this is the first time the function is called, + * and then delegates to that implementation. The instantiation and + * initialization of the delegate implementation uses the standard + * callback object instantiation and initialization methods of Eclipse. + * + * @see com.bolour.sample.eclipse.service.ui.IFunction#compute(long) + */ + public final void run(Document doc) { + try { + getDelegate().run(doc); + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + /** + * Instantiate and initialize the implementation of the function if + * this is the first time the proxy has been called. + * + * @return The implementation delegate (same as the instance variable delegate. + * @throws Exception If the callback object is misconfigured. + */ + private final IDataExtension getDelegate() throws Exception { + if (invoked) { + return delegate; + } + invoked = true; + try { + Object callback = + element.createExecutableExtension(CLASS_ATTRIBUTE); + if (!(callback instanceof IDataExtension)) { + String message = + "callback class '" + + callback.getClass().getName() + + "' is not an IFunction"; + System.err.println(message); + throw new ClassCastException(message); + } + delegate = (IDataExtension) callback; + } catch (CoreException ex) { + System.err.println(ex.getMessage()); + ex.printStackTrace(); + throw ex; + } catch (Error err) { + System.err.println(err.getMessage()); + err.printStackTrace(); + throw err; + } + return delegate; + } + } + +} +