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    }