Package org.jnode.fs.service.def

Source Code of org.jnode.fs.service.def.FileHandleManager

/*
* $Id$
*
* Copyright (C) 2003-2014 JNode.org
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, or
* (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; If not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
package org.jnode.fs.service.def;

import java.io.IOException;
import java.io.VMOpenMode;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;

import org.apache.log4j.Logger;
import org.jnode.fs.FSFile;

/**
* @author epr
*/
final class FileHandleManager {

    /** My logger */
    private static final Logger log = Logger.getLogger(FileHandleManager.class);
    /** A map between File and FileData */
    public final Map<FSFile, FileData> openFiles = new HashMap<FSFile, FileData>();

    /**
     * Create a filehandle for a given file entry.
     *
     * @param file
     * @param mode
     * @throws IOException
     */
    public synchronized FileHandleImpl open(FSFile file, VMOpenMode mode) throws IOException {
        FileData fd = openFiles.get(file);
        if (fd == null) {
            fd = new FileData(file);
            openFiles.put(file, fd);
        }

        return fd.open(mode);
    }

    /**
     * Close a filehandle.
     *
     * @param handle file handle to close.
     *
     * @throws IOException if file is not already open.
     */
    public synchronized void close(FileHandleImpl handle) throws IOException {
        final FSFile file = handle.getFile();
        final FileData fd = openFiles.get(file);
        if (fd != null) {
            fd.close(handle);
            if (!fd.hasHandles()) {
                openFiles.remove(file);
            }
        } else {
            log.error("FileHandle tried to close an unknown file!!");
        }
    }

    /**
     * Duplicate a filehandle.
     *
     * @param handle file handle to duplicate.
     * @param newMode new file open mode.
     *
     * @throws IOException if file is not already open.
     */
    public synchronized FileHandleImpl dup(FileHandleImpl handle, VMOpenMode newMode)
        throws IOException {
        final FSFile file = handle.getFile();
        final FileData fd = openFiles.get(file);
        if (fd != null) {
            return fd.dup(handle, newMode);
        } else {
            throw new IOException("FileHandle tried to dup an unknown file!!");
        }
    }

    class FileData {

        /** My logger */
        @SuppressWarnings("unused")
        private final Logger fdLog = Logger.getLogger(getClass());
        /** The actual file */
        private final FSFile file;
        /** Set of open filehandles */
        private final HashSet<FileHandleImpl> handles = new HashSet<FileHandleImpl>();
        /** Is any of the handles opened for write? */
        private boolean hasWriters;

        public FileData(FSFile file) {
            this.file = file;
        }

        /**
         * Open an extra handle for this file.
         *
         * @param mode file open mode.
         *
         * @throws IOException if file is already open in write mode.
         */
        public FileHandleImpl open(VMOpenMode mode) throws IOException {
            if (mode.canWrite()) {
                if (hasWriters) {
                    throw new IOException("File is already open for writing");
                } else {
                    hasWriters = true;
                }
            }
            final FileHandleImpl handle = new FileHandleImpl(file, mode, FileHandleManager.this);
            handles.add(handle);
            return handle;
        }

        /**
         * Duplicate the given handle for this file.
         *
         * @param handle file handle.
         * @param newMode new open mode.
         *
         * @return duplicate file handle.
         *
         * @throws IOException if handle doesn't exists or file is already open in write mode.
         */
        public FileHandleImpl dup(FileHandleImpl handle, VMOpenMode newMode) throws IOException {
            if (handles.contains(handle)) {
                if (newMode.canWrite()) {
                    if (hasWriters) {
                        throw new IOException("File is already open for writing");
                    } else {
                        hasWriters = true;
                    }
                }
                final FileHandleImpl newHandle;
                newHandle = new FileHandleImpl(file, newMode, FileHandleManager.this);
                handles.add(newHandle);
                return newHandle;
            } else {
                throw new IOException("FileHandle is not known in FileData.dup!!");
            }
        }

        /**
         * Close the given handle for this file.
         *
         * @param handle file handle.
         *
         * @throws IOException if handle doesn't exists.
         */
        public void close(FileHandleImpl handle) throws IOException {
            if (handles.contains(handle)) {
                handles.remove(handle);
                if (handle.getMode().canWrite()) {
                    hasWriters = false;
                }
            } else {
                throw new IOException("FileHandle is not known in FileData.close!!");
            }
        }

        /**
         * Are there open handles for this file?
         *
         * @return <tt>true</tt> if there are open handles.
         */
        public boolean hasHandles() {
            return !handles.isEmpty();
        }
    }
}
TOP

Related Classes of org.jnode.fs.service.def.FileHandleManager

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.