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

package org.netbeans.modules.masterfs;

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

import javax.swing.filechooser.FileSystemView;
import java.beans.PropertyVetoException;
import java.io.File;
import java.io.IOException;
import java.util.*;

/**
 * Provides special delegates, that are virtual: delegates for windows drives,
 * root for Windows and also root for Unix.
 *
 * @author Radek Matous
 */
final class SpecialDelegates {
    private static boolean isUnixRootResolved = false;
    private static FileSystem fs = new WinSpecialFs();
    private static final FileSystemView fsv = FileSystemView.getFileSystemView();

    private SpecialDelegates() {
    }

    /**
     * This method should be called only when resource resPath can't be found
     * in filesystems,that are placed in mount table (MoutTable). Then if this method
     * returns null, then delegate doesn't exists and MasterFileObject for
     * this delegate shouldn't be provided.
     *
     * Mounts LocalFileSystem for root on unix or for windows drive, if not mounted yet
     *
     * @param resPath requested resource name
     * @return returns delegates for windows drives, roots or null
     */
    static FileObject get(final ResourcePath resPath) {
        FileObject retVal;
        if (Utilities.isWindows())
            retVal = getForWindows(resPath);
        else if (Utilities.getOperatingSystem() == Utilities.OS_VMS)
            retVal = getForVMS(resPath);
        else {
            retVal = getForUnix(resPath);
        }
        // here retVal may be null - not all resources must exist
        return retVal;
    }

    /**
     * Mounts LocalFileSystem for root on unix, if not mounted yet.
     * @param resPath requested resource name
     * @return returns delegates for windows drives, roots or null
     */
    private static FileObject getForUnix(final ResourcePath resPath) {
        FileObject retVal = null;
        if (!isUnixRootResolved) {
            mountUnixRoot();
            retVal = MountTable.getDefault().resolveBestDelegate(resPath.getNormalizedPath());
            isUnixRootResolved = true;
        }
        return retVal;
    }

    /**
     * Mounts LocalFileSystem for root on VMS, if not mounted yet.
     * @param resPath requested resource name
     * @return returns delegates for windows drives, roots or null
     */
    private static FileObject getForVMS(final ResourcePath resPath) {
        FileObject retVal = null;
        mountVMSRoot(resPath);
        retVal = MountTable.getDefault().resolveBestDelegate(resPath.getNormalizedPath());
        return retVal;
    }

    private static FileObject getForWindows(final ResourcePath resPath) {
        FileObject retVal = null;
        if (resPath.isRoot())
            retVal = WinRootVirtual.getDefault();
        else if (isWinDrive(resPath))
            retVal = WindowsDriveProxy.getDefault(resPath);
        else {
            WindowsDriveProxy winDrive = WindowsDriveProxy.getDefault(resPath);
            if (winDrive != null && !winDrive.isMounted()) {
                winDrive.lfs = mountWinDrive(winDrive.getResource());
                // try again after mount
                retVal = MountTable.getDefault().resolveBestDelegate(resPath.getNormalizedPath());
            }
        }
        return retVal;
    }

    // use only if Utilities.isWindows returns true
    private static boolean isWinDrive(final ResourcePath resPath) {
        boolean root = resPath.getParent().isRoot();
        if (root) {
           root = (checkValidWindowsDrive (resPath.getFile()) != null); 
        }
        return root;
    }

    private static LocalFileSystem mountWinDrive(final ResourcePath mountPointPath) {
        LocalFileSystem retVal = null;
        final String rootPath = mountPointPath.getNormalizedPath().substring(1) + "/";
        final File root = checkValidWindowsDrive(new File(rootPath));
        if (root != null) {
            retVal = mountLocalFileSystem(root, rootPath);
        }
        return retVal;
    }

    private static void mountUnixRoot() {
        final String rootPath = ResourcePath.getRoot().getNormalizedPath();
        final File root = new File(rootPath);
        if (root.exists())
            mountLocalFileSystem(root, rootPath);
    }
    
    /** mount the local root directory for OpenVMS platform
     * @param mountPointPath root directory to mount
     */
    private static void mountVMSRoot(final ResourcePath mountPointPath) {
        //On OpenVMS platform, root is not allowed, so instead supply
        //a mount point.
        //
        final String rootPath = mountPointPath.getNormalizedPath();
        final File root = new File(rootPath);
        if (root.exists())
            mountLocalFileSystem(root, rootPath);
        
    }

    private static LocalFileSystem mountLocalFileSystem(final File root, final String rootPath) {
        LocalFileSystem retVal;
        //retVal = new LocalFileSystem();
        try {
            //retVal.setRootDirectory(root);
            retVal = ExLocalFileSystem.getInstance(root);            
            MountTable.getDefault().mount(rootPath, retVal);
        } catch (PropertyVetoException e) {
            retVal = null;
        } catch (IOException e) {
            retVal = null;
        }
        return retVal;
    }

