diff --git META-INF/MANIFEST.MF META-INF/MANIFEST.MF index b4cb703..fd88cad 100644 --- META-INF/MANIFEST.MF +++ META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %name Bundle-SymbolicName: org.eclipse.pde.core; singleton:=true -Bundle-Version: 3.7.100.qualifier +Bundle-Version: 3.8.0.qualifier Bundle-Activator: org.eclipse.pde.internal.core.PDECore Bundle-Vendor: %provider-name Bundle-Localization: plugin diff --git plugin.properties plugin.properties index 9c38996..3a8892b 100644 --- plugin.properties +++ plugin.properties @@ -18,6 +18,7 @@ expoint.source.name = Code Source Locations expoint.javadoc.name = Javadoc Locations expoint.target.name = Target Profiles +expoint.bundleClasspathResolvers.name = Bundle Classpath Resolvers target.name.0 = Base RCP (with Source) target.name.1 = Base RCP (Binary Only) diff --git plugin.xml plugin.xml index d68941c..e7362b5 100644 --- plugin.xml +++ plugin.xml @@ -15,6 +15,8 @@ + + + + + + + + + + This extension point allows clients to add bundle classpath entries and source lookup path entries locations and source lookup path. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Nature of the projects this resolver is enabled for. + + + + + + + The class that implements this dynamic bundle classpath entry resolver. The class must implement <code>IBundleClasspathResolver</code> + + + + + + + + + + + + + + + 3.8 + + + + + + + + + The following is an example of a classpath provider: + +<p> +<pre> + <extension + point="org.eclipse.pde.core.bundleClasspathResolvers"> + <resolver + class="org.eclipse.example.pde.SomeResolver" + nature="org.eclipse.example.projectNature"> + </resolver> + </extension> +</pre> +</p> + + + + + + + + + Each classpath resolver must provide a class that implements <code>org.eclipse.pde.core.IBundleClasspathResolver</code> interface. + + + + + + + + + + Copyright (c) 2011 Sonatype, Inc. 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> + + + + diff --git src/org/eclipse/pde/core/IBundleClasspathResolver.java src/org/eclipse/pde/core/IBundleClasspathResolver.java new file mode 0 index 0000000..3c699d0 0 --- /dev/null +++ src/org/eclipse/pde/core/IBundleClasspathResolver.java @@ -0,0 +1,70 @@ +/******************************************************************************* + * Copyright (c) 2011 Sonatype, Inc. 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: + * Sonatype, Inc. - initial API and implementation + * IBM Corporation - ongoing enhancements + *******************************************************************************/ +package org.eclipse.pde.core; + +import java.util.Collection; +import java.util.Map; +import org.eclipse.core.runtime.IPath; +import org.eclipse.jdt.core.IJavaProject; +import org.eclipse.jdt.launching.IRuntimeClasspathEntry; + +/** + * Resolves dynamically generated bundle classpath entries in the context of a java project. + * + *

+ * Generally, dynamically generated bundle classpath entries are not present under project + * source tree but included in the bundle as part build process. During development time such bundle classpath entries + * can be resolved to external jar files or workspace resources. Resolution of the + * same entry may change over time, similarly to how Plug-in Dependencies classpath container can switch between + * external bundles and workspace projects. + *

+ * + *

+ * A resolver is declared as an extension (org.eclipse.pde.core.bundleClasspathResolvers). This + * extension has the following attributes: + *

    + *
  • nature specified nature of the projects this resolver is registered for.
  • + *
  • class specifies the fully qualified name of the Java class that implements + * IBundleClasspathResolver.
  • + *
+ *

+ *

+ * The resolver is consulted when dynamically generated bundle is added to OSGi runtime launch and when looking up + * sources from the bundle. + *

+ * + * @since 3.8 + */ +public interface IBundleClasspathResolver { + + /** + * Returns a possibly empty map describing additional bundle classpath entries for a project in the workspace. + * + *

The map key is a {@link IPath} describing the project relative path to a source directory or library. The value + * is the {@link Collection} of {@link IPath} locations (relative to the project or absolute) that should be added + * to the bundle classpath.

+ * + * @param javaProject the java project to collect classpath entries for + * @return additional entries to add to the bundle classpath. Map of IPath to Collection, possibly empty + */ + public Map/*>*/getAdditionalClasspathEntries(IJavaProject javaProject); + + /** + * Returns a possibly empty collection listing additional classpath entries for the source lookup path of a project in the workspace. + * + *

The {@link Collection} will contain {@link IRuntimeClasspathEntry} describing locations where source can be obtained from.

+ * + * @param javaProject the java project to collect source entries for + * @return additional entries for the source lookup path. Collection of IRuntimeClasspathEntry, possibly empty + */ + public Collection/**/getAdditionalSourceEntries(IJavaProject javaProject); +} diff --git src/org/eclipse/pde/internal/core/ClasspathContainerResolverManager.java src/org/eclipse/pde/internal/core/ClasspathContainerResolverManager.java new file mode 0 index 0000000..73e32b8 0 --- /dev/null +++ src/org/eclipse/pde/internal/core/ClasspathContainerResolverManager.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2011 Sonatype, Inc. 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: + * Sonatype, Inc. - initial API and implementation + * IBM Corporation - ongoing enhancements + *******************************************************************************/ +package org.eclipse.pde.internal.core; + +import java.util.ArrayList; +import java.util.List; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.*; +import org.eclipse.pde.core.IBundleClasspathResolver; + +/** + * Manager for client contributed IBundleClasspathResolvers. Collects the resolvers from the + * org.eclipse.pde.core.bundleClasspathResolvers extension point. Classpath resolvers + * can then be asked to provide additional bundle classpath and source lookup entries for a project. + * + * @see IBundleClasspathResolver + */ +public class ClasspathContainerResolverManager { + + private static final String POINT_ID = "org.eclipse.pde.core.bundleClasspathResolvers"; //$NON-NLS-1$ + private static final String ATT_NATURE = "nature"; //$NON-NLS-1$ + private static final String ATT_CLASS = "class"; //$NON-NLS-1$ + + /** + * Returns all classpath resolvers contributed via extension point that support the given project's nature. + * + * @param project project to check nature of + * @return all classpath resolvers that support the nature, possibly empty + */ + public IBundleClasspathResolver[] getBundleClasspathResolvers(IProject project) { + List result = new ArrayList(); + + IExtensionRegistry registry = Platform.getExtensionRegistry(); + IConfigurationElement[] elements = registry.getConfigurationElementsFor(POINT_ID); + for (int i = 0; i < elements.length; i++) { + String attrNature = elements[i].getAttribute(ATT_NATURE); + try { + if (project.isNatureEnabled(attrNature)) { + result.add(elements[i].createExecutableExtension(ATT_CLASS)); + } + } catch (CoreException e) { + PDECore.log(e.getStatus()); + } + } + + return (IBundleClasspathResolver[]) result.toArray(new IBundleClasspathResolver[result.size()]); + } + +} diff --git src/org/eclipse/pde/internal/core/ClasspathHelper.java src/org/eclipse/pde/internal/core/ClasspathHelper.java index 613fee4..70a85f8 100644 --- src/org/eclipse/pde/internal/core/ClasspathHelper.java +++ src/org/eclipse/pde/internal/core/ClasspathHelper.java @@ -17,6 +17,7 @@ import org.eclipse.core.runtime.*; import org.eclipse.core.runtime.preferences.IEclipsePreferences; import org.eclipse.jdt.core.*; +import org.eclipse.pde.core.IBundleClasspathResolver; import org.eclipse.pde.core.build.IBuild; import org.eclipse.pde.core.build.IBuildEntry; import org.eclipse.pde.core.plugin.*; @@ -199,8 +200,26 @@ list = new ArrayList(); list.add(output); map.put(source, list); + } + } + + // Add additional entries from contributed bundle classpath resolvers + IBundleClasspathResolver[] resolvers = PDECore.getDefault().getClasspathContainerResolverManager().getBundleClasspathResolvers(project); + for (int i = 0; i < resolvers.length; i++) { + Map resolved = resolvers[i].getAdditionalClasspathEntries(jProject); + Iterator resolvedIter = resolved.entrySet().iterator(); + while (resolvedIter.hasNext()) { + Map.Entry resolvedEntry = (Map.Entry) resolvedIter.next(); + IPath ceSource = (IPath) resolvedEntry.getKey(); + ArrayList list = (ArrayList) map.get(ceSource); + if (list == null) { + list = new ArrayList(); + map.put(ceSource, list); + } + list.addAll((Collection) resolvedEntry.getValue()); } } + return map; } @@ -213,9 +232,9 @@ for (int j = 0; j < resources.length; j++) { IResource res = project.findMember(resources[j]); if (res != null) { - ArrayList list = (ArrayList) classpathMap.get(res.getFullPath()); + Collection list = (Collection) classpathMap.get(res.getFullPath()); if (list != null) { - ListIterator li = list.listIterator(); + Iterator li = list.iterator(); while (li.hasNext()) paths.add(li.next()); } @@ -231,11 +250,13 @@ IResource res = project.findMember(libName); if (res != null) path = res.getFullPath(); + else + path = new Path(libName); } - ArrayList list = (ArrayList) classpathMap.get(path); + Collection list = (Collection) classpathMap.get(path); if (list != null) { - ListIterator li = list.listIterator(); + Iterator li = list.iterator(); while (li.hasNext()) paths.add(li.next()); } @@ -271,7 +292,7 @@ Iterator iterator = classpathMap.values().iterator(); List collect = new ArrayList(); while (iterator.hasNext()) { - ArrayList list = (ArrayList) iterator.next(); + Collection list = (Collection) iterator.next(); collect.addAll(list); } paths = (IPath[]) collect.toArray(new IPath[collect.size()]); diff --git src/org/eclipse/pde/internal/core/PDECore.java src/org/eclipse/pde/internal/core/PDECore.java index 2cf46d5..7a13fd6 100644 --- src/org/eclipse/pde/internal/core/PDECore.java +++ src/org/eclipse/pde/internal/core/PDECore.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2000, 2010 IBM Corporation and others. + * Copyright (c) 2000, 2011 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 @@ -17,6 +17,7 @@ import org.eclipse.core.resources.*; import org.eclipse.core.runtime.*; import org.eclipse.jdt.launching.JavaRuntime; +import org.eclipse.pde.core.IBundleClasspathResolver; import org.eclipse.pde.core.plugin.IPluginModelBase; import org.eclipse.pde.core.project.IBundleProjectService; import org.eclipse.pde.internal.core.builders.FeatureRebuilder; @@ -130,6 +131,7 @@ private SourceLocationManager fSourceLocationManager; private JavadocLocationManager fJavadocLocationManager; private SearchablePluginsManager fSearchablePluginsManager; + private ClasspathContainerResolverManager fClasspathContainerResolverManager; // Tracing options manager private TracingOptionsManager fTracingOptionsManager; @@ -215,6 +217,20 @@ return fSourceLocationManager; } + /** + * Returns the singleton instance of the classpath container resolver manager used to dynamically + * resolve a project's classpath. Clients may contribute a {@link IBundleClasspathResolver} to the + * manager through the org.eclipse.pde.core.bundleClasspathResolvers extension. + * + * @return singleton instance of the classpath container resolver manager + */ + public synchronized ClasspathContainerResolverManager getClasspathContainerResolverManager() { + if (fClasspathContainerResolverManager == null) { + fClasspathContainerResolverManager = new ClasspathContainerResolverManager(); + } + return fClasspathContainerResolverManager; + } + public synchronized JavadocLocationManager getJavadocLocationManager() { if (fJavadocLocationManager == null) fJavadocLocationManager = new JavadocLocationManager(); diff --git src/org/eclipse/pde/internal/launching/sourcelookup/PDESourceLookupDirector.java src/org/eclipse/pde/internal/launching/sourcelookup/PDESourceLookupDirector.java index f01326f..e60dda0 100644 --- src/org/eclipse/pde/internal/launching/sourcelookup/PDESourceLookupDirector.java +++ src/org/eclipse/pde/internal/launching/sourcelookup/PDESourceLookupDirector.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2009 IBM Corporation and others. + * Copyright (c) 2005, 2011 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 @@ -10,8 +10,6 @@ * Code 9 Corporation - ongoing enhancements *******************************************************************************/ package org.eclipse.pde.internal.launching.sourcelookup; - -import org.eclipse.pde.internal.launching.PDELaunchingPlugin; import java.io.File; import java.util.*; @@ -25,9 +23,10 @@ import org.eclipse.jdt.launching.IRuntimeClasspathEntry; import org.eclipse.jdt.launching.JavaRuntime; import org.eclipse.jdt.launching.sourcelookup.containers.JavaSourceLookupParticipant; +import org.eclipse.pde.core.IBundleClasspathResolver; import org.eclipse.pde.core.plugin.*; -import org.eclipse.pde.internal.core.PDEClasspathContainer; -import org.eclipse.pde.internal.core.TargetPlatformHelper; +import org.eclipse.pde.internal.core.*; +import org.eclipse.pde.internal.launching.PDELaunchingPlugin; public class PDESourceLookupDirector extends AbstractSourceLookupDirector { @@ -209,6 +208,12 @@ result.add(rte); } } + + // Add additional entries from contributed classpath container resolvers + IBundleClasspathResolver[] resolvers = PDECore.getDefault().getClasspathContainerResolverManager().getBundleClasspathResolvers(project); + for (int i = 0; i < resolvers.length; i++) { + result.addAll(resolvers[i].getAdditionalSourceEntries(jProject)); + } } /* (non-Javadoc)