View Javadoc

1   /**
2    * This file is part of Waarp Project.
3    * 
4    * Copyright 2009, Frederic Bregier, and individual contributors by the @author tags. See the
5    * COPYRIGHT.txt in the distribution for a full listing of individual contributors.
6    * 
7    * All Waarp Project is free software: you can redistribute it and/or modify it under the terms of
8    * the GNU General Public License as published by the Free Software Foundation, either version 3 of
9    * the License, or (at your option) any later version.
10   * 
11   * Waarp is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
12   * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
13   * Public License for more details.
14   * 
15   * You should have received a copy of the GNU General Public License along with Waarp . If not, see
16   * <http://www.gnu.org/licenses/>.
17   */
18  package org.waarp.ftp.core.data;
19  
20  import java.util.List;
21  
22  import org.waarp.common.command.ReplyCode;
23  import org.waarp.common.logging.WaarpLogger;
24  import org.waarp.common.logging.WaarpLoggerFactory;
25  import org.waarp.ftp.core.command.FtpCommandCode;
26  import org.waarp.ftp.core.exception.FtpNoConnectionException;
27  import org.waarp.ftp.core.exception.FtpNoFileException;
28  import org.waarp.ftp.core.session.FtpSession;
29  
30  /**
31   * Class that implements the execution of the Transfer itself.
32   * 
33   * @author Frederic Bregier
34   * 
35   */
36  class FtpTransferExecutor implements Runnable {
37      /**
38       * Internal Logger
39       */
40      private static final WaarpLogger logger = WaarpLoggerFactory
41              .getLogger(FtpTransferExecutor.class);
42  
43      /**
44       * Ftp SessionInterface
45       */
46      private final FtpSession session;
47  
48      /**
49       * FtpTransfer
50       */
51      private final FtpTransfer executeTransfer;
52  
53      /**
54       * Create an executor and launch it
55       * 
56       * @param session
57       * @param executeTransfer
58       */
59      public FtpTransferExecutor(FtpSession session, FtpTransfer executeTransfer) {
60          this.session = session;
61          this.executeTransfer = executeTransfer;
62          if (this.executeTransfer == null) {
63              this.session.getDataConn().getFtpTransferControl()
64                      .setEndOfTransfer();
65              logger.error("No Execution to do");
66              return;
67          }
68      }
69  
70      /**
71       * Internal method, should not be called directly
72       */
73      public void run() {
74          if (executeTransfer == null) {
75              session.getDataConn().getFtpTransferControl().setEndOfTransfer();
76              logger.error("No Execution to do");
77              return;
78          }
79          try {
80              runNextCommand();
81          } catch (InterruptedException e) {
82              logger.error("Executor Interrupted {}", e.getMessage());
83          }
84      }
85  
86      /**
87       * Run the next command or wait for the next
88       * 
89       * @throws InterruptedException
90       */
91      private void runNextCommand() throws InterruptedException {
92          if (FtpCommandCode.isStoreLikeCommand(executeTransfer.getCommand())) {
93              // The command is implicitly done by receiving message
94              waitForCommand();
95              // Store set end
96              try {
97                  session.getDataConn().getFtpTransferControl()
98                          .setEndOfTransfer();
99              } catch (NullPointerException e) {
100                 // ignore, due probably to an already clean session
101             }
102         } else if (FtpCommandCode.isListLikeCommand(executeTransfer
103                 .getCommand())) {
104             // No wait for Command since the answer is already there
105             List<String> list = executeTransfer.getInfo();
106             StringBuilder builder = new StringBuilder();
107             for (String newfileInfo : list) {
108                 builder.append(newfileInfo).append(ReplyCode.CRLF);
109             }
110             if (builder.length() == 0) {
111                 builder.append(ReplyCode.CRLF);
112             }
113             String message = builder.toString();
114             boolean status = false;
115             try {
116                 status = session.getDataConn().getDataNetworkHandler().writeMessage(message);
117             } catch (FtpNoConnectionException e) {
118                 logger.error("No Connection but should not be!", e);
119             }
120             // Set status for check, no wait for the command
121             executeTransfer.setStatus(status);
122             // must explicitly set the end and no wait
123             session.getDataConn().getFtpTransferControl().setEndOfTransfer();
124         } else if (FtpCommandCode.isRetrLikeCommand(executeTransfer
125                 .getCommand())) {
126             // The command must be launched
127             try {
128                 executeTransfer.getFtpFile().trueRetrieve();
129             } catch (FtpNoFileException e) {
130                 // an error occurs
131                 logger.debug(e);
132                 session.getDataConn().getFtpTransferControl()
133                         .setEndOfTransfer();
134             }
135             logger.debug("wait for end of command");
136             waitForCommand();
137             logger.debug("RETR ending");
138             // RETR set end
139             try {
140                 session.getDataConn().getFtpTransferControl()
141                         .setEndOfTransfer();
142             } catch (NullPointerException e) {
143                 // ignore, due probably to an already clean session
144             }
145         } else {
146             // This is an error as unknown transfer command
147             session.getDataConn().getFtpTransferControl().setEndOfTransfer();
148         }
149     }
150 
151     /**
152      * Wait for the command to finish
153      * 
154      * @throws InterruptedException
155      * 
156      */
157     private void waitForCommand() throws InterruptedException {
158         session.getDataConn().getFtpTransferControl().waitForEndOfTransfer();
159     }
160 }