    static File checkValidWindowsDrive(final File root) {
        File retVal = null;
        if (fsv != null) {
            /** filters floppy drives*/
            retVal = (fsv.isFileSystemRoot(root) && !fsv.isFloppyDrive(root)) ? root : null;
            
            /** filters empty CDROM drives*/            
            if (retVal != null && !retVal.exists()) {
                retVal = null;  
            }
        } else {
            for (int i = 0; i < listRoots().length; i++) {
                File windowsDrive = listRoots()[i];
                if (windowsDrive.equals(root)) {
                    retVal = root;
                    break;
                }
            }
        }

        return retVal;
    }

    private static File[] listRoots() {
        File[] all = File.listRoots();
        
        if (Utilities.isWindows() && fsv != null) {
            Set roots = new LinkedHashSet();
            
            for (int i = 0; i < all.length; i++) {
                File file = checkValidWindowsDrive(all[i]);
                if (file != null) {
                    roots.add(file);
                }            
            }        
            all = new File[roots.size()];
            roots.toArray(all);
        }
        return all;
    }

    /**
     *
     */
    private static class WinRootVirtual extends InvalidDummy {
        /** generated Serialized Version UID */
        static final long serialVersionUID = -1244651321879256809L;
        transient private static WinRootVirtual instance = null;
        transient private static ArrayList delegs = null;
        //transient private File root;
        transient private Set listenerList;

        private static WinRootVirtual getDefault() {
            synchronized (WinRootVirtual.class) {
                if (instance == null)
                    instance = new WinRootVirtual(new ResourcePath(""));
            }
            return instance;
        }

        private WinRootVirtual(final ResourcePath resPath) {
            super(resPath);
        }

        public void addFileChangeListener(FileChangeListener fcl) {
            getListenerList().add(fcl);
        }

        public void removeFileChangeListener(FileChangeListener fcl) {
            getListenerList().remove(fcl);
        }

        public FileSystem getFileSystem() throws FileStateInvalidException {
            return fs;
        }

        public boolean isRoot() {
            return true;
        }

        public boolean isFolder() {
            return true;
        }

        public boolean isData() {
            return false;
        }

        public void refresh(final boolean expected) {
            List oldFos = Arrays.asList(getChildren());
            delegs = null;
            List newFos = Arrays.asList(getChildren());
            Set removeSet = new HashSet(oldFos);
            Set addSet = new HashSet(newFos);

            removeSet.removeAll(newFos);
            addSet.removeAll(oldFos);


            for (Iterator iterator = removeSet.iterator(); iterator.hasNext();) {
                FileObject fo = (FileObject) iterator.next();
                FileEvent fe = new FileEvent(this, fo);
                //TODO: here should be fired also from deleted file: fo.fireFileDel..
                fireFileDeletedEvent(Collections.enumeration(getListenerList()), fe);
            }

            for (Iterator iterator = addSet.iterator(); iterator.hasNext();) {
                FileObject fo = (FileObject) iterator.next();

                FileEvent fe = new FileEvent(this, fo);
                if (fo.isFolder())
                    fireFileFolderCreatedEvent(Collections.enumeration(getListenerList()), fe);
                else
                    fireFileDataCreatedEvent(Collections.enumeration(getListenerList()), fe);
            }
        }

        public FileObject[] getChildren() {
            synchronized (WinRootVirtual.class) {
                if (delegs == null) {
                    List roots = Arrays.asList(listRoots());
                    delegs = new ArrayList();
                    for (int i = 0; i < roots.size(); i++) {
                        File root = (File) roots.get(i);
                        ResourcePath resName = getResource().getChild(root.getAbsolutePath());
                        WindowsDriveProxy winDrive = WindowsDriveProxy.getDefault(resName);
                        if (winDrive != null) {
                            delegs.add(winDrive); // getOrCreateRoot
                        }
                    }
                }
            }

            FileObject[] retVal = new FileObject[delegs.size()];
            delegs.toArray(retVal);
            return retVal;
        }

        public boolean isValid() {
            return true;
        }

        public FileObject getFileObject(String name, String ext) {
            FileObject retVal = null;
            FileObject[] chlds = getChildren();
            for (int i = 0; i < chlds.length; i++) {
                FileObject chld = chlds[i];
                if (chld.getName().equals(name) && chld.getExt().equals(ext)) {
                    retVal = chld;
                    break;
                }
            }
            return retVal;
        }

        Set getListenerList() {
            synchronized (WindowsDriveProxy.class) {
                if (listenerList == null) {
                    listenerList = Collections.synchronizedSet(new HashSet());
                }
            }
            return listenerList;
        }
    }

    /**
     *
     */
    private static final class WindowsDriveProxy extends WinRootVirtual {
        /** generated Serialized Version UID */
        static final long serialVersionUID = -1244651321879256718L;
        transient private FileObject delegate;
        transient private boolean isValid = true;

        transient private static final Map instances = new WeakHashMap();
        transient private LocalFileSystem lfs;


