001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.component.file.remote;
018    
019    import java.util.List;
020    
021    import org.apache.camel.Processor;
022    import org.apache.camel.component.file.GenericFile;
023    import org.apache.camel.util.FileUtil;
024    import org.apache.camel.util.ObjectHelper;
025    import org.apache.commons.net.ftp.FTPFile;
026    
027    /**
028     * FTP consumer
029     */
030    public class FtpConsumer extends RemoteFileConsumer<FTPFile> {
031    
032        private String endpointPath;
033    
034        public FtpConsumer(RemoteFileEndpoint<FTPFile> endpoint, Processor processor, RemoteFileOperations<FTPFile> fileOperations) {
035            super(endpoint, processor, fileOperations);
036            this.endpointPath = endpoint.getConfiguration().getDirectory();
037        }
038    
039        protected void pollDirectory(String fileName, List<GenericFile<FTPFile>> fileList) {
040            if (fileName == null) {
041                return;
042            }
043    
044            // remove trailing /
045            fileName = FileUtil.stripTrailingSeparator(fileName);
046    
047            if (log.isTraceEnabled()) {
048                log.trace("Polling directory: " + fileName);
049            }
050            List<FTPFile> files = operations.listFiles(fileName);
051            for (FTPFile file : files) {
052                if (file.isDirectory()) {
053                    RemoteFile<FTPFile> remote = asRemoteFile(fileName, file);
054                    if (endpoint.isRecursive() && isValidFile(remote, true)) {
055                        // recursive scan and add the sub files and folders
056                        String directory = fileName + "/" + file.getName();
057                        pollDirectory(directory, fileList);
058                    }
059                } else if (file.isFile()) {
060                    RemoteFile<FTPFile> remote = asRemoteFile(fileName, file);
061                    if (isValidFile(remote, false)) {
062                        if (isInProgress(remote)) {
063                            if (log.isTraceEnabled()) {
064                                log.trace("Skipping as file is already in progress: " + remote.getFileName());
065                            }
066                        } else {
067                            // matched file so add
068                            fileList.add(remote);
069                        }
070                    }
071                } else {
072                    log.debug("Ignoring unsupported remote file type: " + file);
073                }
074            }
075        }
076    
077        @SuppressWarnings("unchecked")
078        private RemoteFile<FTPFile> asRemoteFile(String directory, FTPFile file) {
079            RemoteFile<FTPFile> answer = new RemoteFile<FTPFile>();
080    
081            answer.setEndpointPath(endpointPath);
082            answer.setFile(file);
083            answer.setFileName(file.getName());
084            answer.setFileNameOnly(file.getName());
085            answer.setFileLength(file.getSize());
086            if (file.getTimestamp() != null) {
087                answer.setLastModified(file.getTimestamp().getTimeInMillis());
088            }
089            answer.setHostname(((RemoteFileConfiguration) endpoint.getConfiguration()).getHost());
090    
091            // all ftp files is considered as relative
092            answer.setAbsolute(false);
093    
094            // create a pseudo absolute name
095            String absoluteFileName = (ObjectHelper.isNotEmpty(directory) ? directory + "/" : "") + file.getName();
096            answer.setAbsoluteFilePath(absoluteFileName);
097    
098            // the relative filename, skip the leading endpoint configured path
099            String relativePath = ObjectHelper.after(absoluteFileName, endpointPath);
100            // skip leading /
101            relativePath = FileUtil.stripLeadingSeparator(relativePath);
102            answer.setRelativeFilePath(relativePath);
103    
104            return answer;
105        }
106    
107    }