/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package org.nbstudio.cachefilesystem; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.Reference; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.Enumeration; import java.util.List; import java.util.Objects; import org.nbstudio.core.Connection; import org.openide.filesystems.FileAlreadyLockedException; import org.openide.filesystems.FileChangeListener; import org.openide.filesystems.FileLock; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileStateInvalidException; import org.openide.filesystems.FileSystem; /** * * @author daimor */ public class CacheFileObject extends FileObject { private final CacheFileSystem fs; private final CacheFileObject parent; private final String name; private Reference lock; public CacheFileObject(CacheFileSystem fs, CacheFileObject parent, String name) { this.fs = fs; this.parent = parent; this.name = name; } @Override public String getName() { int i = name.lastIndexOf('.'); return (i <= 0) ? name : name.substring(0, i); } @Override public String getExt() { int i = name.lastIndexOf('.') + 1; return (i <= 1) || (i == name.length()) ? "" : name.substring(i); } @Override public void rename(FileLock lock, String name, String ext) throws IOException { } @Override public FileSystem getFileSystem() throws FileStateInvalidException { return fs; } @Override public FileObject getParent() { return parent; } @Override public boolean isFolder() { return false || isRoot() || getExt().isEmpty() || "pkg".equalsIgnoreCase(getExt()) || "prj".equalsIgnoreCase(getExt()); } @Override public Date lastModified() { return new Date(0); } @Override public boolean isRoot() { return (parent == null); } @Override public boolean isData() { return !isFolder(); } @Override public boolean isValid() { return true; } @Override public void delete(FileLock lock) throws IOException { } @Override public Object getAttribute(String attrName) { return fs.readAttribute(name, attrName); } @Override public void setAttribute(String attrName, Object value) throws IOException { fs.writeAttribute(name, attrName, value); } @Override public Enumeration<String> getAttributes() { return fs.attributes(name); } @Override public void addFileChangeListener(FileChangeListener fcl) { } @Override public void removeFileChangeListener(FileChangeListener fcl) { } @Override public long getSize() { return 0; } @Override public InputStream getInputStream() throws FileNotFoundException { return fs.inputStream(getFullName()); } @Override public OutputStream getOutputStream(FileLock lock) throws IOException { if (this.name.equalsIgnoreCase(".netbeans.xml")) { return null; } return fs.outputStream(getFullName()); } @Override public synchronized FileLock lock() throws IOException { if (lock != null) { FileLock f = (FileLock) lock.get(); if (f != null) { // System.out.println ("Already locked: " + this); // NOI18N throw new FileAlreadyLockedException(); } } fs.lock(getPath()); FileLock l = new AfLock(); lock = new WeakReference(l); // Thread.dumpStack (); // System.out.println ("Locking file: " + this); // NOI18N return l; } synchronized void unlock(FileLock fLock) { FileLock currentLock = null; if (lock != null) { currentLock = (FileLock) lock.get(); } if (currentLock == fLock) { fs.unlock(getPath()); // clear my lock lock = null; } } @Override public void setImportant(boolean b) { } @Override public FileObject[] getChildren() { List<FileObject> children = new ArrayList(); children.addAll(Arrays.asList(getChildren("*.cls,*.mac"))); return children.toArray(new FileObject[children.size()]); } public CacheFileObject[] getChildren(String filter) { Connection conn = fs.getConnection(); String fullPath = getFullPath(); CacheRootFile curFile = new CacheRootFile(conn.getTitle() + fullPath); File[] files = curFile.listFiles(filter, false, false, false); List<FileObject> children = new ArrayList(); for (File file : files) { String fileName = file.getName(); children.add(new CacheFileObject(fs, this, fileName)); } return children.toArray(new CacheFileObject[children.size()]); } public String getFullPath() { return (parent != null) ? parent.getFullPath() + "/" + name : name; } public String getFullName() { String parentName = (parent != null) ? parent.getFullName() : ""; return (!parentName.isEmpty()) ? parentName + "." + name : name; } @Override public FileObject getFileObject(String name, String ext) { String fileName = name + (ext != null ? "." + ext : ""); if (fileName.equalsIgnoreCase(".netbeans.xml")) { return null; } return new CacheFileObject(fs, this, fileName); } @Override public FileObject createFolder(String name) throws IOException { return new CacheFileObject(fs, this, name); } @Override public FileObject createData(String name, String ext) throws IOException { return new CacheFileObject(fs, this, name); } @Override public boolean isReadOnly() { return false; } /** * Implementation of lock for abstract files. */ private class AfLock extends FileLock { AfLock() { } @Override public void releaseLock() { if (this.isValid()) { super.releaseLock(); unlock(this); } } } @Override public int hashCode() { final int prime = 11; int hash = 1; hash = prime * hash + Objects.hashCode(this.fs); hash = prime * hash + Objects.hashCode(this.parent); hash = prime * hash + Objects.hashCode(this.name); return hash; } @Override public boolean equals(Object obj) { if (obj instanceof CacheFileObject) { CacheFileObject cacheFileObj = (CacheFileObject) obj; boolean result = true; try { result = result && this.fs.equals(cacheFileObj.getFileSystem()); result = result && this.getFullPath().equals(cacheFileObj.getFullPath()); } catch (FileStateInvalidException ex) { result = false; } return result; } else { return false; } } }