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 java.io.File;

import org.openide.ErrorManager;
import org.openide.filesystems.*;
import org.openide.util.Utilities;

import javax.swing.event.EventListenerList;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * Implements FileObject, hosts delegate and mostly uses it whenever possible.
 *
 * @author  Radek Matous
 */
final class MasterFileObject extends BasedOnResourcePath {
    /** generated Serialized Version UID */
    static final long serialVersionUID = -1244651324997356809L;
    transient private final Delegate delegate;
    /** listeners - registered to listen on this FileObject*/
    transient private EventListenerList listeners;

    private static final FileSystem.AtomicAction referenceAction = new MasterFileObject.AtomicAction (null);        
    

    /** Don`t call this constructor directly, use rather getOrCreate*/
    MasterFileObject(ResourcePath resourceName, FileObject deleg) {
        super(resourceName);
        delegate = new Delegate(deleg, new FileChangeListenerImpl(), this);
    }

    /**
     * Implements abstract FileObject.lastModified()
     */
    public java.util.Date lastModified() {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        return deleg.lastModified();
    }

    /**
     * Implements abstract FileObject.isValid()
     */
    public boolean isValid() {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        File f = getResource().getFile();                
        return (f != null) ?  deleg.isValid() && f.exists() : deleg.isValid();
    }

    /**
     * Implements abstract FileObject.getAttribute(String attrName)
     */
    public Object getAttribute(String attrName) {
        if (attrName.equals("FileSystem.rootPath")) {
            return "";//NOI18N
        }
        
        if (attrName.equals("java.io.File")) {
            File file = getResource().getFile();
            if (file != null && file.exists()) {
                return file;
            }
        }
        
        
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        Object attribute = deleg.getAttribute(attrName);
        if (attribute == null) {
            FileObject secDeleg = getDelegate().get();
            if (secDeleg != null && secDeleg.isValid() && secDeleg.isRoot()) {
                attribute = secDeleg.getAttribute(attrName);                
            }
        }
        return attribute;
    }

    /**
     * Implements abstract FileObject.setAttribute(String attrName, Object value)
     */
    public void setAttribute(final String attrName, final Object value) throws IOException {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        deleg.setAttribute(attrName, value);
    }

    /**
     * Implements abstract FileObject.getAttributes()
     */
    public Enumeration getAttributes() {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        return deleg.getAttributes();
    }

    /**
     * Implements abstract FileObject.getSize()
     */
    public long getSize() {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        return deleg.getSize();
    }

    /**
     * Implements abstract FileObject.getInputStream()
     */
    public InputStream getInputStream() throws java.io.FileNotFoundException {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        return deleg.getInputStream();
    }

    /**
     * Implements abstract FileObject.getOutputStream(FileLock lock)
     */
    public OutputStream getOutputStream(FileLock lock) throws java.io.IOException {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        FileLock lck = (deleg.isValid()) ? Delegate.getLockForDelegate(lock, deleg) : null;

        return deleg.getOutputStream(lck);
    }

    /**
     * Implements abstract FileObject.lock()
     */
    public FileLock lock() throws IOException {
        return getDelegate().lock();
    }

    /**
     * Implements abstract FileObject.setImportant(boolean b)
     */
    public void setImportant(final boolean b) {
        FileObject deleg = getValidOrInvalid(getDelegate().get());
        deleg.setImportant(b);
    }


    /**
     * Implements abstract FileObject.isReadOnly()
     */
    public boolean isReadOnly() {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        return deleg.isReadOnly();
    }

    /**
     * Implements FileObject.getMIMEType()
     */
    public String getMIMEType() {
        FileObject deleg = getValidOrInvalid(getDelegate().get());
        return deleg.getMIMEType();
    }

    /**
     * Implements FileObject.existsExt(String extI)
     */
    public boolean existsExt(String ext) {
        FileObject deleg = getValidOrInvalid(getDelegate().getPrefered());
        return deleg.existsExt(ext);
    }

