1 19 20 package org.openide.filesystems; 21 22 import java.io.IOException ; 23 import java.util.ArrayList ; 24 import java.util.Arrays ; 25 import java.util.Collection ; 26 import java.util.Collections ; 27 import java.util.Enumeration ; 28 import java.util.HashSet ; 29 import java.util.Iterator ; 30 import java.util.List ; 31 import java.util.Set ; 32 import java.util.StringTokenizer ; 33 import org.openide.util.Enumerations; 34 import org.openide.util.NbCollections; 35 import org.openide.util.actions.SystemAction; 36 37 92 public class MultiFileSystem extends FileSystem { 93 static final long serialVersionUID = -767493828111559560L; 94 95 96 static final String MASK = "_hidden"; 98 99 private static final int WRITE_SYSTEM_INDEX = 0; 100 101 104 private FileSystem[] systems; 105 106 107 private boolean propagateMasks = false; 108 109 110 private transient MultiFileObject root; 111 112 115 protected MultiFileSystem() { 116 this(new FileSystem[1]); 117 } 118 119 122 public MultiFileSystem(FileSystem[] fileSystems) { 123 this.systems = fileSystems.clone(); 124 } 125 126 129 public void refresh(boolean expected) { 130 Enumeration <AbstractFolder> en = getMultiRoot().existingSubFiles(true); 131 132 while (en.hasMoreElements()) { 133 FileObject fo = en.nextElement(); 134 fo.refresh(expected); 135 } 136 } 137 138 142 protected final void setDelegates(FileSystem[] fileSystems) { 143 FileSystem[] oldSystems = systems; 145 146 this.systems = fileSystems; 148 149 getMultiRoot().updateAllAfterSetDelegates(oldSystems); 150 151 List <FileSystem> oldList = Arrays.asList(oldSystems); 152 List <FileSystem> newList = Arrays.asList(systems); 153 154 Set <FileSystem> toRemove = new HashSet <FileSystem>(oldList); 156 toRemove.removeAll(newList); 157 158 for (Iterator iter = toRemove.iterator(); iter.hasNext();) { 159 FileSystem fs = ((FileSystem) iter.next()); 160 161 if (fs != null) { 162 fs.removeNotify(); 163 } 164 } 165 166 Set <FileSystem> toAdd = new HashSet <FileSystem>(newList); 168 toAdd.removeAll(oldList); 169 170 for (Iterator iter = toAdd.iterator(); iter.hasNext();) { 171 FileSystem fs = ((FileSystem) iter.next()); 172 173 if (fs != null) { 174 fs.addNotify(); 175 } 176 } 177 } 178 179 182 protected final FileSystem[] getDelegates() { 183 return systems; 184 } 185 186 189 public final boolean getPropagateMasks() { 190 return propagateMasks; 191 } 192 193 196 protected final void setPropagateMasks(boolean pm) { 197 propagateMasks = pm; 198 } 199 200 202 public boolean isReadOnly() { 203 return (systems[WRITE_SYSTEM_INDEX] == null) || systems[WRITE_SYSTEM_INDEX].isReadOnly(); 204 } 205 206 208 public String getDisplayName() { 209 return getString("CTL_MultiFileSystem"); 210 } 211 212 214 public FileObject getRoot() { 215 return getMultiRoot(); 216 } 217 218 220 private MultiFileObject getMultiRoot() { 221 synchronized (MultiFileSystem.class) { 222 if (root == null) { 223 root = new MultiFileObject(this); 224 } 225 226 return root; 227 } 228 } 229 230 232 public SystemAction[] getActions() { 233 List <SystemAction> al = new ArrayList <SystemAction>(101); Set <SystemAction> uniq = new HashSet <SystemAction>(101); 236 FileSystem[] del = this.getDelegates(); 237 238 for (int i = 0; i < del.length; i++) { 239 if (del[i] == null) { 240 continue; 241 } 242 243 SystemAction[] acts = del[i].getActions(); 244 245 for (int j = 0; j < acts.length; j++) { 246 if (uniq.add(acts[j])) { 247 al.add(acts[j]); 248 } 249 } 250 } 251 252 return al.toArray(new SystemAction[al.size()]); 253 } 254 255 public SystemAction[] getActions(final Set <FileObject> foSet) { 256 List <SystemAction> al = new ArrayList <SystemAction>(101); Set <SystemAction> uniq = new HashSet <SystemAction>(101); 259 final FileSystem[] del = this.getDelegates(); 260 261 for (int i = 0; i < del.length; i++) { 262 if (del[i] == null) { 263 continue; 264 } 265 266 final SystemAction[] acts = del[i].getActions(foSet); 267 268 for (int j = 0; j < acts.length; j++) { 269 if (uniq.add(acts[j])) { 270 al.add(acts[j]); 271 } 272 } 273 } 274 275 return al.toArray(new SystemAction[al.size()]); 276 } 277 278 @Deprecated public FileObject find(String aPackage, String name, String ext) { 280 Enumeration <String > st = NbCollections.checkedEnumerationByFilter(new StringTokenizer (aPackage, "."), String .class, true); Enumeration <String > en; 283 284 if ((name == null) || (ext == null)) { 285 en = st; 286 } else { 287 en = Enumerations.concat(st, Enumerations.singleton(name + '.' + ext)); 288 } 289 290 return getMultiRoot().find(en); 292 } 293 294 304 public FileObject findResource(String name) { 305 if (name.length() == 0) { 306 return getMultiRoot(); 307 } else { 308 Enumeration <String > tok = NbCollections.checkedEnumerationByFilter(new StringTokenizer (name, "/"), String .class, true); return getMultiRoot().find(tok); 310 } 311 } 312 313 317 325 protected final FileSystem findSystem(FileObject fo) 326 throws IllegalArgumentException { 327 try { 328 if (fo instanceof MultiFileObject) { 329 MultiFileObject mfo = (MultiFileObject) fo; 330 331 return mfo.getLeaderFileSystem(); 332 } 333 } catch (FileStateInvalidException ex) { 334 return this; 337 } 338 339 throw new IllegalArgumentException (fo.getPath()); 340 } 341 342 349 protected final void hideResource(String res, boolean hide) 350 throws IOException { 351 if (hide) { 352 maskFile(createWritableOn(res), res); 354 } else { 355 unmaskFile(createWritableOn(res), res); 356 } 357 } 358 359 367 protected static Enumeration <String > hiddenFiles(FileObject folder, boolean rec) { 368 Enumeration <? extends FileObject> allFiles = folder.getChildren(rec); 369 370 class OnlyHidden implements Enumerations.Processor<FileObject, String > { 371 public String process(FileObject obj, Collection <FileObject> ignore) { 372 String sf = obj.getPath(); 373 374 if (sf.endsWith(MASK)) { 375 return sf.substring(0, sf.length() - MASK.length()); 376 } else { 377 return null; 378 } 379 } 380 } 381 382 return Enumerations.filter(allFiles, new OnlyHidden()); 383 } 384 385 389 398 protected FileObject findResourceOn(FileSystem fs, String res) { 399 return fs.findResource(res); 400 } 401 402 408 protected FileSystem createWritableOn(String name) 409 throws IOException { 410 if ((systems[WRITE_SYSTEM_INDEX] == null) || systems[WRITE_SYSTEM_INDEX].isReadOnly()) { 411 FSException.io("EXC_FSisRO", getDisplayName()); } 413 414 return systems[WRITE_SYSTEM_INDEX]; 415 } 416 417 425 protected FileSystem createWritableOnForRename(String oldName, String newName) 426 throws IOException { 427 return createWritableOn(newName); 428 } 429 430 441 protected Set createLocksOn(String name) throws IOException { 442 FileSystem writable = createWritableOn(name); 443 444 return Collections.singleton(writable); 445 } 446 447 456 protected void notifyMigration(FileObject fo) { 457 } 458 459 464 protected void markUnimportant(FileObject fo) { 465 } 466 467 471 @Deprecated 472 public void prepareEnvironment(FileSystem.Environment env) 473 throws EnvironmentNotSupportedException { 474 FileSystem[] layers = getDelegates(); 475 476 for (int i = 0; i < layers.length; i++) { 477 if (layers[i] != null) { 478 try { 479 layers[i].prepareEnvironment(env); 480 } catch (EnvironmentNotSupportedException ense) { 481 } 483 } 484 } 485 } 486 487 489 public void addNotify() { 490 super.addNotify(); 491 492 for (int i = 0; i < systems.length; i++) { 493 if (systems[i] != null) { 494 systems[i].addNotify(); 495 } 496 } 497 } 498 499 501 public void removeNotify() { 502 super.removeNotify(); 503 504 for (int i = 0; i < systems.length; i++) { 505 if (systems[i] != null) { 506 systems[i].removeNotify(); 507 } 508 } 509 } 510 511 515 521 private static String [] split(String res, String [] store) { 522 if (store == null) { 523 store = new String [3]; 524 } 525 526 int file = res.lastIndexOf('/'); 527 int dot = res.lastIndexOf('.'); 528 529 if (file == -1) { 530 store[0] = ""; } else { 532 store[0] = res.substring(0, file); 533 } 534 535 file++; 536 537 if (dot == -1) { 538 store[1] = res.substring(file); 539 store[2] = ""; } else { 541 store[1] = res.substring(file, dot); 542 store[2] = res.substring(dot + 1); 543 } 544 545 return store; 546 } 547 548 554 Enumeration <FileObject> delegates(final String name) { 555 Enumeration <FileSystem> en = Enumerations.array(systems); 556 557 class Resources implements Enumerations.Processor<FileSystem, FileObject> { 558 public FileObject process(FileSystem fs, Collection <FileSystem> ignore) { 559 if (fs == null) { 560 return null; 561 } else { 562 return findResourceOn(fs, name); 563 } 564 } 565 } 566 567 return Enumerations.filter(en, new Resources()); 568 } 569 570 575 void maskFile(FileSystem fs, String res) throws IOException { 576 FileObject where = findResourceOn(fs, fs.getRoot().getPath()); 577 FileUtil.createData(where, res + MASK); 578 } 579 580 585 void unmaskFile(FileSystem fs, String res) throws IOException { 586 FileObject fo = findResourceOn(fs, res + MASK); 587 588 if (fo != null) { 589 FileLock lock = fo.lock(); 590 591 try { 592 fo.delete(lock); 593 } finally { 594 lock.releaseLock(); 595 } 596 } 597 } 598 599 605 void unmaskFileOnAll(FileSystem fs, String res) throws IOException { 606 FileSystem[] fss = this.getDelegates(); 607 608 for (int i = 0; i < fss.length; i++) { 609 if ((fss[i] == null) || fss[i].isReadOnly()) { 610 continue; 611 } 612 613 unmaskFile(fss[i], res); 614 615 616 if (fss[i] == fs) { 617 return; 618 } 619 } 620 } 621 622 static boolean isMaskFile(FileObject fo) { 623 return fo.getExt().endsWith(MASK); 624 } 625 } 626 | Popular Tags |