You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by js...@apache.org on 2013/04/23 09:52:21 UTC

svn commit: r1470837 - in /camel/trunk: camel-core/ camel-core/src/main/java/org/apache/camel/component/bean/ camel-core/src/main/java/org/apache/camel/component/file/ camel-core/src/main/java/org/apache/camel/component/seda/ camel-core/src/main/java/o...

Author: jstrachan
Date: Tue Apr 23 07:52:20 2013
New Revision: 1470837

URL: http://svn.apache.org/r1470837
Log:
add a few annotations in the spi-annotations project that we can use to annotate endpoints so that we can automatically generate HTML documentation for how to configure them; rather like maven goals work. See CAMEL-6304 for more details. The annotations are in a separate project, spi-annotations - as it makes APT+maven much happier that way; the annotations get included in camel-core as well

Added:
    camel/trunk/tooling/apt/
    camel/trunk/tooling/apt/pom.xml   (with props)
    camel/trunk/tooling/apt/src/
    camel/trunk/tooling/apt/src/main/
    camel/trunk/tooling/apt/src/main/java/
    camel/trunk/tooling/apt/src/main/java/org/
    camel/trunk/tooling/apt/src/main/java/org/apache/
    camel/trunk/tooling/apt/src/main/java/org/apache/camel/
    camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/
    camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/
    camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java   (with props)
    camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/
    camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Func1.java   (with props)
    camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java   (with props)
    camel/trunk/tooling/apt/src/main/resources/
    camel/trunk/tooling/apt/src/main/resources/META-INF/
    camel/trunk/tooling/apt/src/main/resources/META-INF/services/
    camel/trunk/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
    camel/trunk/tooling/apt/src/test/
    camel/trunk/tooling/apt/src/test/java/
    camel/trunk/tooling/apt/src/test/java/org/
    camel/trunk/tooling/apt/src/test/java/org/apache/
    camel/trunk/tooling/apt/src/test/java/org/apache/camel/
    camel/trunk/tooling/apt/src/test/java/org/apache/camel/tools/
    camel/trunk/tooling/apt/src/test/java/org/apache/camel/tools/apt/
    camel/trunk/tooling/spi-annotations/
    camel/trunk/tooling/spi-annotations/pom.xml   (with props)
    camel/trunk/tooling/spi-annotations/src/
    camel/trunk/tooling/spi-annotations/src/main/
    camel/trunk/tooling/spi-annotations/src/main/java/
    camel/trunk/tooling/spi-annotations/src/main/java/org/
    camel/trunk/tooling/spi-annotations/src/main/java/org/apache/
    camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/
    camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/
    camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java   (with props)
    camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java   (with props)
    camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParams.java   (with props)
    camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriPath.java   (with props)
    camel/trunk/tooling/spi-annotations/src/main/resources/
    camel/trunk/tooling/spi-annotations/src/test/
    camel/trunk/tooling/spi-annotations/src/test/java/
    camel/trunk/tooling/spi-annotations/src/test/java/org/
    camel/trunk/tooling/spi-annotations/src/test/java/org/apache/
    camel/trunk/tooling/spi-annotations/src/test/java/org/apache/camel/
Modified:
    camel/trunk/camel-core/pom.xml
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledBatchPollingConsumer.java
    camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollConsumer.java
    camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java
    camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsEndpoint.java
    camel/trunk/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java
    camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
    camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
    camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java
    camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java
    camel/trunk/components/pom.xml
    camel/trunk/tooling/pom.xml

Modified: camel/trunk/camel-core/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/pom.xml?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/pom.xml (original)
+++ camel/trunk/camel-core/pom.xml Tue Apr 23 07:52:20 2013
@@ -33,9 +33,11 @@
 
   <properties>
     <camel.osgi.export.pkg>
+        !org.apache.camel.tools.*,
         org.apache.camel.*;-noimport:=true
     </camel.osgi.export.pkg>
     <camel.osgi.import>
+        org.apache.camel.tools.*;resolution:=optional,
         !org.apache.camel.*,
         !com.googlecode.concurrentlinkedhashmap,
         ${camel.osgi.import.defaults},
@@ -92,6 +94,13 @@
 
     <!-- required dependencies by camel-core -->
     <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>spi-annotations</artifactId>
+      <version>${project.version}</version>
+      <optional>true</optional>
+    </dependency>
+
+    <dependency>
       <groupId>com.googlecode.concurrentlinkedhashmap</groupId>
       <artifactId>concurrentlinkedhashmap-lru</artifactId>
     </dependency>
@@ -142,6 +151,7 @@
 
   <build>
     <plugins>
+
     <!-- Shade the googlecode stuff for OSGi -->
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
@@ -157,6 +167,9 @@
                 <includes>
                   <include>com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru</include>
                 </includes>
+                <excludes>
+                  <exclude>org.apache.camel:apt</exclude>
+                </excludes>
               </artifactSet>
               <relocations>
                  <relocation>
@@ -375,6 +388,24 @@
         </plugins>
       </build>
     </profile>
+
+    <!-- enables the APT dependency so that it can be disabled in IDE builds -->
+    <profile>
+      <id>apt</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+
+      <dependencies>
+        <!-- enable the APT processor -->
+        <dependency>
+          <groupId>org.apache.camel</groupId>
+          <artifactId>apt</artifactId>
+          <version>${project.version}</version>
+          <scope>provided</scope>
+        </dependency>
+      </dependencies>
+    </profile>
   </profiles>
 
 </project>

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/bean/BeanEndpoint.java Tue Apr 23 07:52:20 2013
@@ -20,16 +20,23 @@ import org.apache.camel.Component;
 import org.apache.camel.ExchangePattern;
 import org.apache.camel.Processor;
 import org.apache.camel.impl.ProcessorEndpoint;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
 
 /**
  * Endpoint for the bean component.
  *
  * @version 
  */