    /**
     * Implements abstract FileObject.isData()
     */
    public boolean isData() {
        return (!isFolder());
    }

    /**
     * Implements abstract FileObject.isFolder()
     */
    public boolean isFolder() {
        if (getDelegate().hasMountAbleFlag()) return true;

        FileObject deleg = getValidOrInvalid(getDelegate().get(true));
        return deleg.isFolder();
    }

    /**
     * Implements FileObject.isVirtual()
     */
    public boolean isVirtual() {
        FileObject deleg = getValidOrInvalid(getDelegate().get());
        return deleg.isVirtual();
    }

    /**
     * Implements abstract FileObject.addFileChangeListener(FileChangeListener fcl)
     */
    public void addFileChangeListener(final FileChangeListener fcl) {
        synchronized (this) {
            if (listeners == null) {
                listeners = new EventListenerList();
            }
            listeners.add(FileChangeListener.class, fcl);
        }
    }

    /**
     * Implements abstract FileObject.removeFileChangeListener(FileChangeListener fcl)
     */
    public void removeFileChangeListener(FileChangeListener fcl) {
        synchronized (this) {
            if (listeners != null) {
                listeners.remove(FileChangeListener.class, fcl);
            }
        }
    }

    /**
     * Implements abstract FileObject.transformChildren()
     */
    public FileObject[] getChildren() {
        //TODO: tryAutoMount() causes #42772: Deadlock in masterfs
        //tryAutoMount();
        enterCriticalSection();
        try {
            FileObject deleg = getValidOrInvalid(getDelegate().get());
            return transformChildren(deleg.getChildren());
        } finally {
            finishCriticalSection();
        }
    }

    /**
     * Implements abstract FileObject.getFileObject(String nameI, String extI)
     */
    public FileObject getFileObject(String name, String ext) {
        //TODO: tryAutoMount() causes #42772: Deadlock in masterfs
        //tryAutoMount();
        enterCriticalSection();
        try {
            ResourcePath parentResource = getResource();
            ResourcePath childResourcePath = parentResource.getChild(name, ext);
            MasterFileObject retVal = null;
            /*since rev. 1.31 added following condition cause
            #47885: MasterFS impl of FileObject.getFileObject() should be tighten up
            */
            if (childResourcePath != null && parentResource.equals(childResourcePath.getParent())) {
                retVal = getCache().getOrCreate(childResourcePath);
                if (retVal == null) {
                    File f = childResourcePath.getFile();
                    boolean canRefresh = true;
                    if (Utilities.isWindows() && childResourcePath.getParent().isRoot()) {
                        canRefresh = (SpecialDelegates.checkValidWindowsDrive(f) != null); 
                    }
                    if (canRefresh) {
                        if (f != null && f.exists()) {
                            this.refresh();
                            retVal = getCache().getOrCreate(childResourcePath);
                            //assert retVal != null : childResourcePath.toString(); 
                        }
                    }
                }
            }
            return retVal;
        } finally {
            finishCriticalSection();
        }
    }

    /**
     * Implements FileObject.transformChildren(boolean rec)
     */
    public Enumeration getChildren(boolean rec) {
        Enumeration my = org.openide.util.Enumerations.array (this.getChildren());
        
        if (rec == false)
            return my;

        return org.openide.util.Enumerations.queue (
            my, getChildsEnum ()
        );
    }

    /**
     * Implements FileObject.getFolders(boolean rec)
     */
    public Enumeration getFolders(boolean rec) {
        return org.openide.util.Enumerations.filter (
            getChildren (rec), new AcceptFolders (true)
        );
    }

    /**
     * Implements FileObject.getData(boolean rec)
     */
    public Enumeration getData(boolean rec) {
        return org.openide.util.Enumerations.filter (
            getChildren (rec), new AcceptFolders (false)
        );
    }

    /** Selector from folders and data files.
     */
    private final class AcceptFolders implements org.openide.util.Enumerations.Processor {
        private boolean folders;
        
