1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package goldengate.common.file.passthrough;
22
23 import goldengate.common.command.exception.CommandAbstractException;
24 import goldengate.common.command.exception.Reply450Exception;
25 import goldengate.common.command.exception.Reply502Exception;
26 import goldengate.common.command.exception.Reply530Exception;
27 import goldengate.common.command.exception.Reply550Exception;
28 import goldengate.common.exception.FileEndOfTransferException;
29 import goldengate.common.exception.FileTransferException;
30 import goldengate.common.exception.NoRestartException;
31 import goldengate.common.file.DataBlock;
32 import goldengate.common.file.DirInterface;
33 import goldengate.common.file.Restart;
34 import goldengate.common.file.SessionInterface;
35 import goldengate.common.logging.GgInternalLogger;
36 import goldengate.common.logging.GgInternalLoggerFactory;
37
38 import java.io.File;
39 import java.io.IOException;
40 import java.nio.channels.FileChannel;
41
42 import org.jboss.netty.buffer.ChannelBuffer;
43
44
45
46
47
48
49
50
51
52
53
54 public abstract class PassthroughBasedFileImpl implements
55 goldengate.common.file.FileInterface {
56
57
58
59 private static final GgInternalLogger logger = GgInternalLoggerFactory
60 .getLogger(PassthroughBasedFileImpl.class);
61
62
63
64
65 protected final SessionInterface session;
66
67
68
69
70
71 private final PassthroughBasedDirImpl dir;
72
73
74
75
76 private final PassthroughBasedAuthImpl auth;
77
78
79
80
81 protected String currentFile = null;
82
83
84
85
86 protected boolean isReady = false;
87
88
89
90
91 protected boolean isAppend = false;
92
93
94
95
96 protected PassthroughFile pfile = null;
97
98
99
100 public static PassthroughFileFactory factory = null;
101
102
103
104
105
106
107
108
109
110
111 public PassthroughBasedFileImpl(SessionInterface session,
112 PassthroughBasedDirImpl dir, String path, boolean append)
113 throws CommandAbstractException {
114 this.session = session;
115 auth = (PassthroughBasedAuthImpl) session.getAuth();
116 this.dir = dir;
117 currentFile = path;
118 isReady = true;
119 isAppend = append;
120 File file = getFileFromPath(path);
121 try {
122 pfile = factory.create(this);
123 } catch (PassthroughException e1) {
124 throw new Reply450Exception(e1.getMessage());
125 }
126 if (append) {
127 try {
128 setPosition(file.length());
129 } catch (IOException e) {
130 logger.error("Error during position:", e);
131 }
132 } else {
133 try {
134 setPosition(0);
135 } catch (IOException e) {
136 }
137 }
138 }
139
140 public void clear() throws CommandAbstractException {
141 closeFile();
142 isReady = false;
143 currentFile = null;
144 isAppend = false;
145 }
146
147 public void checkIdentify() throws Reply530Exception {
148 if (!getSession().getAuth().isIdentified()) {
149 throw new Reply530Exception("User not authentified");
150 }
151 }
152
153 public SessionInterface getSession() {
154 return session;
155 }
156
157 public DirInterface getDir() {
158 return dir;
159 }
160
161
162
163
164
165
166
167
168 protected File getFileFromPath(String path) throws CommandAbstractException {
169 String newdir = getDir().validatePath(path);
170 String truedir = auth.getAbsolutePath(newdir);
171 return new File(truedir);
172 }
173
174
175
176
177
178
179
180 protected String getRelativePath(File file) {
181 return auth.getRelativePath(PassthroughBasedDirImpl.normalizePath(file
182 .getAbsolutePath()));
183 }
184
185 public boolean isDirectory() throws CommandAbstractException {
186 checkIdentify();
187 return pfile.isDirectory();
188 }
189
190 public boolean isFile() throws CommandAbstractException {
191 checkIdentify();
192 return pfile.isFile();
193 }
194
195 public String getFile() throws CommandAbstractException {
196 checkIdentify();
197 return currentFile;
198 }
199
200 public boolean closeFile() throws CommandAbstractException {
201 try {
202 pfile.close();
203 } catch (PassthroughException e) {
204 throw new Reply450Exception(e.getMessage());
205 }
206 position = 0;
207 isReady = false;
208
209 return true;
210 }
211
212 public boolean abortFile() throws CommandAbstractException {
213 if (isInWriting() &&
214 ((PassthroughBasedFileParameterImpl) getSession()
215 .getFileParameter()).deleteOnAbort) {
216 delete();
217 }
218 closeFile();
219 return true;
220 }
221
222 public long length() throws CommandAbstractException {
223 checkIdentify();
224 if (!isReady) {
225 return -1;
226 }
227 if (!exists()) {
228 return -1;
229 }
230 return pfile.length();
231 }
232
233 public boolean isInReading() throws CommandAbstractException {
234 if (!isReady) {
235 return false;
236 }
237 return pfile.isInReading();
238 }
239
240 public boolean isInWriting() throws CommandAbstractException {
241 if (!isReady) {
242 return false;
243 }
244 return pfile.isInWriting();
245 }
246
247 public boolean canRead() throws CommandAbstractException {
248 checkIdentify();
249 if (!isReady) {
250 return false;
251 }
252 return pfile.canRead();
253 }
254
255 public boolean canWrite() throws CommandAbstractException {
256 checkIdentify();
257 if (!isReady) {
258 return false;
259 }
260 return pfile.canWrite();
261 }
262
263 public boolean exists() throws CommandAbstractException {
264 checkIdentify();
265 if (!isReady) {
266 return false;
267 }
268 return pfile.exists();
269 }
270
271 public boolean delete() throws CommandAbstractException {
272 checkIdentify();
273 if (!isReady) {
274 return false;
275 }
276 if (!exists()) {
277 return true;
278 }
279 closeFile();
280 try {
281 return pfile.delete();
282 } catch (PassthroughException e) {
283 throw new Reply550Exception(e.getMessage());
284 }
285 }
286
287 public boolean renameTo(String path) throws CommandAbstractException {
288 checkIdentify();
289 if (!isReady) {
290 return false;
291 }
292 try {
293 return pfile.renameTo(path);
294 } catch (PassthroughException e) {
295 throw new Reply550Exception(e.getMessage());
296 }
297 }
298
299 public DataBlock getMarker() throws CommandAbstractException {
300 throw new Reply502Exception("No marker implemented");
301 }
302
303 public boolean restartMarker(Restart restart)
304 throws CommandAbstractException {
305 try {
306 long newposition = ((PassthroughBasedRestartImpl) restart)
307 .getPosition();
308 try {
309 setPosition(newposition);
310 } catch (IOException e) {
311 throw new Reply502Exception("Cannot set the marker position");
312 }
313 return true;
314 } catch (NoRestartException e) {
315 }
316 return false;
317 }
318
319 public boolean retrieve() throws CommandAbstractException {
320 checkIdentify();
321 if (isReady) {
322 restartMarker(getSession().getRestart());
323 return canRead();
324 }
325 return false;
326 }
327
328 public boolean store() throws CommandAbstractException {
329 checkIdentify();
330 if (isReady) {
331 restartMarker(getSession().getRestart());
332 return canWrite();
333 }
334 return false;
335 }
336
337 public DataBlock readDataBlock() throws FileTransferException,
338 FileEndOfTransferException {
339 if (isReady) {
340 DataBlock dataBlock = new DataBlock();
341 ChannelBuffer buffer = null;
342 buffer = getBlock(getSession().getBlockSize());
343 if (buffer != null) {
344 dataBlock.setBlock(buffer);
345 if (dataBlock.getByteCount() < getSession().getBlockSize()) {
346 dataBlock.setEOF(true);
347 }
348 return dataBlock;
349 }
350 }
351 throw new FileTransferException("No file is ready");
352 }
353
354 public void writeDataBlock(DataBlock dataBlock)
355 throws FileTransferException {
356 if (isReady) {
357 if (dataBlock.isEOF()) {
358 writeBlockEnd(dataBlock.getBlock());
359 return;
360 }
361 writeBlock(dataBlock.getBlock());
362 return;
363 }
364 throw new FileTransferException("No file is ready");
365 }
366
367
368
369
370 private long position = 0;
371
372
373
374
375
376
377
378 public long getPosition() {
379 return position;
380 }
381
382
383
384
385
386
387
388
389 public void setPosition(long position) throws IOException {
390 try {
391 pfile.position(position);
392 } catch (PassthroughException e) {
393 throw new IOException(e);
394 }
395 this.position = position;
396 }
397
398
399
400 public void flush() {
401 if (isReady) {
402 try {
403 pfile.flush();
404 } catch (PassthroughException e) {
405 }
406 }
407 }
408
409
410
411
412
413
414
415
416
417
418
419 private void writeBlock(ChannelBuffer buffer) throws FileTransferException {
420 if (!isReady) {
421 throw new FileTransferException("No file is ready");
422 }
423
424 if (buffer == null) {
425 return;
426 }
427 int bufferSize = buffer.readableBytes();
428 int size;
429 try {
430 size = pfile.write(buffer);
431 } catch (PassthroughException e) {
432 throw new FileTransferException("Cannot write to file");
433 }
434 boolean result = size == bufferSize;
435 if (!result) {
436 try {
437 pfile.close();
438 } catch (PassthroughException e) {
439 }
440
441
442 throw new FileTransferException("Internal error, file is not ready");
443 }
444 position += size;
445 }
446
447
448
449
450
451
452
453
454
455
456 private void writeBlockEnd(ChannelBuffer buffer)
457 throws FileTransferException {
458 writeBlock(buffer);
459 try {
460 closeFile();
461 } catch (CommandAbstractException e) {
462 }
463 }
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478 private ChannelBuffer getBlock(int sizeblock) throws FileTransferException,
479 FileEndOfTransferException {
480 if (!isReady) {
481 throw new FileTransferException("No file is ready");
482 }
483 ChannelBuffer buffer;
484 try {
485 buffer = pfile.read(sizeblock);
486 } catch (PassthroughException e) {
487 throw new FileEndOfTransferException("Cannot read the file");
488 }
489 int sizeout = buffer.readableBytes();
490 if (sizeout < sizeblock) {
491 try {
492 pfile.close();
493 } catch (PassthroughException e) {
494 }
495 isReady = false;
496 }
497 if (sizeout <= 0) {
498 throw new FileEndOfTransferException("End of file");
499 }
500 position += sizeout;
501 return buffer;
502 }
503
504
505
506
507
508
509
510
511
512
513
514 protected boolean get(FileChannel fileChannelOut) {
515 if (!isReady) {
516 return false;
517 }
518 long size = pfile.length();
519 long transfert;
520 try {
521 transfert = pfile.transferTo(fileChannelOut);
522 } catch (PassthroughException e) {
523 return false;
524 }
525 if (transfert == size) {
526 position += size;
527 }
528 return transfert == size;
529 }
530 }