1 19 20 package org.netbeans.modules.masterfs.filebasedfs.fileobjects; 21 import java.io.ByteArrayInputStream ; 22 import org.netbeans.modules.masterfs.filebasedfs.naming.FileNaming; 23 import org.netbeans.modules.masterfs.filebasedfs.naming.NamingFactory; 24 import org.netbeans.modules.masterfs.filebasedfs.utils.FileInfo; 25 import org.openide.filesystems.FileObject; 26 27 import java.io.File ; 28 import java.io.FileNotFoundException ; 29 import java.io.IOException ; 30 import java.io.InputStream ; 31 import java.io.OutputStream ; 32 import java.lang.ref.Reference ; 33 import java.lang.ref.WeakReference ; 34 import java.util.*; 35 import org.openide.filesystems.FileLock; 36 37 40 public final class FileObjectFactory { 41 private final Map allInstances = Collections.synchronizedMap(new WeakHashMap()); 42 private RootObj root; 43 44 public static FileObjectFactory getInstance(final FileInfo fInfo) { 45 return new FileObjectFactory(fInfo); 46 } 47 48 public final RootObj getRoot() { 49 return root; 50 } 51 public int getSize() { 52 synchronized (allInstances) { 53 return allInstances.size(); 54 } 55 } 56 57 public final FileObject findFileObject(final FileInfo fInfo) { 58 FileObject retVal = null; 59 File f = fInfo.getFile(); 60 61 synchronized (allInstances) { 62 retVal = this.get(f); 63 if (retVal == null || !retVal.isValid()) { 64 final File parent = f.getParentFile(); 65 if (parent != null) { 66 retVal = this.create(fInfo); 67 } else { 68 retVal = this.getRoot(); 69 } 70 71 } 72 73 assert retVal == null || retVal.isValid() : retVal.toString(); 74 return retVal; 75 } 76 } 77 78 79 private BaseFileObj create(final FileInfo fInfo) { 80 if (fInfo.isWindowsFloppy()) { 81 return null; 82 } 83 84 if (!fInfo.isConvertibleToFileObject()) { 85 return null; 86 } 87 88 final File file = fInfo.getFile(); 89 FileNaming name = fInfo.getFileNaming(); 90 name = (name == null) ? NamingFactory.fromFile(file) : name; 91 92 if (name == null) return null; 93 94 if (name.isFile() && !name.isDirectory()) { 95 assert name.getFile() != null && (name.getFile().isFile() || !name.getFile().isDirectory()) : name; 96 final FileObj realRoot = new FileObj(file, name); 97 FolderObj par = (FolderObj)realRoot.getExistingParent(); 98 if (par != null && par.getChildrenCache().getChild(name.getName(), false) == null) { 99 return null; 100 } 101 return putInCache(realRoot, realRoot.getFileName().getId()); 102 } 103 104 if (!name.isFile() && name.isDirectory()) { 105 assert name.getFile() != null && (!name.getFile().isFile() || name.getFile().isDirectory()) : name; 106 final FolderObj realRoot = new FolderObj(file, name); 107 FolderObj par = (FolderObj)realRoot.getExistingParent(); 108 if (par != null && par.getChildrenCache().getChild(name.getName(), false) == null) { 109 return null; 110 } 111 return putInCache(realRoot, realRoot.getFileName().getId()); 112 } 113 114 if (!name.isFile() && !name.isDirectory() || fInfo.isUnixSpecialFile()) { 115 assert name.getFile() != null && (name.getFile().isFile() == name.getFile().isDirectory()) : name; 116 final FileObj realRoot = new FileObj(file, name) { 117 public InputStream getInputStream() throws FileNotFoundException { 118 return new ByteArrayInputStream (new byte[] {}); 119 } 120 public boolean isReadOnly() { 121 return true; 122 } 123 124 public OutputStream getOutputStream(final FileLock lock) throws IOException { 125 throw new IOException (file.getAbsolutePath()); 126 } 127 128 public boolean canWrite() { 129 return !isReadOnly(); 130 } 131 }; 132 FolderObj par = (FolderObj)realRoot.getExistingParent(); 133 if (par != null && par.getChildrenCache().getChild(name.getName(), false) == null) { 134 return null; 135 } 136 return putInCache(realRoot, realRoot.getFileName().getId()); 137 } 138 139 assert false; 140 return null; 141 } 142 143 public final void refreshAll(final boolean expected) { 144 final Set all2Refresh = new HashSet(); 145 synchronized (allInstances) { 146 final Iterator it = allInstances.values().iterator(); 147 while (it.hasNext()) { 148 final Object obj = it.next(); 149 if (obj instanceof List) { 150 for (Iterator iterator = ((List)obj).iterator(); iterator.hasNext();) { 151 WeakReference ref = (WeakReference ) iterator.next(); 152 final BaseFileObj fo = (BaseFileObj) ((ref != null) ? ref.get() : null); 153 if (fo != null) { 154 all2Refresh.add(fo); 155 } 156 } 157 } else { 158 final WeakReference ref = (WeakReference ) obj; 159 final BaseFileObj fo = (BaseFileObj) ((ref != null) ? ref.get() : null); 160 if (fo != null) { 161 all2Refresh.add(fo); 162 } 163 } 164 } 165 } 166 167 168 for (Iterator iterator = all2Refresh.iterator(); iterator.hasNext();) { 169 final BaseFileObj fo = (BaseFileObj) iterator.next(); 170 fo.refresh(expected); 171 } 172 } 173 174 public final void rename () { 175 final Map toRename = new HashMap(); 176 synchronized (allInstances) { 177 final Iterator it = allInstances.entrySet().iterator(); 178 while (it.hasNext()) { 179 Map.Entry entry = (Map.Entry)it.next(); 180 final Object obj = entry.getValue(); 181 final Integer key = (Integer )entry.getKey(); 182 if (!(obj instanceof List)) { 183 final WeakReference ref = (WeakReference ) obj; 184 185 final BaseFileObj fo = (BaseFileObj) ((ref != null) ? ref.get() : null); 186 187 if (fo != null) { 188 Integer computedId = fo.getFileName().getId(); 189 if (!key.equals(computedId)) { 190 toRename.put(key,fo); 191 } 192 } 193 } else { 194 for (Iterator iterator = ((List)obj).iterator(); iterator.hasNext();) { 195 WeakReference ref = (WeakReference ) iterator.next(); 196 final BaseFileObj fo = (BaseFileObj) ((ref != null) ? ref.get() : null); 197 if (fo != null) { 198 Integer computedId = fo.getFileName().getId(); 199 if (!key.equals(computedId)) { 200 toRename.put(key,ref); 201 } 202 } 203 } 204 205 } 206 } 207 208 for (Iterator iterator = toRename.entrySet().iterator(); iterator.hasNext();) { 209 final Map.Entry entry = (Map.Entry ) iterator.next(); 210 Object key = entry.getKey(); 211 Object previous = allInstances.remove(key); 212 if (previous instanceof List) { 213 List list = (List)previous; 214 list.remove(entry.getValue()); 215 allInstances.put(key, previous); 216 } else { 217 BaseFileObj bfo = (BaseFileObj )entry.getValue(); 218 putInCache(bfo, bfo.getFileName().getId()); 219 } 220 } 221 } 222 } 223 224 public final BaseFileObj get(final File file) { 225 final Object o; 226 synchronized (allInstances) { 227 final Object value = allInstances.get(NamingFactory.createID(file)); 228 Reference ref = null; 229 ref = (Reference ) (value instanceof Reference ? value : null); 230 ref = (ref == null && value instanceof List ? FileObjectFactory.getReference((List) value, file) : ref); 231 232 o = (ref != null) ? ref.get() : null; 233 assert (o == null || o instanceof BaseFileObj); 234 } 235 236 return (BaseFileObj) o; 237 } 238 239 private static Reference getReference(final List list, final File file) { 240 Reference retVal = null; 241 for (int i = 0; retVal == null && i < list.size(); i++) { 242 final Reference ref = (Reference ) list.get(i); 243 final BaseFileObj cachedElement = (ref != null) ? (BaseFileObj) ref.get() : null; 244 if (cachedElement != null && cachedElement.getFileName().getFile().compareTo(file) == 0) { 245 retVal = ref; 246 } 247 } 248 return retVal; 249 } 250 251 private FileObjectFactory(final FileInfo fInfo) { 252 final File rootFile = fInfo.getFile(); 253 assert rootFile.getParentFile() == null; 254 255 final BaseFileObj realRoot = create(fInfo); 256 root = new RootObj(realRoot); 257 } 258 259 260 private BaseFileObj putInCache(final BaseFileObj newValue, final Integer id) { 261 synchronized (allInstances) { 262 final WeakReference newRef = new WeakReference (newValue); 263 final Object listOrReference = allInstances.put(id, newRef); 264 265 if (listOrReference != null) { 266 if (listOrReference instanceof List) { 267 ((List) listOrReference).add(newRef); 268 allInstances.put(id, listOrReference); 269 } else { 270 assert (listOrReference instanceof WeakReference ); 271 final Reference oldRef = (Reference ) listOrReference; 272 BaseFileObj oldValue = (oldRef != null) ? (BaseFileObj)oldRef.get() : null; 273 274 if (oldValue != null && !newValue.getFileName().equals(oldValue.getFileName())) { 275 final List l = new ArrayList(); 276 l.add(oldRef); 277 l.add(newRef); 278 allInstances.put(id, l); 279 } 280 } 281 } 282 } 283 284 return newValue; 285 } 286 } 287 | Popular Tags |