        public AcceptFolders (boolean folders) {
            this.folders = folders;
        }
        
        public Object process (Object o, Collection nothing) {
            final FileObject fo = (FileObject) o;
            if (folders) {
                return fo.isFolder() ? fo : null;
            } else {
                return fo.isData() ? fo : null;
            }
        }
    } // end of AcceptFolders

    /**
     * Implements abstract FileObject.getFileSystem()
     */

    public FileSystem getFileSystem() throws FileStateInvalidException {
        return MasterFileSystem.getDefault();
    }

    /**
     * Implements abstract FileObject.createFolder(String nameI)
     */
    public FileObject createFolder(final String name) throws IOException {
        return new AtomicAction(this).createFolder(name);
    }

    /**
     * Implements FileObject.createData(String nameI)
     */
    public FileObject createData(final String name) throws IOException {
        return new AtomicAction(this).createData(name);
    }

    /**
     * Implements abstract FileObject.createData(String nameI, String extI)
     */
    public FileObject createData(final String name, final String ext) throws IOException {
        return new AtomicAction(this).createData(name, ext);
    }

    /**
     * Implements abstract FileObject.copy (FileObject target, String nameI, String extI)
     */
    public FileObject copy(FileObject target, String name, String ext) throws IOException {
        // overwritten only because of included in sync. section
        return new AtomicAction(this).copy(target, name, ext);
    }

    /**
     * Implements abstract FileObject.delete(FileLock lock)
     */
    public void delete(FileLock lock) throws IOException {
        if (getDelegate().hasMountAbleFlag() || 
                MountTable.getDefault().getMountedFileSystem(this.getResource().getNormalizedPath()) != null) {
            FileObject deleg = getDelegate().get();
            if (deleg != null && deleg.isRoot())
                MountTable.getDefault().unmount(getDelegateFileSystem());
        }
        new AtomicAction(this).delete(lock);
    }

    /**
     * Implements abstract FileObject.move (FileLock lock, FileObject target, String nameI, String extI)
     */
    public FileObject move(FileLock lock, FileObject target, String name, String ext) throws IOException {
        // overwritten only because of included in sync. section
        enterExclusiveCriticalSection();
        try {
            return new AtomicAction(this).move(lock, target, name, ext);
        } finally {
            finishExclusiveCriticalSection();
        }
    }

    private FileObject superMove(FileLock lock, FileObject target, String name, String ext) throws IOException {
        return super.move(lock, target, name, ext);
    }

    /**
     * Implements FileObject.refresh(boolean expected)
     */
    public void refresh(final boolean expected) {
        try {
            if (expected)
                new AtomicAction(this).refreshExpected();
            else
                new AtomicAction(this).refresh();
        } catch (IOException e) {
            // shouldn't occure
            ErrorManager.getDefault().notify(e);
        }
    }

    /**
     * Implements abstract FileObject.getParent()
     */
    public FileObject getParent() {
        FileObject retVal = null;
        ResourcePath parentRes = getResource().getParent();
        if (parentRes != null) {
            parentRes = (parentRes.getParent() == null) ? ResourcePath.getRoot() : parentRes;
            retVal = Cache.getDefault().getOrCreate(parentRes);
            if (retVal == null) {
                retVal = Cache.getDefault().getValidOrInvalid(parentRes);
            }
        }
        return retVal;
    }

