/* * Sun Public License Notice * * The contents of this file are subject to the Sun Public License * Version 1.0 (the "License"). You may not use this file except in * compliance with the License. A copy of the License is available at * http://www.sun.com/ * * The Original Code is NetBeans. The Initial Developer of the Original * Code is Sun Microsystems, Inc. Portions Copyright 1997-2000 Sun * Microsystems, Inc. All Rights Reserved. */ package org.openide.filesystems; import java.beans.*; import java.io.*; import java.lang.ref.*; import java.util.Enumeration; import org.openide.util.RequestProcessor; /** Request for parsing of an filesystem. Can be stoped. * * @author Jaroslav Tulach */ final class RefreshRequest extends Object implements Runnable { /** how much folders refresh at one request */ private static final int REFRESH_COUNT = 30; private static RequestProcessor REFRESHER = new RequestProcessor ("FS refresher"); // NOI18N /** fs to work on */ private Reference system; /** enumeration of folders Reference (FileObjects) to process */ private Enumeration en; /** how often invoke itself */ private int refreshTime; /** task to call us */ private RequestProcessor.Task task; /** Constructor * @param fs file system to refresh * @param ms refresh time */ public RefreshRequest (AbstractFileSystem fs, int ms) { system = new WeakReference (fs); refreshTime = ms; task = REFRESHER.post (this, ms, Thread.MIN_PRIORITY); } /** Getter for the time. */ public int getRefreshTime () { return refreshTime; } /** Stops the task. */ public synchronized void stop () { refreshTime = 0; if (task == null) { // null task means that the request processor is running => // wait for end of task execution try { wait (); } catch (InterruptedException ex) { } } } /** Refreshes the system. */ public void run () { // this code is executed only in RequestProcessor thread int ms; RequestProcessor.Task t; synchronized (this) { // the synchronization is here to be sure // that ms = refreshTime; if (ms <= 0) { // finish silently if already stopped return; } t = task; } try { // by setting task to null we indicate that we are currently processing // files and that any stop should wait till the processing is over task = null; doLoop (ms); } finally { synchronized (this) { // reseting task variable back to indicate that // the processing is over task = t; notifyAll (); } // plan the task for next execution if (system != null && system.get () != null) t.schedule (ms); else refreshTime = 0; } } private void doLoop (int ms) { AbstractFileSystem system = (AbstractFileSystem)this.system.get (); if (system == null) { // end for ever the fs does not exist no more return; } if (en == null || !en.hasMoreElements ()) { // start again from root en = existingFolders (system); } for (int i = 0; i < REFRESH_COUNT && en.hasMoreElements (); i++) { AbstractFolder fo = (AbstractFolder)en.nextElement (); if (fo != null && (!fo.isFolder() || fo.isInitialized ())) { fo.refresh (); } if (refreshTime <= 0) { // after each refresh check the current value of refreshTime // again and if it goes to zero exit as fast a you can return; } } // clear the queue if (!en.hasMoreElements ()) { en = null; } } /** Existing folders for abstract file objects. */ private static Enumeration existingFolders (AbstractFileSystem fs) { return fs.existingFileObjects (fs.getAbstractRoot()); } /** * Overriden for debugging/logging purposes. */ public String toString() { AbstractFileSystem fs = (AbstractFileSystem)system.get(); return "RefreshRequest for " + // NOI18N (fs == null ? "gone FS" : fs.getSystemName()); // NOI18N } }