[155723] Runtime bridge doesn't allow multiple components
diff --git a/plugins/org.eclipse.jst.server.core/plugin.xml b/plugins/org.eclipse.jst.server.core/plugin.xml
index f8e59fe..cf23753 100644
--- a/plugins/org.eclipse.jst.server.core/plugin.xml
+++ b/plugins/org.eclipse.jst.server.core/plugin.xml
@@ -5,6 +5,7 @@
<extension-point id="runtimeClasspathProviders" name="%extensionPointRuntimeClasspathProviders" schema="schema/runtimeClasspathProviders.exsd"/>
<extension-point id="runtimeFacetMappings" name="%extensionPointRuntimeFacetMappings" schema="schema/runtimeFacetMappings.exsd"/>
<extension-point id="serverProfilers" name="%extensionPointServerProfilers" schema="schema/serverProfilers.exsd"/>
+ <extension-point id="internalRuntimeComponentProviders" name="internalRuntimeComponentProviders" schema="schema/internalRuntimeComponentProviders.exsd"/>
<extension point="org.eclipse.jdt.core.classpathContainerInitializer">
<classpathContainerInitializer
diff --git a/plugins/org.eclipse.jst.server.core/schema/internalRuntimeComponentProviders.exsd b/plugins/org.eclipse.jst.server.core/schema/internalRuntimeComponentProviders.exsd
new file mode 100644
index 0000000..bacc5c9
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.core/schema/internalRuntimeComponentProviders.exsd
@@ -0,0 +1,138 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<!-- Schema file written by PDE -->
+<schema targetNamespace="org.eclipse.jst.server.core">
+<annotation>
+ <appInfo>
+ <meta.schema plugin="org.eclipse.jst.server.core" id="runtimeComponentProviders" name="Runtime Component Providers"/>
+ </appInfo>
+ <documentation>
+ This extension point is internal and experimental and should not be used by downstream components.
+This extension point is used to provide new runtime components to an existing facet runtime.
+ </documentation>
+ </annotation>
+
+ <element name="extension">
+ <complexType>
+ <sequence>
+ <element ref="runtimeComponentProvider" minOccurs="1" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="point" type="string" use="required">
+ <annotation>
+ <documentation>
+ a fully qualified identifier of the target extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="id" type="string">
+ <annotation>
+ <documentation>
+ an optional identifier of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="name" type="string">
+ <annotation>
+ <documentation>
+ an optional name of the extension instance
+ </documentation>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <element name="runtimeComponentProvider">
+ <annotation>
+ <appInfo>
+ <meta.element labelAttribute="name"/>
+ </appInfo>
+ </annotation>
+ <complexType>
+ <sequence>
+ </sequence>
+ <attribute name="id" type="string" use="required">
+ <annotation>
+ <documentation>
+ specifies a unique identifier for this extension point
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="runtimeTypeIds" type="string" use="required">
+ <annotation>
+ <documentation>
+ a comma separated list of runtime type ids that this provider may support. Used for memory & performance reasons
+ </documentation>
+ </annotation>
+ </attribute>
+ <attribute name="class" type="string" use="required">
+ <annotation>
+ <documentation>
+ specifies the fully qualified name of the Java class that extends <samp>RuntimeClasspathProviderDelegate</samp>.
+Runtime classpath provider instances of this type will delegate to instances of this class.
+ </documentation>
+ <appInfo>
+ <meta.attribute kind="java" basedOn="org.eclipse.jst.server.core.RuntimeClasspathProviderDelegate"/>
+ </appInfo>
+ </annotation>
+ </attribute>
+ </complexType>
+ </element>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="since"/>
+ </appInfo>
+ <documentation>
+ 1.5.1
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="examples"/>
+ </appInfo>
+ <documentation>
+ The following is an example of a runtime component provider extension point:
+
+<pre>
+ <extension point="org.eclipse.jst.server.core.runtimeComponentProviders">
+ <runtimeComponentProvider
+ id="com.example.runtimeComponentProvider"
+ runtimeTypeIds="com.example.runtime, com.example2.*"
+ class="com.example.ExampleRuntimeComponentProvider"/>
+ </extension>
+</pre>
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="apiInfo"/>
+ </appInfo>
+ <documentation>
+ Value of the attribute <b>class</b> must be a fully qualified name of a Java class that extends <b>org.eclipse.jst.server.core.RuntimeClasspathProviderDelegate</b> and contains a public 0-arg constructor.
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="implementation"/>
+ </appInfo>
+ <documentation>
+
+ </documentation>
+ </annotation>
+
+ <annotation>
+ <appInfo>
+ <meta.section type="copyright"/>
+ </appInfo>
+ <documentation>
+ Copyright (c) 2006 IBM Corporation and others.<br>
+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
+<a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>
+ </documentation>
+ </annotation>
+
+</schema>
diff --git a/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/JavaServerPlugin.java b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/JavaServerPlugin.java
index acd18d6..22b76d6 100644
--- a/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/JavaServerPlugin.java
+++ b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/JavaServerPlugin.java
@@ -45,6 +45,9 @@
// cached copy of all runtime classpath providers
private static List runtimeClasspathProviders;
+ // cached copy of all runtime component providers
+ private static List runtimeComponentProviders;
+
// cached copy of all runtime facet mappings
private static List runtimeFacetMappings;
@@ -322,6 +325,57 @@
}
/**
+ * Returns the runtime component provider that supports the given runtime type, or <code>null</code>
+ * if none. This convenience method searches the list of known runtime
+ * component providers for the one with a matching runtime type.
+ * The runtimeType may not be null.
+ *
+ * @param runtimeType a runtime type
+ * @return the runtime component provider instance, or <code>null</code> if
+ * there is no runtime component provider with the given id
+ */
+ public static RuntimeComponentProviderWrapper findRuntimeComponentProvider(IRuntimeType runtimeType) {
+ if (runtimeType == null)
+ throw new IllegalArgumentException();
+
+ if (runtimeComponentProviders == null)
+ loadRuntimeComponentProviders();
+
+ Iterator iterator = runtimeComponentProviders.iterator();
+ while (iterator.hasNext()) {
+ RuntimeComponentProviderWrapper runtimeComponentProvider = (RuntimeComponentProviderWrapper) iterator.next();
+ if (runtimeComponentProvider.supportsRuntimeType(runtimeType))
+ return runtimeComponentProvider;
+ }
+ return null;
+ }
+
+ /**
+ * Load the runtime component providers.
+ */
+ private static synchronized void loadRuntimeComponentProviders() {
+ if (runtimeComponentProviders != null)
+ return;
+ Trace.trace(Trace.CONFIG, "->- Loading .runtimeComponentProviders extension point ->-");
+ IExtensionRegistry registry = Platform.getExtensionRegistry();
+ IConfigurationElement[] cf = registry.getConfigurationElementsFor(JavaServerPlugin.PLUGIN_ID, "internalRuntimeComponentProviders");
+
+ int size = cf.length;
+ List list = new ArrayList(size);
+ for (int i = 0; i < size; i++) {
+ try {
+ list.add(new RuntimeComponentProviderWrapper(cf[i]));
+ Trace.trace(Trace.CONFIG, " Loaded runtimeComponentProviders: " + cf[i].getAttribute("id"));
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE, " Could not load runtimeComponentProvider: " + cf[i].getAttribute("id"), t);
+ }
+ }
+ runtimeComponentProviders = list;
+
+ Trace.trace(Trace.CONFIG, "-<- Done loading .runtimeComponentProviders extension point -<-");
+ }
+
+ /**
* Load the runtime facet mappings.
*/
private static synchronized void loadRuntimeFacetMapping() {
diff --git a/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeBridge.java b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeBridge.java
index 998c21a..336ee89 100644
--- a/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeBridge.java
+++ b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeBridge.java
@@ -1,5 +1,6 @@
/******************************************************************************
* Copyright (c) 2005 BEA Systems, Inc.
+ * Copyright (c) 2006 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
@@ -191,6 +192,13 @@
components.add(RuntimeManager.createRuntimeComponent(rcv, properties));
}
+ RuntimeComponentProviderWrapper componentProvider = JavaServerPlugin.findRuntimeComponentProvider(runtime.getRuntimeType());
+ if (componentProvider != null) {
+ List list = componentProvider.getComponents(runtime);
+ if (list != null)
+ components.addAll(list);
+ }
+
return components;
}
diff --git a/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeComponentProviderDelegate.java b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeComponentProviderDelegate.java
new file mode 100644
index 0000000..e5185f5
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeComponentProviderDelegate.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.jst.server.core.internal;
+
+import java.util.List;
+
+import org.eclipse.wst.server.core.IRuntime;
+/**
+ * A runtime component provider can provide additional runtime components for a facet runtime.
+ * This provider is scoped by runtime type and may provide components for multiple
+ * runtime instances.
+ * <p>
+ * This abstract class is intended to be extended only by clients
+ * to extend the <code>internalRuntimeComponentProviders</code> extension point.
+ * </p>
+ * <p>
+ * <b>Provisional API:</b> This class/interface is part of an interim API that is still under development and expected to
+ * change significantly before reaching stability. It is being made available at this early stage to solicit feedback
+ * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken
+ * (repeatedly) as the API evolves.
+ * </p>
+ *
+ * @plannedfor 2.0
+ */
+public abstract class RuntimeComponentProviderDelegate {
+ public RuntimeComponentProviderDelegate() {
+ // default constructor
+ }
+
+ /**
+ * Add runtime components to the given runtime. Components should be created by calling
+ * RuntimeManager.createRuntimeComponent(IRuntimeComponentVersion, Map)
+ *
+ * @param runtime a server runtime
+ * @return a list of runtimes, or an empty list or null if there are no additional components
+ */
+ public abstract List getRuntimeComponents(IRuntime runtime);
+}
\ No newline at end of file
diff --git a/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeComponentProviderWrapper.java b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeComponentProviderWrapper.java
new file mode 100644
index 0000000..fd74dcc
--- /dev/null
+++ b/plugins/org.eclipse.jst.server.core/sjavacore/org/eclipse/jst/server/core/internal/RuntimeComponentProviderWrapper.java
@@ -0,0 +1,128 @@
+/*******************************************************************************
+ * Copyright (c) 2006 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
+ *******************************************************************************/
+package org.eclipse.jst.server.core.internal;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.wst.server.core.IRuntime;
+import org.eclipse.wst.server.core.IRuntimeType;
+/**
+ *
+ */
+public class RuntimeComponentProviderWrapper {
+ private IConfigurationElement element;
+ private RuntimeComponentProviderDelegate delegate;
+
+ /**
+ * Create a new runtime component handler.
+ *
+ * @param element a configuration element
+ */
+ public RuntimeComponentProviderWrapper(IConfigurationElement element) {
+ super();
+ this.element = element;
+ }
+
+ protected IConfigurationElement getElement() {
+ return element;
+ }
+
+ /**
+ *
+ * @return the id
+ */
+ public String getId() {
+ return element.getAttribute("id");
+ }
+
+ public String[] getRuntimeTypeIds() {
+ try {
+ List list = new ArrayList();
+ StringTokenizer st = new StringTokenizer(element.getAttribute("runtimeTypeIds"), ",");
+ while (st.hasMoreTokens()) {
+ String str = st.nextToken();
+ if (str != null && str.length() > 0)
+ list.add(str.trim());
+ }
+ String[] s = new String[list.size()];
+ list.toArray(s);
+ return s;
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Could not parse runtime type ids: " + element);
+ return null;
+ }
+ }
+
+ /**
+ * Returns true if the given server resource type (given by the
+ * id) can be opened with this editor. This result is based on
+ * the result of the getServerResources() method.
+ *
+ * @param runtimeType a runtime type
+ * @return boolean
+ */
+ public boolean supportsRuntimeType(IRuntimeType runtimeType) {
+ if (runtimeType == null)
+ return false;
+ String id = runtimeType.getId();
+ if (id == null || id.length() == 0)
+ return false;
+
+ String[] s = getRuntimeTypeIds();
+ if (s == null)
+ return false;
+
+ int size = s.length;
+ for (int i = 0; i < size; i++) {
+ if (s[i].endsWith("*")) {
+ if (id.length() >= s[i].length() && id.startsWith(s[i].substring(0, s[i].length() - 1)))
+ return true;
+ } else if (id.equals(s[i]))
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * Loads the delegate class.
+ */
+ protected RuntimeComponentProviderDelegate getDelegate() {
+ if (delegate == null) {
+ try {
+ delegate = (RuntimeComponentProviderDelegate) element.createExecutableExtension("class");
+ } catch (Throwable t) {
+ Trace.trace(Trace.SEVERE, "Could not create delegate " + toString() + ": " + t.getMessage());
+ }
+ }
+ return delegate;
+ }
+
+ /*
+ * @see RuntimeComponentProviderDelegate#getRuntimeComponents(IRuntime)
+ */
+ public List getComponents(IRuntime runtime) {
+ if (runtime == null)
+ return null;
+ try {
+ return getDelegate().getRuntimeComponents(runtime);
+ } catch (Exception e) {
+ Trace.trace(Trace.SEVERE, "Error calling delegate " + toString() + ": " + e.getMessage());
+ }
+ return null;
+ }
+
+ public String toString() {
+ return "RuntimeComponentProviderWrapper[" + getId() + "]";
+ }
+}
\ No newline at end of file