    /**
     * Implements abstract FileObject.rename()
     *
     * Note: uses fs.unmount uses exclusiveSection, then this method rename should not
     * be called from synchronized section inside MasterFileObject.
     */
    public void rename(FileLock lock, String name, String ext) throws IOException {
        //TODO: rename is wrong implemeted
        enterCriticalSection();
        try {
            FileObject deleg = getValidOrInvalid(getDelegate().get());
            if (isReadOnly()) {
                Utils.throwIOException("EXC_CannotRename",
                        new Object[]{getPath(), getHFs().getDisplayName()});
            }

            ResourcePath oldResName = getResource();
            //TODO: should'nt be renamed before deleg.rename, which can fail
            //TODO: write new test, if also children were renamed
            setResource(oldResName.getParent().getChild(name, ext));
            Cache.getDefault().replace(oldResName.getNormalizedPath(), this);
            if (isRoot() || !deleg.isRoot()) {
                try {
                    //TODO: here is fired exception sometimes
                    FileLock lck = Delegate.getLockForDelegate(lock, deleg);
                    deleg.rename(lck, name, ext);
                    MountTable.getDefault().renameCachedFileObjects(oldResName.getNormalizedPath(), getResource().getNormalizedPath());
                    return;
                } catch (IOException iex) {
                    setResource(oldResName);
                    throw iex;
                }
            }
            // ugly, time consuming piece of code:
            // fs must be unmounted, renamed and mounted again
            // Can`t be implemented before SPI will be introduced
            // because there is no uniform manner how to create filesystems:
            // something like createFileSystem (java.io.File)
            //deleg = Delegate.getPrefered(this);
            throw new IOException("Not implemented yet");
        } finally {
            finishCriticalSection();
        }
    }

    public final Object writeReplace() {
        return new Replace(getPath());
    }

    Delegate getDelegate() {
        return delegate;
    }

    private static MasterFileSystem getHFs() {
        return MasterFileSystem.getDefault();
    }

    private static Cache getCache() {
        return Cache.getDefault();
    }

    private MasterFileObject[] transformChildren(FileObject[] delegs) {
        final ArrayList aList = new ArrayList(delegs.length);
        for (int i = 0; i < delegs.length; i++) {
            FileObject hfo = transformChild(delegs[i]);
            if (hfo != null)
                aList.add(hfo);
        }
        MasterFileObject[] retVal = new MasterFileObject[aList.size()];
        aList.toArray(retVal);
        return retVal;
    }

    private FileObject transformChild(final FileObject deleg) {
        FileObject hfo;
        if (deleg instanceof InvalidDummy) {
            InvalidDummy res = (InvalidDummy) deleg;
            hfo = getCache().getOrCreate(res.getResource());
        } else {
            ResourcePath res = getResource().getChild(deleg.getNameExt());
            if (MountTable.getDefault().getMountedFileSystem(res.getNormalizedPath()) != null)
                hfo = getCache().getOrCreate(res, null);
            else 
                hfo = getCache().getOrCreate(res, deleg);
        }
        return hfo;
    }

    private void tryAutoMount() {
        SyncSection.getDefault().enterExclusiveSection();
        try {
            FileObject deleg = getDelegate().get();
            if (getDelegate().hasMountAbleFlag() && deleg != null && !deleg.isRoot()) {
                FileSystem fs = ProviderCall.createFileSystem(getPath());
                if (fs != null) {
                    try {
                        MountTable.getDefault().mount(getPath(), fs);
                    } catch (IOException iex) {
                        ErrorManager.getDefault().notify(iex);
                    }
                }
            }
        } finally {
            SyncSection.getDefault().finishExclusiveSection();
        }

    }

    /** Transforms fe.getFile to it`s wraper*/
    private MasterFileObject eventFileToMasterFileObject(FileEvent fe) {
        FileObject file = fe.getFile();
        if (file != null) {
            FileObject dFile = null;
            ResourcePath child = getResource().getChild(file.getNameExt());
            
            dFile = getCache().get(child);
            dFile = (dFile != null) ? dFile : getCache().getOrCreate(child);
            dFile = (dFile != null) ? dFile : getCache().getValidOrInvalid(child);            
            dFile = (dFile != null) ? dFile : this;
            return (MasterFileObject) dFile;
        }
        return this;
    }


    private org.openide.util.Enumerations.Processor getChildsEnum() {
        return new org.openide.util.Enumerations.Processor  () {
            public Object process(final Object o, Collection toAdd) {
                final FileObject fo = (FileObject) o;
                if (fo != null)
                    toAdd.addAll (Arrays.asList (fo.getChildren()));
                return fo;
            }
        };
    }


