1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package goldengate.ftp.filesystembased;
22
23 import goldengate.common.command.exception.CommandAbstractException;
24 import goldengate.common.exception.FileEndOfTransferException;
25 import goldengate.common.exception.FileTransferException;
26 import goldengate.common.file.DataBlock;
27 import goldengate.common.file.filesystembased.FilesystemBasedFileImpl;
28 import goldengate.common.logging.GgInternalLogger;
29 import goldengate.common.logging.GgInternalLoggerFactory;
30 import goldengate.ftp.core.exception.FtpNoConnectionException;
31 import goldengate.ftp.core.file.FtpFile;
32 import goldengate.ftp.core.session.FtpSession;
33
34 import java.util.concurrent.locks.ReentrantLock;
35
36 import org.jboss.netty.channel.Channel;
37 import org.jboss.netty.channel.ChannelFuture;
38 import org.jboss.netty.channel.Channels;
39
40
41
42
43
44
45
46 public abstract class FilesystemBasedFtpFile extends FilesystemBasedFileImpl implements FtpFile {
47
48
49
50 private static final GgInternalLogger logger = GgInternalLoggerFactory
51 .getLogger(FilesystemBasedFtpFile.class);
52
53
54
55
56 private final ReentrantLock retrieveLock = new ReentrantLock();
57
58
59
60
61
62
63
64
65
66 public FilesystemBasedFtpFile(FtpSession session,
67 FilesystemBasedFtpDir dir, String path, boolean append)
68 throws CommandAbstractException {
69 super(session, dir, path, append);
70 }
71
72 @Override
73 public long length() throws CommandAbstractException {
74 long length = super.length();
75 if (((FtpSession) getSession()).getDataConn()
76 .isFileStreamBlockAsciiImage()) {
77 long block = (long) Math.ceil((double) length /
78 (double) getSession().getBlockSize());
79 length += (block + 3) * 3;
80 }
81 return length;
82 }
83
84
85
86
87
88
89 public void trueRetrieve() {
90 retrieveLock.lock();
91 try {
92 if (!isReady) {
93 return;
94 }
95
96 try {
97 ((FtpSession) session).getDataConn().getFtpTransferControl()
98 .waitForDataNetworkHandlerReady();
99 } catch (InterruptedException e) {
100
101 logger.warn("DataNetworkHandler was not ready", e);
102 return;
103 }
104
105 Channel channel = ((FtpSession) session).getDataConn()
106 .getCurrentDataChannel();
107 DataBlock block = null;
108 try {
109 block = readDataBlock();
110 } catch (FileEndOfTransferException e) {
111
112
113
114 closeFile();
115 ((FtpSession) session).getDataConn().getFtpTransferControl()
116 .setPreEndOfTransfer();
117 return;
118 }
119 if (block == null) {
120
121
122
123 closeFile();
124 ((FtpSession) session).getDataConn().getFtpTransferControl()
125 .setPreEndOfTransfer();
126 return;
127 }
128
129 ChannelFuture future = null;
130 while (block != null && !block.isEOF()) {
131 future = Channels.write(channel, block);
132
133 if (channel.isWritable()) {
134 try {
135 block = readDataBlock();
136 } catch (FileEndOfTransferException e) {
137 closeFile();
138
139 try {
140 future.await();
141 } catch (InterruptedException e1) {
142 throw new FileTransferException("Interruption catched");
143 }
144 if (future.isSuccess()) {
145 ((FtpSession) session).getDataConn()
146 .getFtpTransferControl().setPreEndOfTransfer();
147 } else {
148 throw new FileTransferException("File transfer in error");
149 }
150 return;
151 }
152 } else {
153 return;
154 }
155 try {
156 future.await();
157 } catch (InterruptedException e) {
158 closeFile();
159 throw new FileTransferException("Interruption catched");
160 }
161 if (! future.isSuccess()) {
162 closeFile();
163 throw new FileTransferException("File transfer in error");
164 }
165 }
166
167 closeFile();
168 if (block != null) {
169 future = Channels.write(channel, block);
170 }
171
172 if (future != null) {
173 try {
174 future.await();
175 } catch (InterruptedException e) {
176 throw new FileTransferException("Interruption catched");
177 }
178 if (future.isSuccess()) {
179 ((FtpSession) session).getDataConn().getFtpTransferControl()
180 .setPreEndOfTransfer();
181 } else {
182 throw new FileTransferException("Write is not successful");
183 }
184 }
185 } catch (FileTransferException e) {
186
187 ((FtpSession) session).getDataConn().getFtpTransferControl()
188 .setTransferAbortedFromInternal(true);
189 } catch (FtpNoConnectionException e) {
190 logger.error("Should not be", e);
191 ((FtpSession) session).getDataConn().getFtpTransferControl()
192 .setTransferAbortedFromInternal(true);
193 } catch (CommandAbstractException e) {
194 logger.error("Should not be", e);
195 ((FtpSession) session).getDataConn().getFtpTransferControl()
196 .setTransferAbortedFromInternal(true);
197 } finally {
198 retrieveLock.unlock();
199 }
200 }
201 }