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