    private Enumeration getEnumOfListeners() {
        Object[] fcls;
        synchronized (this) {
            if (listeners == null) {
                return org.openide.util.Enumerations.empty();
            }
            fcls = listeners.getListenerList();
        }

        if (fcls == null || fcls.length == 0) {
            return org.openide.util.Enumerations.empty();
        }

        class OnlyListeners implements org.openide.util.Enumerations.Processor {
            public Object process(final Object o, Collection toAdd) {
                if (o instanceof FileChangeListener) {
                    return o;
                }
                return null;
            }
        }
        
        return org.openide.util.Enumerations.filter (
            org.openide.util.Enumerations.array (fcls), new OnlyListeners ()
        );
    }

    FileSystem getDelegateFileSystem() {
        FileObject deleg = getDelegate().get();
        try {
            return (deleg != null) ? deleg.getFileSystem() : null;
        } catch (FileStateInvalidException fsx) {
            ErrorManager.getDefault().notify(ErrorManager.INFORMATIONAL, fsx);
        }
        return null;
    }

    static void refreshAfterMount(FileObject newDelegate, FileObject oldDelegate, MasterFileObject hfo) {
        ResourcePath parentRes = hfo.getResource().getParent();
        MasterFileObject parent = (parentRes != null) ? getCache().get(parentRes) : null;

        // basically refresh on file
        if (newDelegate != null) {
            // added children
            if (newDelegate.isFolder()) {
                // compare old children and new children
                Set oldChildren = new HashSet(Arrays.asList(oldDelegate.getChildren()));
                Set newChildren = new HashSet(Arrays.asList(newDelegate.getChildren()));
                retainOnlyDifferent(oldChildren, newChildren);
                handleCreated(newChildren, hfo);
            }
            // changed

/*
            if (oldDelegate.isFolder() == newDelegate.isFolder()) {
                handleChanged(hfo, parent);
            }
*/
        } else {
            // deleted
            handleDeleted(hfo, parent);
        }
    }

    private static void handleDeleted(MasterFileObject hfo, MasterFileObject parent) {
        hfo.fireFileDeletedEvent(hfo.getEnumOfListeners(), new FileEvent(hfo));
        if (parent != null)
            parent.fireFileDeletedEvent(parent.getEnumOfListeners(), new FileEvent(parent, hfo));
    }

    private static void handleChanged(MasterFileObject hfo, MasterFileObject parent) {
        hfo.fireFileChangedEvent(hfo.getEnumOfListeners(), new FileEvent(hfo));
        if (parent != null)
            parent.fireFileChangedEvent(parent.getEnumOfListeners(), new FileEvent(parent, hfo));
    }

    private static void handleCreated(Set newChildren, MasterFileObject hfo) {
        Iterator addIt = newChildren.iterator();
        while (addIt.hasNext()) {
            FileObject addDeleg = (FileObject) addIt.next();
            ResourcePath name = hfo.getResource().getChild(addDeleg.getNameExt());
            MasterFileObject addHfo = getCache().get(name);
            boolean resetDelg = false;
            if (addHfo == null) {
                addHfo = getCache().getOrCreate(name, addDeleg);
                resetDelg = true;
            }
            if (addHfo.isFolder())
                hfo.fireFileFolderCreatedEvent(hfo.getEnumOfListeners(), new FileEvent(hfo, addHfo));
            else
                hfo.fireFileDataCreatedEvent(hfo.getEnumOfListeners(), new FileEvent(hfo, addHfo));

            if (resetDelg)
                addHfo.getDelegate ().reset(addHfo.getResource());
        }
    }

