alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

What this is

This file is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Other links

The source code

/*
 *                 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-2004 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.core;

import java.util.*;
import java.beans.*;

import org.openide.ErrorManager;
import org.openide.cookies.InstanceCookie;
import org.openide.filesystems.*;
import org.openide.loaders.*;
import org.openide.util.RequestProcessor;
import org.openide.util.Task;
import org.openide.util.TaskListener;
import org.netbeans.core.projects.*;

/**
 * This class implements compile/runtime library path needed for the installed
 * modules to work well with the IDE. The folder watches for changes in the path
 * and mounts/unmounts FileSystems to/from repository.
 *
 * @author Jaroslav Tulach
 */
public class AutomountSupport extends FolderInstance 
implements RepositoryListener, Runnable {
    /** processor for working with automount */
    private static RequestProcessor RP = new RequestProcessor ("Automount"); // NOI18N
    
    /** thread variable to signal that we caused the update of filesystems */
    private static ThreadLocal VAR = new ThreadLocal ();

    /** A task to signal when processing has finished or began */
    private static DblTask defaultTask;

    /** store delay */
    private static final int DELAY = 1000;

    /** set of filesystems that were discovered by the folder recognizer and
     * added by it. The rest of filesystems that are not in the list is 
     * either added by Repository.addFileSystem by somebody else and thus 
     * is waiting for being flushed or was removed 
     */
    private static Set createdByMe = new org.openide.util.WeakSet ();
    
    /** set of filesystems that was recently added and should not be removed */
    private static Set sticky = new org.openide.util.WeakSet ();
//    private static Set sticky = new HashSet ();

    /** set of filesystems that was recently removed and should not be added */
    private static Set shineAway = new org.openide.util.WeakSet ();
//    private static Set shineAway = new HashSet ();

    /** cookies, which are known to throw errors */
    private static Set errCookies = new org.openide.util.WeakSet ();
    
    /** is the default instance */
    private boolean defaultInstance;
    
    /** New recognizer of the folder */
    private AutomountSupport(DataObject.Container fld, boolean defaultInstance) {
        super(fld);
        this.defaultInstance = defaultInstance;
    }
    
    /** Constructs an array of filesystems to 
     */
    protected Object createInstance(InstanceCookie[] cookies) 
    throws java.io.IOException, ClassNotFoundException {
        ArrayList arr = new ArrayList ();
        for (int i = 0; i < cookies.length; i++) {
            Object obj;
            try {
                obj = cookies[i].instanceCreate ();
            } catch (java.io.IOException ex) {
                if (errCookies.add(cookies[i])) {
                    ErrorManager.getDefault ().notify(ErrorManager.INFORMATIONAL, ex);
                }
                continue;
            }
            errCookies.remove(cookies[i]);
            if (obj instanceof FileSystem) {
                arr.add (obj);
                continue;
            }
            
            if (obj instanceof FileSystem[]) {
                arr.addAll (Arrays.asList ((FileSystem[])obj));
                continue;
            }
        }
        
        Object retValue;
        if (arr.size () == 1) {
            // return the filesystem
            retValue = arr.get (0);
        } else {
            // return array of filesystems
            retValue = arr.toArray (new FileSystem[0]);
        }
        

        if (defaultInstance) {
            // update for the topmost instance
            updateFileSystems (arr);
        }

        return retValue;
    }
    
    protected Object instanceForCookie (DataObject obj, InstanceCookie cookie)
    throws java.io.IOException, ClassNotFoundException {
        if (errCookies.contains(cookie)) {
            obj.delete();
            return null;
        }
        try {
            return super.instanceForCookie(obj, cookie);
        } catch (java.io.IOException ioe) {
            ErrorManager.getDefault ().notify(ErrorManager.INFORMATIONAL, ioe);
            
            obj.delete();
            return null;
        }
    }
    
    /** Accepts also folders - by creating the AutomountSupport for them.
     */
    protected InstanceCookie acceptContainer (DataObject.Container container) {
        return new AutomountSupport (container, false);
    }
        

    /**
     * Accepts only FileSystem instances.
     */
    protected InstanceCookie acceptCookie(InstanceCookie cookie) throws java.io.IOException, ClassNotFoundException {
        if (cookie instanceof InstanceCookie.Of) {
            InstanceCookie.Of of = (InstanceCookie.Of)cookie;
            if (of.instanceOf (FileSystem.class) || of.instanceOf (FileSystem[].class)) {
                return cookie;
            } else {
                return null;
            }
        }

        // else the regular check for filesystems from the instance
        Class c = cookie.instanceClass();
        if (c.isArray ()) {
            c = c.getComponentType ();
        }
        
	//System.err.println("AcceptCookie on " + c);
        if (FileSystem.class.isAssignableFrom(c))
            return cookie;
        else
            return null;
    }
    
    /** Processing of filesystems will be done in a separate thread.
     */
    protected Task postCreationTask (Runnable run) {
        return RP.post (run);
    }

    /** Returns a list of objects created in this instance.
     */
    private List getList () {
        Object fsOrFss = null;
        try {
            fsOrFss = instanceCreate ();
        } catch (java.io.IOException ex) {
            ErrorManager.getDefault ().notify (ex);
        } catch (ClassNotFoundException ex) {
            ErrorManager.getDefault ().notify (ex);
        }
        
        if (fsOrFss == null) {
            return Collections.EMPTY_LIST;
        }

        if (fsOrFss instanceof FileSystem) {
            return Collections.nCopies (1, fsOrFss);
        } else {
            return Arrays.asList ((FileSystem[])fsOrFss);
        }
    }

    /** Initialize the support.
     * @return the task one can use to wait for the process to finish
     */
    public static synchronized Task initialize () {
//        if (defaultInstance != null) {
//            return defaultInstance;
//        }
        if (defaultTask != null) {
            return defaultTask;
        }

        DataFolder folder = NbPlaces.getDefault().findSessionFolder ("Mount"); // NOI18N
        AutomountSupport auto = new AutomountSupport (folder, true);
        
        RequestProcessor.Task storeTask = RP.create (auto);
        // give the store task minimal priority to work as
        // less as possible
        storeTask.setPriority (Thread.MIN_PRIORITY);
 
        defaultTask = new DblTask (auto, storeTask);

        //
        // because the listener auto.fileSystemAdded and auto.fileSystemRemoved
        // delegates to defaultTask the task should be initilized before we
        // attach the listener to the repository
        //
        Repository rep = Repository.getDefault ();
        rep.addRepositoryListener (auto);

        synchronized (auto) {
            sticky.addAll (Arrays.asList (rep.toArray ()));
            if (sticky.size () > 1) {
                // there is more than just default filesystem => then check 
                // if everything is stored
                defaultTask.store ();
            }
        }
        
        //
        // the start of processing should be done at the end, when all tasks
        // are initialized (storeTask, defaultTask)
        // 
        auto.recreate ();


        return defaultTask;
    }
    
    /** Checks whether everything is saved.
     */
    public void run () {
        // and save 
        try { 
            FileSystem fs = Repository.getDefault ().getDefaultFileSystem();
            fs.runAtomicAction (new FileSystem.AtomicAction () {
                public void run () {
                    DataFolder df = NbPlaces.getDefault().findSessionFolder ("Mount"); // NOI18N
                    List list = getList ();

                    /* iterate all subfolders recursively and check whether everything is saved as it should be*/
                    Enumeration en = df.getPrimaryFile().getFolders(true);
                    while (en.hasMoreElements()) {
                        try {
                            DataFolder dfChild = (DataFolder)DataFolder.find((FileObject)en.nextElement());
                            checkSaved(list,dfChild, dfChild.getChildren(), false);
                        } catch (DataObjectNotFoundException e) {
                            continue;
                        }
                    }

                    /* and finally check mount folder */
                    checkSaved (list, df, df.getChildren (), true);
                }
            });
        } catch (java.io.IOException ex) {
            // cannot be thrown because it is not thrown from the inside code either
            throw new IllegalStateException ();
        }
           
    }

    /** FileSystem added. RepositoryListener.
     */
    public void fileSystemAdded (final RepositoryEvent ev) {
        defaultTask.fs (ev);
    }

    /** FileSystem removed. RepositoryListener.
     */
    public void fileSystemRemoved (final RepositoryEvent ev) {
        defaultTask.fs (ev);
    }

    /** FileSystem reorder. RepositoryListener.
     */
    public void fileSystemPoolReordered (RepositoryReorderedEvent ev) {
        if (VAR.get () == null) {
            if (isLog ()) {
                log ("Reorder in repository"); // NOI18N
                synchronized (Repository.getDefault ()) {
                    FileSystem[] arr = Repository.getDefault ().toArray ();
                    for (int i = 0; i < arr.length; i++) {
                        log ("   " + i + "th = " + arr[i]);
                    }
                }
            }
            defaultTask.store ();
        } else {
            log ("Repository reordered by AU"); // NOI18N
        }
    }
    
    /** Finds out whether a filesystem is contained in a repository.
     * @param fs filesystem 
     * @return true if so false otherwise
     */
    private static boolean containsFS (FileSystem fs) {
        FileSystem[] arr = Repository.getDefault ().toArray ();
        for (int i = 0; i < arr.length; i++) {
            if (arr[i] == fs) {
                return true;
            }
        }
        return false;
    }
    
    /** compute filename in the same manner as InstanceDataObject.create
     * [PENDING] in next version this should be replaced by public support
     * likely from FileUtil
     * @see issue #17186
     */
    private static String escape(String name) throws java.io.IOException {
        try {
            java.lang.reflect.Method escape = 
                InstanceDataObject.class.getDeclaredMethod(
                    "escapeAndCut", new Class[] {String.class}); //NOI18N
            escape.setAccessible(true);
            return (String) escape.invoke(null, new String[] {name});
        } catch (Exception ex) {
            throw (java.io.IOException) ErrorManager.getDefault().
                annotate(new java.io.IOException("Escape support failed"), ex); // NOI18N
        }
    }
    
    /**
     * Computes a new name of file for use in folder df. If the reguested file
     * already exists in the given folder try to append a number.
     * This method should be deleted after #21083 is implemented.
     */
    public static String computeNewName(String requiredName, DataFolder df) throws java.io.IOException {
        if ((requiredName == null) || (requiredName.length() == 0)) {
            return null;
        }
        
        boolean isUsed = true;
        String srcName = requiredName;
        int i = 1;
        while (isUsed) {
            isUsed = false;
            String escaped = escape(srcName);
            String uniqueName = FileUtil.findFreeFileName(
                df.getPrimaryFile(), escaped, "settings" // NOI18N
            );
            if (!escaped.equals(uniqueName)) {
                isUsed = true;
                srcName = requiredName + "_" + i;
                i++;
            }
        }
        return srcName;
    }

    /** Stores filesystems that are not stored now.
     * @param now list of FileSystems read from disk
     * @param arr array of dat objects in the Mount folder
     */
    private void checkSaved (List now, DataFolder df, DataObject[] arr, boolean isSaveEnabled) {
        Repository rep = Repository.getDefault ();
        synchronized (rep) {
            List asList = Arrays.asList (rep.toArray ());
            List exists = new ArrayList (asList);
            exists.removeAll(createdByMe);            
            exists.removeAll (now);
            
            ArrayList order = new ArrayList (asList.size () * 2);
            order.addAll (Arrays.asList (arr));

            sticky.removeAll(now);

            // remove all data objects in the main level, that should not be there
            HashSet doNotDeleteFileSystems = new HashSet (asList);
            // just work with those that are created by me
            doNotDeleteFileSystems.retainAll (createdByMe);

            // if the order is different we will need diff
            List onlyOrder = new ArrayList (asList);
            onlyOrder.retainAll (now);
            boolean diff = onlyOrder.size () == now.size () && !onlyOrder.equals (now);
            if (diff) {
                // improve the order of data objects
                class Cmp extends HashMap implements Comparator {
                    public int compare (Object o1, Object o2) {
                        return index (o1) - index (o2);
                    }
                    
                    private int index (Object o1) {
                        return ((Integer)get (o1)).intValue ();
                    }
                }
                
                Cmp cmp = new Cmp ();
                int i = onlyOrder.size ();
                Iterator it = order.iterator ();
                while (it.hasNext ()) {
                    DataObject obj = (DataObject)it.next ();
                    i++;
                    
                    InstanceCookie ic = (InstanceCookie)obj.getCookie (InstanceCookie.class);
                    if (ic != null) {
                        try {
                            Object o = ic.instanceCreate ();
                            int indx = onlyOrder.indexOf (o);
                            if (indx >= 0) {
                                cmp.put (obj, new Integer (indx));
                                continue;
                            }
                        } catch (ClassNotFoundException ex) {
                            ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, ex);
                        } catch (java.io.IOException ex) {
                            ErrorManager.getDefault ().notify (ErrorManager.INFORMATIONAL, ex);
                        }
                    }
                    cmp.put (obj, new Integer (i));
                }
                
                Collections.sort (order, cmp);
            }
            
            Iterator it = exists.iterator ();
            if (isSaveEnabled) {
                while (it.hasNext ()) {
                    FileSystem fs = (FileSystem)it.next ();
                    if (fs.isDefault ()) {
                        continue;
                    }
                    try {
                        InstanceDataObject dobj;
                        String name = computeNewName(fs.getDisplayName(), df);
                        try {
                            dobj = InstanceDataObject.create (df, name, fs, null);
                            createdByMe.add(fs);
                        } catch(java.io.NotSerializableException nse) {
                            // this can happen when filesystem fs refuses to store itself by
                            // returning null from writeReplace
                            continue;
                        }
                    
                        if (dobj.instanceCreate () != fs) {
                            StringBuffer sb = new StringBuffer (255);
                            sb.append ("This bug is caused by wrong implementation of InstanceDataObject, see "); // NOI18N
                            sb.append ("http://www.netbeans.org/issues/show_bug.cgi?id=14557"); // NOI18N
                            sb.append ("\nSTORING: "); // NOI18N
                            sb.append (fs);
                            sb.append ("\nINSTNCE: "); // NOI18N
                            sb.append (dobj.instanceCreate ()); // NOI18N

                            throw new IllegalStateException (sb.toString ());

                        }
                    
                        // if we wrote the FS to disk, we do not want to delete it
                        doNotDeleteFileSystems.add (fs);
                    
                        if (isLog ()) {
                            log (" written to disk: " + fs + " into: " + dobj); // NOI18N
                        }
                    
                        order.add (dobj);
                        sticky.remove (fs);
                    
                        diff = true;
                    } catch (java.io.IOException ex) {
                        ErrorManager.getDefault ().notify (ex);
                    } catch (ClassNotFoundException ex) {
                        ErrorManager.getDefault ().notify (ex);
                    }
                }
            }

            for (int i = 0; i < arr.length; i++) {
                InstanceCookie ic = (InstanceCookie)arr[i].getCookie (InstanceCookie.class);
                if (ic != null) {
                    try {
                        Object obj = ic.instanceCreate ();
                        if ((obj instanceof FileSystem) && !doNotDeleteFileSystems.contains (obj)) {
                            arr[i].delete ();
                            createdByMe.retainAll (Arrays.asList(rep.toArray ()));                            
                            if (isLog ()) {
                                log ("  deleted from disk: " + obj + " from: " + arr[i]); // NOI18N
                            }
                            order.remove (arr[i]);
                            diff = true;
                        }
                    } catch (ClassNotFoundException ex) {
                        ErrorManager.getDefault ().notify (ex);
                    } catch (java.io.IOException ex) {
                        ErrorManager.getDefault ().notify (ex);
                    }
                }
            }

            // update the order of filesystems
            if (diff) {
                try {
                    df.setOrder ((DataObject[])order.toArray (new DataObject[0]));
                    if (isFinished ()) {
                        log ("I should not be finished");
                        waitFinished ();
                        log ("And I am not no longer: " + isFinished ());
                    }
                    
                    if (isLog ()) {
                        log ("Changed order on the disk"); // NOI18N
                        Iterator x = order.iterator ();
                        int i = 0; 
                        while (x.hasNext ()) {
                            DataObject obj = (DataObject)x.next ();
                            InstanceCookie ic = (InstanceCookie)obj.getCookie (InstanceCookie.class);
                            if (ic != null) {
                                log ("  " + i++ + " is: " + ic.instanceCreate ()); // NOI18N
                            }
                        }
                    }
                } catch (java.io.IOException ex) {
                    ErrorManager.getDefault ().notify (ex);
                } catch (ClassNotFoundException ex) {
                    ErrorManager.getDefault ().notify (ex);
                }
            }
            
/*
            // add all filestems that are missing
            ArrayList list = new ArrayList (now);
            list.addAll (Arrays.asList (rep.toArray ()));
            updateFileSystems (list);
*/
        }
    }

    /*
     * Updates the filesystems.
     * @param current collection of FileSystem objects
     */
    private static void updateFileSystems (List future) {
        Repository rep = Repository.getDefault ();
        synchronized (rep) {
            List exists = Arrays.asList (rep.toArray ());

            // remove all existing without those future
            Collection toRemove = new LinkedList (exists);
            toRemove.removeAll (future);

            // also do not remove sticky filesystems
            toRemove.removeAll (sticky);
            
            log ("sticky: " + sticky);
            
            // just keep those filesystems that are created by me
            toRemove.retainAll (createdByMe);
            
//            log ("by me : " + createdByMe);

            if (isLog ()) {
                Iterator it = toRemove.iterator ();
                while (it.hasNext ()) {
                    FileSystem fs = (FileSystem)it.next ();
                    log ("  r: " + fs + " contains: " + sticky.contains (fs)); // NOI18N
                }
            }

            // add all future without those that exists
            Collection toAdd = new LinkedList (future);
            toAdd.removeAll (exists);
            
            // also do not add filesystems recently removed
            toAdd.removeAll (shineAway);
//            log ("shineAway: " + shineAway); // NOI18N

            if (isLog ()) {
                Iterator it = toAdd.iterator ();
                while (it.hasNext ()) {
                    FileSystem fs = (FileSystem)it.next ();
                    log ("  a: " + fs + " contains: " + sticky.contains (fs));  // NOI18N
                }
            }
            
            VAR.set (VAR);

            // remove & add changes
            cycleFileSystems (toRemove, false);
            cycleFileSystems (toAdd, true);
            // mount the new ones to the repository

            VAR.set (null);
            
            // now all that are recognized by me (future) can be also treated
            // as created by me
            
            createdByMe.addAll (future);
            
            // and as such no other filesystems are created by me any longer
            createdByMe.retainAll (Arrays.asList(rep.toArray ()));
            
            
            
            // update the order
            FileSystem[] arr = rep.toArray ();
            
            // in future keep only those that are in filesystems
            List future1 = new LinkedList (future);
            future1.retainAll (Arrays.asList (arr));
            
            int[] perm = new int[arr.length];
            int old = future1.size () + 1;

            
            boolean diff = false;
            for (int i = 0; i < arr.length; i++) {
                if (arr[i].isDefault ()) {
                    perm[i] = 0;
                    continue;
                }
                
                int indx = future1.indexOf (arr[i]);

                if (indx == -1) {
                    // filesystem added by somebody else
                    indx = old++;
                } else {
                    indx++;
                }

                perm[indx] = i;
                diff |= indx != i;
            }
            
            if (diff) {
                if (isLog ()) {
                    log ("Doing reorder"); // NOI18N
                    for (int i = 0; i < arr.length; i++) {
                        log ("  " + i + " <- " + perm[i] + " now: " + arr[i]);  // NOI18N
                    }
                
                    log ("On disk"); // NOI18N
                    Iterator x = future1.iterator ();
                    while (x.hasNext ()) {
                        log ("  " + x.next ()); // NOI18N
                    }
                    
                    log ("------"); // NOI18N
                }
                
                VAR.set (VAR);
                try {
                    rep.reorder (perm);
                } finally {
                    VAR.set (null);
                }
            } else {
                log ("No reoder"); // NOI18N
            }
/*            
            arr = rep.toArray ();
            if (future.size () != arr.length - 1) {
                log ("Not the same size: " + future.size () + " arr: " + arr.length);
            } else {
                for (int i = 0; i < arr.length - 1; i++) {
                    if (arr[i + 1] != future.get (i)) {
                        log ("  Help:" + i + " arr: " + arr[i + 1] + " current: " + future.get (i));
                    } else {
                        log ("  " + i + " arr: " + arr[i + 1]);
                    }
                }
            }
 */
        }
    }
    
    private static void cycleFileSystems (Collection fss, boolean add) {
        Repository repository = Repository.getDefault ();
        for (Iterator it = fss.iterator(); it.hasNext(); ) {
            FileSystem fs = (FileSystem)it.next();
            
            if (add) {
                // special handling for already mounted filesystems
                FileSystem old = repository.findFileSystem (fs.getSystemName ());
                if (old != null && old != fs && sticky.remove (old)) {
                    // if the sticky object was there (for example mounted before 
                    // the automount was initialized) => replace it with this one
                    repository.removeFileSystem (old);
                }
                    
                repository.addFileSystem(fs);
            } else {
                repository.removeFileSystem (fs);
            }
        }
    }
    
    /** error manager.
     */
    private static ErrorManager err;
    
    /** Checks whether we log.
     */
    private static boolean isLog () {
        if (err == null) {
            err = ErrorManager.getDefault ().getInstance ("org.netbeans.core.AutomountSupport"); // NOI18N
        }
        return err.isLoggable (ErrorManager.INFORMATIONAL);
    }
    
    /** Logs to error manager.
     */
    private static void log (String msg) {
        if (isLog ()) {
            err.log (msg);
        }
    }
    
    /** Double task. Delegates to two tasks.
     */
    private static final class DblTask extends Task 
    implements TaskListener {
        /** task that loads objects in */
        private Task defaultInstance;
        /** task that stores objects to disk */
        private RequestProcessor.Task storeTask;
        /** task that updates state of AutomountSupport from Repository */
        private Task updateTask = Task.EMPTY;
        /** true if store task has been called at least once */
        private boolean isStoring;
        
        
        public DblTask (Task defaultInstance, RequestProcessor.Task storeTask) {
            this.defaultInstance = defaultInstance;
            this.storeTask = storeTask;
            
            defaultInstance.addTaskListener (this);
            storeTask.addTaskListener (this);
        }
            
        /** Invokes the store task.
         */
        public void store () {
            synchronized (this) {
                storeTask.schedule (DELAY);
                isStoring = true;
            }
            notifyRunning ();
        }
        
        /** Test whether the task has finished running.
        * @return true if so
        */
        private synchronized boolean areBothFinished () {
            boolean t1 = !isStoring || storeTask.isFinished (); // either we are not storing at all or we finished storing
            if (!t1) return false;
            
            boolean t2 = defaultInstance.isFinished ();
            if (!t2) return false;
            
            boolean t3 = updateTask.isFinished (); 
            
            return t3;
        }

        /** Wait until the task is finished. 
        * Changed not to be final in version 1.5
        */
        public void waitFinished () {
            log ("Entered waitFinished");
            for (int i = 0; i < 2; i++) {
                do {
                    updateTask.waitFinished ();
                    defaultInstance.waitFinished ();

                    // get the value of isStoring that could be modified 
                    // by different thread in synchronized block
                    boolean storing;
                    synchronized (this) {
                        storing = isStoring;
                    }

                    if (storing) {
                        storeTask.waitFinished ();
                        // do the check once more, as this usually triggers
                        // the FolderInstance creation
                        continue;
                    }
                } while (!areBothFinished ());
            }
            log ("Leaving waitFinished");
        }
            
        /** Task finished.
         */
        public void taskFinished (Task t) {
            if (areBothFinished ()) {
                notifyFinished ();
            }
        }
        
        /** Processes a filesystem that was added or removed.
         */
        public synchronized void fs (RepositoryEvent ev) {
            boolean isNull = VAR.get () == null;
            if (!isNull) {
                // ok, no need to continue
                log ("fs: " + ev.getFileSystem () + " added: " + ev.isAdded () + " by AU support"); // NOI18N
                return;
            }
            
            class Run implements Runnable {
                public RepositoryEvent ev;
                
                public Run (RepositoryEvent ev) {
                    this.ev = ev;
                }
                
                public void run () {
                    Repository rep = Repository.getDefault ();
                    synchronized (rep) {
                        FileSystem fs = ev.getFileSystem ();
                        boolean c = containsFS (fs);
                        boolean added = ev.isAdded ();

                        log ("fs: " + fs + " added: " + added + " contains: " + c); // NOI18N
                        
                        if (added) {
                            if (c) {
                                sticky.add (fs);
                                shineAway.remove (fs);
                                defaultTask.store ();
                            }
                        } else {
                            if (!c) {
                                sticky.remove (fs);
                                shineAway.add (fs);
                                defaultTask.store ();
                            }
                        }
                    }
                    // removes the listener
                    removeTaskListener (DblTask.this);
                    ev = null;
                }
                
            }
            
            Task task = RP.post(new Run (ev));
            
            task.addTaskListener (DblTask.this);
            updateTask = task;
        }
    }
}
... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.