activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From chir...@apache.org
Subject svn commit: r521021 - in /activemq/camel/trunk: camel-core/ camel-core/src/main/java/org/apache/camel/builder/ camel-xbean/ camel-xbean/src/main/java/org/apache/camel/spring/ camel-xbean/src/test/java/org/apache/camel/spring/ camel-xbean/src/test/resou...
Date Wed, 21 Mar 2007 22:11:13 GMT
Author: chirino
Date: Wed Mar 21 15:11:12 2007
New Revision: 521021

URL: http://svn.apache.org/viewvc?view=rev&rev=521021
Log:
Added the Fluent Annotations so that the spring processor can do better mapping of the builders
to XML
Got the first spring based builder test case working!


Added:
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/Fluent.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FluentArg.java
    activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/IllegalRouteException.java
    activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/MethodInfo.java
Modified:
    activemq/camel/trunk/camel-core/pom.xml
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java
    activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
    activemq/camel/trunk/camel-xbean/pom.xml
    activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/CamelBeanDefinitionParser.java
    activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderAction.java
    activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderFactory.java
    activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderStatement.java
    activemq/camel/trunk/camel-xbean/src/test/java/org/apache/camel/spring/SpringXMLExtensionTest.java
    activemq/camel/trunk/camel-xbean/src/test/resources/org/apache/camel/spring/spring_xml_extension_test.xml

Modified: activemq/camel/trunk/camel-core/pom.xml
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/pom.xml?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-core/pom.xml (original)
+++ activemq/camel/trunk/camel-core/pom.xml Wed Mar 21 15:11:12 2007
@@ -50,6 +50,9 @@
 
   <build>
     <plugins>
+      <!--
+      Disabling the xbean annotation processor for now since it's qdox parser is choking
on the 
+      Java 1.5 stuff
       <plugin>
         <groupId>org.apache.xbean</groupId>
         <artifactId>maven-xbean-plugin</artifactId>
@@ -66,6 +69,7 @@
           </execution>
         </executions>
       </plugin>
