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.modules.masterfs;

import org.openide.filesystems.*;
import org.openide.util.NbBundle;
import org.openide.util.actions.SystemAction;
import org.openide.util.Utilities;

import javax.swing.*;
import java.awt.*;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.Serializable;
import java.util.*;

/**
 * Implementation of FileSystem, that allows to host filesystems, that can be mounted
 * and unmounted.
 *
 * @author  Radek Matous
 */
final public class MasterFileSystem extends FileSystem implements FileStatusListener {
    /** generated Serialized Version UID */
    private static final long serialVersionUID = -97134851800761145L;
    //transient ArrayList rootChilds;
    transient private static MasterFileSystem instance;
    transient private final StatusImpl status = new StatusImpl();

    static MasterFileSystem getDefault() {
        boolean init = false;
        synchronized (MasterFileSystem.class) {
            if (instance == null)  {
                instance = new MasterFileSystem();
                init = true;                
            }
            
        }
        if (init) {
            ProviderCall.init();
        }
        return instance;
    }
    
    public static MasterFileSystem settingsFactory(FileObject inst) {
        return getDefault();
    }

    private MasterFileSystem() {
        init();
    }

    private Object writeReplace () {
        return new Replace ();
    }

    private void init() {
        try {
            setSystemName(getClass().getName()); //NOI18N
        } catch (PropertyVetoException pvx) {
            ///nobody can`t have registered VetoableChangeListener, so no exception
            // can`t be fired
        }
        registerFileStatusListener();
    }

    private void registerFileStatusListener() {
        Enumeration en = MountTable.getDefault().geAllFileSystems();
        while (en.hasMoreElements()) {
            FileSystem fs = (FileSystem) en.nextElement();
            fs.addNotify();
            fs.addFileStatusListener(this);
        }
    }

    public String getDisplayName() {
        return NbBundle.getMessage(MasterFileSystem.class, "LBL_this_computer");
    }

    // XXX should be a MasterFileSystemBeanInfo that hides this property (hidden=true)!
    public boolean isReadOnly() {
        return false;
    }

    public FileObject getRoot() {
        return Cache.getDefault().getOrCreate(ResourcePath.getRoot());
    }
    
    public FileObject findResource(String name) {
        ResourcePath resPath = new ResourcePath (name);
        FileObject retVal = Cache.getDefault().get(resPath);
        if (Utilities.getOperatingSystem() == Utilities.OS_VMS) {
            if (retVal == null) retVal = getStepByStepVMS(resPath);
        } else {
            if (retVal == null) retVal = getStepByStep(resPath);
        }
        return retVal;
    }

    /**
     * May look strange. BUT: Every call of getFileObject tries to mount
     * filesystem, that may be requested to provide delegates.
     */
    private FileObject getStepByStep(ResourcePath resPath) {
        FileObject retVal = getRoot();
        Enumeration elems = resPath.getElements();
        while (elems.hasMoreElements()) {
            String nameExt = (String)elems.nextElement();
            retVal = retVal.getFileObject(nameExt);
           if (retVal == null) return null;
        }
        return retVal;
    }

    /** Returns the root for OpenVMS platform given the path
     * @param name the path to search root from
     * @return the root
     */
    private static String findVMSRoot(String name) {
         if (name.length() > 0) {
             StringTokenizer stok = new StringTokenizer(name, "/");
             String rootName = "";
             while (stok.hasMoreTokens()) {
                 rootName += "/" + stok.nextToken();
                 if (new File(rootName).exists()) {
                    return rootName;
                 }
             }
         } 
         return null;
    }
    
    /** Returns the root for OpenVMS platform. The root is in the form
     *  of "/".
     *  @param name name of the file specification to extract the root from
     *  @return the FileObject instance representing the root directory
     */
     private static FileObject getRootForVMS(String name) {
         return Cache.getDefault().getOrCreate(new ResourcePath(name));   
    }
    
    /**
     * May look strange. BUT: Every call of getFileObject tries to mount
     * filesystem, that may be requested to provide delegates.
     */
    private static FileObject getStepByStepVMS(ResourcePath resPath) {
        //On OpenVMS platform, the root is not "/"
        //
        String root = findVMSRoot(resPath.getNormalizedPath());
        if (root == null)
            return null;
        
        FileObject retVal = getRootForVMS(root);
        //Get the part of the path that begins after the root
        //
        ResourcePath subPath = new ResourcePath(
            resPath.getNormalizedPath().substring(root.length()));
        Enumeration elems = subPath.getElements();
       
        while (elems.hasMoreElements()) {
            String nameExt = (String)elems.nextElement();
            //"000000" needs to be filtered out on OpenVMS platform
            //
            if (nameExt.equals("000000"))
                continue;
            retVal = retVal.getFileObject(nameExt);
            if (retVal == null) return null;
        }
        return retVal;
    }

    
    public void addNotify() {
    }

    public void removeNotify() {
        Cache.getDefault().clear();
    }


    public void refresh(boolean expected) {
        Enumeration en = MountTable.getDefault().geAllFileSystems();
        SyncSection.getDefault().enterSection();
        try {
            while (en.hasMoreElements()) {
                FileSystem fs = (FileSystem) en.nextElement();
                fs.refresh(expected);
            }
        } finally {
            SyncSection.getDefault().finishSection();
        }
    }


    public SystemAction[] getActions() {
        return getEmptyActions();
    }

    private SystemAction[] getEmptyActions() {
        return new SystemAction[]{};
    }

