Author: jstrachan Date: Wed Oct 31 17:04:13 2012 New Revision: 1404252 URL: http://svn.apache.org/viewvc?rev=1404252&view=rev Log: added a helper method so we can easily discover all the components on the classpath or in the Registry (assuming they all use the camel-package-maven-plugin that is for classpath discovery :)
Added: camel/trunk/camel-core/src/main/java/org/apache/camel/util/LoadPropertiesException.java (with props) camel/trunk/camel-core/src/test/java/org/apache/camel/component/ComponentDiscoveryTest.java (with props) Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java camel/trunk/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java?rev=1404252&r1=1404251&r2=1404252&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/DefaultClassResolver.java Wed Oct 31 17:04:13 2012 @@ -18,6 +18,7 @@ package org.apache.camel.impl; import java.io.InputStream; import java.net.URL; +import java.util.Enumeration; import org.apache.camel.spi.ClassResolver; import org.apache.camel.util.CastUtils; @@ -88,6 +89,12 @@ public class DefaultClassResolver implem return ObjectHelper.loadResourceAsURL(uri); } + @Override + public Enumeration<URL> loadResourcesAsURL(String uri) { + ObjectHelper.notEmpty(uri, "uri"); + return ObjectHelper.loadResourcesAsURL(uri); + } + protected Class<?> loadClass(String name, ClassLoader loader) { ObjectHelper.notEmpty(name, "name"); return ObjectHelper.loadClass(name, loader); Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java?rev=1404252&r1=1404251&r2=1404252&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/spi/ClassResolver.java Wed Oct 31 17:04:13 2012 @@ -18,6 +18,7 @@ package org.apache.camel.spi; import java.io.InputStream; import java.net.URL; +import java.util.Enumeration; /** * A class resolver for loading classes in a loosly coupled manner to cater for different platforms such @@ -117,4 +118,11 @@ public interface ClassResolver { */ URL loadResourceAsURL(String uri); + /** + * Loads the given resources as a URL + * + * @param uri the uri of the resource + * @return the URLs found on the classpath + */ + Enumeration<URL> loadResourcesAsURL(String uri); } Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java?rev=1404252&r1=1404251&r2=1404252&view=diff ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java (original) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/CamelContextHelper.java Wed Oct 31 17:04:13 2012 @@ -16,9 +16,19 @@ */ package org.apache.camel.util; +import java.io.IOException; +import java.net.URL; +import java.util.Enumeration; import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.SortedMap; +import java.util.StringTokenizer; +import java.util.TreeMap; import org.apache.camel.CamelContext; +import org.apache.camel.Component; import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.NoSuchBeanException; @@ -34,6 +44,7 @@ import static org.apache.camel.util.Obje * @version */ public final class CamelContextHelper { + public static final String COMPONENT_DESCRIPTOR = "META-INF/services/org/apache/camel/component.properties"; /** * Utility classes should not have a public constructor. @@ -338,4 +349,45 @@ public final class CamelContextHelper { return null; } + /** + * Finds all possible Components on the classpath and Registry + */ + public static SortedMap<String, Properties> findComponents(CamelContext camelContext) throws LoadPropertiesException { + SortedMap<String,Properties> map = new TreeMap<String, Properties>(); + Enumeration<URL> iter = camelContext.getClassResolver().loadResourcesAsURL(COMPONENT_DESCRIPTOR); + while (iter.hasMoreElements()) { + URL url = iter.nextElement(); + try { + Properties properties = new Properties(); + properties.load(url.openStream()); + String names = properties.getProperty("components"); + if (names != null) { + StringTokenizer tok = new StringTokenizer(names); + while (tok.hasMoreTokens()) { + String name = tok.nextToken(); + map.put(name, properties); + } + } + } catch (IOException e) { + throw new LoadPropertiesException(url, e); + } + } + + // lets see what other components are in the registry + Map<String,Component> beanMap = camelContext.getRegistry().lookupByType(Component.class); + Set<Map.Entry<String,Component>> entries = beanMap.entrySet(); + for (Map.Entry<String, Component> entry : entries) { + String name = entry.getKey(); + if (!map.containsKey(name)) { + Properties properties = new Properties(); + Component component = entry.getValue(); + if (component != null) { + properties.put("component", component); + properties.put("class", component.getClass().getName()); + map.put(name, properties); + } + } + } + return map; + } } Added: camel/trunk/camel-core/src/main/java/org/apache/camel/util/LoadPropertiesException.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/util/LoadPropertiesException.java?rev=1404252&view=auto ============================================================================== --- camel/trunk/camel-core/src/main/java/org/apache/camel/util/LoadPropertiesException.java (added) +++ camel/trunk/camel-core/src/main/java/org/apache/camel/util/LoadPropertiesException.java Wed Oct 31 17:04:13 2012 @@ -0,0 +1,38 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.util; + +import org.apache.camel.CamelException; + +import java.net.URL; + +/** + * Represents a failure to open a Properties file at a given URL + */ +public class LoadPropertiesException extends CamelException { + private final URL url; + + public LoadPropertiesException(URL url, Exception cause) { + super("Failed to load URL: " + url + ". Reason: " + cause, cause); + this.url = url; + } + + public URL getUrl() { + return url; + } +} Propchange: camel/trunk/camel-core/src/main/java/org/apache/camel/util/LoadPropertiesException.java ------------------------------------------------------------------------------ svn:eol-style = native Added: camel/trunk/camel-core/src/test/java/org/apache/camel/component/ComponentDiscoveryTest.java URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/test/java/org/apache/camel/component/ComponentDiscoveryTest.java?rev=1404252&view=auto ============================================================================== --- camel/trunk/camel-core/src/test/java/org/apache/camel/component/ComponentDiscoveryTest.java (added) +++ camel/trunk/camel-core/src/test/java/org/apache/camel/component/ComponentDiscoveryTest.java Wed Oct 31 17:04:13 2012 @@ -0,0 +1,60 @@ +/** + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component; + +import org.apache.camel.CamelContext; +import org.apache.camel.impl.DefaultCamelContext; +import org.apache.camel.util.CamelContextHelper; +import org.junit.Test; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.SortedMap; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +/** + * Test we can auto discover components on the classpath + */ +public class ComponentDiscoveryTest { + private static final transient Logger LOG = LoggerFactory.getLogger(ComponentDiscoveryTest.class); + + @Test + public void testComponentDiscovery() throws Exception { + CamelContext context = new DefaultCamelContext(); + + SortedMap<String,Properties> map = CamelContextHelper.findComponents(context); + assertNotNull("Should never return null", map); + assertTrue("Component map should never be empty", !map.isEmpty()); + + String[] expectedComponentNames = {"file", "vm"}; + for (String expectedName : expectedComponentNames) { + Properties properties = map.get(expectedName); + assertTrue("Component map contain component: " + expectedName, properties != null); + } + + Set<Map.Entry<String,Properties>> entries = map.entrySet(); + for (Map.Entry<String, Properties> entry : entries) { + LOG.info("Found component " + entry.getKey() + " with properties: " + entry.getValue()); + } + } +} Propchange: camel/trunk/camel-core/src/test/java/org/apache/camel/component/ComponentDiscoveryTest.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java?rev=1404252&r1=1404251&r2=1404252&view=diff ============================================================================== --- camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java (original) +++ camel/trunk/components/camel-core-osgi/src/main/java/org/apache/camel/core/osgi/OsgiClassResolver.java Wed Oct 31 17:04:13 2012 @@ -19,6 +19,7 @@ package org.apache.camel.core.osgi; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.Enumeration; import org.apache.camel.impl.DefaultClassResolver; import org.apache.camel.util.CastUtils; @@ -72,6 +73,16 @@ public class OsgiClassResolver extends D return bundleContext.getBundle().getResource(uri); } + @Override + public Enumeration<URL> loadResourcesAsURL(String uri) { + ObjectHelper.notEmpty(uri, "uri"); + try { + return bundleContext.getBundle().getResources(uri); + } catch (IOException e) { + throw new RuntimeException("Cannot load resource: " + uri, e); + } + } + protected Class<?> doLoadClass(String name, Bundle loader) { ObjectHelper.notEmpty(name, "name"); Class<?> answer = null;