+      -->
 
       <!-- generate the attached tests jar -->
       <plugin>

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/Fluent.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/Fluent.java?view=auto&rev=521021
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/Fluent.java (added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/Fluent.java Wed
Mar 21 15:11:12 2007
@@ -0,0 +1,30 @@
+/*
+ * 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.builder;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** 
+ * Used to annotate fluent API methods.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.METHOD)
+public @interface Fluent {
+}

Added: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FluentArg.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FluentArg.java?view=auto&rev=521021
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FluentArg.java
(added)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FluentArg.java
Wed Mar 21 15:11:12 2007
@@ -0,0 +1,31 @@
+/*
+ * 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.builder;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/** 
+ * Used to annotate the parameter of a {@see Fluent} method.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.PARAMETER)
+public @interface FluentArg {
+	String value();
+}

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java
(original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/FromBuilder.java
Wed Mar 21 15:11:12 2007
@@ -54,14 +54,16 @@
     /**
      * Sends the exchange to the given endpoint URI
      */
-    public ProcessorFactory<E> to(String uri) {
+    @Fluent
+    public ProcessorFactory<E> to(@FluentArg("uri") String uri) {
         return to(endpoint(uri));
     }
 
     /**
      * Sends the exchange to the given endpoint
      */
-    public ProcessorFactory<E> to(Endpoint<E> endpoint) {
+    @Fluent
+    public ProcessorFactory<E> to(@FluentArg("endpoint") Endpoint<E> endpoint)
{
         ToBuilder<E> answer = new ToBuilder<E>(this, endpoint);
         addProcessBuilder(answer);
         return answer;
@@ -70,21 +72,24 @@
     /**
      * Sends the exchange to a list of endpoints using the {@link MulticastProcessor} pattern
      */
-    public ProcessorFactory<E> to(String... uris) {
+    @Fluent
+    public ProcessorFactory<E> to(@FluentArg("uris") String... uris) {
         return to(endpoints(uris));
     }
 
     /**
      * Sends the exchange to a list of endpoints using the {@link MulticastProcessor} pattern
      */
-    public ProcessorFactory<E> to(Endpoint<E>... endpoints) {
+    @Fluent
+    public ProcessorFactory<E> to(@FluentArg("endpoints") Endpoint<E>... endpoints)
{
         return to(endpoints(endpoints));
     }
 
     /**
      * Sends the exchange to a list of endpoint using the {@link MulticastProcessor} pattern
      */
-    public ProcessorFactory<E> to(Collection<Endpoint<E>> endpoints) {
+    @Fluent
+    public ProcessorFactory<E> to(@FluentArg("endpoints") Collection<Endpoint<E>>
endpoints) {
         return addProcessBuilder(new MulticastBuilder<E>(this, endpoints));
     }
 
@@ -92,7 +97,8 @@
      * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed
by each endpoint in turn
      * and for request/response the output of one endpoint will be the input of the next
endpoint
      */
-    public ProcessorFactory<E> pipeline(String... uris) {
+    @Fluent
+    public ProcessorFactory<E> pipeline(@FluentArg("uris") String... uris) {
         return pipeline(endpoints(uris));
     }
 
@@ -100,7 +106,8 @@
      * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed
by each endpoint in turn
      * and for request/response the output of one endpoint will be the input of the next
endpoint
      */
-    public ProcessorFactory<E> pipeline(Endpoint<E>... endpoints) {
+    @Fluent
+    public ProcessorFactory<E> pipeline(@FluentArg("endpoints") Endpoint<E>...
endpoints) {
         return pipeline(endpoints(endpoints));
     }
 
@@ -108,14 +115,16 @@
      * Creates a {@link Pipeline} of the list of endpoints so that the message will get processed
by each endpoint in turn
      * and for request/response the output of one endpoint will be the input of the next
endpoint
      */
-    public ProcessorFactory<E> pipeline(Collection<Endpoint<E>> endpoints)
{
+    @Fluent
+    public ProcessorFactory<E> pipeline(@FluentArg("endpoints") Collection<Endpoint<E>>
endpoints) {
         return addProcessBuilder(new PipelineBuilder<E>(this, endpoints));
     }
 
     /**
      * Adds the custom processor to this destination
      */
-    public ConstantProcessorBuilder<E> process(Processor<E> processor) {
+    @Fluent
+    public ConstantProcessorBuilder<E> process(@FluentArg("processor") Processor<E>
processor) {
         ConstantProcessorBuilder<E> answer = new ConstantProcessorBuilder<E>(processor);
         addProcessBuilder(answer);
         return answer;
@@ -127,7 +136,8 @@
      *
      * @return the builder for a predicate
      */
-    public FilterBuilder<E> filter(Predicate<E> predicate) {
+    @Fluent
+    public FilterBuilder<E> filter(@FluentArg("predicate") Predicate<E> predicate)
{
         FilterBuilder<E> answer = new FilterBuilder<E>(this, predicate);
         addProcessBuilder(answer);
         return answer;
@@ -138,6 +148,7 @@
      *
      * @return the builder for a choice expression
      */
+    @Fluent
     public ChoiceBuilder<E> choice() {
         ChoiceBuilder<E> answer = new ChoiceBuilder<E>(this);
         addProcessBuilder(answer);
@@ -147,10 +158,11 @@
     /**
      * Creates a dynamic <a href="http://activemq.apache.org/camel/recipient-list.html">Recipient
List</a> pattern.
      *
-     * @param valueBuilder is the builder of the expression used in the {@link RecipientList}
to decide the destinations
+     * @param receipients is the builder of the expression used in the {@link RecipientList}
to decide the destinations
      */
-    public RecipientListBuilder<E> recipientList(ValueBuilder<E> valueBuilder)
{
-        RecipientListBuilder<E> answer = new RecipientListBuilder<E>(this, valueBuilder);
+    @Fluent
+    public RecipientListBuilder<E> recipientList(@FluentArg("receipients") ValueBuilder<E>
receipients) {
+        RecipientListBuilder<E> answer = new RecipientListBuilder<E>(this, receipients);
         addProcessBuilder(answer);
         return answer;
     }
@@ -159,11 +171,12 @@
      * A builder for the <a href="http://activemq.apache.org/camel/splitter.html">Splitter</a>
pattern
      * where an expression is evaluated to iterate through each of the parts of a message
and then each part is then send to some endpoint.
      *
-     * @param valueBuilder the builder for the value used as the expression on which to split
+     * @param receipients the builder for the value used as the expression on which to split
      * @return the builder
      */
-    public SplitterBuilder<E> splitter(ValueBuilder<E> valueBuilder) {
-        SplitterBuilder<E> answer = new SplitterBuilder<E>(this, valueBuilder);
+    @Fluent
+    public SplitterBuilder<E> splitter(@FluentArg("receipients") ValueBuilder<E>
receipients) {
+        SplitterBuilder<E> answer = new SplitterBuilder<E>(this, receipients);
         addProcessBuilder(answer);
         return answer;
     }
@@ -174,7 +187,8 @@
      * @param errorHandlerBuilder the error handler to be used by default for all child routes
      * @return the current builder with the error handler configured
      */
-    public FromBuilder<E> errorHandler(ErrorHandlerBuilder errorHandlerBuilder) {
+    @Fluent
+    public FromBuilder<E> errorHandler(@FluentArg("handler") ErrorHandlerBuilder errorHandlerBuilder)
{
         setErrorHandlerBuilder(errorHandlerBuilder);
         return this;
     }
@@ -182,13 +196,29 @@
     /**
      * Configures whether or not the error handler is inherited by every processing node
(or just the top most one)
      *
-     * @param value the falg as to whether error handlers should be inherited or not
+     * @param condition the falg as to whether error handlers should be inherited or not
      * @return the current builder
      */
-    public FromBuilder<E> inheritErrorHandler(boolean value) {
-        setInheritErrorHandler(value);
+    @Fluent
+    public FromBuilder<E> inheritErrorHandler(@FluentArg("condition") boolean condition)
{
+        setInheritErrorHandler(condition);
         return this;
     }
+    
+    @Fluent
+    public InterceptorBuilder<E> intercept() {
+        InterceptorBuilder<E> answer = new InterceptorBuilder<E>(this);
+        addProcessBuilder(answer);
+        return answer;
+    }
+
+    @Fluent
+    public InterceptorBuilder<E> intercept(@FluentArg("interceptor") InterceptorProcessor<E>
interceptor) {
+        InterceptorBuilder<E> answer = new InterceptorBuilder<E>(this);
+        answer.add(interceptor);
+        addProcessBuilder(answer);
+        return answer;
+    }
 
 
     // Properties
@@ -243,16 +273,4 @@
         return processors;
     }
 
-    public InterceptorBuilder<E> intercept() {
-        InterceptorBuilder<E> answer = new InterceptorBuilder<E>(this);
-        addProcessBuilder(answer);
-        return answer;
-    }
-
-    public InterceptorBuilder<E> intercept(InterceptorProcessor<E> interceptor)
{
-        InterceptorBuilder<E> answer = new InterceptorBuilder<E>(this);
-        answer.add(interceptor);
-        addProcessBuilder(answer);
-        return answer;
-    }
 }

Modified: activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
(original)
+++ activemq/camel/trunk/camel-core/src/main/java/org/apache/camel/builder/RouteBuilder.java
Wed Mar 21 15:11:12 2007
@@ -53,11 +53,13 @@
      */
     public abstract void configure();
 
-    public FromBuilder<E> from(String uri) {
+    @Fluent
+    public FromBuilder<E> from( @FluentArg("uri") String uri) {
         return from(endpoint(uri));
     }
 
-    public FromBuilder<E> from(Endpoint<E> endpoint) {
+    @Fluent
+    public FromBuilder<E> from( @FluentArg("endpoint") Endpoint<E> endpoint)
{
         FromBuilder<E> answer = new FromBuilder<E>(this, endpoint);
         fromBuilders.add(answer);
         return answer;

Modified: activemq/camel/trunk/camel-xbean/pom.xml
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/pom.xml?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/pom.xml (original)
+++ activemq/camel/trunk/camel-xbean/pom.xml Wed Mar 21 15:11:12 2007
@@ -56,6 +56,53 @@
     </dependency>
 
     <dependency>
+      <groupId>org.apache.xbean</groupId>
+      <artifactId>xbean-spring</artifactId>
+      <version>2.8</version>
+    </dependency>
+    
+      <dependency>
+        <groupId>org.springframework</groupId>
+        <artifactId>spring</artifactId>
+        <version>2.0</version>
+        <exclusions>
+          <exclusion>
+            <groupId>javax.mail</groupId>
+            <artifactId>mail</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>javax.resource</groupId>
+            <artifactId>connector</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>javax.transaction</groupId>
+            <artifactId>jta</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-support</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-orm</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-hibernate</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-remoting</artifactId>
+          </exclusion>
+          <exclusion>
+            <groupId>org.springframework</groupId>
+            <artifactId>spring-core</artifactId>
+          </exclusion>
+        </exclusions>
+      </dependency>
+    
+
+    <dependency>
       <groupId>commons-logging</groupId>
       <artifactId>commons-logging</artifactId>
       <optional>false</optional>

Modified: activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/CamelBeanDefinitionParser.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/CamelBeanDefinitionParser.java?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/CamelBeanDefinitionParser.java
(original)
+++ activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/CamelBeanDefinitionParser.java
Wed Mar 21 15:11:12 2007
@@ -1,15 +1,28 @@
 package org.apache.camel.spring;
 
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Method;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
 import java.util.List;
+import java.util.Set;
 
+import org.apache.camel.builder.Fluent;
+import org.apache.camel.builder.FluentArg;
 import org.apache.camel.builder.RouteBuilder;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
 import org.springframework.beans.factory.support.AbstractBeanDefinition;
 import org.springframework.beans.factory.support.BeanDefinitionBuilder;
 import org.springframework.beans.factory.xml.AbstractBeanDefinitionParser;
 import org.springframework.beans.factory.xml.ParserContext;
 import org.springframework.util.xml.DomUtils;
+import org.w3c.dom.Attr;
 import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
 import org.w3c.dom.Node;
 import org.w3c.dom.NodeList;
 
@@ -46,20 +59,140 @@
 		NodeList childElements = element.getChildNodes();
 		ArrayList<RouteBuilderAction> actions = new ArrayList<RouteBuilderAction>(childElements.getLength());
 		if (childElements != null && childElements.getLength() > 0) {
+			Element previousElement=null;
 			for (int i = 0; i < childElements.getLength(); ++i) {
 				Node node = childElements.item(i);
 				if( node.getNodeType() == Node.ELEMENT_NODE ) {
-					currentBuilder = parseAction(currentBuilder, actions, (Element)node);
+					currentBuilder = parseAction(currentBuilder, actions, (Element)node, previousElement);
+					previousElement = (Element)node;
 				}
 			}
 		}
 		
+		rc.setActions(actions);
 		return rc;
 	}
 
-	private Class parseAction(Class currentBuilder, ArrayList<RouteBuilderAction> actions,
Element element) {
-		actions.add( new RouteBuilderAction(element.getNodeName()) );
-		return currentBuilder;
+	private Class parseAction(Class currentBuilder, ArrayList<RouteBuilderAction> actions,
Element element, Element previousElement) {
+		
+		String actionName = element.getLocalName();
+		
+		// Get a list of method names that match the action.
+		ArrayList<MethodInfo> methods = findFluentMethodsWithName( currentBuilder, element.getLocalName()
);		
+		if( methods.isEmpty() ) {
+			throw new IllegalRouteException(actionName, previousElement==null? null : previousElement.getLocalName());
+		}
+		
+		// Pick the best method out of the list.  Sort by argument length.  Pick first longest
match.
+		Collections.sort(methods, new Comparator<MethodInfo>(){
+			public int compare(MethodInfo m1, MethodInfo m2) {
+				return m1.method.getParameterTypes().length - m2.method.getParameterTypes().length; 
+			}
+		});
+		
+		// Build an ordered list of the element attributes.
+		HashMap<String, Object> attributes = getAttributes(element);
+		
+		// Do we have enough parameters for this action.
+		MethodInfo match=findBestMethod(methods, attributes);
+		if( match == null )
+			throw new IllegalRouteException(actionName, previousElement==null? null : previousElement.getLocalName());
+			
+		actions.add( new RouteBuilderAction(match, attributes) );
+		return match.method.getReturnType();
+	}
+
+	private MethodInfo findBestMethod(ArrayList<MethodInfo> methods, HashMap<String,
Object> attributes) {
+		Set<String> attributeNames = attributes.keySet();
+		for (MethodInfo method : methods) {
+			Set<String> parameterNames = method.parameters.keySet();
+			
+			// If all the parameters are specified as parameters.
+			if(    attributeNames.size()==parameterNames.size() 
+				&& attributeNames.containsAll(parameterNames)) {
+				return method;
+			}
+		}
+		return null;
+	}
+
+	private HashMap<String, Object> getAttributes(Element element) {
+		HashMap<String, Object> attributes = new HashMap<String, Object>();
+		NamedNodeMap childNodes = element.getAttributes();
+		for( int i=0; i < childNodes.getLength(); i++) {
+			Node node = childNodes.item(i);
+			if( node.getNodeType() == Node.ATTRIBUTE_NODE ) {
+				Attr attr = (Attr) node;
+				
+				String str = attr.getValue();
+				Object value = str;
+				
+				// If the value starts with # then it's a bean reference
+				if( str.startsWith("#")) {
+					str = str.substring(1);
+					// Support using ## to escape the bean reference feature.
+					if( !str.startsWith("#")) {
+						value = new RuntimeBeanReference(str);
+					}					
+				}
+				
+				attributes.put(attr.getName(), value);
+			}
+		}
+		return attributes;
+	}
+
+	/**
+	 * Finds all the methods on the clazz that match the name and which have the
+	 * {@see Fluent} annotation and whoes parameters have the {@see FluentArg} annotation.
+	 *  
+	 * @param clazz
+	 * @param name
+	 * @return
+	 */
+	private ArrayList<MethodInfo> findFluentMethodsWithName(Class clazz, String name)
{
+		ArrayList<MethodInfo> rc = new ArrayList<MethodInfo>();
+		Method[] methods = clazz.getMethods();
+		for (int i = 0; i < methods.length; i++) {
+			Method method = methods[i];
+			if( name.equals(method.getName())) {
+				
+				if( !method.isAnnotationPresent(Fluent.class) ) {
+					List<Annotation> l = Arrays.asList(method.getAnnotations());
+					System.out.println(l);
+					continue;
+				}
+				
+				
+				LinkedHashMap<String, Class> map = new LinkedHashMap<String, Class>();
+				Class<?>[] parameters = method.getParameterTypes();
+				for (int j = 0; j < parameters.length; j++) {
+					Class<?> parameter = parameters[j];
+					FluentArg annotation = getParameterAnnotation(FluentArg.class, method, j);
+					if( annotation!=null ) {
+						map.put(annotation.value(), parameter);
+					} else {
+						break;
+					}
+				}
+				
+				// If all the parameters were annotated...
+				if( parameters.length == map.size() ) {
+					rc.add(new MethodInfo(method, map));
+				}
+			}
+		}
+		return rc;
+	}
+
+	private <T> T getParameterAnnotation(Class<T> annotationClass, Method method,
int index) {
+		Annotation[] annotations = method.getParameterAnnotations()[index];
+		for (int i = 0; i < annotations.length; i++) {
+			if( annotationClass.isAssignableFrom(annotations[i].getClass()) ) {
+				return (T)annotations[i];
+			}
+		}
+		return null;
 	}
 
 }

Added: activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/IllegalRouteException.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/IllegalRouteException.java?view=auto&rev=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/IllegalRouteException.java
(added)
+++ activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/IllegalRouteException.java
Wed Mar 21 15:11:12 2007
@@ -0,0 +1,20 @@
+package org.apache.camel.spring;
+
+public class IllegalRouteException extends IllegalArgumentException {
+
+	private static final long serialVersionUID = -2166507687211986107L;
+	private final String actionName;
+	private final String previousAction;
+
+	public IllegalRouteException(String actionName, String previousAction) {
+		super("Illegal route.");
+		this.actionName = actionName;
+		this.previousAction = previousAction;
+	}
+
+	@Override
+	public String getMessage() {
+		String errorContext = previousAction==null ? "as the starting action." : "after action
'"+previousAction+"'.";
+		return super.getMessage() + "The action '"+actionName+"' cannot be used "+errorContext;
+	}
+}

Added: activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/MethodInfo.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/MethodInfo.java?view=auto&rev=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/MethodInfo.java
(added)
+++ activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/MethodInfo.java
Wed Mar 21 15:11:12 2007
@@ -0,0 +1,23 @@
+/**
+ * 
+ */
+package org.apache.camel.spring;
+
+import java.lang.reflect.Method;
+import java.util.LinkedHashMap;
+
+import org.springframework.beans.BeanWrapperImpl;
+
+public class MethodInfo {
+	final Method method;
+	final LinkedHashMap<String, Class> parameters;
+	
+	public MethodInfo(Method method, LinkedHashMap<String, Class> parameters) {
+		this.method=method;
+		this.parameters=parameters;
+	}
+
+	public String getName() {
+		return method.getName();
+	}
+}
\ No newline at end of file

Modified: activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderAction.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderAction.java?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderAction.java
(original)
+++ activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderAction.java
Wed Mar 21 15:11:12 2007
@@ -1,17 +1,53 @@
 package org.apache.camel.spring;
 
-import org.apache.camel.builder.RouteBuilder;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.springframework.beans.SimpleTypeConverter;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.config.RuntimeBeanReference;
 
 public class RouteBuilderAction {
 
-	private final String name;
+	private final MethodInfo methodInfo;
+	private final HashMap<String, Object> parameterValues;
 
-	public RouteBuilderAction(String name) {
-		this.name = name;
+	public RouteBuilderAction(MethodInfo methodInfo, HashMap<String, Object> parameterValues)
{
+		this.methodInfo = methodInfo;
+		this.parameterValues = parameterValues;
 	}
 
-	public void create(RouteBuilder builder) {
-		// TODO Auto-generated method stub
+	public Object invoke(BeanFactory beanFactory, Object builder) {
+		SimpleTypeConverter converter = new SimpleTypeConverter();
+		Object args[] = new Object[methodInfo.parameters.size()];
+		int pos=0;
+		for (Map.Entry<String, Class> entry :  methodInfo.parameters.entrySet()) {
+			String paramName = entry.getKey();
+			Class paramClass = entry.getValue();
+			Object value = parameterValues.get(paramName);
+			if( value != null ) {
+				if( value.getClass() == RuntimeBeanReference.class ) {
+					value = beanFactory.getBean(((RuntimeBeanReference)value).getBeanName());
+				}
+				args[pos] = converter.convertIfNecessary(value, paramClass);				
+			}
+			
+		}
+		
+		try {
+			return methodInfo.method.invoke(builder, args);
+		} catch (InvocationTargetException e) {
+			throw new IllegalArgumentException(e.getCause());
+		} catch (RuntimeException e) {
+			throw e;
+		} catch (Throwable e) {
+			throw new IllegalArgumentException(e);
+		}
 		
+	}
+
+	public String getName() {
+		return methodInfo.getName();
 	}
 }

Modified: activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderFactory.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderFactory.java?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderFactory.java
(original)
+++ activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderFactory.java
Wed Mar 21 15:11:12 2007
@@ -3,19 +3,24 @@
 import java.util.ArrayList;
 
 import org.apache.camel.builder.RouteBuilder;
+import org.springframework.beans.BeansException;
+import org.springframework.beans.factory.BeanFactory;
+import org.springframework.beans.factory.BeanFactoryAware;
 import org.springframework.beans.factory.FactoryBean;
 
-public class RouteBuilderFactory implements FactoryBean {
+public class RouteBuilderFactory implements FactoryBean, BeanFactoryAware {
 	private ArrayList<RouteBuilderStatement> routes;
 	private boolean singleton;
+	private BeanFactory beanFactory;
 
 	class SpringRouteBuilder extends RouteBuilder {
 		private ArrayList<RouteBuilderStatement> routes;
+		private BeanFactory beanFactory;
 
 		@Override
 		public void configure() {
 			for (RouteBuilderStatement routeFactory : routes) {
-				routeFactory.create(this);
+				routeFactory.create(beanFactory, this);
 			}
 		}
 
@@ -25,10 +30,15 @@
 		public void setRoutes(ArrayList<RouteBuilderStatement> routes) {
 			this.routes = routes;
 		}
+
+		public void setBeanFactory(BeanFactory beanFactory) {
+			this.beanFactory = beanFactory;
+		}
 	}
 	
 	public Object getObject() throws Exception {
 		SpringRouteBuilder builder = new SpringRouteBuilder();
+		builder.setBeanFactory(beanFactory);
 		builder.setRoutes(routes);
 		return builder;
 	}
@@ -51,5 +61,8 @@
 		this.routes = routes;
 	}
 
+	public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
+		this.beanFactory = beanFactory;
+	}
 
 }

Modified: activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderStatement.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderStatement.java?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderStatement.java
(original)
+++ activemq/camel/trunk/camel-xbean/src/main/java/org/apache/camel/spring/RouteBuilderStatement.java
Wed Mar 21 15:11:12 2007
@@ -1,11 +1,29 @@
 package org.apache.camel.spring;
 
-import org.apache.camel.builder.RouteBuilder;
+import java.util.ArrayList;
+
+import org.springframework.beans.factory.BeanFactory;
 
 public class RouteBuilderStatement {
+	private ArrayList<RouteBuilderAction> actions;
+
+	public void create(BeanFactory beanFactory, Object builder) {
+		Object currentBuilder = builder;
+		RouteBuilderAction lastAction=null;
+		for (RouteBuilderAction action : actions) {
+			// The last action may have left us without a builder to invoke next!
+			if( builder == null ) {
+				throw new IllegalArgumentException("Invalid route configuration.  The '"+lastAction.getName()+"'
action cannot be followed by the '"+action.getName()+"' action.");
+			}
+			currentBuilder = action.invoke(beanFactory, currentBuilder);
+			lastAction = action;
+		}
+	}
 
-	public void create(RouteBuilder builder) {
-		// TODO Auto-generated method stub
-		
+	public ArrayList<RouteBuilderAction> getActions() {
+		return actions;
+	}
+	public void setActions(ArrayList<RouteBuilderAction> actions) {
+		this.actions = actions;
 	}
 }

Modified: activemq/camel/trunk/camel-xbean/src/test/java/org/apache/camel/spring/SpringXMLExtensionTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/test/java/org/apache/camel/spring/SpringXMLExtensionTest.java?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/test/java/org/apache/camel/spring/SpringXMLExtensionTest.java
(original)
+++ activemq/camel/trunk/camel-xbean/src/test/java/org/apache/camel/spring/SpringXMLExtensionTest.java
Wed Mar 21 15:11:12 2007
@@ -16,11 +16,19 @@
  */
 package org.apache.camel.spring;
 
-import org.apache.camel.builder.RouteBuilder;
-import org.springframework.context.support.ClassPathXmlApplicationContext;
+import java.util.Map;
+import java.util.Set;
 
 import junit.framework.TestCase;
 
+import org.apache.camel.Endpoint;
+import org.apache.camel.Exchange;
+import org.apache.camel.Processor;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.processor.DeadLetterChannel;
+import org.apache.camel.processor.SendProcessor;
+import org.springframework.context.support.ClassPathXmlApplicationContext;
+
 /**
  * @version $Revision: 520164 $
  */
@@ -41,5 +49,39 @@
 	public void testSimpleRoute() {
 		RouteBuilder builder = (RouteBuilder) ctx.getBean("testSimpleRoute");
 		assertNotNull(builder);
+		
+        Map<Endpoint<Exchange>, Processor<Exchange>> routeMap = builder.getRouteMap();
+        Set<Map.Entry<Endpoint<Exchange>, Processor<Exchange>>> routes
= routeMap.entrySet();
+        assertEquals("Number routes created", 1, routes.size());
+        for (Map.Entry<Endpoint<Exchange>, Processor<Exchange>> route :
routes) {
+            Endpoint<Exchange> key = route.getKey();
+            assertEquals("From endpoint", "queue:a", key.getEndpointUri());
+            Processor processor = getProcessorWithoutErrorHandler(route);
+
+            assertTrue("Processor should be a SendProcessor but was: " + processor + " with
type: " + processor.getClass().getName(), processor instanceof SendProcessor);
+            SendProcessor sendProcessor = (SendProcessor) processor;
+            assertEquals("Endpoint URI", "queue:b", sendProcessor.getDestination().getEndpointUri());
+        }
+		
 	}
+	
+	
+    /**
+     * By default routes should be wrapped in the {@link DeadLetterChannel} so lets unwrap
that and return the actual processor
+     */
+    protected Processor<Exchange> getProcessorWithoutErrorHandler(Map.Entry<Endpoint<Exchange>,
Processor<Exchange>> route) {
+        Processor<Exchange> processor = route.getValue();
+        return unwrapErrorHandler(processor);
+    }
+
+    protected Processor<Exchange> unwrapErrorHandler(Processor<Exchange> processor)
{
+        assertTrue("Processor should be a DeadLetterChannel but was: " + processor + " with
type: " + processor.getClass().getName(), processor instanceof DeadLetterChannel);
+        DeadLetterChannel deadLetter = (DeadLetterChannel) processor;
+        return deadLetter.getOutput();
+    }
+
+    protected void assertEndpointUri(Endpoint<Exchange> endpoint, String uri) {
+        assertEquals("Endoint uri for: " + endpoint, uri, endpoint.getEndpointUri());
+    }
+	
 }

Modified: activemq/camel/trunk/camel-xbean/src/test/resources/org/apache/camel/spring/spring_xml_extension_test.xml
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/camel-xbean/src/test/resources/org/apache/camel/spring/spring_xml_extension_test.xml?view=diff&rev=521021&r1=521020&r2=521021
==============================================================================
--- activemq/camel/trunk/camel-xbean/src/test/resources/org/apache/camel/spring/spring_xml_extension_test.xml
(original)
+++ activemq/camel/trunk/camel-xbean/src/test/resources/org/apache/camel/spring/spring_xml_extension_test.xml
Wed Mar 21 15:11:12 2007
@@ -16,21 +16,17 @@
     limitations under the License.
 -->
 <beans xmlns="http://www.springframework.org/schema/beans"
-      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-      xmlns:c="http://activemq.apache.org/camel/schema/camel-1.0.xsd"
-      xsi:schemaLocation="
-         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
-         http://activemq.apache.org/camel/schema/camel-1.0.xsd http://activemq.apache.org/camel/schema/camel-1.0.xsd">
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="
+       http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
+       http://activemq.apache.org/camel/schema/camel-1.0.xsd http://activemq.apache.org/camel/schema/camel-1.0.xsd
+    ">
 
-    <c:routeBuilder id="testSimpleRoute">
-       <c:route>
-         <c:from uri="queue:a"/>
-         <c:to uri="queue:b"/>
-       </c:route>
-       <c:route>
-         <c:from uri="queue:c"/>
-         <c:to uri="queue:d"/>
-       </c:route>
-    </c:routeBuilder>
+    <routeBuilder id="testSimpleRoute" xmlns="http://activemq.apache.org/camel/schema/camel-1.0.xsd">
+       <route>
+         <from uri="queue:a"/>
+         <to uri="queue:b"/>
+       </route>
+    </routeBuilder>
 
 </beans>



Mime
View raw message