1 16 package org.apache.commons.vfs.provider; 17 18 import org.apache.commons.logging.Log; 19 import org.apache.commons.logging.LogFactory; 20 import org.apache.commons.vfs.Capability; 21 import org.apache.commons.vfs.FileListener; 22 import org.apache.commons.vfs.FileName; 23 import org.apache.commons.vfs.FileObject; 24 import org.apache.commons.vfs.FileSelector; 25 import org.apache.commons.vfs.FileSystem; 26 import org.apache.commons.vfs.FileSystemException; 27 import org.apache.commons.vfs.FileSystemManager; 28 import org.apache.commons.vfs.FileSystemOptions; 29 import org.apache.commons.vfs.FilesCache; 30 import org.apache.commons.vfs.VfsLog; 31 import org.apache.commons.vfs.events.AbstractFileChangeEvent; 32 import org.apache.commons.vfs.events.ChangedEvent; 33 import org.apache.commons.vfs.events.CreateEvent; 34 import org.apache.commons.vfs.events.DeleteEventAbstractFile; 35 import org.apache.commons.vfs.util.Messages; 36 37 import java.io.File ; 38 import java.util.ArrayList ; 39 import java.util.Collection ; 40 import java.util.HashMap ; 41 import java.util.HashSet ; 42 import java.util.Map ; 43 44 49 public abstract class AbstractFileSystem 50 extends AbstractVfsComponent 51 implements FileSystem 52 { 53 private final static Log log = LogFactory.getLog(AbstractFileSystem.class); 54 55 private final FileName rootName; 56 private FileObject parentLayer; 57 private final Collection caps = new HashSet (); 59 60 63 65 68 private final Map listenerMap = new HashMap (); 69 70 73 private final FileSystemOptions fileSystemOptions; 74 75 78 private long useCount; 79 80 private FileSystemKey cacheKey; 81 82 85 private int openStreams; 86 87 protected AbstractFileSystem(final FileName rootName, 88 final FileObject parentLayer, 89 final FileSystemOptions fileSystemOptions) 90 { 91 this.parentLayer = parentLayer; 93 this.rootName = rootName; 94 this.fileSystemOptions = fileSystemOptions; 95 96 } 98 99 102 public void init() throws FileSystemException 103 { 104 addCapabilities(caps); 105 } 106 107 110 public void close() 111 { 112 closeCommunicationLink(); 113 114 parentLayer = null; 115 } 116 117 120 public void closeCommunicationLink() 121 { 122 synchronized (this) 123 { 124 doCloseCommunicationLink(); 125 } 126 } 127 128 131 protected void doCloseCommunicationLink() 132 { 133 } 134 135 139 protected abstract FileObject createFile(final FileName name) 140 throws Exception ; 141 142 145 protected abstract void addCapabilities(Collection caps); 146 147 150 public FileName getRootName() 151 { 152 return rootName; 153 } 154 155 158 protected void putFileToCache(final FileObject file) 159 { 160 getCache().putFile(file); 161 } 163 164 private FilesCache getCache() 165 { 166 FilesCache files; 167 { 169 files = getContext().getFileSystemManager().getFilesCache(); 170 if (files == null) 171 { 172 throw new RuntimeException (Messages.getString("vfs.provider/files-cache-missing.error")); 173 } 174 } 175 176 return files; 177 } 178 179 182 protected FileObject getFileFromCache(final FileName name) 183 { 184 return getCache().getFile(this, name); 185 } 187 188 191 protected void removeFileFromCache(final FileName name) 192 { 193 getCache().removeFile(this, name); 194 } 195 196 199 public boolean hasCapability(final Capability capability) 200 { 201 return caps.contains(capability); 202 } 203 204 208 public Object getAttribute(final String attrName) throws FileSystemException 209 { 210 throw new FileSystemException("vfs.provider/get-attribute-not-supported.error"); 211 } 212 213 217 public void setAttribute(final String attrName, final Object value) 218 throws FileSystemException 219 { 220 throw new FileSystemException("vfs.provider/set-attribute-not-supported.error"); 221 } 222 223 226 public FileObject getParentLayer() throws FileSystemException 227 { 228 return parentLayer; 229 } 230 231 234 public FileObject getRoot() throws FileSystemException 235 { 236 return resolveFile(rootName); 237 244 } 245 246 249 public FileObject resolveFile(final String nameStr) throws FileSystemException 250 { 251 final FileName name = getFileSystemManager().resolveName(rootName, nameStr); 253 return resolveFile(name); 254 } 255 256 259 public synchronized FileObject resolveFile(final FileName name) throws FileSystemException 260 { 261 return resolveFile(name, true); 262 } 263 264 private synchronized FileObject resolveFile(final FileName name, final boolean useCache) throws FileSystemException 265 { 266 if (!rootName.getRootURI().equals(name.getRootURI())) 267 { 268 throw new FileSystemException("vfs.provider/mismatched-fs-for-name.error", 269 new Object []{ 270 name, rootName, name.getRootURI()}); 271 } 272 273 FileObject file; 275 if (useCache) 276 { 277 file = getFileFromCache(name); 278 } 279 else 280 { 281 file = null; 282 } 283 if (file == null) 285 { 286 try 287 { 288 synchronized (this) 289 { 290 file = createFile(name); 291 } 292 } 293 catch (Exception e) 294 { 295 throw new FileSystemException("vfs.provider/resolve-file.error", name, e); 296 } 297 298 if (useCache) 300 { 301 putFileToCache(file); 302 } 303 } 305 return file; 306 } 307 308 311 public File replicateFile(final FileObject file, 312 final FileSelector selector) 313 throws FileSystemException 314 { 315 if (!file.exists()) 316 { 317 throw new FileSystemException("vfs.provider/replicate-missing-file.error", file.getName()); 318 } 319 320 try 321 { 322 return doReplicateFile(file, selector); 323 } 324 catch (final Exception e) 325 { 326 throw new FileSystemException("vfs.provider/replicate-file.error", file.getName(), e); 327 } 328 } 329 330 333 public FileSystemOptions getFileSystemOptions() 334 { 335 return fileSystemOptions; 336 } 337 338 341 public FileSystemManager getFileSystemManager() 342 { 343 return getContext().getFileSystemManager(); 344 } 346 347 352 public double getLastModTimeAccuracy() 353 { 354 return 0; 355 } 356 357 360 protected File doReplicateFile(final FileObject file, 361 final FileSelector selector) 362 throws Exception 363 { 364 return getContext().getReplicator().replicateFile(file, selector); 365 } 366 367 370 public void addJunction(final String junctionPoint, 371 final FileObject targetFile) 372 throws FileSystemException 373 { 374 throw new FileSystemException("vfs.provider/junctions-not-supported.error", rootName); 375 } 376 377 380 public void removeJunction(final String junctionPoint) throws FileSystemException 381 { 382 throw new FileSystemException("vfs.provider/junctions-not-supported.error", rootName); 383 } 384 385 388 public void addListener(final FileObject file, 389 final FileListener listener) 390 { 391 synchronized (listenerMap) 392 { 393 ArrayList listeners = (ArrayList ) listenerMap.get(file.getName()); 394 if (listeners == null) 395 { 396 listeners = new ArrayList (); 397 listenerMap.put(file.getName(), listeners); 398 } 399 listeners.add(listener); 400 } 401 } 402 403 406 public void removeListener(final FileObject file, 407 final FileListener listener) 408 { 409 synchronized (listenerMap) 410 { 411 final ArrayList listeners = (ArrayList ) listenerMap.get(file.getName()); 412 if (listeners != null) 413 { 414 listeners.remove(listener); 415 } 416 } 417 } 418 419 422 public void fireFileCreated(final FileObject file) 423 { 424 fireEvent(new CreateEvent(file)); 425 } 426 427 430 public void fireFileDeleted(final FileObject file) 431 { 432 fireEvent(new DeleteEventAbstractFile(file)); 433 } 434 435 439 public void fireFileChanged(final FileObject file) 440 { 441 fireEvent(new ChangedEvent(file)); 442 } 443 444 447 public boolean isReleaseable() 448 { 449 return useCount < 1; 450 } 451 452 void freeResources() 453 { 454 } 455 456 459 private void fireEvent(final AbstractFileChangeEvent event) 460 { 461 synchronized (listenerMap) 462 { 463 final FileObject file = event.getFile(); 464 final ArrayList listeners = (ArrayList ) listenerMap.get(file.getName()); 465 if (listeners != null) 466 { 467 final int count = listeners.size(); 468 for (int i = 0; i < count; i++) 469 { 470 final FileListener listener = (FileListener) listeners.get(i); 471 try 472 { 473 event.notify(listener); 474 } 475 catch (final Exception e) 476 { 477 final String message = Messages.getString("vfs.provider/notify-listener.warn", file); 478 VfsLog.warn(getLogger(), log, message, e); 480 } 481 } 482 } 483 } 484 } 485 486 void fileDetached(FileObject fileObject) 487 { 488 useCount--; 489 } 490 491 void fileAttached(FileObject fileObject) 492 { 493 useCount++; 494 495 } 496 497 void setCacheKey(FileSystemKey cacheKey) 498 { 499 this.cacheKey = cacheKey; 500 } 501 502 FileSystemKey getCacheKey() 503 { 504 return this.cacheKey; 505 } 506 507 void streamOpened() 508 { 509 synchronized (this) 510 { 511 openStreams++; 512 } 513 } 514 515 void streamClosed() 516 { 517 synchronized (this) 518 { 519 if (openStreams > 0) 520 { 521 openStreams--; 522 if (openStreams < 1) 523 { 524 notifyAllStreamsClosed(); 525 } 526 } 527 } 528 } 529 530 533 protected void notifyAllStreamsClosed() 534 { 535 } 536 537 540 public boolean isOpen() 541 { 542 synchronized (this) 543 { 544 return openStreams > 0; 545 } 546 } 547 } 548 | Popular Tags |