org.jboss.jbossts.fileio.xalib.txdirs.dir.XADir.java Source code

Java tutorial

Introduction

Here is the source code for org.jboss.jbossts.fileio.xalib.txdirs.dir.XADir.java

Source

/*     JBoss, Home of Professional Open Source Copyright 2008, Red Hat
 *  Middleware LLC, and individual contributors as indicated by the
 *  @author tags.
 *     See the copyright.txt in the distribution for a full listing of
 *  individual contributors. This copyrighted material is made available
 *  to anyone wishing to use, modify, copy, or redistribute it subject to
 *  the terms and conditions of the GNU Lesser General Public License, v. 2.1.
 *  This program is distributed in the hope that it will be useful, but
 *  WITHOUT A 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, v.2.1
 *  along with this distribution; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor,
 *  Boston, MA  02110-1301, USA.
 *
 *  (C) 2008,
 *  @author Red Hat Middleware LLC.
 */
package org.jboss.jbossts.fileio.xalib.txdirs.dir;

import org.apache.commons.transaction.file.FileResourceManager;
import org.apache.commons.transaction.file.ResourceManagerException;
import org.apache.commons.transaction.util.CommonsLoggingLogger;
import org.apache.commons.transaction.util.PrintWriterLogger;
import org.apache.commons.logging.LogFactory;
import org.jboss.jbossts.fileio.xalib.txdirs.exceptions.NotDirectoryException;
import org.jboss.jbossts.fileio.xalib.txdirs.exceptions.IncompleteTransactionsException;
import org.jboss.jbossts.fileio.xalib.Globals;
import javax.transaction.TransactionManager;
import javax.transaction.Transaction;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import java.util.LinkedList;
import java.io.*;

/**
 * Instances of this class represent a transactional directory on which
 * file operations such as create, rename and delete can be applied. The
 * contents (files) of this directory are represented by {@link XADirFile}
 * objects. Through these objects the application programmer can access the
 * file operations.
 * <p>
 * It provides methods to list the files in the directory and access the
 * {@link org.apache.commons.transaction.file.FileResourceManager} of the Apache
 * commons transaction project.
 *
 * @see XADirFile
 * @see org.apache.commons.transaction.file.FileResourceManager
 * @see org.jboss.jbossts.fileio.xalib.txdirs.dir.XAFileResourceManager 
 *
 * @author Ioannis Ganotis
 * @version Aug 6, 2008
 */
public class XADir implements Serializable, Closeable {
    private String curTxId;
    transient private FileResourceManager freMngr;
    private long length;

    /**
     * Constructor to create objects that represent a transactional directory.
     * <p>
     * The constructor checks if the <code>storeDir</code> is a directory or not.
     * If it is not then {@link org.jboss.jbossts.fileio.xalib.txdirs.exceptions.NotDirectoryException}
     * exception is thrown. Otherwise, a new <code>FileResourceManager</code> object
     * is created to allow access to transactional methods (e.g. start, commit, rollback
     * a transaction)
     *
     * @param storeDir directory where main data should go after commit
     * @exception org.jboss.jbossts.fileio.xalib.txdirs.exceptions.NotDirectoryException
     *            if the <code>storeDir</code> is not a directory
     * @exception org.apache.commons.transaction.file.ResourceManagerException
     *            if an error in the <code>FileResourceManager</code> occurs
     */
    public XADir(File storeDir) throws IOException, ResourceManagerException {
        if (!storeDir.exists()) {
            storeDir.mkdir();
        } else {
            if (!storeDir.isDirectory())
                throw new NotDirectoryException("The file given is not a directory.");
        }

        length = storeDir.list().length;
        String workDir = storeDir.getCanonicalPath() + "/" + Globals.WORK_DIR_NAME;
        freMngr = new FileResourceManager(storeDir.getCanonicalPath(), workDir, false,
                new PrintWriterLogger(new PrintWriter(System.out), XADirFile.class.getName(), false));
        freMngr.start(); // start the FileResourceManager service, must be started
    } // before using any of its methods

    /**
     * This method lists all the files under the transactional directory.
     * It lists only files and not <code>File</code>s as in Java this may
     * also mean directories.
     * @return a list of <code>XADirFile</code> objects which represent
     *         the files within the directory
     */
    public synchronized XADirFile[] listTXFiles() {
        File dir = new File(freMngr.getStoreDir());
        File[] files = dir.listFiles();
        LinkedList<XADirFile> xaDirFileList = new LinkedList<XADirFile>();

        for (File f : files) {
            if (!f.isDirectory()) {
                xaDirFileList.add(new XADirFile(f, this));
            }
        }
        XADirFile[] xaDirFiles = new XADirFile[xaDirFileList.size()];
        xaDirFileList.toArray(xaDirFiles);
        return xaDirFiles;
    }

    /**
     * This method must be used after a <code>TransactionManager</code>
     * has begun and within the boundaries of a transaction (<code>begin,
     * commit/rollback</code>).
     * <p>
     * The method also creates a new {@link XAFileResourceManager} and
     * enlists it to the transaction obtained by the <code>txnMngr</code>.
     *
     * @param txnMngr the <code>TransactionManager</code> used to commit
     *                or rollback the file operations
     * @exception javax.transaction.RollbackException
     *            if an error occurs while enlisting the <code>XAResource</code>
     * @exception javax.transaction.SystemException
     *            if there is a problem enlisting the XAResource created
     *            within this method or when the <code>getTransaction</code> in the
     *            <code>TransactionManager</code> fails or when the TransactionManager
     *            is not in ready (<code>Status.ACTIVE</code>) mode
     */
    public synchronized void startTransactionOn(TransactionManager txnMngr)
            throws SystemException, RollbackException {
        curTxId = "txDir-" + freMngr.getWorkDir().replace('/', '_').replace('\\', '_').replace(':', '_') + "_"
                + Thread.currentThread().getId() + "!" + System.nanoTime();
        XAFileResourceManager xafre = new XAFileResourceManager(freMngr, curTxId);
        Transaction tx = txnMngr.getTransaction();
        tx.enlistResource(xafre);
    }

    /**
     * Returns the <code>FileResourceManager</code> object used to access
     * transaction and file operations (e.g. startTransaction, copyResource).
     *
     * @return the <code>FileResourceManager</code> object
     */
    protected FileResourceManager getFreMngr() {
        return freMngr;
    }

    /**
     * This is the name of the "shadow" folder which keeps the changes whilst
     * a transaction is still in progress.
     *
     * @return a <code>String</code> which contains the name of the "shadow"
     *         folder
     */
    protected String getCurTxId() {
        return curTxId;
    }

    /**
     * Increases the counter of files in the directory by one
     */
    protected void increaseLength() {
        length++;
    }

    /**
     * Decreases the counter of files in the directory by one
     */
    protected void decreaseLength() {
        length--;
    }

    /**
     * Returns the number of files (not directories) under this
     * transactional directory.
     *
     * @return a <code>long</code> representing the number of files
     *         within the transactional directory
     */
    public long length() {
        return length;
    }

    /**
     * As this class represents a transactional directory, the application
     * programmer must call this method after his transactional work is over.
     * The method will release and remove any of the "shadow" files/folders
     * used whilist the transaction was in progress.
     * <p>
     * If there are pending transactions the method will fail to close.
     *
     * @exception IOException if an I/O error occurs
     */
    public void close() throws IOException {
        File store = new File(freMngr.getWorkDir());
        if (store.list().length != 0) // pending txs exist
            throw new IncompleteTransactionsException();

        store.delete();
        freMngr = null;
    }
}