    public SystemAction[] getActions(java.util.Set foSet) {
        SyncSection.getDefault().enterSection();
        try {
            //check if all fileobjects come from the same filesystem
            MasterFileObject hfo = getUniqueMasterFileObject(foSet);
            if (hfo == null) return getEmptyActions();

            FileSystem firstFs = getDelegateFileSystem(hfo.getDelegate().get());
            FileSystem secondFs = getDelegateFileSystem(hfo.getDelegate().getPrefered());
            if (firstFs == null) return getEmptyActions();

            if (secondFs != firstFs ) {
                return mergeActionsFromBothDelegates(foSet, firstFs, secondFs);
            }

            return firstFs.getActions(Utils.transformToDelegates(foSet, false));
        } finally {
            SyncSection.getDefault().finishSection();
        }
    }

    private static FileSystem getDelegateFileSystem(FileObject foDel) {
        if (foDel == null) return null;
        FileSystem fsDel = null;
        try {
            fsDel = foDel.getFileSystem();
        } catch (FileStateInvalidException e) {
            return null;
        }
        return fsDel;
    }

    private static MasterFileObject getUniqueMasterFileObject(Set hfoSet) {
        MasterFileObject retVal = null;
        FileSystem lastFs = null;
        for (Iterator it = hfoSet.iterator(); it.hasNext();) {
            Object o = it.next();
            if (!(o instanceof MasterFileObject)) return null;

            retVal = (MasterFileObject) o;
            FileObject deleg = retVal.getDelegate().get();
            if (deleg == null) continue;
            FileSystem fs = getDelegateFileSystem(deleg);
            if (fs == null) continue;

            if (lastFs != null && lastFs != fs) return null;
            lastFs = fs;
        }
        return retVal;
    }

    private SystemAction[] mergeActionsFromBothDelegates(Set hfoSet, FileSystem firstFs, FileSystem secondFs) {
        Set mergedActions = new HashSet(hfoSet.size());

        Set firstSet = Utils.transformToDelegates(hfoSet, false);
        SystemAction[] firstActions = firstFs.getActions(firstSet);
        mergedActions.addAll(Arrays.asList(firstActions));

        Set secondSet = Utils.transformToDelegates(hfoSet, true);
        SystemAction[] secondActions = secondFs.getActions(secondSet);
        mergedActions.addAll(Arrays.asList(secondActions));

        return (SystemAction[]) mergedActions.toArray(new SystemAction[mergedActions.size()]);
    }


    /** Notifies listener about change in annotataion of a few files.
     * @param ev event describing the change
     */
    public void annotationChanged(final FileStatusEvent ev) {
        /** Ugly piece of code, that relies on impl. of FileStatusEvent and its
         * usage of Set of FileObjects. Adopted from TreeFS.
         */
        HashSet set = new HashSet(1) {
            public boolean contains(Object o) {
                if (o instanceof MasterFileObject) {
                    MasterFileObject fo = (MasterFileObject) o;
                    FileObject deleg = fo.getDelegate().get();
                    return deleg != null && ev.hasChanged(deleg);
                }
                return false;
            }
        };


        fireFileStatusChanged(new FileStatusEvent(
                this, set, ev.isIconChange(), ev.isNameChange()
        ));
    }


    public FileSystem.Status getStatus() {
        return status;
    }

    final void fireFileStatus (FileStatusEvent event) {
        fireFileStatusChanged(event);
    }

    
    private static final class StatusImpl implements FileSystem.HtmlStatus {
        public Image annotateIcon(Image icon, int iconType, Set files) {
            //int size = files.size();
            Set transformedSet = new HashSet();
            Image retVal = null;

            MasterFileObject hfo = Utils.transformSet(files, transformedSet);
            if (hfo != null) {
                FileSystem fs = hfo.getDelegateFileSystem();
                retVal = (fs != null) ? fs.getStatus().annotateIcon(icon, iconType, transformedSet) : icon;

                if (/*size == 1 && */fs != null && hfo.getDelegate().get() == fs.getRoot()) {
                    retVal = Utils.getRootIcon(iconType, fs);
                } else {
                    if (hfo.getDelegate().hasMountAbleFlag()) {
                        retVal = ProviderCall.getIcon(hfo.getPath(), iconType);
                    }

                }
            }
            return (retVal != null) ? retVal : icon;
        }

        public String annotateName(String name, Set files) {
            Set transformedSet = new HashSet();
            MasterFileObject hfo = Utils.transformSet(files, transformedSet);
            if (hfo != null) {
                FileSystem fs = hfo.getDelegateFileSystem();
                name = (fs != null) ? fs.getStatus().annotateName(name, transformedSet) : name;
            }
            return name;
        }

        public String annotateNameHtml(String name, Set files) {
            Set transformedSet = new HashSet();
            MasterFileObject hfo = Utils.transformSet(files, transformedSet);
            if (hfo != null) {
                FileSystem fs = hfo.getDelegateFileSystem();
                if (fs != null && fs.getStatus() instanceof FileSystem.HtmlStatus) {
                    return ((FileSystem.HtmlStatus) fs.getStatus()).annotateNameHtml(name, transformedSet);
                }
            }
            return null;
        }
    }
    
    private static final class Replace implements Serializable {
        static final long serialVersionUID = 50485340814380L;
        
        public Object readResolve () {
            return MasterFileSystem.getDefault();
        }
    } // end of Replace
}
... 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.