CAMEL-7188: Fixed findComponents to work in OSGi, so we can discover all the Camel components in the container.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/6fc97272 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/6fc97272 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/6fc97272 Branch: refs/heads/camel-2.12.x Commit: 6fc972721eac58b90babf316880ef89fb929f2d5 Parents: 535b966 Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Feb 13 11:26:34 2014 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Feb 13 11:27:22 2014 +0100 ---------------------------------------------------------------------- .../apache/camel/impl/DefaultClassResolver.java | 6 +++- .../management/mbean/ManagedCamelContext.java | 4 ++- .../org/apache/camel/spi/ClassResolver.java | 10 +++++- .../apache/camel/util/CamelContextHelper.java | 16 +++++++-- .../camel/core/osgi/OsgiClassResolver.java | 37 +++++++++++++++++++- 5 files changed, 67 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/6fc97272/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java b/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java index d43e336..a5b49e2 100644 --- a/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java +++ b/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java @@ -89,8 +89,12 @@ public class DefaultClassResolver implements ClassResolver { return ObjectHelper.loadResourceAsURL(uri); } - @Override public Enumeration<URL> loadResourcesAsURL(String uri) { + return loadAllResourcesAsURL(uri); + } + + @Override + public Enumeration<URL> loadAllResourcesAsURL(String uri) { ObjectHelper.notEmpty(uri, "uri"); return ObjectHelper.loadResourcesAsURL(uri); } http://git-wip-us.apache.org/repos/asf/camel/blob/6fc97272/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java index 62de546..d20f8d3 100644 --- a/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java +++ b/camel-core/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java @@ -373,9 +373,11 @@ public class ManagedCamelContext extends ManagedPerformanceCounter implements Ti public Map<String, Properties> findComponents() throws Exception { Map<String, Properties> answer = context.findComponents(); for (Map.Entry<String, Properties> entry : answer.entrySet()) { - // remove component as its not serializable over JMX + // remove component and com as its not serializable over JMX if (entry.getValue() != null) { entry.getValue().remove("component"); + // and components which just list all the components in the JAR/bundle and that is verbose and not needed + entry.getValue().remove("components"); } } return answer; http://git-wip-us.apache.org/repos/asf/camel/blob/6fc97272/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java b/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java index f4360ee..485cb49 100644 --- a/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java +++ b/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java @@ -119,10 +119,18 @@ public interface ClassResolver { URL loadResourceAsURL(String uri); /** - * Loads the given resources as a URL + * Loads the given resources as a URL from the current bundle/classloader * * @param uri the uri of the resource * @return the URLs found on the classpath */ Enumeration<URL> loadResourcesAsURL(String uri); + + /** + * Loads the given resources as a URL from all bundles/classloaders + * + * @param uri the uri of the resource + * @return the URLs found on the classpath + */ + Enumeration<URL> loadAllResourcesAsURL(String uri); } http://git-wip-us.apache.org/repos/asf/camel/blob/6fc97272/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java ---------------------------------------------------------------------- diff --git a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java index 10629a7..c8d80e7 100644 --- a/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java +++ b/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java @@ -35,7 +35,10 @@ import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.NoSuchBeanException; import org.apache.camel.NoSuchEndpointException; +import org.apache.camel.spi.ClassResolver; import org.apache.camel.spi.RouteStartupOrder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import static org.apache.camel.util.ObjectHelper.isEmpty; import static org.apache.camel.util.ObjectHelper.isNotEmpty; @@ -51,6 +54,8 @@ public final class CamelContextHelper { public static final String COMPONENT_DESCRIPTOR = "META-INF/services/org/apache/camel/component.properties"; public static final String COMPONENT_DOCUMENTATION_PREFIX = "org/apache/camel/component/"; + private static final Logger LOG = LoggerFactory.getLogger(CamelContextHelper.class); + /** * Utility classes should not have a public constructor. */ @@ -359,7 +364,9 @@ public final class CamelContextHelper { * and from the {@link org.apache.camel.spi.Registry}. */ public static SortedMap<String, Properties> findComponents(CamelContext camelContext) throws LoadPropertiesException { - Enumeration<URL> iter = camelContext.getClassResolver().loadResourcesAsURL(COMPONENT_DESCRIPTOR); + ClassResolver resolver = camelContext.getClassResolver(); + LOG.info("Finding all components using class resolver: {} -> {}", new Object[]{resolver}); + Enumeration<URL> iter = resolver.loadAllResourcesAsURL(COMPONENT_DESCRIPTOR); return findComponents(camelContext, iter); } @@ -369,6 +376,7 @@ public final class CamelContextHelper { SortedMap<String, Properties> map = new TreeMap<String, Properties>(); while (componentDescriptionIter != null && componentDescriptionIter.hasMoreElements()) { URL url = componentDescriptionIter.nextElement(); + LOG.info("Finding components in url: {}", url); try { Properties properties = new Properties(); properties.load(url.openStream()); @@ -382,7 +390,11 @@ public final class CamelContextHelper { String className = null; InputStream is = null; try { - is = camelContext.getClassResolver().loadResourceAsStream(COMPONENT_BASE + name); + // now load the component name resource so we can grab its properties and the class name + Enumeration<URL> urls = camelContext.getClassResolver().loadAllResourcesAsURL(COMPONENT_BASE + name); + if (urls != null && urls.hasMoreElements()) { + is = urls.nextElement().openStream(); + } if (is != null) { Properties compProperties = new Properties(); compProperties.load(is); http://git-wip-us.apache.org/repos/asf/camel/blob/6fc97272/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java ---------------------------------------------------------------------- diff --git a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java index 8e7327c..a52ec41 100644 --- a/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java +++ b/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java @@ -20,9 +20,11 @@ import java.io.IOException; import java.io.InputStream; import java.net.URL; import java.util.Enumeration; +import java.util.Vector; import org.apache.camel.impl.DefaultClassResolver; import org.apache.camel.util.CastUtils; +import org.apache.camel.util.FileUtil; import org.apache.camel.util.ObjectHelper; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; @@ -38,7 +40,8 @@ public class OsgiClassResolver extends DefaultClassResolver { public OsgiClassResolver(BundleContext context) { this.bundleContext = context; } - + + @Override public Class<?> resolveClass(String name) { LOG.trace("Resolve class {}", name); name = ObjectHelper.normalizeClassName(name); @@ -50,10 +53,12 @@ public class OsgiClassResolver extends DefaultClassResolver { return clazz; } + @Override public <T> Class<T> resolveClass(String name, Class<T> type) { return CastUtils.cast(resolveClass(name)); } + @Override public InputStream loadResourceAsStream(String uri) { ObjectHelper.notEmpty(uri, "uri"); URL url = loadResourceAsURL(uri); @@ -68,6 +73,7 @@ public class OsgiClassResolver extends DefaultClassResolver { return answer; } + @Override public URL loadResourceAsURL(String uri) { ObjectHelper.notEmpty(uri, "uri"); return bundleContext.getBundle().getResource(uri); @@ -83,6 +89,35 @@ public class OsgiClassResolver extends DefaultClassResolver { } } + @Override + public Enumeration<URL> loadAllResourcesAsURL(String uri) { + ObjectHelper.notEmpty(uri, "uri"); + Vector<URL> answer = new Vector<URL>(); + + try { + Enumeration<URL> e = bundleContext.getBundle().getResources(uri); + while (e != null && e.hasMoreElements()) { + answer.add(e.nextElement()); + } + + String path = FileUtil.onlyPath(uri); + String name = FileUtil.stripPath(uri); + if (path != null && name != null) { + for (Bundle bundle : bundleContext.getBundles()) { + LOG.trace("Finding all entries in path: {} with pattern: {}", path, name); + e = bundle.findEntries(path, name, false); + while (e != null && e.hasMoreElements()) { + answer.add(e.nextElement()); + } + } + } + } catch (IOException e) { + throw new RuntimeException("Cannot load resource: " + uri, e); + } + + return answer.elements(); + } + protected Class<?> doLoadClass(String name, Bundle loader) { ObjectHelper.notEmpty(name, "name"); Class<?> answer = null;