Coverage Report - org.webslinger.commons.vfs.AbstractGenerifiedFileObject
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractGenerifiedFileObject
88%
108/123
100%
26/26
0
AbstractGenerifiedFileObject$1
100%
2/2
N/A
0
AbstractGenerifiedFileObject$DefaultFileContent
84%
31/37
67%
2/3
0
AbstractGenerifiedFileObject$DefaultFileContent$1
100%
2/2
N/A
0
AbstractGenerifiedFileObject$DefaultFileContent$2
100%
5/5
N/A
0
AbstractGenerifiedFileObject$DefaultFileContent$3
100%
5/5
N/A
0
AbstractGenerifiedFileObject$DefaultFileContent$4
0%
0/5
N/A
0
 
 1  
 package org.webslinger.commons.vfs;
 2  
 
 3  
 import java.io.Closeable;
 4  
 import java.io.FilterInputStream;
 5  
 import java.io.InputStream;
 6  
 import java.io.IOException;
 7  
 import java.io.OutputStream;
 8  
 import java.net.MalformedURLException;
 9  
 import java.net.URL;
 10  
 import java.security.AccessController;
 11  
 import java.security.PrivilegedActionException;
 12  
 import java.security.PrivilegedExceptionAction;
 13  
 import java.security.cert.Certificate;
 14  
 import java.util.ArrayList;
 15  
 import java.util.Arrays;
 16  
 import java.util.Collection;
 17  
 import java.util.HashSet;
 18  
 import java.util.Iterator;
 19  
 import java.util.Map;
 20  
 import java.util.Set;
 21  
 import java.util.List;
 22  
 import java.util.concurrent.atomic.AtomicReference;
 23  
 
 24  
 import org.apache.commons.vfs.FileContent;
 25  
 import org.apache.commons.vfs.FileContentInfo;
 26  
 import org.apache.commons.vfs.FileContentInfoFactory;
 27  
 import org.apache.commons.vfs.FileName;
 28  
 import org.apache.commons.vfs.FileObject;
 29  
 import org.apache.commons.vfs.FileType;
 30  
 import org.apache.commons.vfs.FileSelector;
 31  
 import org.apache.commons.vfs.FileSystem;
 32  
 import org.apache.commons.vfs.FileSystemException;
 33  
 import org.apache.commons.vfs.FileUtil;
 34  
 import org.apache.commons.vfs.NameScope;
 35  
 import org.apache.commons.vfs.RandomAccessContent;
 36  
 import org.apache.commons.vfs.Selectors;
 37  
 import org.apache.commons.vfs.operations.DefaultFileOperations;
 38  
 import org.apache.commons.vfs.operations.FileOperations;
 39  
 import org.apache.commons.vfs.provider.AbstractFileSystem;
 40  
 import org.apache.commons.vfs.provider.DefaultFileSelectorInfo;
 41  
 import org.apache.commons.vfs.provider.DefaultURLStreamHandler;
 42  
 import org.apache.commons.vfs.provider.UriParser;
 43  
 import org.apache.commons.vfs.util.MonitorInputStream;
 44  
 import org.apache.commons.vfs.util.MonitorOutputStream;
 45  
 import org.apache.commons.vfs.util.RandomAccessMode;
 46  
 
 47  
 import org.webslinger.lang.AtomicCollection;
 48  
 import org.webslinger.commons.vfs.util.Walker;
 49  
 
 50  252092
 public abstract class AbstractGenerifiedFileObject<N extends FileName, F extends AbstractGenerifiedFileObject<N, F, S>, S extends AbstractGenerifiedFileSystem<N, F, S>> implements FileObject, GenerifiedFileObject<N, F, S>  {
 51  
     protected final S fs;
 52  
     protected final N name;
 53  54024
     protected final DefaultFileContent content = new DefaultFileContent();
 54  54024
     protected final AtomicReference<FileType> type = new AtomicReference<FileType>(null);
 55  54024
     protected final AtomicReference<F[]> children = new AtomicReference<F[]>(null);
 56  
     protected FileOperations operations;
 57  
 
 58  54024
     public AbstractGenerifiedFileObject(N name, S fs) {
 59  54024
         this.name = name;
 60  54024
         this.fs = fs;
 61  54024
     }
 62  
 
 63  
     protected void injectType(FileType newType) throws FileSystemException {
 64  15522
         type.set(newType);
 65  15522
         F parent = getParent();
 66  15522
         if (parent == null) return;
 67  13645
         parent.childChanged((F) this, newType);
 68  13645
     }
 69  
 
 70  
     protected void childChanged(F child, FileType newType) throws FileSystemException {
 71  13645
         children.set(null);
 72  13645
     }
 73  
 
 74  
     public N getName() {
 75  2006272
         return name;
 76  
     }
 77  
 
 78  
     public URL getURL() throws FileSystemException {
 79  879
         final StringBuffer buf = new StringBuffer();
 80  
         try {
 81  879
             return AccessController.doPrivileged(
 82  1758
                 new PrivilegedExceptionAction<URL>() {
 83  
                     public URL run() throws MalformedURLException {
 84  879
                         return new URL(UriParser.extractScheme(name.getURI(), buf), "", -1, buf.toString(), fs.getStreamHandler());
 85  
                     }
 86  
                 }
 87  
             );
 88  0
         } catch (final PrivilegedActionException e) {
 89  0
             throw new FileSystemException("vfs.provider/get-url.error", name, e.getException());
 90  
         }
 91  
     }
 92  
 
 93  
     public FileType getType() throws FileSystemException {
 94  
         FileType type;
 95  
         do {
 96  474892
             type = this.type.get();
 97  474896
             if (type != null) return type;
 98  150157
             type = doGetType();
 99  150157
         } while (!this.type.compareAndSet(null, type));
 100  150156
         return type;
 101  
     }
 102  
 
 103  
     public boolean exists() throws FileSystemException {
 104  288978
         return getType() != FileType.IMAGINARY;
 105  
     }
 106  
 
 107  
     public boolean isHidden() throws FileSystemException {
 108  0
         return false;
 109  
     }
 110  
 
 111  
     public boolean isReadable() throws FileSystemException {
 112  0
         return true;
 113  
     }
 114  
 
 115  
     public boolean isWriteable() throws FileSystemException {
 116  0
         return false;
 117  
     }
 118  
 
 119  
     public F getParent() throws FileSystemException {
 120  56919
         if (this == fs.getRoot()) {
 121  4463
             return null;
 122  
         }
 123  52466
         return fs.resolveFile(name.getParent());
 124  
     }
 125  
 
 126  
     public S getFileSystem() {
 127  210019
         return fs;
 128  
     }
 129  
 
 130  
     public FileObject[] getChildren() throws FileSystemException {
 131  430202
         F[] newChildren = null;
 132  
 OUTER:
 133  
         do {
 134  430204
             F[] children = this.children.get();
 135  430203
             if (children != null) return children;
 136  93201
             newChildren = buildChildren();
 137  93201
         } while (!children.compareAndSet(null, newChildren));
 138  93199
         return newChildren;
 139  
     }
 140  
 
 141  
     private F[] buildChildren() throws FileSystemException {
 142  93201
         String[] names = doListChildren();
 143  93201
         F[] children = getFileSystem().newArray(names.length);
 144  712165
         for (int i = 0; i < names.length; i++) {
 145  618964
             children[i] = resolveFile(names[i]);
 146  
         }
 147  93201
         return children;
 148  
     }
 149  
 
 150  
     public F getChild(String name) throws FileSystemException {
 151  930454
         for (FileObject child: getChildren()) {
 152  826315
             if (child.getName().getBaseName().equals(name)) return (F) child;
 153  
         }
 154  104129
         return null;
 155  
     }
 156  
 
 157  
     public F resolveFile(String name, NameScope scope) throws FileSystemException {
 158  739481
         return fs.resolveFile(fs.getFileSystemManager().resolveName(this.name, name, scope));
 159  
     }
 160  
 
 161  
     public F resolveFile(String name) throws FileSystemException {
 162  739204
         return resolveFile(name, NameScope.FILE_SYSTEM);
 163  
     }
 164  
 
 165  
     public F[] findFiles(FileSelector selector) throws FileSystemException {
 166  314
         if (!exists()) return null;
 167  314
         ArrayList<LayeredFileObject> list = new ArrayList<LayeredFileObject>();
 168  314
         findFiles(selector, true, list);
 169  314
         return list.toArray(getFileSystem().newArray(list.size()));
 170  
     }
 171  
 
 172  
     public void findFiles(FileSelector selector, boolean depthwise, List selected) throws FileSystemException {
 173  314
         Walker.walk(this, selector, depthwise, selected);
 174  314
     }
 175  
 
 176  
     public boolean delete() throws FileSystemException {
 177  296
         return delete(Selectors.SELECT_SELF) > 0;
 178  
     }
 179  
 
 180  
     public int delete(FileSelector selector) throws FileSystemException {
 181  313
         if (getType() == FileType.IMAGINARY) return 0;
 182  298
         int deleted = 0;
 183  604
         for (F file: findFiles(selector)) {
 184  306
             if (file.getType().hasChildren()) {
 185  110
                 if (file.getChildren().length != 0) {
 186  0
                     continue;
 187  
                 }
 188  
             }
 189  
             try {
 190  306
                 file.doDelete();
 191  0
             } catch (Throwable t) {
 192  0
                 throw VFSUtil.makeFileSystemException(t);
 193  306
             }
 194  306
             deleted++;
 195  
         }
 196  298
         return deleted;
 197  
     }
 198  
 
 199  
     protected void createParentFolder() throws FileSystemException {
 200  15216
         F parent = getParent();
 201  15216
         if (parent == null) return;
 202  13339
         parent.createFolder();
 203  13339
     }
 204  
 
 205  
     public void createFolder() throws FileSystemException {
 206  14829
         createParentFolder();
 207  14829
         doCreateFolder();
 208  14829
         injectType(FileType.FOLDER);
 209  14829
     }
 210  
 
 211  
 
 212  
     public void createFile() throws FileSystemException {
 213  10
         createParentFolder();
 214  10
         doCreateFile();
 215  10
         injectType(FileType.FILE);
 216  10
     }
 217  
 
 218  
     protected void doCopyFile(FileObject src) throws FileSystemException {
 219  
         try {
 220  13
             FileUtil.copyContent(src, this);
 221  0
         } catch (Exception e) {
 222  0
             throw VFSUtil.makeFileSystemException(e);
 223  13
         }
 224  13
     }
 225  
 
 226  
     protected void doCopyFolder(FileObject src) throws FileSystemException {
 227  1
         createFolder();
 228  1
     }
 229  
 
 230  
     protected void doCopyMetaData(FileObject src) throws FileSystemException {
 231  14
         getContent().setLastModifiedTime(src.getContent().getLastModifiedTime());
 232  14
     }
 233  
 
 234  
     private final void doCopy(FileObject src) throws FileSystemException {
 235  14
         FileType destType = getType();
 236  14
         FileType srcType = src.getType();
 237  14
         if (destType != FileType.IMAGINARY && destType != srcType) delete(Selectors.SELECT_ALL);
 238  14
         if (srcType.hasContent()) doCopyFile(src);
 239  14
         if (srcType.hasChildren()) doCopyFolder(src);
 240  14
         doCopyMetaData(src);
 241  14
     }
 242  
 
 243  
     public void copyFrom(FileObject src, FileSelector selector) throws FileSystemException {
 244  14
         if (src == this) return;
 245  28
         for (FileObject file: src.findFiles(selector)) {
 246  14
             if (file == src) {
 247  14
                 doCopy(src);
 248  
             } else {
 249  0
                 FileObject destChild = resolveFile(src.getName().getRelativeName(file.getName()), NameScope.DESCENDENT_OR_SELF);
 250  0
                 destChild.copyFrom(file, Selectors.SELECT_SELF);
 251  
             }
 252  
         }
 253  14
     }
 254  
 
 255  
     public void moveTo(FileObject dest) throws FileSystemException {
 256  2
         if (dest == this) return;
 257  2
         dest.copyFrom(this, Selectors.SELECT_ALL);
 258  4
         for (FileObject file: findFiles(Selectors.SELECT_ALL)) {
 259  2
             file.delete();
 260  
         }
 261  2
     }
 262  
 
 263  
     public boolean canRenameTo(FileObject target) {
 264  0
         return false;
 265  
     }
 266  
 
 267  
     public FileContent getContent() {
 268  111321
         return content;
 269  
     }
 270  
 
 271  
     public void close() throws FileSystemException {
 272  5527
         getContent().close();
 273  5527
         refresh();
 274  5527
     }
 275  
 
 276  
     public void refresh() throws FileSystemException {
 277  292682
         children.set(null);
 278  292682
         type.set(null);
 279  292682
     }
 280  
 
 281  
     public boolean isAttached() {
 282  0
         return true;
 283  
     }
 284  
 
 285  
     public boolean isContentOpen() {
 286  0
         return getContent().isOpen();
 287  
     }
 288  
 
 289  
     public FileOperations getFileOperations() throws FileSystemException {
 290  209
         if (operations == null) operations = new DefaultFileOperations(this);
 291  209
         return operations;
 292  
     }
 293  
 
 294  
     public String toString() {
 295  141
         return getName().toString();
 296  
     }
 297  
 
 298  
     protected abstract FileType doGetType() throws FileSystemException;
 299  
     protected abstract String[] doListChildren() throws FileSystemException;
 300  
     protected abstract void doDelete() throws FileSystemException;
 301  
     protected abstract void doCreateFolder() throws FileSystemException;
 302  
     protected abstract void doCreateFile() throws FileSystemException;
 303  
     protected abstract long doGetSize() throws FileSystemException;
 304  
     protected abstract long doGetLastModifiedTime() throws FileSystemException;
 305  
     protected abstract void doSetLastModifiedTime(long lastModifiedTime) throws FileSystemException;
 306  
     protected abstract boolean doAttributeExists(String name) throws FileSystemException;
 307  
     protected abstract Map<String, Object> doGetAttributes() throws FileSystemException;
 308  
     protected abstract String[] doGetAttributeNames() throws FileSystemException;
 309  
     protected abstract Object doGetAttribute(String name) throws FileSystemException;
 310  
     protected abstract void doRemoveAttribute(String name) throws FileSystemException;
 311  
     protected abstract void doSetAttribute(String name, Object value) throws FileSystemException;
 312  
     protected abstract Certificate[] doGetCertificates() throws FileSystemException;
 313  
     protected abstract InputStream doGetInputStream() throws FileSystemException;
 314  
     protected abstract OutputStream doGetOutputStream(boolean append) throws FileSystemException;
 315  
     protected abstract RandomAccessContent doGetRandomAccessContent(RandomAccessMode mode) throws FileSystemException;
 316  
 
 317  
     protected FileContentInfoFactory getFileContentInfoFactory() {
 318  948
         return getFileSystem().getFileSystemManager().getFileContentInfoFactory();
 319  
     }
 320  
 
 321  
     protected FileContentInfo doGetContentInfo() throws FileSystemException {
 322  948
         return getFileContentInfoFactory().create(getContent());
 323  
     }
 324  
 
 325  54972
     protected class DefaultFileContent implements FileContent {
 326  54024
         protected AtomicCollection<Closeable> streams = new AtomicCollection<Closeable>(new HashSet<Closeable>()) {
 327  
             protected Collection<Closeable> copyCollection(Collection<Closeable> old) {
 328  14244
                 return new HashSet<Closeable>(old);
 329  
             }
 330  
         };
 331  
 
 332  
         public F getFile() {
 333  948
             return (F) AbstractGenerifiedFileObject.this;
 334  
         }
 335  
 
 336  
         public long getSize() throws FileSystemException {
 337  994
             return doGetSize();
 338  
         }
 339  
 
 340  
         public long getLastModifiedTime() throws FileSystemException {
 341  23805
             return doGetLastModifiedTime();
 342  
         }
 343  
 
 344  
         public void setLastModifiedTime(long lastModifiedTime) throws FileSystemException {
 345  45
             doSetLastModifiedTime(lastModifiedTime);
 346  45
         }
 347  
 
 348  
         public boolean attributeExists(String name) throws FileSystemException {
 349  43190
             return doAttributeExists(name);
 350  
         }
 351  
 
 352  
         public Map<String, ?> getAttributes() throws FileSystemException {
 353  47
             return doGetAttributes();
 354  
         }
 355  
 
 356  
         public String[] getAttributeNames() throws FileSystemException {
 357  10
             return doGetAttributeNames();
 358  
         }
 359  
 
 360  
         public Object getAttribute(String name) throws FileSystemException {
 361  24200
             return doGetAttribute(name);
 362  
         }
 363  
 
 364  
         public void removeAttribute(String name) throws FileSystemException {
 365  6
             doRemoveAttribute(name);
 366  6
         }
 367  
 
 368  
         public void setAttribute(String name, Object value) throws FileSystemException {
 369  32
             doSetAttribute(name, value);
 370  32
         }
 371  
 
 372  
         public Certificate[] getCertificates() throws FileSystemException {
 373  360
             return doGetCertificates();
 374  
         }
 375  
 
 376  
         public InputStream getInputStream() throws FileSystemException {
 377  6745
             return openStream(new MonitorInputStream(doGetInputStream()) {
 378  
                 protected void onClose() throws IOException {
 379  
                     try {
 380  6745
                         super.onClose();
 381  
                     } finally {
 382  6745
                         closeStream(this);
 383  6745
                     }
 384  6745
                 }
 385  
             });
 386  
         }
 387  
 
 388  
         public OutputStream getOutputStream() throws FileSystemException {
 389  225
             return getOutputStream(false);
 390  
         }
 391  
 
 392  
         public OutputStream getOutputStream(boolean append) throws FileSystemException {
 393  377
             createParentFolder();
 394  377
             OutputStream realOutputStream = doGetOutputStream(append);
 395  377
             injectType(FileType.FILE);
 396  377
             return openStream(new MonitorOutputStream(realOutputStream) {
 397  
                 protected void onClose() throws IOException {
 398  
                     try {
 399  377
                         super.onClose();
 400  
                     } finally {
 401  377
                         closeStream(this);
 402  377
                     }
 403  377
                 }
 404  
             });
 405  
         }
 406  
 
 407  
         public RandomAccessContent getRandomAccessContent(RandomAccessMode mode) throws FileSystemException {
 408  
             //System.err.println("getRandomAccessContent(" + mode + "): realFile=" + realFile);
 409  0
             RandomAccessContent realRandomAccessContent = doGetRandomAccessContent(mode);
 410  0
             if (mode.requestWrite()) injectType(FileType.FILE);
 411  0
             return openStream(new MonitorRandomAccessContent(realRandomAccessContent) {
 412  
                 protected void onClose() throws IOException {
 413  
                     try {
 414  0
                         super.onClose();
 415  
                     } finally {
 416  0
                         closeStream(this);
 417  0
                     }
 418  0
                 }
 419  
             });
 420  
         }
 421  
 
 422  
         public FileContentInfo getContentInfo() throws FileSystemException {
 423  5319
             return doGetContentInfo();
 424  
         }
 425  
 
 426  
         protected <T extends Closeable> T openStream(T in) {
 427  7122
             streams.add(in);
 428  7122
             return in;
 429  
         }
 430  
 
 431  
         protected <T extends Closeable> void closeStream(T in) {
 432  7122
             streams.remove(in);
 433  7122
         }
 434  
 
 435  
         public boolean isOpen() {
 436  459
             return !streams.collection().isEmpty();
 437  
         }
 438  
 
 439  
         public void close() throws FileSystemException {
 440  
             try {
 441  5527
                 for (Closeable stream: this.streams.collection()) {
 442  0
                     stream.close();
 443  
                 }
 444  0
             } catch (Throwable t) {
 445  0
                 throw VFSUtil.makeFileSystemException(t);
 446  5527
             }
 447  5527
         }
 448  
     }
 449  
 }