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 2007/06/11 20:32:35 UTC

svn commit: r546215 - in /activemq/camel/trunk/components/camel-ftp/src: main/ main/java/ main/java/org/ main/java/org/apache/ main/java/org/apache/camel/ main/java/org/apache/camel/component/ main/java/org/apache/camel/component/file/ main/java/org/ap...

Author: jstrachan
Date: Mon Jun 11 11:32:33 2007
New Revision: 546215

URL: http://svn.apache.org/viewvc?view=rev&rev=546215
Log:
applied Noah's patch for CAMEL-13 with many thanks! I added an extra test case for FTP using Apache FtpServer; other than that, great work Noah! More more! :)

Added:
    activemq/camel/trunk/components/camel-ftp/src/main/
    activemq/camel/trunk/components/camel-ftp/src/main/java/
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperationFailedException.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpProducer.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileBinding.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileComponent.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileExchange.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileMessage.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpProducer.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/package.html   (with props)
    activemq/camel/trunk/components/camel-ftp/src/main/resources/
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/ftp
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/sftp
    activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/webdav
    activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/
    activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/
    activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/
    activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/
    activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/
    activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpRouteTest.java   (with props)
    activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/UriConfigurationTest.java   (with props)

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,122 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.Processor;
+import org.apache.commons.net.ftp.FTPClient;
+import org.apache.commons.net.ftp.FTPFile;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.concurrent.ScheduledExecutorService;
+
+public class FtpConsumer extends RemoteFileConsumer<RemoteFileExchange> {
+    private boolean recursive = true;
+    private String regexPattern = "";
+    private long lastPollTime = 0L;
+    private final FtpEndpoint endpoint;
+    private FTPClient client;
+
+    public FtpConsumer(FtpEndpoint endpoint, Processor processor, FTPClient client) {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+        this.client = client;
+    }
+
+    public FtpConsumer(FtpEndpoint endpoint, Processor processor, FTPClient client, ScheduledExecutorService executor) {
+        super(endpoint, processor, executor);
+        this.endpoint = endpoint;
+        this.client = client;
+    }
+
+    protected void poll() throws Exception {
+        final String fileName = endpoint.getConfiguration().getFile();
+        if (endpoint.getConfiguration().isDirectory()) {
+            pollDirectory(fileName);
+        }
+        else {
+            client.changeWorkingDirectory(fileName.substring(0, fileName.lastIndexOf('/')));
+            final FTPFile[] files = client.listFiles(fileName.substring(fileName.lastIndexOf('/') + 1));
+            pollFile(files[0]);
+        }
+        lastPollTime = System.currentTimeMillis();
+    }
+
+    protected void pollDirectory(String dir) throws Exception {
+        client.changeWorkingDirectory(dir);
+        for (FTPFile ftpFile : client.listFiles()) {
+            if (ftpFile.isFile()) {
+                pollFile(ftpFile);
+            }
+            else if (ftpFile.isDirectory()) {
+                if (isRecursive()) {
+                    pollDirectory(getFullFileName(ftpFile));
+                }
+            }
+            else {
+                throw new RuntimeException("");
+            }
+        }
+    }
+
+    protected String getFullFileName(FTPFile ftpFile) throws IOException {
+        return client.printWorkingDirectory() + "/" + ftpFile.getName();
+    }
+
+    private void pollFile(FTPFile ftpFile) throws Exception {
+        if (ftpFile.getTimestamp().getTimeInMillis() > lastPollTime) { // TODO do we need to adjust the TZ? can we?
+            if (isMatched(ftpFile)) {
+                final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+                client.retrieveFile(ftpFile.getName(), byteArrayOutputStream);
+                getProcessor().process(endpoint.createExchange(getFullFileName(ftpFile), byteArrayOutputStream));
+            }
+        }
+    }
+
+    protected boolean isMatched(FTPFile file) {
+        boolean result = true;
+        if (regexPattern != null && regexPattern.length() > 0) {
+            result = file.getName().matches(getRegexPattern());
+        }
+        return result;
+    }
+
+    public boolean isRecursive() {
+        return recursive;
+    }
+
+    public void setRecursive(boolean recursive) {
+        this.recursive = recursive;
+    }
+
+    public long getLastPollTime() {
+        return lastPollTime;
+    }
+
+    public void setLastPollTime(long lastPollTime) {
+        this.lastPollTime = lastPollTime;
+    }
+
+    public String getRegexPattern() {
+        return regexPattern;
+    }
+
+    public void setRegexPattern(String regexPattern) {
+        this.regexPattern = regexPattern;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpConsumer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,55 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.Processor;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.commons.net.ftp.FTPClient;
+
+import java.io.IOException;
+
+public class FtpEndpoint extends RemoteFileEndpoint<RemoteFileExchange> {
+    private static final transient Log log = LogFactory.getLog(FtpEndpoint.class);
+
+    public FtpEndpoint(String uri, RemoteFileComponent remoteFileComponent, RemoteFileConfiguration configuration) {
+        super(uri, remoteFileComponent, configuration);
+    }
+
+    public FtpProducer createProducer() throws Exception {
+        return new FtpProducer(this, createFtpClient());
+    }
+
+    public FtpConsumer createConsumer(Processor processor) throws Exception {
+        final FtpConsumer consumer = new FtpConsumer(this, processor, createFtpClient());
+        configureConsumer(consumer);
+        return consumer;
+    }
+
+    protected FTPClient createFtpClient() throws IOException {
+        final FTPClient client = new FTPClient();
+        String host = getConfiguration().getHost();
+        int port = getConfiguration().getPort();
+        log.debug("Connecting to host: " + host + " port: " + port);
+
+        client.connect(host, port);
+        client.login(getConfiguration().getUsername(), getConfiguration().getPassword());
+        client.setFileType(getConfiguration().isBinary() ? FTPClient.BINARY_FILE_TYPE : FTPClient.ASCII_FILE_TYPE);
+        return client;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperationFailedException.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperationFailedException.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperationFailedException.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperationFailedException.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,48 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.RuntimeCamelException;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class FtpOperationFailedException extends RuntimeCamelException {
+    private final int code;
+    private final String reason;
+
+    public FtpOperationFailedException(int code, String reason) {
+        super("Ftp Operation failed: " + reason.trim() + " Code: " + code);
+        this.code = code;
+        this.reason = reason;
+    }
+
+    /**
+     * Return the failure code
+     */
+    public int getCode() {
+        return code;
+    }
+
+    /**
+     * Return the failure reason
+     */
+    public String getReason() {
+        return reason;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpOperationFailedException.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpProducer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpProducer.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpProducer.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpProducer.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,95 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.commons.net.ftp.FTPClient;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class FtpProducer extends RemoteFileProducer<RemoteFileExchange> {
+    FtpEndpoint endpoint;
+    private final FTPClient client;
+
+    public FtpProducer(FtpEndpoint endpoint, FTPClient client) {
+        super(endpoint);
+        this.endpoint = endpoint;
+        this.client = client;
+    }
+
+    public void process(Exchange exchange) throws Exception {
+        process(endpoint.toExchangeType(exchange));
+    }
+
+    public void process(RemoteFileExchange exchange) throws Exception {
+        final String fileName;
+        InputStream payload = exchange.getIn().getBody(InputStream.class);
+        final String endpointFile = endpoint.getConfiguration().getFile();
+        client.changeWorkingDirectory(endpointFile); // TODO this line might not be needed... check after finish writing unit tests
+        if (endpointFile == null) {
+            throw new NullPointerException("Null Endpoint File");
+        }
+        else {
+            if (endpoint.getConfiguration().isDirectory()) {
+                fileName = endpointFile + "/" + exchange.getIn().getMessageId();
+            }
+            else {
+                fileName = endpointFile;
+            }
+        }
+        buildDirectory(client, fileName.substring(0, fileName.lastIndexOf('/')));
+        final boolean success = client.storeFile(fileName, payload);
+        if (success) {
+
+        }
+        else {
+            throw new RuntimeCamelException("error sending file");
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+//        client.connect(endpoint.getConfiguration().getHost());
+//        client.login(endpoint.getConfiguration().getUsername(), endpoint.getConfiguration().getPassword());
+//        client.setFileType(endpoint.getConfiguration().isBinary() ? FTPClient.BINARY_FILE_TYPE : FTPClient.ASCII_FILE_TYPE);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        client.disconnect();
+        super.doStop();
+    }
+
+    protected static boolean buildDirectory(FTPClient ftpClient, String dirName) throws IOException {
+        boolean atLeastOneSuccess = false;
+        final StringBuilder sb = new StringBuilder(dirName.length());
+        final String[] dirs = dirName.split("\\/");
+        for (String dir : dirs) {
+            sb.append('/').append(dir);
+            final boolean success = ftpClient.makeDirectory(sb.toString());
+            System.out.println(sb.toString() + " = " + success);
+            if (!atLeastOneSuccess && success) {
+                atLeastOneSuccess = true;
+            }
+        }
+        return atLeastOneSuccess;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/FtpProducer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileBinding.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileBinding.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileBinding.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileBinding.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,26 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import java.io.OutputStream;
+
+public class RemoteFileBinding {
+    public Object extractBodyFromOutputStream(RemoteFileExchange exchange, OutputStream outputStream) {
+        return outputStream;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileBinding.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileComponent.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileComponent.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileComponent.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileComponent.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,75 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.impl.DefaultComponent;
+import org.apache.camel.util.IntrospectionSupport;
+
+import java.net.URI;
+import java.util.Map;
+
+public class RemoteFileComponent extends DefaultComponent<RemoteFileExchange> {
+    private RemoteFileConfiguration configuration;
+
+    public RemoteFileComponent() {
+        this.configuration = new RemoteFileConfiguration();
+    }
+
+    public RemoteFileComponent(RemoteFileConfiguration configuration) {
+        this.configuration = configuration;
+    }
+
+    public RemoteFileComponent(CamelContext context) {
+        super(context);
+        this.configuration = new RemoteFileConfiguration();
+    }
+
+    public static RemoteFileComponent remoteFileComponent() {
+        return new RemoteFileComponent();
+    }
+
+    protected RemoteFileEndpoint createEndpoint(String uri, String remaining, Map parameters) throws Exception {
+        RemoteFileConfiguration config = getConfiguration().copy();
+        config.configure(new URI(uri));
+
+        // lets make sure we copy the configuration as each endpoint can customize its own version
+        final RemoteFileEndpoint endpoint;
+        if ("ftp".equals(config.getProtocol())) {
+            endpoint = new FtpEndpoint(uri, this, config);
+        }
+        else if ("sftp".equals(config.getProtocol())) {
+            endpoint = new SftpEndpoint(uri, this, config);
+        }
+        else {
+            throw new RuntimeCamelException("Unsupported protocol: " + config.getProtocol());
+        }
+
+        IntrospectionSupport.setProperties(endpoint.getConfiguration(), parameters);
+        return endpoint;
+    }
+
+    public RemoteFileConfiguration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(RemoteFileConfiguration configuration) {
+        this.configuration = configuration;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileComponent.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,146 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.RuntimeCamelException;
+
+import java.net.URI;
+
+public class RemoteFileConfiguration implements Cloneable {
+    private String protocol;
+    private String username;
+    private String host;
+    private int port;
+    private String password;
+    private String file;
+    private boolean binary = false;
+    private boolean directory = true;
+
+    public RemoteFileConfiguration() {
+    }
+
+    public RemoteFileConfiguration(URI uri) {
+        configure(uri);
+    }
+
+    public RemoteFileConfiguration copy() {
+        try {
+            return (RemoteFileConfiguration) clone();
+        }
+        catch (CloneNotSupportedException e) {
+            throw new RuntimeCamelException(e);
+        }
+    }
+
+    public void configure(URI uri) {
+        setProtocol(uri.getScheme());
+        setDefaultPort();
+        setUsername(uri.getUserInfo());
+        setHost(uri.getHost());
+        setPort(uri.getPort());
+        setFile(uri.getPath());
+    }
+
+    protected void setDefaultPort() {
+        if ("ftp".equalsIgnoreCase(protocol)) {
+            setPort(21);
+        }
+        else if ("sftp".equalsIgnoreCase(protocol)) {
+            setPort(22);
+        }
+    }
+
+    public String getFile() {
+        return file;
+    }
+
+    public void setFile(String file) {
+        this.file = file;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(String host) {
+        this.host = host;
+    }
+
+    public int getPort() {
+        return port;
+    }
+
+    public void setPort(int port) {
+        if (port != -1) { // use default
+            this.port = port;
+        }
+    }
+
+    public String getPassword() {
+        return password;
+    }
+
+    public void setPassword(String password) {
+        this.password = password;
+    }
+
+    public String getProtocol() {
+        return protocol;
+    }
+
+    public void setProtocol(String protocol) {
+        this.protocol = protocol;
+    }
+
+    public String getUsername() {
+        return username;
+    }
+
+    public void setUsername(String username) {
+        this.username = username;
+    }
+
+    public boolean isBinary() {
+        return binary;
+    }
+
+    public void setBinary(boolean binary) {
+        this.binary = binary;
+    }
+
+    public boolean isDirectory() {
+        return directory;
+    }
+
+    public void setDirectory(boolean directory) {
+        this.directory = directory;
+    }
+
+    public String toString() {
+        return "RemoteFileConfiguration{" +
+                "protocol='" + protocol + '\'' +
+                ", username='" + username + '\'' +
+                ", host='" + host + '\'' +
+                ", port=" + port +
+                ", password='" + password + '\'' +
+                ", file='" + file + '\'' +
+                ", binary=" + binary +
+                ", directory=" + directory +
+                '}';
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConfiguration.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,36 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.Processor;
+import org.apache.camel.impl.ScheduledPollConsumer;
+
+import java.util.concurrent.ScheduledExecutorService;
+
+public abstract class RemoteFileConsumer<T extends RemoteFileExchange> extends ScheduledPollConsumer<T> {
+    RemoteFileEndpoint<T> endpoint;
+
+    public RemoteFileConsumer(RemoteFileEndpoint<T> endpoint, Processor processor) {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+    }
+
+    public RemoteFileConsumer(RemoteFileEndpoint<T> endpoint, Processor processor, ScheduledExecutorService executor) {
+        super(endpoint, processor, executor);
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileConsumer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,63 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.impl.ScheduledPollEndpoint;
+
+import java.io.ByteArrayOutputStream;
+
+public abstract class RemoteFileEndpoint<T extends RemoteFileExchange> extends ScheduledPollEndpoint<T> {
+    private RemoteFileBinding binding;
+    private RemoteFileConfiguration configuration;
+
+    public RemoteFileEndpoint(String uri, RemoteFileComponent component, RemoteFileConfiguration configuration) {
+        super(uri, component);
+        this.configuration = configuration;
+    }
+
+    protected RemoteFileBinding createRemoteFileBinding() {
+        return new RemoteFileBinding();
+    }
+
+    public T createExchange() {
+        return (T) new RemoteFileExchange(getContext(), getBinding());
+    }
+
+    public T createExchange(String fullFileName, ByteArrayOutputStream outputStream) {
+        return (T) new RemoteFileExchange(getContext(), getBinding(), getConfiguration().getHost(), fullFileName, outputStream);
+    }
+
+    public RemoteFileBinding getBinding() {
+        if (binding == null) {
+            binding = createRemoteFileBinding();
+        }
+        return binding;
+    }
+
+    public void setBinding(RemoteFileBinding binding) {
+        this.binding = binding;
+    }
+
+    public boolean isSingleton() {
+        return true;
+    }
+
+    public RemoteFileConfiguration getConfiguration() {
+        return configuration;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileExchange.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileExchange.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileExchange.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileExchange.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,45 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.impl.DefaultExchange;
+
+import java.io.ByteArrayOutputStream;
+
+public class RemoteFileExchange<T extends RemoteFileBinding> extends DefaultExchange {
+    private T binding;
+
+    public RemoteFileExchange(CamelContext context, T binding) {
+        super(context);
+        this.binding = binding;
+    }
+
+    public RemoteFileExchange(CamelContext context, T binding, String host, String fullFileName, ByteArrayOutputStream outputStream) {
+        this(context, binding);
+        setIn(new RemoteFileMessage(host, fullFileName, outputStream));
+    }
+
+    public T getBinding() {
+        return binding;
+    }
+
+    public void setBinding(T binding) {
+        this.binding = binding;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileExchange.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileMessage.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileMessage.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileMessage.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileMessage.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,88 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.impl.DefaultMessage;
+
+import java.io.OutputStream;
+import java.util.Map;
+
+public class RemoteFileMessage extends DefaultMessage {
+    private OutputStream outputStream;
+    private String fullFileName;
+    private String hostname;
+
+    public RemoteFileMessage() {
+    }
+
+    public RemoteFileMessage(String hostname, String fullFileName, OutputStream outputStream) {
+        this.hostname = hostname;
+        this.fullFileName = fullFileName;
+        this.outputStream = outputStream;
+        setMessageId(hostname + ":" + fullFileName);
+    }
+
+    public String getHostname() {
+        return hostname;
+    }
+
+    public void setHostname(String hostname) {
+        this.hostname = hostname;
+    }
+
+    public String getFullFileName() {
+        return fullFileName;
+    }
+
+    public void setFullFileName(String fullFileName) {
+        this.fullFileName = fullFileName;
+    }
+
+    public OutputStream getOutputStream() {
+        return outputStream;
+    }
+
+    public void setOutputStream(OutputStream outputStream) {
+        this.outputStream = outputStream;
+    }
+
+    @Override
+    public RemoteFileExchange getExchange() {
+        return (RemoteFileExchange) super.getExchange();
+    }
+
+    @Override
+    protected Object createBody() {
+        if (outputStream != null) {
+            return getExchange().getBinding().extractBodyFromOutputStream(getExchange(), outputStream);
+        }
+        return null;
+    }
+
+    @Override
+    public RemoteFileMessage newInstance() {
+        return new RemoteFileMessage();
+    }
+
+    @Override
+    protected void populateInitialHeaders(Map<String, Object> map) {
+        super.populateInitialHeaders(map);
+        map.put("file.remote.host", hostname);
+        map.put("file.remote.name", fullFileName);
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileMessage.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,26 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.impl.DefaultProducer;
+
+public abstract class RemoteFileProducer<T extends RemoteFileExchange> extends DefaultProducer<T> {
+    protected RemoteFileProducer(RemoteFileEndpoint<T> endpoint) {
+        super(endpoint);
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/RemoteFileProducer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,122 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import com.jcraft.jsch.ChannelSftp;
+import org.apache.camel.Processor;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.util.concurrent.ScheduledExecutorService;
+
+public class SftpConsumer extends RemoteFileConsumer<RemoteFileExchange> {
+    private boolean recursive = true;
+    private String regexPattern = "";
+    private long lastPollTime = 0L;
+    private final SftpEndpoint endpoint;
+    private ChannelSftp channel;
+
+    public SftpConsumer(SftpEndpoint endpoint, Processor processor, ChannelSftp channel) {
+        super(endpoint, processor);
+        this.endpoint = endpoint;
+        this.channel = channel;
+    }
+
+    public SftpConsumer(SftpEndpoint endpoint, Processor processor, ChannelSftp channel, ScheduledExecutorService executor) {
+        super(endpoint, processor, executor);
+        this.endpoint = endpoint;
+        this.channel = channel;
+    }
+
+    protected void poll() throws Exception {
+        final String fileName = endpoint.getConfiguration().getFile();
+        if (endpoint.getConfiguration().isDirectory()) {
+            pollDirectory(fileName);
+        }
+        else {
+            channel.cd(fileName.substring(0, fileName.lastIndexOf('/')));
+            final ChannelSftp.LsEntry file = (ChannelSftp.LsEntry) channel.ls(fileName.substring(fileName.lastIndexOf('/') + 1)).get(0);
+            pollFile(file);
+        }
+        lastPollTime = System.currentTimeMillis();
+    }
+
+    protected void pollDirectory(String dir) throws Exception {
+        channel.cd(dir);
+        for (ChannelSftp.LsEntry sftpFile : (ChannelSftp.LsEntry[]) channel.ls(".").toArray(new ChannelSftp.LsEntry[]{})) {
+            if (sftpFile.getFilename().startsWith(".")) {
+                // skip
+            }
+            else if (sftpFile.getAttrs().isDir()) {
+                if (isRecursive()) {
+                    pollDirectory(getFullFileName(sftpFile));
+                }
+            }
+            else {
+                pollFile(sftpFile);
+            }
+        }
+    }
+
+    protected String getFullFileName(ChannelSftp.LsEntry sftpFile) throws IOException {
+        return channel.pwd() + "/" + sftpFile.getFilename();
+    }
+
+    private void pollFile(ChannelSftp.LsEntry sftpFile) throws Exception {
+        if (sftpFile.getAttrs().getMTime() * 1000 > lastPollTime) { // TODO do we need to adjust the TZ?
+            if (isMatched(sftpFile)) {
+                final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
+                channel.get(sftpFile.getFilename(), byteArrayOutputStream);
+                getProcessor().process(endpoint.createExchange(getFullFileName(sftpFile), byteArrayOutputStream));
+            }
+        }
+    }
+
+    protected boolean isMatched(ChannelSftp.LsEntry sftpFile) {
+        boolean result = true;
+        if (regexPattern != null && regexPattern.length() > 0) {
+            result = sftpFile.getFilename().matches(getRegexPattern());
+        }
+        return result;
+    }
+
+    public boolean isRecursive() {
+        return recursive;
+    }
+
+    public void setRecursive(boolean recursive) {
+        this.recursive = recursive;
+    }
+
+    public long getLastPollTime() {
+        return lastPollTime;
+    }
+
+    public void setLastPollTime(long lastPollTime) {
+        this.lastPollTime = lastPollTime;
+    }
+
+    public String getRegexPattern() {
+        return regexPattern;
+    }
+
+    public void setRegexPattern(String regexPattern) {
+        this.regexPattern = regexPattern;
+    }
+}
+

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpConsumer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,75 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.JSch;
+import com.jcraft.jsch.JSchException;
+import com.jcraft.jsch.Session;
+import com.jcraft.jsch.UserInfo;
+import org.apache.camel.Processor;
+
+public class SftpEndpoint extends RemoteFileEndpoint<RemoteFileExchange> {
+    public SftpEndpoint(String uri, RemoteFileComponent remoteFileComponent, RemoteFileConfiguration configuration) {
+        super(uri, remoteFileComponent, configuration);
+    }
+
+    public SftpProducer createProducer() throws Exception {
+        return new SftpProducer(this, createChannelSftp());
+    }
+
+    public SftpConsumer createConsumer(Processor processor) throws Exception {
+        final SftpConsumer consumer = new SftpConsumer(this, processor, createChannelSftp());
+        configureConsumer(consumer);
+        return consumer;
+    }
+
+    protected ChannelSftp createChannelSftp() throws JSchException {
+        final JSch jsch = new JSch();
+        final Session session = jsch.getSession(getConfiguration().getUsername(), getConfiguration().getHost());
+        // TODO there's got to be a better way to deal with accepting new hosts...
+        session.setUserInfo(new UserInfo() {
+            public String getPassphrase() {
+                return null;
+            }
+
+            public String getPassword() {
+                return SftpEndpoint.this.getConfiguration().getPassword();
+            }
+
+            public boolean promptPassword(String string) {
+                return true;
+            }
+
+            public boolean promptPassphrase(String string) {
+                return true;
+            }
+
+            public boolean promptYesNo(String string) {
+                return true;
+            }
+
+            public void showMessage(String string) {
+            }
+        });
+        session.connect();
+        final ChannelSftp channel = (ChannelSftp) session.openChannel("sftp");
+        channel.connect();
+        return channel;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpEndpoint.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpProducer.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpProducer.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpProducer.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpProducer.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,99 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import com.jcraft.jsch.ChannelSftp;
+import com.jcraft.jsch.SftpException;
+import org.apache.camel.Exchange;
+import org.apache.camel.RuntimeCamelException;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public class SftpProducer extends RemoteFileProducer<RemoteFileExchange> {
+    SftpEndpoint endpoint;
+    private final ChannelSftp channel;
+
+    public SftpProducer(SftpEndpoint endpoint, ChannelSftp channelSftp) {
+        super(endpoint);
+        this.endpoint = endpoint;
+        this.channel = channelSftp;
+    }
+
+    public void process(Exchange exchange) throws Exception {
+        process(endpoint.toExchangeType(exchange));
+    }
+
+    public void process(RemoteFileExchange exchange) throws Exception {
+        final String fileName;
+        InputStream payload = exchange.getIn().getBody(InputStream.class);
+        final String endpointFile = endpoint.getConfiguration().getFile();
+        channel.cd(endpointFile);
+        if (endpointFile == null) {
+            throw new NullPointerException("Null Endpoint File");
+        }
+        else {
+            if (endpoint.getConfiguration().isDirectory()) {
+                fileName = endpointFile + "/" + exchange.getIn().getMessageId();
+            }
+            else {
+                fileName = endpointFile;
+            }
+        }
+        buildDirectory(channel, fileName.substring(0, fileName.lastIndexOf('/')));
+        try {
+            channel.put(payload, fileName);
+        }
+        catch (SftpException e) {
+            throw new RuntimeCamelException("error sending file", e);
+        }
+    }
+
+    @Override
+    protected void doStart() throws Exception {
+        super.doStart();
+//        channel.connect(endpoint.getConfiguration().getHost());
+//        channel.login(endpoint.getConfiguration().getUsername(), endpoint.getConfiguration().getPassword());
+//        channel.setFileType(endpoint.getConfiguration().isBinary() ? SftpClient.BINARY_FILE_TYPE : SftpClient.ASCII_FILE_TYPE);
+    }
+
+    @Override
+    protected void doStop() throws Exception {
+        channel.disconnect();
+        super.doStop();
+    }
+
+    protected static boolean buildDirectory(ChannelSftp sftpClient, String dirName) throws IOException {
+        boolean atLeastOneSuccess = false;
+        final StringBuilder sb = new StringBuilder(dirName.length());
+        final String[] dirs = dirName.split("\\/");
+        for (String dir : dirs) {
+            sb.append('/').append(dir);
+            try {
+                sftpClient.mkdir(sb.toString());
+                if (!atLeastOneSuccess) {
+                    atLeastOneSuccess = true;
+                }
+            }
+            catch (SftpException e) {
+                // ignore
+            }
+        }
+        return atLeastOneSuccess;
+    }
+}
\ No newline at end of file

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/SftpProducer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/package.html
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/package.html?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/package.html (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/package.html Mon Jun 11 11:32:33 2007
@@ -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.
+-->
+<html>
+<head>
+</head>
+<body>
+
+Defines the File transport for communicating with Remote Files
+
+</body>
+</html>

Propchange: activemq/camel/trunk/components/camel-ftp/src/main/java/org/apache/camel/component/file/remote/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/ftp
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/ftp?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/ftp (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/ftp Mon Jun 11 11:32:33 2007
@@ -0,0 +1 @@
+class=org.apache.camel.component.file.remote.RemoteFileComponent

Added: activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/sftp
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/sftp?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/sftp (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/sftp Mon Jun 11 11:32:33 2007
@@ -0,0 +1 @@
+class=org.apache.camel.component.file.remote.RemoteFileComponent

Added: activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/webdav
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/webdav?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/webdav (added)
+++ activemq/camel/trunk/components/camel-ftp/src/main/resources/META-INF/services/org/apache/camel/component/webdav Mon Jun 11 11:32:33 2007
@@ -0,0 +1 @@
+class=org.apache.camel.component.file.remote.RemoteFileComponent

Added: activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpRouteTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpRouteTest.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpRouteTest.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpRouteTest.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,103 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import org.apache.camel.ContextTestSupport;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.ftpserver.ConfigurableFtpServerContext;
+import org.apache.ftpserver.FtpServer;
+import org.apache.ftpserver.config.PropertiesConfiguration;
+import org.apache.ftpserver.ftplet.Configuration;
+import org.apache.ftpserver.interfaces.FtpServerContext;
+
+import java.util.Properties;
+
+/**
+ * @version $Revision: 1.1 $
+ */
+public class FtpRouteTest extends ContextTestSupport {
+    protected MockEndpoint resultEndpoint;
+    protected String startEndpointUri = "ftp://admin@localhost:20010/tmp/camel?password=admin";
+    protected FtpServer ftpServer;
+
+    public void testFtpRouteWithTextMessage() throws Exception {
+        String expectedBody = "Hello there!";
+
+        resultEndpoint.expectedBodiesReceived(expectedBody);
+
+        // TODO when we support multiple marshallers for messages
+        // we can support passing headers over files using serialized/XML files
+        //resultEndpoint.message(0).header("cheese").isEqualTo(123);
+
+        sendExchange(expectedBody);
+
+        resultEndpoint.assertIsSatisfied();
+    }
+
+    protected void sendExchange(final Object expectedBody) {
+        template.sendBody(startEndpointUri, expectedBody, "cheese", 123);
+    }
+
+    @Override
+    protected void setUp() throws Exception {
+        ftpServer = createFtpServer();
+        ftpServer.start();
+
+        super.setUp();
+
+        resultEndpoint = (MockEndpoint) context.getEndpoint("mock:result");
+        createFtpServer();
+    }
+
+    @Override
+    protected void tearDown() throws Exception {
+        super.tearDown();
+        if (ftpServer != null) {
+            ftpServer.stop();
+        }
+    }
+
+    protected RouteBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            public void configure() throws Exception {
+                from(startEndpointUri).to("mock:result");
+            }
+        };
+    }
+
+    protected FtpServer createFtpServer() throws Exception {
+        // get the configuration object
+        Properties properties = createFtpServerProperties();
+        Configuration config = new PropertiesConfiguration(properties);
+
+        // create servce context
+        FtpServerContext ftpConfig = new ConfigurableFtpServerContext(config);
+
+        // create the server object and start it
+        return new FtpServer(ftpConfig);
+    }
+
+    protected Properties createFtpServerProperties() {
+        Properties properties = new Properties();
+        //properties.setProperty("config.data-connection.passive.ports", "20010");
+        properties.setProperty("config.listeners.default.port", "20010");
+        properties.setProperty("config.create-default-user", "true");
+        return properties;
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/FtpRouteTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/UriConfigurationTest.java
URL: http://svn.apache.org/viewvc/activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/UriConfigurationTest.java?view=auto&rev=546215
==============================================================================
--- activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/UriConfigurationTest.java (added)
+++ activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/UriConfigurationTest.java Mon Jun 11 11:32:33 2007
@@ -0,0 +1,106 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.file.remote;
+
+import junit.framework.TestCase;
+import org.apache.camel.CamelContext;
+import org.apache.camel.Endpoint;
+import org.apache.camel.impl.DefaultCamelContext;
+
+/**
+ * @version $Revision: 532790 $
+ */
+public class UriConfigurationTest extends TestCase {
+    protected CamelContext context = new DefaultCamelContext();
+
+    public void testFtpConfigurationAscii() throws Exception {
+        Endpoint endpoint = context.getEndpoint("ftp://camel-user@localhost:123/tmp?password=secret");
+        assertTrue("Endpoint not an FtpEndpoint: " + endpoint, endpoint instanceof FtpEndpoint);
+        FtpEndpoint ftpEndpoint = (FtpEndpoint) endpoint;
+
+        assertEquals("localhost", ftpEndpoint.getConfiguration().getHost());
+        assertEquals(123, ftpEndpoint.getConfiguration().getPort());
+        assertEquals("camel-user", ftpEndpoint.getConfiguration().getUsername());
+        assertEquals("/tmp", ftpEndpoint.getConfiguration().getFile());
+        assertEquals(true, ftpEndpoint.getConfiguration().isDirectory());
+        assertEquals(false, ftpEndpoint.getConfiguration().isBinary());
+    }
+
+    public void testFtpConfigurationBinary() throws Exception {
+        Endpoint endpoint = context.getEndpoint("ftp://camel-user@localhost:123/tmp?password=secret&binary=true");
+        assertTrue("Endpoint not an FtpEndpoint: " + endpoint, endpoint instanceof FtpEndpoint);
+        FtpEndpoint ftpEndpoint = (FtpEndpoint) endpoint;
+
+        assertEquals("localhost", ftpEndpoint.getConfiguration().getHost());
+        assertEquals(123, ftpEndpoint.getConfiguration().getPort());
+        assertEquals("camel-user", ftpEndpoint.getConfiguration().getUsername());
+        assertEquals("/tmp", ftpEndpoint.getConfiguration().getFile());
+        assertEquals(true, ftpEndpoint.getConfiguration().isDirectory());
+        assertEquals(true, ftpEndpoint.getConfiguration().isBinary());
+    }
+
+    public void testFtpConfigurationDefaultPort() throws Exception {
+        Endpoint endpoint = context.getEndpoint("ftp://camel-user@localhost/tmp?password=secret");
+        assertTrue("Endpoint not an FtpEndpoint: " + endpoint, endpoint instanceof FtpEndpoint);
+        FtpEndpoint ftpEndpoint = (FtpEndpoint) endpoint;
+
+        assertEquals("localhost", ftpEndpoint.getConfiguration().getHost());
+        assertEquals(21, ftpEndpoint.getConfiguration().getPort());
+        assertEquals("camel-user", ftpEndpoint.getConfiguration().getUsername());
+        assertEquals("/tmp", ftpEndpoint.getConfiguration().getFile());
+        assertEquals(true, ftpEndpoint.getConfiguration().isDirectory());
+        assertEquals(false, ftpEndpoint.getConfiguration().isBinary());
+    }
+
+    public void testSftpConfigurationDefaultPort() throws Exception {
+        Endpoint endpoint = context.getEndpoint("sftp://camel-user@localhost/tmp?password=secret");
+        assertTrue("Endpoint not an SftpEndpoint: " + endpoint, endpoint instanceof SftpEndpoint);
+        SftpEndpoint sftpEndpoint = (SftpEndpoint) endpoint;
+
+        assertEquals("localhost", sftpEndpoint.getConfiguration().getHost());
+        assertEquals(22, sftpEndpoint.getConfiguration().getPort());
+        assertEquals("camel-user", sftpEndpoint.getConfiguration().getUsername());
+        assertEquals("/tmp", sftpEndpoint.getConfiguration().getFile());
+        assertEquals(true, sftpEndpoint.getConfiguration().isDirectory());
+        assertEquals(false, sftpEndpoint.getConfiguration().isBinary());
+    }
+
+    public void testSftpConfigurationDirectory() throws Exception {
+        Endpoint endpoint = context.getEndpoint("sftp://camel-user@localhost:123/tmp?password=secret");
+        assertTrue("Endpoint not an SftpEndpoint: " + endpoint, endpoint instanceof SftpEndpoint);
+        SftpEndpoint sftpEndpoint = (SftpEndpoint) endpoint;
+
+        assertEquals("localhost", sftpEndpoint.getConfiguration().getHost());
+        assertEquals(123, sftpEndpoint.getConfiguration().getPort());
+        assertEquals("camel-user", sftpEndpoint.getConfiguration().getUsername());
+        assertEquals("/tmp", sftpEndpoint.getConfiguration().getFile());
+        assertEquals(true, sftpEndpoint.getConfiguration().isDirectory());
+    }
+
+    public void testSftpConfigurationFile() throws Exception {
+        Endpoint endpoint = context.getEndpoint("sftp://camel-user@localhost:123/tmp/file?password=secret&directory=false");
+        assertTrue("Endpoint not an SftpEndpoint: " + endpoint, endpoint instanceof SftpEndpoint);
+        SftpEndpoint sftpEndpoint = (SftpEndpoint) endpoint;
+
+        assertEquals("localhost", sftpEndpoint.getConfiguration().getHost());
+        assertEquals(123, sftpEndpoint.getConfiguration().getPort());
+        assertEquals("camel-user", sftpEndpoint.getConfiguration().getUsername());
+        assertEquals("/tmp/file", sftpEndpoint.getConfiguration().getFile());
+        assertEquals(false, sftpEndpoint.getConfiguration().isDirectory());
+    }
+}

Propchange: activemq/camel/trunk/components/camel-ftp/src/test/java/org/apache/camel/component/file/remote/UriConfigurationTest.java
------------------------------------------------------------------------------
    svn:eol-style = native