1 16 package org.apache.commons.vfs.provider; 17 18 import org.apache.commons.vfs.FileContent; 19 import org.apache.commons.vfs.FileContentInfo; 20 import org.apache.commons.vfs.FileContentInfoFactory; 21 import org.apache.commons.vfs.FileObject; 22 import org.apache.commons.vfs.FileSystemException; 23 import org.apache.commons.vfs.RandomAccessContent; 24 import org.apache.commons.vfs.util.MonitorInputStream; 25 import org.apache.commons.vfs.util.MonitorOutputStream; 26 import org.apache.commons.vfs.util.MonitorRandomAccessContent; 27 import org.apache.commons.vfs.util.RandomAccessMode; 28 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.io.OutputStream ; 32 import java.security.cert.Certificate ; 33 import java.util.Collections ; 34 import java.util.Map ; 35 import java.util.Set ; 36 37 42 public final class DefaultFileContent implements FileContent 43 { 44 50 51 static final int STATE_CLOSED = 0; 52 static final int STATE_OPENED = 1; 53 54 private final AbstractFileObject file; 55 private Map attrs; 56 private Map roAttrs; 57 private FileContentInfo fileContentInfo; 58 private final FileContentInfoFactory fileContentInfoFactory; 59 60 private final ThreadLocal threadData = new ThreadLocal (); 61 62 65 private int openStreams = 0; 66 67 public DefaultFileContent(final AbstractFileObject file, final FileContentInfoFactory fileContentInfoFactory) 68 { 69 this.file = file; 70 this.fileContentInfoFactory = fileContentInfoFactory; 71 } 72 73 private FileContentThreadData getThreadData() 74 { 75 FileContentThreadData data = (FileContentThreadData) this.threadData.get(); 76 if (data == null) 77 { 78 data = new FileContentThreadData(); 79 this.threadData.set(data); 80 } 81 return data; 82 } 83 84 void streamOpened() 85 { 86 synchronized (this) 87 { 88 openStreams++; 89 } 90 ((AbstractFileSystem) file.getFileSystem()).streamOpened(); 91 } 92 93 void streamClosed() 94 { 95 synchronized (this) 96 { 97 if (openStreams > 0) 98 { 99 openStreams--; 100 if (openStreams < 1) 101 { 102 file.notifyAllStreamsClosed(); 103 } 104 } 105 } 106 ((AbstractFileSystem) file.getFileSystem()).streamClosed(); 107 } 108 109 112 public FileObject getFile() 113 { 114 return file; 115 } 116 117 120 public long getSize() throws FileSystemException 121 { 122 if (!file.getType().hasContent()) 124 { 125 throw new FileSystemException("vfs.provider/get-size-not-file.error", file); 126 } 127 133 134 try 135 { 136 return file.doGetContentSize(); 138 } 139 catch (final Exception exc) 140 { 141 throw new FileSystemException("vfs.provider/get-size.error", new Object []{file}, exc); 142 } 143 } 144 145 148 public long getLastModifiedTime() throws FileSystemException 149 { 150 156 if (!file.getType().hasAttributes()) 157 { 158 throw new FileSystemException("vfs.provider/get-last-modified-no-exist.error", file); 159 } 160 try 161 { 162 return file.doGetLastModifiedTime(); 163 } 164 catch (final Exception e) 165 { 166 throw new FileSystemException("vfs.provider/get-last-modified.error", file, e); 167 } 168 } 169 170 173 public void setLastModifiedTime(final long modTime) throws FileSystemException 174 { 175 181 if (!file.getType().hasAttributes()) 182 { 183 throw new FileSystemException("vfs.provider/set-last-modified-no-exist.error", file); 184 } 185 try 186 { 187 file.doSetLastModifiedTime(modTime); 188 } 189 catch (final Exception e) 190 { 191 throw new FileSystemException("vfs.provider/set-last-modified.error", file, e); 192 } 193 } 194 195 198 public Map getAttributes() throws FileSystemException 199 { 200 if (!file.getType().hasAttributes()) 201 { 202 throw new FileSystemException("vfs.provider/get-attributes-no-exist.error", file); 203 } 204 if (roAttrs == null) 205 { 206 try 207 { 208 attrs = file.doGetAttributes(); 209 roAttrs = Collections.unmodifiableMap(attrs); 210 } 211 catch (final Exception e) 212 { 213 throw new FileSystemException("vfs.provider/get-attributes.error", file, e); 214 } 215 } 216 return roAttrs; 217 } 218 219 222 public String [] getAttributeNames() throws FileSystemException 223 { 224 getAttributes(); 225 final Set names = attrs.keySet(); 226 return (String []) names.toArray(new String [names.size()]); 227 } 228 229 232 public Object getAttribute(final String attrName) 233 throws FileSystemException 234 { 235 getAttributes(); 236 return attrs.get(attrName.toLowerCase()); 237 } 238 239 242 public void setAttribute(final String attrName, final Object value) 243 throws FileSystemException 244 { 245 if (!file.getType().hasAttributes()) 246 { 247 throw new FileSystemException("vfs.provider/set-attribute-no-exist.error", new Object []{attrName, file}); 248 } 249 try 250 { 251 file.doSetAttribute(attrName, value); 252 } 253 catch (final Exception e) 254 { 255 throw new FileSystemException("vfs.provider/set-attribute.error", new Object []{attrName, file}, e); 256 } 257 258 if (attrs != null) 259 { 260 attrs.put(attrName, value); 261 } 262 } 263 264 267 public Certificate [] getCertificates() throws FileSystemException 268 { 269 if (!file.exists()) 270 { 271 throw new FileSystemException("vfs.provider/get-certificates-no-exist.error", file); 272 } 273 279 280 try 281 { 282 final Certificate [] certs = file.doGetCertificates(); 283 if (certs != null) 284 { 285 return certs; 286 } 287 else 288 { 289 return new Certificate [0]; 290 } 291 } 292 catch (final Exception e) 293 { 294 throw new FileSystemException("vfs.provider/get-certificates.error", file, e); 295 } 296 } 297 298 301 public InputStream getInputStream() throws FileSystemException 302 { 303 309 310 final InputStream instr = file.getInputStream(); 312 final InputStream wrappedInstr = new FileContentInputStream(file, instr); 313 314 this.getThreadData().addInstr(wrappedInstr); 315 streamOpened(); 316 317 return wrappedInstr; 319 } 320 321 325 public RandomAccessContent getRandomAccessContent(final RandomAccessMode mode) throws FileSystemException 326 { 327 333 334 final RandomAccessContent rastr = file.getRandomAccessContent(mode); 336 337 this.getThreadData().setRastr(new FileRandomAccessContent(file, rastr)); 338 streamOpened(); 339 340 return this.getThreadData().getRastr(); 342 } 343 344 347 public OutputStream getOutputStream() throws FileSystemException 348 { 349 return getOutputStream(false); 350 } 351 352 355 public OutputStream getOutputStream(boolean bAppend) throws FileSystemException 356 { 357 360 if (this.getThreadData().getOutstr() != null) 361 { 362 throw new FileSystemException("vfs.provider/write-in-use.error", file); 363 } 364 365 final OutputStream outstr = file.getOutputStream(bAppend); 367 368 this.getThreadData().setOutstr(new FileContentOutputStream(file, outstr)); 370 streamOpened(); 371 372 return this.getThreadData().getOutstr(); 374 } 375 376 380 public void close() throws FileSystemException 381 { 382 try 383 { 384 while (getThreadData().getInstrsSize() > 0) 386 { 387 final FileContentInputStream instr = (FileContentInputStream) getThreadData().removeInstr(0); 388 instr.close(); 389 } 390 391 if (this.getThreadData().getOutstr() != null) 393 { 394 this.getThreadData().closeOutstr(); 395 } 396 397 if (this.getThreadData().getRastr() != null) 399 { 400 try 401 { 402 this.getThreadData().closeRastr(); 403 } 404 catch (IOException e) 405 { 406 throw new FileSystemException(e); 407 } 408 } 409 } 410 finally 411 { 412 threadData.set(null); 413 } 414 } 415 416 419 private void endInput(final FileContentInputStream instr) 420 { 421 getThreadData().removeInstr(instr); 422 streamClosed(); 423 429 } 430 431 434 private void endRandomAccess() 435 { 436 streamClosed(); 437 } 439 440 443 private void endOutput() throws Exception 444 { 445 streamClosed(); 446 447 this.getThreadData().setOutstr(null); 448 450 file.endOutput(); 451 } 452 453 459 460 466 public boolean isOpen() 467 { 468 return getThreadData().hasStreams(); 470 } 471 472 478 public boolean isOpenGlobal() 479 { 480 synchronized (this) 481 { 482 return openStreams > 0; 483 } 484 } 485 486 490 private final class FileContentInputStream 491 extends MonitorInputStream 492 { 493 private final FileObject file; 495 496 FileContentInputStream(final FileObject file, final InputStream instr) 497 { 498 super(instr); 499 this.file = file; 500 } 501 502 505 public void close() throws FileSystemException 506 { 507 try 508 { 509 super.close(); 510 } 511 catch (final IOException e) 512 { 513 throw new FileSystemException("vfs.provider/close-instr.error", file, e); 514 } 515 } 516 517 520 protected void onClose() throws IOException 521 { 522 try 523 { 524 super.onClose(); 525 } 526 finally 527 { 528 endInput(this); 529 } 530 } 531 } 532 533 536 private final class FileRandomAccessContent extends MonitorRandomAccessContent 537 { 538 private final FileObject file; 540 541 FileRandomAccessContent(final FileObject file, final RandomAccessContent content) 542 { 543 super(content); 544 this.file = file; 545 } 546 547 550 protected void onClose() throws IOException 551 { 552 try 553 { 554 super.onClose(); 555 } 556 finally 557 { 558 endRandomAccess(); 559 } 560 } 561 } 562 563 566 final class FileContentOutputStream extends MonitorOutputStream 567 { 568 private final FileObject file; 570 571 FileContentOutputStream(final FileObject file, final OutputStream outstr) 572 { 573 super(outstr); 574 this.file = file; 575 } 576 577 580 public void close() throws FileSystemException 581 { 582 try 583 { 584 super.close(); 585 } 586 catch (final IOException e) 587 { 588 throw new FileSystemException("vfs.provider/close-outstr.error", file, e); 589 } 590 } 591 592 595 protected void onClose() throws IOException 596 { 597 try 598 { 599 super.onClose(); 600 } 601 finally 602 { 603 try 604 { 605 endOutput(); 606 } 607 catch (Exception e) 608 { 609 throw new FileSystemException("vfs.provider/close-outstr.error", file, e); 610 } 611 } 612 } 613 } 614 615 618 public FileContentInfo getContentInfo() throws FileSystemException 619 { 620 if (fileContentInfo == null) 621 { 622 fileContentInfo = fileContentInfoFactory.create(this); 623 } 624 625 return fileContentInfo; 626 } 627 } 628 | Popular Tags |