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.io.IOException;
020    import java.io.InputStream;
021    
022    import com.jcraft.jsch.ChannelSftp;
023    import com.jcraft.jsch.SftpException;
024    
025    import org.apache.camel.Exchange;
026    import org.apache.camel.RuntimeCamelException;
027    
028    public class SftpProducer extends RemoteFileProducer<RemoteFileExchange> {
029        SftpEndpoint endpoint;
030        private final ChannelSftp channel;
031    
032        public SftpProducer(SftpEndpoint endpoint, ChannelSftp channelSftp) {
033            super(endpoint);
034            this.endpoint = endpoint;
035            this.channel = channelSftp;
036        }
037    
038        public void process(Exchange exchange) throws Exception {
039            process(endpoint.toExchangeType(exchange));
040        }
041    
042        public void process(RemoteFileExchange exchange) throws Exception {
043            final String fileName;
044            InputStream payload = exchange.getIn().getBody(InputStream.class);
045            final String endpointFile = endpoint.getConfiguration().getFile();
046            channel.cd(endpointFile);
047            if (endpointFile == null) {
048                throw new NullPointerException("Null Endpoint File");
049            } else {
050                if (endpoint.getConfiguration().isDirectory()) {
051                    fileName = endpointFile + "/" + exchange.getIn().getMessageId();
052                } else {
053                    fileName = endpointFile;
054                }
055            }
056            buildDirectory(channel, fileName.substring(0, fileName.lastIndexOf('/')));
057            try {
058                channel.put(payload, fileName);
059            } catch (SftpException e) {
060                throw new RuntimeCamelException("error sending file", e);
061            }
062        }
063    
064        @Override
065        protected void doStart() throws Exception {
066            super.doStart();
067            // channel.connect(endpoint.getConfiguration().getHost());
068            // channel.login(endpoint.getConfiguration().getUsername(),
069            // endpoint.getConfiguration().getPassword());
070            // channel.setFileType(endpoint.getConfiguration().isBinary() ?
071            // SftpClient.BINARY_FILE_TYPE : SftpClient.ASCII_FILE_TYPE);
072        }
073    
074        @Override
075        protected void doStop() throws Exception {
076            channel.disconnect();
077            super.doStop();
078        }
079    
080        protected static boolean buildDirectory(ChannelSftp sftpClient, String dirName) throws IOException {
081            boolean atLeastOneSuccess = false;
082            final StringBuilder sb = new StringBuilder(dirName.length());
083            final String[] dirs = dirName.split("\\/");
084            for (String dir : dirs) {
085                sb.append('/').append(dir);
086                try {
087                    sftpClient.mkdir(sb.toString());
088                    if (!atLeastOneSuccess) {
089                        atLeastOneSuccess = true;
090                    }
091                } catch (SftpException e) {
092                    // ignore
093                }
094            }
095            return atLeastOneSuccess;
096        }
097    }