+@UriEndpoint(scheme = "bean")
 public class BeanEndpoint extends ProcessorEndpoint {
+    @UriParam
     private boolean cache;
+    @UriParam
     private boolean multiParameterArray;
+    @UriParam
     private String beanName;
+    @UriParam
     private String method;
     private BeanHolder beanHolder;
 
@@ -54,6 +61,9 @@ public class BeanEndpoint extends Proces
         return beanName;
     }
 
+    /**
+     * Sets the name of the bean to invoke
+     */
     public void setBeanName(String beanName) {
         this.beanName = beanName;
     }
@@ -78,6 +88,9 @@ public class BeanEndpoint extends Proces
         return method;
     }
 
+    /**
+     * Sets the name of the method to invoke on the bean
+     */
     public void setMethod(String method) {
         this.method = method;
     }

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/FileEndpoint.java Tue Apr 23 07:52:20 2013
@@ -23,17 +23,27 @@ import org.apache.camel.Component;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.processor.idempotent.MemoryIdempotentRepository;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
 import org.apache.camel.util.FileUtil;
 import org.apache.camel.util.ObjectHelper;
 
 /**
  * File endpoint.
  */
+@UriEndpoint(scheme = "file", consumerClass = FileConsumer.class)
 public class FileEndpoint extends GenericFileEndpoint<File> {
 
     private FileOperations operations = new FileOperations(this);
+    /**
+     *
+     */
+    @UriPath
     private File file;
+    @UriParam
     private boolean copyAndDeleteOnRenameFail = true;
+    @UriParam
     private boolean forceWrites = true;
 
     public FileEndpoint() {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/file/GenericFileConsumer.java Tue Apr 23 07:52:20 2013
@@ -28,6 +28,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.ShutdownRunningTask;
 import org.apache.camel.impl.ScheduledBatchPollingConsumer;
+import org.apache.camel.spi.UriParam;
 import org.apache.camel.util.CastUtils;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.StopWatch;
@@ -47,6 +48,7 @@ public abstract class GenericFileConsume
     protected volatile ShutdownRunningTask shutdownRunningTask;
     protected volatile int pendingExchanges;
     protected Processor customProcessor;
+    @UriParam
     protected boolean eagerLimitMaxMessagesPerPoll = true;
     protected volatile boolean prepareOnStartup;
 

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/seda/SedaEndpoint.java Tue Apr 23 07:52:20 2013
@@ -39,6 +39,8 @@ import org.apache.camel.api.management.M
 import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.processor.MulticastProcessor;
 import org.apache.camel.spi.BrowsableEndpoint;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
 import org.apache.camel.util.EndpointHelper;
 import org.apache.camel.util.MessageHelper;
 import org.apache.camel.util.ServiceHelper;
@@ -52,14 +54,19 @@ import org.slf4j.LoggerFactory;
  * asynchronous SEDA exchanges on a {@link BlockingQueue} within a CamelContext
  */
 @ManagedResource(description = "Managed SedaEndpoint")
+@UriEndpoint(scheme = "seda", consumerClass = SedaConsumer.class)
 public class SedaEndpoint extends DefaultEndpoint implements BrowsableEndpoint, MultipleConsumersSupport {
     private static final transient Logger LOG = LoggerFactory.getLogger(SedaEndpoint.class);
     private volatile BlockingQueue<Exchange> queue;
+    @UriParam
     private int size = Integer.MAX_VALUE;
+    @UriParam
     private int concurrentConsumers = 1;
     private volatile ExecutorService multicastExecutor;
+    @UriParam
     private boolean multipleConsumers;
     private WaitForTaskToComplete waitForTaskToComplete = WaitForTaskToComplete.IfReplyExpected;
+    @UriParam
     private long timeout = 30000;
     private final Set<SedaProducer> producers = new CopyOnWriteArraySet<SedaProducer>();
     private final Set<SedaConsumer> consumers = new CopyOnWriteArraySet<SedaConsumer>();

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/component/timer/TimerEndpoint.java Tue Apr 23 07:52:20 2013
@@ -28,6 +28,8 @@ import org.apache.camel.RuntimeCamelExce
 import org.apache.camel.api.management.ManagedAttribute;
 import org.apache.camel.api.management.ManagedResource;
 import org.apache.camel.impl.DefaultEndpoint;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
 
 /**
  * Represents a timer endpoint that can generate periodic inbound exchanges triggered by a timer.
@@ -35,14 +37,23 @@ import org.apache.camel.impl.DefaultEndp
  * @version 
  */
 @ManagedResource(description = "Managed TimerEndpoint")
+@UriEndpoint(scheme = "timer", consumerClass = TimerConsumer.class)
 public class TimerEndpoint extends DefaultEndpoint implements MultipleConsumersSupport {
+    @UriParam
     private String timerName;
+    @UriParam
     private Date time;
+    @UriParam
     private long period = 1000;
+    @UriParam
     private long delay = 1000;
+    @UriParam
     private boolean fixedRate;
+    @UriParam
     private boolean daemon = true;
+    @UriParam
     private Timer timer;
+    @UriParam
     private long repeatCount;
 
     public TimerEndpoint() {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledBatchPollingConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledBatchPollingConsumer.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledBatchPollingConsumer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledBatchPollingConsumer.java Tue Apr 23 07:52:20 2013
@@ -23,6 +23,7 @@ import org.apache.camel.Endpoint;
 import org.apache.camel.Exchange;
 import org.apache.camel.Processor;
 import org.apache.camel.ShutdownRunningTask;
+import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.ShutdownAware;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -34,6 +35,7 @@ public abstract class ScheduledBatchPoll
     private static final transient Logger LOG = LoggerFactory.getLogger(ScheduledBatchPollingConsumer.class);
     protected volatile ShutdownRunningTask shutdownRunningTask;
     protected volatile int pendingExchanges;
+    @UriParam
     protected int maxMessagesPerPoll;
 
     public ScheduledBatchPollingConsumer(Endpoint endpoint, Processor processor) {

Modified: camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollConsumer.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollConsumer.java (original)
+++ camel/trunk/camel-core/src/main/java/org/apache/camel/impl/ScheduledPollConsumer.java Tue Apr 23 07:52:20 2013
@@ -27,6 +27,7 @@ import org.apache.camel.LoggingLevel;
 import org.apache.camel.PollingConsumerPollingStrategy;
 import org.apache.camel.Processor;
 import org.apache.camel.SuspendableService;
+import org.apache.camel.spi.UriParam;
 import org.apache.camel.spi.PollingConsumerPollStrategy;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.ServiceHelper;
@@ -46,13 +47,21 @@ public abstract class ScheduledPollConsu
     private ScheduledFuture<?> future;
 
     // if adding more options then align with ScheduledPollEndpoint#configureScheduledPollConsumerProperties
+    @UriParam
     private boolean startScheduler = true;
+    @UriParam
     private long initialDelay = 1000;
+    @UriParam
     private long delay = 500;
+    @UriParam
     private TimeUnit timeUnit = TimeUnit.MILLISECONDS;
+    @UriParam
     private boolean useFixedDelay = true;
+    @UriParam
     private PollingConsumerPollStrategy pollStrategy = new DefaultPollingConsumerPollStrategy();
+    @UriParam
     private LoggingLevel runLoggingLevel = LoggingLevel.TRACE;
+    @UriParam
     private boolean sendEmptyMessageWhenIdle;
     private volatile boolean polling;
 

Modified: camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java (original)
+++ camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsConfiguration.java Tue Apr 23 07:52:20 2013
@@ -26,6 +26,8 @@ import javax.jms.Session;
 
 import org.apache.camel.LoggingLevel;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
 import org.apache.camel.util.ObjectHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -51,6 +53,7 @@ import static org.apache.camel.component
 /**
  * @version
  */
+@UriParams
 public class JmsConfiguration implements Cloneable {
 
     public static final String QUEUE_PREFIX = "queue:";
@@ -65,77 +68,127 @@ public class JmsConfiguration implements
     private ConnectionFactory templateConnectionFactory;
     private ConnectionFactory listenerConnectionFactory;
     private int acknowledgementMode = -1;
+    @UriParam
     private String acknowledgementModeName;
     // Used to configure the spring Container
     private ExceptionListener exceptionListener;
+    @UriParam
     private ConsumerType consumerType = ConsumerType.Default;
     private ErrorHandler errorHandler;
     private LoggingLevel errorHandlerLoggingLevel = LoggingLevel.WARN;
+    @UriParam
     private boolean errorHandlerLogStackTrace = true;
+    @UriParam
     private boolean autoStartup = true;
+    @UriParam
     private boolean acceptMessagesWhileStopping;
+    @UriParam
     private String clientId;
+    @UriParam
     private String durableSubscriptionName;
     private boolean subscriptionDurable;
+    @UriParam
     private boolean exposeListenerSession = true;
     private TaskExecutor taskExecutor;
+    @UriParam
     private boolean pubSubNoLocal;
+    @UriParam
     private int concurrentConsumers = 1;
+    @UriParam
     private int maxMessagesPerTask = -1;
     private int cacheLevel = -1;
+    @UriParam
     private String cacheLevelName;
+    @UriParam
     private long recoveryInterval = -1;
+    @UriParam
     private long receiveTimeout = -1;
+    @UriParam
     private long requestTimeout = 20000L;
+    @UriParam
     private long requestTimeoutCheckerInterval = 1000L;
+    @UriParam
     private int idleTaskExecutionLimit = 1;
+    @UriParam
     private int idleConsumerLimit = 1;
+    @UriParam
     private int maxConcurrentConsumers;
     // JmsTemplate only
+    @UriParam
     private Boolean explicitQosEnabled;
+    @UriParam
     private boolean deliveryPersistent = true;
+    @UriParam
     private boolean replyToDeliveryPersistent = true;
+    @UriParam
     private long timeToLive = -1;
     private MessageConverter messageConverter;
+    @UriParam
     private boolean mapJmsMessage = true;
+    @UriParam
     private boolean messageIdEnabled = true;
+    @UriParam
     private boolean messageTimestampEnabled = true;
+    @UriParam
     private int priority = -1;
     // Transaction related configuration
+    @UriParam
     private boolean transacted;
+    @UriParam
     private boolean transactedInOut;
+    @UriParam
     private boolean lazyCreateTransactionManager = true;
     private PlatformTransactionManager transactionManager;
+    @UriParam
     private String transactionName;
+    @UriParam
     private int transactionTimeout = -1;
+    @UriParam
     private boolean preserveMessageQos;
+    @UriParam
     private boolean disableReplyTo;
+    @UriParam
     private boolean eagerLoadingOfProperties;
     // Always make a JMS message copy when it's passed to Producer
+    @UriParam
     private boolean alwaysCopyMessage;
+    @UriParam
     private boolean useMessageIDAsCorrelationID;
     private JmsProviderMetadata providerMetadata = new JmsProviderMetadata();
     private JmsOperations metadataJmsOperations;
+    @UriParam
     private String replyToDestination;
+    @UriParam
     private String replyToDestinationSelectorName;
     private JmsMessageType jmsMessageType;
     private JmsKeyFormatStrategy jmsKeyFormatStrategy;
+    @UriParam
     private boolean transferExchange;
+    @UriParam
     private boolean transferException;
+    @UriParam
     private boolean testConnectionOnStartup;
+    @UriParam
     private boolean asyncStartListener;
+    @UriParam
     private boolean asyncStopListener;
     // if the message is a JmsMessage and mapJmsMessage=false, force the
     // producer to send the javax.jms.Message body to the next JMS destination
+    @UriParam
     private boolean forceSendOriginalMessage;
     // to force disabling time to live (works in both in-only or in-out mode)
+    @UriParam
     private boolean disableTimeToLive;
     private ReplyToType replyToType;
+    @UriParam
     private boolean asyncConsumer;
     // the cacheLevelName of reply manager
+    @UriParam
     private String replyToCacheLevelName;
+    @UriParam
     private boolean allowNullBody = true;
     private MessageListenerContainerFactory messageListenerContainerFactory;
+    @UriParam
     private boolean includeSentJMSMessageID;
     private DefaultTaskExecutorType defaultTaskExecutorType;
 

Modified: camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsEndpoint.java (original)
+++ camel/trunk/components/camel-jms/src/main/java/org/apache/camel/component/jms/JmsEndpoint.java Tue Apr 23 07:52:20 2013
@@ -45,6 +45,9 @@ import org.apache.camel.impl.DefaultExch
 import org.apache.camel.impl.SynchronousDelegateProducer;
 import org.apache.camel.spi.HeaderFilterStrategy;
 import org.apache.camel.spi.HeaderFilterStrategyAware;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriPath;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.slf4j.Logger;
@@ -65,14 +68,19 @@ import org.springframework.util.ErrorHan
  * @version
  */
 @ManagedResource(description = "Managed JMS Endpoint")
+@UriEndpoint(scheme = "jms", consumerClass = JmsConsumer.class)
 public class JmsEndpoint extends DefaultEndpoint implements HeaderFilterStrategyAware, MultipleConsumersSupport, Service {
     protected final Logger log = LoggerFactory.getLogger(getClass());
+    @UriParam
     private HeaderFilterStrategy headerFilterStrategy;
     private boolean pubSubDomain;
     private JmsBinding binding;
     private String destinationName;
+    @UriPath
     private Destination destination;
+    @UriParam
     private String selector;
+    @UriParam
     private JmsConfiguration configuration;
     private final AtomicBoolean running = new AtomicBoolean();
 

Modified: camel/trunk/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java (original)
+++ camel/trunk/components/camel-sjms/src/main/java/org/apache/camel/component/sjms/SjmsEndpoint.java Tue Apr 23 07:52:20 2013
@@ -30,30 +30,46 @@ import org.apache.camel.component.sjms.p
 import org.apache.camel.component.sjms.producer.InOutProducer;
 import org.apache.camel.impl.DefaultEndpoint;
 import org.apache.camel.spi.HeaderFilterStrategy;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * A JMS Endpoint
  */
+@UriEndpoint(scheme = "sjms", consumerClass = SjmsConsumer.class)
 public class SjmsEndpoint extends DefaultEndpoint implements MultipleConsumersSupport {
     protected final transient Logger logger = LoggerFactory.getLogger(getClass());
 
     private SessionPool sessions;
+    @UriParam
     private boolean synchronous = true;
+    @UriParam
     private boolean transacted;
+    @UriParam
     private String namedReplyTo;
     private SessionAcknowledgementType acknowledgementMode = SessionAcknowledgementType.AUTO_ACKNOWLEDGE;
     private boolean topic;
+    @UriParam
     private int sessionCount = 1;
+    @UriParam
     private int producerCount = 1;
+    @UriParam
     private int consumerCount = 1;
+    @UriParam
     private long ttl = -1;
+    @UriParam
     private boolean persistent = true;
+    @UriParam
     private String durableSubscriptionId;
+    @UriParam
     private long responseTimeOut = 5000;
+    @UriParam
     private String messageSelector;
+    @UriParam
     private int transactionBatchCount = -1;
+    @UriParam
     private long transactionBatchTimeout = 5000;
     private TransactionCommitStrategy transactionCommitStrategy;
 

Modified: camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java (original)
+++ camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlConsumer.java Tue Apr 23 07:52:20 2013
@@ -29,6 +29,7 @@ import org.apache.camel.ExchangePattern;
 import org.apache.camel.Message;
 import org.apache.camel.Processor;
 import org.apache.camel.impl.ScheduledBatchPollingConsumer;
+import org.apache.camel.spi.UriParam;
 import org.apache.camel.util.CastUtils;
 import org.apache.camel.util.ObjectHelper;
 import org.springframework.dao.DataAccessException;
@@ -45,12 +46,19 @@ public class SqlConsumer extends Schedul
     private final String query;
     private final JdbcTemplate jdbcTemplate;
 
+    @UriParam
     private String onConsume;
+    @UriParam
     private String onConsumeFailed;
+    @UriParam
     private String onConsumeBatchComplete;
+    @UriParam
     private boolean useIterator = true;
+    @UriParam
     private boolean routeEmptyResultSet;
+    @UriParam
     private int expectedUpdateCount = -1;
+    @UriParam
     private boolean breakBatchOnConsumeFail;
 
     private static final class DataHolder {

Modified: camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java (original)
+++ camel/trunk/components/camel-sql/src/main/java/org/apache/camel/component/sql/SqlEndpoint.java Tue Apr 23 07:52:20 2013
@@ -20,6 +20,7 @@ import org.apache.camel.Component;
 import org.apache.camel.Consumer;
 import org.apache.camel.Processor;
 import org.apache.camel.Producer;
+import org.apache.camel.spi.*;
 import org.apache.camel.impl.DefaultPollingEndpoint;
 import org.apache.camel.util.UnsafeUriCharactersEncoder;
 import org.springframework.jdbc.core.JdbcTemplate;
@@ -29,17 +30,28 @@ import org.springframework.jdbc.core.Jdb
  * question marks (that are parameter placeholders), sharp signs should be used.
  * This is because in camel question mark has other meaning.
  */
+@UriEndpoint(scheme = "sql", consumerClass = SqlConsumer.class)
 public class SqlEndpoint extends DefaultPollingEndpoint {
     private JdbcTemplate jdbcTemplate;
+    @UriPath
     private String query;
+    @UriParam
     private boolean batch;
+    @UriParam
     private int maxMessagesPerPoll;
+    @UriParam
     private SqlProcessingStrategy processingStrategy = new DefaultSqlProcessingStrategy();
+    @UriParam
     private SqlPrepareStatementStrategy prepareStatementStrategy = new DefaultSqlPrepareStatementStrategy();
+    @UriParam
     private String onConsume;
+    @UriParam
     private String onConsumeFailed;
+    @UriParam
     private String onConsumeBatchComplete;
+    @UriParam
     private boolean allowNamedParameters = true;
+    @UriParam
     private boolean alwaysPopulateStatement;
 
     public SqlEndpoint() {
@@ -81,6 +93,9 @@ public class SqlEndpoint extends Default
         return query;
     }
 
+    /**
+     * Sets the SQL query to perform
+     */
     public void setQuery(String query) {
         this.query = query;
     }
@@ -89,6 +104,9 @@ public class SqlEndpoint extends Default
         return batch;
     }
 
+    /**
+     * Enables or disables batch mode
+     */
     public void setBatch(boolean batch) {
         this.batch = batch;
     }
@@ -97,6 +115,9 @@ public class SqlEndpoint extends Default
         return maxMessagesPerPoll;
     }
 
+    /**
+     * Sets the maximum number of messages to poll
+     */
     public void setMaxMessagesPerPoll(int maxMessagesPerPoll) {
         this.maxMessagesPerPoll = maxMessagesPerPoll;
     }

Modified: camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java (original)
+++ camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshConfiguration.java Tue Apr 23 07:52:20 2013
@@ -19,20 +19,31 @@ package org.apache.camel.component.ssh;
 import java.net.URI;
 
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
 import org.apache.camel.util.ObjectHelper;
 import org.apache.sshd.common.KeyPairProvider;
 
+@UriParams
 public class SshConfiguration implements Cloneable {
     public static final int DEFAULT_SSH_PORT = 22;
 
+    @UriParam
     private String username;
+    @UriParam
     private String host;
+    @UriParam
     private int port = DEFAULT_SSH_PORT;
+    @UriParam
     private String password;
+    @UriParam
     private String pollCommand;
     private KeyPairProvider keyPairProvider;
+    @UriParam
     private String keyType = KeyPairProvider.SSH_RSA;
+    @UriParam
     private String certResource;
+    @UriParam
     private long timeout = 30000;
 
     public SshConfiguration() {

Modified: camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java (original)
+++ camel/trunk/components/camel-ssh/src/main/java/org/apache/camel/component/ssh/SshEndpoint.java Tue Apr 23 07:52:20 2013
@@ -25,6 +25,8 @@ import org.apache.camel.Processor;
 import org.apache.camel.Producer;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.impl.ScheduledPollEndpoint;
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
 import org.apache.sshd.ClientChannel;
 import org.apache.sshd.ClientSession;
 import org.apache.sshd.SshClient;
@@ -38,10 +40,12 @@ import org.slf4j.LoggerFactory;
 /**
  * Represents an SSH endpoint.
  */
+@UriEndpoint(scheme = "ssh", consumerClass = SshConsumer.class)
 public class SshEndpoint extends ScheduledPollEndpoint {
     protected final transient Logger log = LoggerFactory.getLogger(getClass());
 
     private SshClient client;
+    @UriParam
     private SshConfiguration sshConfiguration;
 
     public SshEndpoint() {

Modified: camel/trunk/components/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/components/pom.xml?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/components/pom.xml (original)
+++ camel/trunk/components/pom.xml Tue Apr 23 07:52:20 2013
@@ -178,6 +178,7 @@
     <module>camel-zookeeper</module>
   </modules>
 
+
   <build>
     <plugins>
       <plugin>
@@ -195,4 +196,33 @@
       </plugin>
     </plugins>
   </build>
+  <reporting>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.camel</groupId>
+        <artifactId>camel-package-maven-plugin</artifactId>
+        <version>${project.version}</version>
+      </plugin>
+    </plugins>
+  </reporting>
+
+  <profiles>
+    <!-- enables the APT dependency so that it can be disabled in IDE builds -->
+    <profile>
+      <id>apt</id>
+      <activation>
+        <activeByDefault>true</activeByDefault>
+      </activation>
+
+      <dependencies>
+        <!-- enable the APT processor -->
+        <dependency>
+          <groupId>org.apache.camel</groupId>
+          <artifactId>apt</artifactId>
+          <version>${project.version}</version>
+          <scope>provided</scope>
+        </dependency>
+      </dependencies>
+    </profile>
+  </profiles>
 </project>

Added: camel/trunk/tooling/apt/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/apt/pom.xml?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/apt/pom.xml (added)
+++ camel/trunk/tooling/apt/pom.xml Tue Apr 23 07:52:20 2013
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>tooling</artifactId>
+    <version>2.12-SNAPSHOT</version>
+  </parent>
+
+
+  <artifactId>apt</artifactId>
+  <name>Camel :: Annotation Processor</name>
+  <description>Processes Camel endpoint source code</description>
+
+  <properties>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.camel</groupId>
+      <artifactId>spi-annotations</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <!-- testing -->
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>${junit-version}</version>
+      <scope>test</scope>
+    </dependency>
+
+    <!-- logging -->
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-log4j12</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+
+
+  <build>
+      <plugins>
+        <plugin>
+          <artifactId>maven-compiler-plugin</artifactId>
+          <version>${maven-compiler-plugin-version}</version>
+          <configuration>
+            <source>1.6</source>
+            <target>1.6</target>
+            <!-- Disable annotation processing for ourselves. -->
+              <proc>none</proc>
+              <verbose>false</verbose>
+<!--
+            <compilerArgument>-proc:none</compilerArgument>
+-->
+          </configuration>
+        </plugin>
+      </plugins>
+  </build>
+
+</project>

Propchange: camel/trunk/tooling/apt/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java (added)
+++ camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java Tue Apr 23 07:52:20 2013
@@ -0,0 +1,336 @@
+/**
+ *
+ * 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.tools.apt;
+
+import org.apache.camel.spi.UriEndpoint;
+import org.apache.camel.spi.UriParam;
+import org.apache.camel.spi.UriParams;
+import org.apache.camel.tools.apt.util.Func1;
+import org.apache.camel.tools.apt.util.Strings;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.Filer;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.element.VariableElement;
+import javax.lang.model.type.MirroredTypeException;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.ElementFilter;
+import javax.lang.model.util.Elements;
+import javax.tools.Diagnostic;
+import javax.tools.FileObject;
+import javax.tools.StandardLocation;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.io.Writer;
+import java.net.URI;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.SortedMap;
+import java.util.TreeMap;
+
+/**
+ * Processes all Camel endpoints
+ */
+//@SupportedOptions({"foo"})
+@SupportedAnnotationTypes({"org.apache.camel.*", "org.apache.camel.spi.*"})
+@SupportedSourceVersion(SourceVersion.RELEASE_6)
+public class EndpointAnnotationProcessor extends AbstractProcessor {
+    public boolean process(Set<? extends TypeElement> annotations, final RoundEnvironment roundEnv) {
+        if (roundEnv.processingOver()) {
+            return true;
+        }
+        Set<? extends Element> elements = roundEnv.getElementsAnnotatedWith(UriEndpoint.class);
+        for (Element element : elements) {
+            if (element instanceof TypeElement) {
+                processEndpointClass(roundEnv, (TypeElement) element);
+            }
+        }
+        return true;
+    }
+
+    protected void processEndpointClass(final RoundEnvironment roundEnv, final TypeElement classElement) {
+        final UriEndpoint uriEndpoint = classElement.getAnnotation(UriEndpoint.class);
+        if (uriEndpoint != null) {
+            String scheme = uriEndpoint.scheme();
+            if (!Strings.isNullOrEmpty(scheme)) {
+                String packageName = "org.apache.camel.component";
+                String fileName = scheme + ".html";
+                Func1<PrintWriter, Void> handler = new Func1<PrintWriter, Void>() {
+                    @Override
+                    public Void call(PrintWriter writer) {
+                        writeHtmlDocumentation(writer, roundEnv, classElement, uriEndpoint);
+                        return null;
+                    }
+                };
+                processFile(packageName, fileName, handler);
+            }
+        }
+    }
+
+    protected void writeHtmlDocumentation(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, UriEndpoint uriEndpoint) {
+        writer.println("<html>");
+        writer.println("<header>");
+        String scheme = uriEndpoint.scheme();
+        String title = scheme + " endpoint";
+        writer.println("<title>" + "</title>");
+        writer.println("</header>");
+        writer.println("<body>");
+        writer.println("<h1>" + title + "</h1>");
+
+        showDocumentationAndFieldInjections(writer, roundEnv, classElement, "");
+
+        // This code is not my fault, it seems to honestly be the hacky way to find a class name in APT :)
+        TypeMirror consumerType = null;
+        try {
+            uriEndpoint.consumerClass();
+        } catch (MirroredTypeException mte) {
+            consumerType = mte.getTypeMirror();
+        }
+
+        boolean found = false;
+        String consumerClassName = null;
+        String consumerPrefix = Strings.getOrElse(uriEndpoint.consumerPrefix(), "");
+        if (consumerType != null) {
+            consumerClassName = consumerType.toString();
+            TypeElement consumerElement = findTypeElement(roundEnv, consumerClassName);
+            if (consumerElement != null) {
+                writer.println("<h2>" + scheme + " consumer" + "</h2>");
+                showDocumentationAndFieldInjections(writer, roundEnv, consumerElement, consumerPrefix);
+                found = true;
+            }
+        }
+        if (!found && consumerClassName != null) {
+            warning("APT could not find consumer class " + consumerClassName);
+        }
+        writer.println("</body>");
+        writer.println("</html>");
+    }
+
+
+    protected void showDocumentationAndFieldInjections(PrintWriter writer, RoundEnvironment roundEnv, TypeElement classElement, String prefix) {
+        String classDoc = processingEnv.getElementUtils().getDocComment(classElement);
+        if (!Strings.isNullOrEmpty(classDoc)) {
+            writer.println("<p>" + classDoc.trim() + "</p>");
+        }
+
+        SortedMap<String, List<String>> sortedMap = new TreeMap<String, List<String>>();
+        findClassProperties(roundEnv, sortedMap, classElement, prefix);
+        if (!sortedMap.isEmpty()) {
+            writer.println("<table class='table'>");
+            writer.println("  <tr>");
+            writer.println("    <th>Name</th>");
+            writer.println("    <th>Type</th>");
+            writer.println("    <th>Description</th>");
+            // see defaultValue above
+            // writer.println("    <th>Default Value</th>");
+            writer.println("  </tr>");
+            Set<Map.Entry<String, List<String>>> entries = sortedMap.entrySet();
+            for (Map.Entry<String, List<String>> entry : entries) {
+                String name = entry.getKey();
+                List<String> values = entry.getValue();
+                writer.println("  <tr>");
+                writer.println("    <td>" + name + "</td>");
+                for (String value : values) {
+                    writer.println(value);
+                }
+                writer.println("  </tr>");
+                writer.println("</table>");
+            }
+        }
+    }
+
+    protected void findClassProperties(RoundEnvironment roundEnv, SortedMap<String, List<String>> sortedMap, TypeElement classElement, String prefix) {
+        Elements elementUtils = processingEnv.getElementUtils();
+        while (true) {
+            List<VariableElement> fieldElements = ElementFilter.fieldsIn(classElement.getEnclosedElements());
+            if (fieldElements.isEmpty()) {
+                break;
+            }
+            for (VariableElement fieldElement : fieldElements) {
+                UriParam param = fieldElement.getAnnotation(UriParam.class);
+                String fieldName = fieldElement.getSimpleName().toString();
+                if (param != null) {
+                    String name = param.name();
+                    if (Strings.isNullOrEmpty(name)) {
+                        name = fieldName;
+                    }
+                    name = prefix + name;
+                    // if the field type is a nested parameter then iterate through its fields
+                    TypeMirror fieldType = fieldElement.asType();
+                    String fieldTypeName = fieldType.toString();
+                    TypeElement fieldTypeElement = findTypeElement(roundEnv, fieldTypeName);
+                    UriParams fieldParams = null;
+                    if (fieldTypeElement != null) {
+                        fieldParams = fieldTypeElement.getAnnotation(UriParams.class);
+                    }
+                    if (fieldParams != null) {
+                        String nestedPrefix = prefix;
+                        String extraPrefix = fieldParams.prefix();
+                        if (!Strings.isNullOrEmpty(extraPrefix)) {
+                            nestedPrefix += extraPrefix;
+                        }
+                        findClassProperties(roundEnv, sortedMap, fieldTypeElement, nestedPrefix);
+                    } else {
+                        String docComment = elementUtils.getDocComment(fieldElement);
+                        if (Strings.isNullOrEmpty(docComment)) {
+                            String setter = "set" + fieldName.substring(0, 1).toUpperCase();
+                            if (fieldName.length() > 1) {
+                                setter += fieldName.substring(1);
+                            }
+                            //  lets find the setter
+                            List<ExecutableElement> methods = ElementFilter.methodsIn(classElement.getEnclosedElements());
+                            for (ExecutableElement method : methods) {
+                                String methodName = method.getSimpleName().toString();
+                                if (setter.equals(methodName) && method.getParameters().size() == 1) {
+                                    String doc = elementUtils.getDocComment(method);
+                                    if (!Strings.isNullOrEmpty(doc)) {
+                                        docComment = doc;
+                                        break;
+                                    }
+                                }
+                            }
+                        }
+                        if (docComment == null) {
+                            docComment = "";
+                        }
+                        List<String> values = new ArrayList<String>();
+                        values.add("    <td>" + fieldTypeName + "</td>");
+                        values.add("    <td>" + docComment.trim() + "</td>");
+
+                        // TODO would be nice here to create a default endpoint/consumer object
+                        // and return the default value of the field so we can put it into the docs
+                        Object defaultValue = null;
+                        if (defaultValue != null) {
+                            values.add("    <td>" + defaultValue + "</td>");
+                        }
+                        if (sortedMap.containsKey(name)) {
+                            error("Duplicate parameter annotation named '" + name + "' on class " + classElement.getQualifiedName());
+                        } else {
+                            sortedMap.put(name, values);
+                        }
+                    }
+                }
+            }
+            TypeElement baseTypeElement = null;
+            TypeMirror superclass = classElement.getSuperclass();
+            if (superclass != null) {
+                baseTypeElement = findTypeElement(roundEnv, superclass.toString());
+            }
+            if (baseTypeElement != null) {
+                classElement = baseTypeElement;
+            } else {
+                break;
+            }
+        }
+    }
+
+
+    protected TypeElement findTypeElement(RoundEnvironment roundEnv, String className) {
+        if (!Strings.isNullOrEmpty(className) && !"java.lang.Object".equals(className)) {
+            Set<? extends Element> rootElements = roundEnv.getRootElements();
+            for (Element rootElement : rootElements) {
+                if (rootElement instanceof TypeElement) {
+                    TypeElement typeElement = (TypeElement) rootElement;
+                    String aRootName = typeElement.getQualifiedName().toString();
+                    if (className.equals(aRootName)) {
+                        return typeElement;
+                    }
+                }
+            }
+        }
+        return null;
+    }
+
+
+    /**
+     * Helper method to produce class output text file using the given handler
+     */
+    protected void processFile(String packageName, String fileName, Func1<PrintWriter, Void> handler) {
+        PrintWriter writer = null;
+        try {
+            Writer out = null;
+            Filer filer = processingEnv.getFiler();
+            FileObject resource;
+            try {
+                resource = filer.getResource(StandardLocation.CLASS_OUTPUT, packageName, fileName);
+            } catch (Throwable e) {
+                //resource = filer.createResource(StandardLocation.CLASS_OUTPUT, "org.apache.camel", "CamelAPT2.txt", rootElements.toArray(new Element[rootElements.size()]));
+                resource = filer.createResource(StandardLocation.CLASS_OUTPUT, packageName, fileName, new Element[0]);
+            }
+            URI uri = resource.toUri();
+            File file = null;
+            if (uri != null) {
+                try {
+                    file = new File(uri);
+                } catch (Exception e) {
+                    warning("Could not convert output directory resource URI to a file " + e);
+                }
+            }
+            if (file == null) {
+                warning("No class output directory could be found!");
+            } else {
+                file.getParentFile().mkdirs();
+                out = new FileWriter(file);
+                if (out == null) {
+                    out = resource.openWriter();
+                }
+                writer = new PrintWriter(out);
+                handler.call(writer);
+            }
+        } catch (IOException e) {
+            log(e);
+        } finally {
+            if (writer != null) {
+                writer.close();
+            }
+        }
+    }
+
+    protected void log(String message) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.NOTE, message);
+    }
+
+    protected void warning(String message) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.WARNING, message);
+    }
+
+    protected void error(String message) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, message);
+    }
+
+    protected void log(Throwable e) {
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, e.getMessage());
+        StringWriter buffer = new StringWriter();
+        PrintWriter writer = new PrintWriter(buffer);
+        e.printStackTrace(writer);
+        writer.close();
+        processingEnv.getMessager().printMessage(Diagnostic.Kind.ERROR, buffer.toString());
+
+    }
+}

Propchange: camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/EndpointAnnotationProcessor.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Func1.java
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Func1.java?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Func1.java (added)
+++ camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Func1.java Tue Apr 23 07:52:20 2013
@@ -0,0 +1,25 @@
+/**
+ *
+ * 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.tools.apt.util;
+
+/**
+ * Represents a function with 1 argument
+ */
+public interface Func1<T1,R> {
+    public R call(T1 t1);
+}

Propchange: camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Func1.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java (added)
+++ camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java Tue Apr 23 07:52:20 2013
@@ -0,0 +1,37 @@
+/**
+ *
+ * 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.tools.apt.util;
+
+/**
+ * Some String helper methods
+ */
+public class Strings {
+    /**
+     * Returns true if the given text is null or empty string
+     */
+    public static boolean isNullOrEmpty(String text) {
+        return text == null || text.length() == 0;
+    }
+
+    /**
+     * Returns the value or the defaultValue if it is null
+     */
+    public static String getOrElse(String text, String defaultValue) {
+        return (text != null) ? text : defaultValue;
+    }
+}

Propchange: camel/trunk/tooling/apt/src/main/java/org/apache/camel/tools/apt/util/Strings.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor (added)
+++ camel/trunk/tooling/apt/src/main/resources/META-INF/services/javax.annotation.processing.Processor Tue Apr 23 07:52:20 2013
@@ -0,0 +1 @@
+org.apache.camel.tools.apt.EndpointAnnotationProcessor
\ No newline at end of file

Modified: camel/trunk/tooling/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/pom.xml?rev=1470837&r1=1470836&r2=1470837&view=diff
==============================================================================
--- camel/trunk/tooling/pom.xml (original)
+++ camel/trunk/tooling/pom.xml Tue Apr 23 07:52:20 2013
@@ -31,6 +31,8 @@
   <packaging>pom</packaging>
 
   <modules>
+    <module>spi-annotations</module>
+    <module>apt</module>
     <module>maven</module>
     <module>archetypes</module>
     <module>camel-manual</module>

Added: camel/trunk/tooling/spi-annotations/pom.xml
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/spi-annotations/pom.xml?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/spi-annotations/pom.xml (added)
+++ camel/trunk/tooling/spi-annotations/pom.xml Tue Apr 23 07:52:20 2013
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <groupId>org.apache.camel</groupId>
+    <artifactId>tooling</artifactId>
+    <version>2.12-SNAPSHOT</version>
+  </parent>
+
+
+  <artifactId>spi-annotations</artifactId>
+  <name>Camel :: SPI Annotations</name>
+  <description>Annotations for Camel Endpoint developers</description>
+
+  <properties>
+<!--
+       <camel.osgi.export.pkg>
+           org.apache.camel.spi*;-noimport:=true
+       </camel.osgi.export.pkg>
+-->
+  </properties>
+
+  <dependencies>
+  </dependencies>
+
+
+</project>

Propchange: camel/trunk/tooling/spi-annotations/pom.xml
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java (added)
+++ camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java Tue Apr 23 07:52:20 2013
@@ -0,0 +1,49 @@
+/**
+ * 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.spi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Represents an annotated Camel <a href="http://camel.apache.org/endpoint.html">Endpoint</a>
+ * which can have its properties (and the properties on its consumer) injected from the
+ * Camel URI path and its query parameters
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ElementType.TYPE})
+public @interface UriEndpoint {
+    /**
+     * Represents the URI scheme name of this endpoint
+     */
+    String scheme();
+
+    /**
+     * Represents the consumer class which is injected and created by consumers
+     */
+    Class<?> consumerClass() default Object.class;
+
+    /**
+     * The configuration parameter name prefix used on parameter names to separate the endpoint
+     * properties from the consumer properties
+     */
+    String consumerPrefix() default "";
+}
\ No newline at end of file

Propchange: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java (added)
+++ camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java Tue Apr 23 07:52:20 2013
@@ -0,0 +1,39 @@
+/**
+ * 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.spi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Represents an injection point of a Camel Uri parameter value on an Endpoint or Consumer, usually configured via a URI style query parameter in a URI
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ElementType.FIELD })
+public @interface UriParam {
+    /**
+     * Returns the name of the parameter.
+     *
+     * If this is not specified then the name of the field or property which has this annotation is used.
+     */
+    String name() default "";
+
+}
\ No newline at end of file

Propchange: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParam.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParams.java
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParams.java?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParams.java (added)
+++ camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParams.java Tue Apr 23 07:52:20 2013
@@ -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.spi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Used to annotate a nested configuration parameter type (such as a nested Configuration object) which can then be used on a
+ * Component, Endpoint and/or Consumer and then be configured via Camel URI query arguments.
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ElementType.TYPE })
+public @interface UriParams {
+    /**
+     * Returns the prefix used to access nested properties of this configuration object
+     */
+    String prefix() default "";
+
+}
\ No newline at end of file

Propchange: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriParams.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriPath.java
URL: http://svn.apache.org/viewvc/camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriPath.java?rev=1470837&view=auto
==============================================================================
--- camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriPath.java (added)
+++ camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriPath.java Tue Apr 23 07:52:20 2013
@@ -0,0 +1,32 @@
+/**
+ * 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.spi;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Represents an injection point of a Camel Uri path value (the remaining part of a Camel URI without any query arguments)
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Documented
+@Target({ElementType.FIELD })
+public @interface UriPath {
+}
\ No newline at end of file

Propchange: camel/trunk/tooling/spi-annotations/src/main/java/org/apache/camel/spi/UriPath.java
------------------------------------------------------------------------------
    svn:eol-style = native