    private static void retainOnlyDifferent(Set oldChildren, Set newChildren) {
        Iterator oldIt = oldChildren.iterator();
        Iterator newIt = newChildren.iterator();
        while (oldIt.hasNext()) {
            if (!newIt.hasNext()) break;
            FileObject oldFo = (FileObject) oldIt.next();
            while (newIt.hasNext()) {
                FileObject newFo = (FileObject) newIt.next();
                if (newFo.getNameExt().equals(oldFo.getNameExt())) {
                    newIt.remove();
                    oldIt.remove();
                    break;
                }
            }
            newIt = newChildren.iterator();
        }
    }

    private FileObject getValidOrInvalid(FileObject deleg) {
        return getValidOrInvalid(deleg, this);
    }

    private static FileObject getValidOrInvalid(FileObject deleg, final MasterFileObject hfo) {
        if (deleg == null) deleg = new InvalidDummy(hfo.getResource());
        return deleg;
    }

    private void finishCriticalSection() {
        SyncSection.getDefault().finishSection();
    }

    private void enterCriticalSection() {
        SyncSection.getDefault().enterSection();
    }

    private void finishExclusiveCriticalSection() {
        SyncSection.getDefault().finishExclusiveSection();
    }

    private void enterExclusiveCriticalSection() {
        SyncSection.getDefault().enterExclusiveSection();
    }

    public static final class Replace extends Object implements java.io.Serializable {
        /** generated Serialized Version UID */
        static final long serialVersionUID = -8552332135435542113L;
        private final String path;

        /** Constructor
         */
        public Replace(final String path) {
            this.path = path;
        }

        /** Finds the right file.
         */
        public Object readResolve() {
            FileSystem fs = MasterFileSystem.getDefault();
            FileObject retVal = fs == null ? null : fs.findResource(path);
            return retVal;
        }

    } // end of Replace

    private final class FileChangeListenerImpl implements FileChangeListener {
        /**
         * Implements FileChangeListener.fileDataCreated(FileEvent fe)
         */
        public void fileDataCreated(FileEvent fe) {
            if (fe.isExpected() && fe.firedFrom(referenceAction)) return;
            MasterFileObject eventFile = eventFileToMasterFileObject(fe);            
            FileEvent fe2Fire = new FileEvent(MasterFileObject.this, eventFile, fe.isExpected());
            FileObject eventFileDelegate = eventFile.getDelegate().get();
            FileObject meDelegate = MasterFileObject.this.getDelegate().get();
            
            if (eventFileDelegate == fe.getFile() && meDelegate == fe.getSource()) {                        
                fireFileDataCreatedEvent(getEnumOfListeners(), fe2Fire);
            }
        }

        /**
         * Implements FileChangeListener.fileFolderCreated(FileEvent fe)
         */
        public void fileFolderCreated(FileEvent fe) {
            if (fe.isExpected() && fe.firedFrom(referenceAction)) return;
            MasterFileObject eventFile = eventFileToMasterFileObject(fe);
            FileEvent fe2Fire = new FileEvent(MasterFileObject.this, eventFile, fe.isExpected());
            FileObject eventFileDelegate = eventFile.getDelegate().get();
            FileObject meDelegate = MasterFileObject.this.getDelegate().get();
            
            if (eventFileDelegate == fe.getFile() && meDelegate == fe.getSource()) {                        
                fireFileFolderCreatedEvent(getEnumOfListeners(), fe2Fire);
            }
        }

        /**
         * Implements FileChangeListener.fileDeleted(FileEvent fe)
         */
        public void fileDeleted(FileEvent fe) {
            if (fe.isExpected() && fe.firedFrom(referenceAction)) return;
            MasterFileObject eventFile = eventFileToMasterFileObject(fe);                        
            FileEvent fe2Fire = new FileEvent(MasterFileObject.this, eventFile, fe.isExpected());
            FileObject eventFileDelegate = eventFile.getDelegate().get();
            FileObject meDelegate = MasterFileObject.this.getDelegate().get();
            
            if (eventFileDelegate == fe.getFile() && meDelegate == fe.getSource()) {                        
                fireFileDeletedEvent(getEnumOfListeners(), fe2Fire);
            }
        }