        private static WindowsDriveProxy getDefault(ResourcePath resPath) {
            WindowsDriveProxy in;
            String winDrivePath = getWindowsDriveSubstr(resPath.getNormalizedPath());
            if (winDrivePath == null) return null;

            resPath = new ResourcePath(winDrivePath);
            synchronized (WindowsDriveProxy.class) {
                in = (WindowsDriveProxy) instances.get(resPath);
                if (in == null) {
                    in = new WindowsDriveProxy(resPath);
                    instances.put(in.getResource(), in);
                }
            }
            return in;
        }


        private static String getWindowsDriveSubstr(String resPath) {
            int idx = resPath.indexOf(':');
            return (idx == -1) ? null : resPath.substring(0, idx + 1);
        }


        private WindowsDriveProxy(ResourcePath resPath) {
            super(resPath);
        }

        public boolean isRoot() {
            return false;
        }

        public boolean isFolder() {
            return true;
        }

        public boolean isData() {
            return false;
        }

        public boolean isValid() {
            return isValid;
        }

        public FileObject[] getChildren() {
            FileObject deleg = getDelegate(true);
            return (deleg != null) ? deleg.getChildren() : new FileObject [] {};
        }

        public FileObject getFileObject(String name, String ext) {
            FileObject deleg = getDelegate(true);
            return (deleg != null) ? deleg.getFileObject(name, ext) : null;
        }

        public FileObject getParent() {
            return WinRootVirtual.getDefault();
        }

        private FileObject getDelegate() {
            return getDelegate(false);
        }

        private FileObject getDelegate(boolean create) {
            if (delegate == null && create /*&& !isMounted()*/) {

                delegate = new InvalidDummy(getResource());
                lfs = mountWinDrive(getResource());
                delegate = MountTable.getDefault().resolveBestDelegate(getResource().getNormalizedPath());
                if (delegate != null) {
                    synchronized (getListenerList()) {
                        Iterator it = getListenerList().iterator();
                        while (it.hasNext()) {
                            FileChangeListener fcl = (FileChangeListener) it.next();
                            delegate.addFileChangeListener(fcl);
                            it.remove();

                        }
                    }
                } else {
                    isValid = false;
                }
            }
            return delegate;
        }

        public FileSystem getFileSystem() throws FileStateInvalidException {
            return (lfs != null) ? lfs : fs;
        }


        public FileObject createFolder(String name) throws IOException {
            return (getDelegate() != null) ? getDelegate().createFolder(name) :
                    super.createFolder(name);
        }

        public FileObject createData(String name, String ext) throws IOException {
            return (getDelegate() != null) ? getDelegate().createData(name) :
                    super.createData(name);
        }


        public Object getAttribute(String attrName) {
            return (getDelegate() != null) ? getDelegate().getAttribute(attrName) :
                    super.getAttribute(attrName);
        }

        public void setAttribute(String attrName, Object value) throws IOException {
            if (getDelegate() != null)
                getDelegate().setAttribute(attrName, value);
            else
                super.setAttribute(attrName, value);
        }

        public Enumeration getAttributes() {
            return (getDelegate() != null) ? getDelegate().getAttributes() :
                    super.getAttributes();
        }

        public void addFileChangeListener(FileChangeListener fcl) {
            if (getDelegate() != null)
                getDelegate().addFileChangeListener(fcl);
            else
                super.addFileChangeListener(fcl);
        }

        public void removeFileChangeListener(FileChangeListener fcl) {
            if (getDelegate() != null)
                getDelegate().removeFileChangeListener(fcl);
            else
                super.removeFileChangeListener(fcl);
        }

        private boolean isMounted() {
            return lfs != null;
        }
    }

    private static final class WinSpecialFs extends FileSystem {
        public boolean isReadOnly() {
            return false;
        }

        public FileObject getRoot() {
            return WinRootVirtual.getDefault();
        }

        public FileObject findResource(String name) {
            ResourcePath resPath = new ResourcePath(name);
            if (resPath.isRoot()) return getRoot();
            return WindowsDriveProxy.getDefault(resPath);
        }

        public SystemAction[] getActions() {
            return new SystemAction[]{
                (SystemAction) SharedClassObject.findObject(WinRootRefreshAction.class, true)};
        }
        
        public SystemAction[] getActions(java.util.Set foSet) {
            Iterator it = foSet.iterator();
            while (it.hasNext()) {
                Object o = it.next();
                if (o instanceof WindowsDriveProxy) return new SystemAction[]{};
            }
            return getActions();
        }

        public String getDisplayName() {
            return null;
        }
    }

    static class  WinRootRefreshAction extends CallableSystemAction {
        public WinRootRefreshAction () {super ();}
            
        public void performAction() {
            MasterFileSystem.getDefault().getRoot().refresh();
        }

        public HelpCtx getHelpCtx() {
            return new HelpCtx("org.openide.actions.FileSystemRefreshAction");//NOI18N
        }

        public String getName() {
            return NbBundle.getMessage(MasterFileSystem.class, "LAB_Refresh");//NOI18N
        }
    };
    
}
... 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.