001 /**
002 *
003 * Licensed to the Apache Software Foundation (ASF) under one or more
004 * contributor license agreements. See the NOTICE file distributed with
005 * this work for additional information regarding copyright ownership.
006 * The ASF licenses this file to You under the Apache License, Version 2.0
007 * (the "License"); you may not use this file except in compliance with
008 * the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018 package org.apache.camel.component.file.remote;
019
020 import org.apache.camel.Processor;
021 import org.apache.commons.net.ftp.FTPClient;
022 import org.apache.commons.net.ftp.FTPFile;
023
024 import java.io.ByteArrayOutputStream;
025 import java.io.IOException;
026 import java.util.concurrent.ScheduledExecutorService;
027
028 public class FtpConsumer extends RemoteFileConsumer<RemoteFileExchange> {
029 private boolean recursive = true;
030 private String regexPattern = "";
031 private long lastPollTime = 0L;
032 private final FtpEndpoint endpoint;
033 private FTPClient client;
034
035 public FtpConsumer(FtpEndpoint endpoint, Processor processor, FTPClient client) {
036 super(endpoint, processor);
037 this.endpoint = endpoint;
038 this.client = client;
039 }
040
041 public FtpConsumer(FtpEndpoint endpoint, Processor processor, FTPClient client, ScheduledExecutorService executor) {
042 super(endpoint, processor, executor);
043 this.endpoint = endpoint;
044 this.client = client;
045 }
046
047 protected void poll() throws Exception {
048 final String fileName = endpoint.getConfiguration().getFile();
049 if (endpoint.getConfiguration().isDirectory()) {
050 pollDirectory(fileName);
051 }
052 else {
053 client.changeWorkingDirectory(fileName.substring(0, fileName.lastIndexOf('/')));
054 final FTPFile[] files = client.listFiles(fileName.substring(fileName.lastIndexOf('/') + 1));
055 pollFile(files[0]);
056 }
057 lastPollTime = System.currentTimeMillis();
058 }
059
060 protected void pollDirectory(String dir) throws Exception {
061 client.changeWorkingDirectory(dir);
062 for (FTPFile ftpFile : client.listFiles()) {
063 if (ftpFile.isFile()) {
064 pollFile(ftpFile);
065 }
066 else if (ftpFile.isDirectory()) {
067 if (isRecursive()) {
068 pollDirectory(getFullFileName(ftpFile));
069 }
070 }
071 else {
072 throw new RuntimeException("");
073 }
074 }
075 }
076
077 protected String getFullFileName(FTPFile ftpFile) throws IOException {
078 return client.printWorkingDirectory() + "/" + ftpFile.getName();
079 }
080
081 private void pollFile(FTPFile ftpFile) throws Exception {
082 if (ftpFile.getTimestamp().getTimeInMillis() > lastPollTime) { // TODO do we need to adjust the TZ? can we?
083 if (isMatched(ftpFile)) {
084 final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
085 client.retrieveFile(ftpFile.getName(), byteArrayOutputStream);
086 getProcessor().process(endpoint.createExchange(getFullFileName(ftpFile), byteArrayOutputStream));
087 }
088 }
089 }
090
091 protected boolean isMatched(FTPFile file) {
092 boolean result = true;
093 if (regexPattern != null && regexPattern.length() > 0) {
094 result = file.getName().matches(getRegexPattern());
095 }
096 return result;
097 }
098
099 public boolean isRecursive() {
100 return recursive;
101 }
102
103 public void setRecursive(boolean recursive) {
104 this.recursive = recursive;
105 }
106
107 public long getLastPollTime() {
108 return lastPollTime;
109 }
110
111 public void setLastPollTime(long lastPollTime) {
112 this.lastPollTime = lastPollTime;
113 }
114
115 public String getRegexPattern() {
116 return regexPattern;
117 }
118
119 public void setRegexPattern(String regexPattern) {
120 this.regexPattern = regexPattern;
121 }
122 }