        /**
         * Implements FileChangeListener.fileChanged(FileEvent fe)
         */
        public void fileChanged(FileEvent fe) {
            if (fe.isExpected() && fe.firedFrom(referenceAction)) return;
            MasterFileObject eventFile = eventFileToMasterFileObject(fe);                        
            FileEvent fe2Fire = new FileEvent(MasterFileObject.this, eventFile, fe.isExpected());
            FileObject eventFileDelegate = eventFile.getDelegate().get();
            FileObject meDelegate = MasterFileObject.this.getDelegate().get();
            
            if (eventFileDelegate == fe.getFile() && meDelegate == fe.getSource()) {                        
                fireFileChangedEvent(getEnumOfListeners(), fe2Fire);
            }
        }

        /**
         * Implements FileChangeListener.fileRenamed(FileRenameEvent fe)
         */
        public void fileRenamed(FileRenameEvent fe) {
            if (fe.isExpected() && fe.firedFrom(referenceAction)) return;
            String name = fe.getName();
            String ext = fe.getExt();

            MasterFileObject eventFile = eventFileToMasterFileObject(fe);                        
            FileRenameEvent fe2Fire = new FileRenameEvent(MasterFileObject.this, eventFile, name, ext);
            FileObject eventFileDelegate = eventFile.getDelegate().get();
            FileObject meDelegate = MasterFileObject.this.getDelegate().get();
            
            if (eventFileDelegate == fe.getFile() && meDelegate == fe.getSource()) {                        
                fireFileRenamedEvent(getEnumOfListeners(), fe2Fire);
            }
        }

        /**
         * Implements FileChangeListener.fileAttributeChanged(FileAttributeEvent fe)
         */
        public void fileAttributeChanged(FileAttributeEvent fe) {
            if (fe.isExpected() && fe.firedFrom(referenceAction)) return;
            
            MasterFileObject eventFile = eventFileToMasterFileObject(fe);                        
            FileAttributeEvent fe2Fire = new FileAttributeEvent(MasterFileObject.this, eventFile,
                    fe.getName(), fe.getOldValue(), fe.getNewValue());
            FileObject eventFileDelegate = eventFile.getDelegate().get();
            FileObject meDelegate = MasterFileObject.this.getDelegate().get();
            
            if (eventFileDelegate == fe.getFile() && meDelegate == fe.getSource()) {                        
                fireFileAttributeChangedEvent(getEnumOfListeners(), fe2Fire);
            }
        }
    }

    private static final class AtomicAction implements FileSystem.AtomicAction {
        private int operation;
        private final MasterFileObject hfoI;
        private String nameI;
        private String extI;
        private FileObject targetI;
        private FileLock fLockI;
        private FileObject retVal;

        private static final int CREATE_DATA_OP = 0;
        private static final int CREATE_FOLDER_OP = 1;
        private static final int CREATE_DATA_EXT_OP = 2;
        private static final int COPY_OP = 3;
        private static final int REFRESH_EXPECTED_OP = 4;
        private static final int REFRESH_OP = 5;
        private static final int DELETE_OP = 6;
        private static final int MOVE_OP = 7;

        private AtomicAction(final MasterFileObject hfo) {
            this.hfoI = hfo;
        }

        private FileObject createFolder(final String name) throws IOException {
            init(name);
            operation = CREATE_FOLDER_OP;
            // calls createFolder ()
            getHFs().runAtomicAction(this);
            return retVal;
        }


        FileObject createData(final String name) throws IOException {
            init(name);
            operation = CREATE_DATA_OP;
            //calls createData
            getHFs().runAtomicAction(this);
            return retVal;
        }

        FileObject createData(final String name, final String ext) throws IOException {
            init(name, ext);
            operation = CREATE_DATA_EXT_OP;
            //calls createDataExt
            getHFs().runAtomicAction(this);
            return retVal;
        }

        FileObject copy(FileObject target, String name, String ext) throws IOException {
            init(target, name, ext);
            operation = COPY_OP;
            //calls copy
            getHFs().runAtomicAction(this);
            return retVal;
        }

