View Javadoc

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