1 19 20 package org.netbeans.modules.masterfs.filebasedfs.children; 21 22 import org.netbeans.modules.masterfs.filebasedfs.naming.FileName; 23 import org.netbeans.modules.masterfs.filebasedfs.naming.FileNaming; 24 import org.netbeans.modules.masterfs.filebasedfs.naming.NamingFactory; 25 import org.netbeans.modules.masterfs.filebasedfs.utils.FileInfo; 26 27 import java.io.File ; 28 import java.util.*; 29 import org.netbeans.modules.masterfs.providers.ProvidedExtensions; 30 31 34 public final class ChildrenSupport { 35 36 static final int NO_CHILDREN_CACHED = 0; 37 static final int SOME_CHILDREN_CACHED = 1; 38 static final int ALL_CHILDREN_CACHED = 2; 39 40 private Set notExistingChildren; 41 private Set existingChildren; 42 private int status = ChildrenSupport.NO_CHILDREN_CACHED; 43 44 public ChildrenSupport() { 45 } 46 47 public Set getCachedChildren() { 48 return getExisting(false); 49 } 50 51 public synchronized Set getChildren(final FileNaming folderName, final boolean rescan) { 52 if (rescan || !isStatus(ChildrenSupport.ALL_CHILDREN_CACHED)) { 53 rescanChildren(folderName); 54 setStatus(ChildrenSupport.ALL_CHILDREN_CACHED); 55 } 58 59 return getExisting(false); 61 } 62 63 public synchronized FileNaming getChild(final String childName, final FileNaming folderName, final boolean rescan) { 64 FileNaming retval = null; 65 if (rescan || isStatus(ChildrenSupport.NO_CHILDREN_CACHED)) { 66 retval = rescanChild(folderName, childName); 67 } else if (isStatus(ChildrenSupport.SOME_CHILDREN_CACHED)) { 68 retval = lookupChildInCache(folderName, childName, true); 69 if (retval == null && lookupChildInCache(folderName, childName, false) == null) { 70 retval = rescanChild(folderName, childName); 71 } 72 } else if (isStatus(ChildrenSupport.ALL_CHILDREN_CACHED)) { 73 retval = lookupChildInCache(folderName, childName, true); 74 } 75 setStatus(ChildrenSupport.SOME_CHILDREN_CACHED); 76 return retval; 77 } 78 79 82 83 public synchronized void removeChild(final FileNaming folderName, final FileNaming childName) { 84 assert childName != null; 85 assert childName.getParent().equals(folderName); 86 getExisting().remove(childName); 87 getNotExisting().add(childName); 88 } 89 90 private synchronized void addChild(final FileNaming folderName, final FileNaming childName) { 91 assert childName != null; 92 assert childName.getParent().equals(folderName); 93 getExisting().add(childName); 94 getNotExisting().remove(childName); 95 } 96 97 98 99 public synchronized Map refresh(final FileNaming folderName) { 100 Map retVal = new HashMap(); 101 Set e = new HashSet(getExisting(false)); 102 Set nE = new HashSet(getNotExisting(false)); 103 104 if (isStatus(ChildrenSupport.SOME_CHILDREN_CACHED)) { 105 Set existingToCheck = new HashSet(e); 106 for (Iterator itExisting = existingToCheck.iterator(); itExisting.hasNext();) { 107 FileNaming fnToCheck = (FileNaming) itExisting.next(); 108 FileNaming fnRescanned = rescanChild(folderName, fnToCheck.getName()); 109 if (fnRescanned == null) { 110 retVal.put(fnToCheck, ChildrenCache.REMOVED_CHILD); 111 } else { 112 assert fnToCheck.equals(fnRescanned); 113 } 114 } 115 116 Set notExistingToCheck = new HashSet(nE); 117 for (Iterator itNotExisting = notExistingToCheck.iterator(); itNotExisting.hasNext();) { 118 FileNaming fnToCheck = (FileNaming) itNotExisting.next(); 119 assert fnToCheck != null; 120 FileNaming fnRescanned = rescanChild(folderName, fnToCheck.getName()); 121 if (fnRescanned != null) { 122 retVal.put(fnToCheck, ChildrenCache.ADDED_CHILD); 123 } 124 } 125 } else if (isStatus(ChildrenSupport.ALL_CHILDREN_CACHED)) { 126 retVal = rescanChildren(folderName); 127 } 128 return retVal; 129 } 130 131 public String toString() { 132 return getExisting(false).toString(); 133 } 134 135 boolean isStatus(int status) { 136 return this.status == status; 137 } 138 139 private void setStatus(int status) { 140 if (this.status < status) { 141 this.status = status; 142 } 143 } 144 145 146 private FileNaming rescanChild(final FileNaming folderName, final String childName) { 147 final File folder = folderName.getFile(); 148 final File child = new File (folder, childName); 149 final FileInfo fInfo = new FileInfo(child); 150 151 FileNaming retval = (fInfo.isConvertibleToFileObject()) ? NamingFactory.fromFile(folderName, child) : null; 152 if (retval != null) { 153 addChild(folderName, retval); 154 } else { 155 FileName fChild = new FileName(folderName, child) { 156 public boolean isDirectory() { 157 return false; 158 } 159 160 public boolean isFile() { 161 return false; 162 } 163 }; 164 165 removeChild(folderName, fChild); 166 } 167 168 return retval; 169 } 170 171 private Map rescanChildren(final FileNaming folderName) { 172 final Map retval = new HashMap(); 173 final Set newChildren = new LinkedHashSet(); 174 175 final File folder = folderName.getFile(); 176 assert folderName.getFile().getAbsolutePath().equals(folderName.toString()); 177 178 final File [] childs = folder.listFiles(); 179 if (childs != null) { 181 for (int i = 0; i < childs.length; i++) { 182 final FileInfo fInfo = new FileInfo(childs[i]); 183 if (fInfo.isConvertibleToFileObject()) { 184 FileNaming child = NamingFactory.fromFile(folderName, childs[i]); 185 assert child.getParent() == folderName; 186 newChildren.add(child); 187 } 188 } 189 } 190 191 Set deleted = new HashSet(getExisting(false)); 192 deleted.removeAll(newChildren); 193 for (Iterator itRem = deleted.iterator(); itRem.hasNext();) { 194 FileNaming fnRem = (FileNaming) itRem.next(); 195 removeChild(folderName, fnRem); 196 retval.put(fnRem, ChildrenCache.REMOVED_CHILD); 197 } 198 199 Set added = new HashSet(newChildren); 200 added.removeAll(getExisting(false)); 201 for (Iterator itAdd = added.iterator(); itAdd.hasNext();) { 202 FileNaming fnAdd = (FileNaming) itAdd.next(); 203 addChild(folderName, fnAdd); 204 retval.put(fnAdd, ChildrenCache.ADDED_CHILD); 205 } 206 207 return retval; 208 } 209 210 private FileNaming lookupChildInCache(final FileNaming folder, final String childName, boolean lookupExisting) { 211 final File f = new File (folder.getFile(), childName); 212 final Integer id = NamingFactory.createID(f); 213 214 class FakeNaming implements FileNaming { 215 public FileNaming lastEqual; 216 217 public String getName() { 218 return childName; 219 } 220 public FileNaming getParent() { 221 return folder; 222 } 223 public boolean isRoot() { 224 return false; 225 } 226 227 public File getFile() { 228 return f; 229 } 230 231 public Integer getId() { 232 return id; 233 } 234 public boolean rename(String name) { 235 throw new IllegalStateException (); 237 } 238 public boolean rename(String name, ProvidedExtensions.IOHandler h) { 239 throw new IllegalStateException (); 241 } 242 243 public boolean equals(Object obj) { 244 if (hashCode() == obj.hashCode()) { 245 assert lastEqual == null : "Just one can be there"; if (obj instanceof FileNaming) { 247 lastEqual = (FileNaming)obj; 248 } 249 return true; 250 } 251 return false; 252 } 253 254 public int hashCode() { 255 return id.intValue(); 256 } 257 258 public Integer getId(boolean recompute) { 259 return id; 260 261 } 262 263 public boolean isFile() { 264 return this.getFile().isFile(); 265 } 266 267 public boolean isDirectory() { 268 return !isFile(); 269 } 270 } 271 FakeNaming fake = new FakeNaming(); 272 273 final Set cache = (lookupExisting) ? getExisting(false) : getNotExisting(false); 274 if (cache.contains(fake)) { 275 assert fake.lastEqual != null : "If cache contains the object, we set lastEqual"; return fake.lastEqual; 277 } else { 278 return null; 279 } 280 } 281 282 private synchronized Set getExisting() { 283 return getExisting(true); 284 } 285 286 private synchronized Set getExisting(boolean init) { 287 if (init && existingChildren == null) { 288 existingChildren = new HashSet(); 289 } 290 return existingChildren != null ? existingChildren : new HashSet(); 291 } 292 293 private synchronized Set getNotExisting() { 294 return getNotExisting(true); 295 } 296 297 private synchronized Set getNotExisting(boolean init) { 298 if (init && notExistingChildren == null) { 299 notExistingChildren = new HashSet(); 300 } 301 return notExistingChildren != null ? notExistingChildren : new HashSet(); 302 } 303 } 304 | Popular Tags |