        void delete(FileLock fLock) throws IOException {
            init(fLock, null, null, null);
            operation = DELETE_OP;
            //calls delete
            getHFs().runAtomicAction(this);
        }

        FileObject move(FileLock lock, FileObject target, String name, String ext) throws IOException {
            init(lock, target, name, ext);
            operation = MOVE_OP;
            //calls move
            getHFs().runAtomicAction(this);
            return retVal;
        }

        void refreshExpected() throws IOException {
            operation = REFRESH_EXPECTED_OP;
            //calls iRefreshExpected
            getHFs().runAtomicAction(this);
        }

        void refresh() throws IOException {
            operation = REFRESH_OP;
            //calls iRefresh
            getHFs().runAtomicAction(this);
        }

        public void run() throws IOException {
            hfoI.enterCriticalSection();
            try {
                switch (operation) {
                    case CREATE_FOLDER_OP:
                        createFolder();
                        break;
                    case CREATE_DATA_OP:
                        createData();
                        break;
                    case CREATE_DATA_EXT_OP:
                        createDataExt();
                        break;
                    case COPY_OP:
                        copy();
                        break;
                    case REFRESH_EXPECTED_OP:
                        iRefreshExpected();
                        break;
                    case REFRESH_OP:
                        iRefresh();
                        break;
                    case DELETE_OP:
                        delete();
                        break;
                    case MOVE_OP:
                        move();
                        break;
                }
            } finally {
                hfoI.finishCriticalSection();
            }
        }

        private void init(FileLock fLock, final FileObject target, final String name, final String ext) {
            init(target, name, ext);
            this.fLockI = fLock;
        }

        private void init(final FileObject target, final String name, final String ext) {
            init(name, ext);
            this.targetI = target;
        }

        private void init(final String name, final String ext) {
            init(name);
            this.extI = ext;
        }

        private void init(final String name) {
            this.nameI = name;
            retVal = null;
        }

        // real implementation
        private void createFolder() throws IOException {
            FileObject deleg = getValidOrInvalid(hfoI.getDelegate().get(), hfoI);
            deleg.createFolder(nameI);
            retVal = getCache().getOrCreate(hfoI.getResource().getChild(nameI));
        }

        private void createData() throws IOException {
            FileObject deleg = getValidOrInvalid(hfoI.getDelegate().get(), hfoI);
            deleg.createData(nameI);
            retVal = getCache().getOrCreate(hfoI.getResource().getChild(nameI));
        }

        private void createDataExt() throws IOException {
            FileObject deleg = getValidOrInvalid(hfoI.getDelegate().get(), hfoI);
            deleg.createData(nameI, extI);
            retVal = getCache().getOrCreate(hfoI.getResource().getChild(nameI, extI));
        }

        private void copy() throws IOException {
            FileObject deleg = getValidOrInvalid(hfoI.getDelegate().getPrefered(), hfoI);
            retVal = deleg.copy(targetI, nameI, extI);
        }

        private void delete() throws IOException {
            FileObject deleg = getValidOrInvalid(hfoI.getDelegate().get(), hfoI);
            FileLock lck = Delegate.getLockForDelegate(fLockI, deleg);
            deleg.delete(lck);
        }

        private void move() throws IOException {
            retVal = hfoI.superMove(fLockI, targetI, nameI, extI);
        }

        private void iRefreshExpected() {
            FileObject deleg = getValidOrInvalid(hfoI.getDelegate().get(), hfoI);
            if (deleg != null) deleg.refresh(true);
        }

        private void iRefresh() {
            FileObject deleg = getValidOrInvalid(hfoI.getDelegate().get(), hfoI);
            if (deleg != null) deleg.refresh(false);
        }
        
        public boolean equals(Object obj) {
            return (obj instanceof AtomicAction);
        }

        public int hashCode() {
            return AtomicAction.class.hashCode();
        }
        
    }

}
... 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.