com.archivas.clienttools.arcutils.model.ArcMoverDirectory.java Source code

Java tutorial

Introduction

Here is the source code for com.archivas.clienttools.arcutils.model.ArcMoverDirectory.java

Source

// Copyright 2007 Hitachi Data Systems
// All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may
// not use this file except in compliance with the License. You may obtain
// a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
// License for the specific language governing permissions and limitations
// under the License.

package com.archivas.clienttools.arcutils.model;

import com.archivas.clienttools.arcutils.api.JobException;
import com.archivas.clienttools.arcutils.impl.adapter.BadElementException;
import com.archivas.clienttools.arcutils.impl.adapter.StorageAdapter;
import com.archivas.clienttools.arcutils.impl.adapter.StorageAdapterException;
import com.archivas.clienttools.arcutils.profile.AbstractProfileBase;
import com.archivas.clienttools.arcutils.utils.FileUtil;
import org.apache.http.HttpStatus;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Abstraction layer to provide common interface to Files which are stored on different platforms
 * (including non-OS filesystems) where java.io is not sufficient.
 * <p>
 * This is similar to the parts of {@link java.io.File} that pertain to directories.
 */
public class ArcMoverDirectory extends ArcMoverFile {
    public static final String PACKAGE_NAME = ArcMoverDirectory.class.getPackage().getName();
    public static final String CLASS_FULL_NAME = ArcMoverDirectory.class.getName();
    public static final String CLASS_NAME = CLASS_FULL_NAME.substring(PACKAGE_NAME.length() + 1);
    public static Logger LOG = Logger.getLogger(CLASS_FULL_NAME);
    private StorageAdapter storageAdapter;

    private List<ArcMoverFile> files = null;
    private boolean canRead = true;
    private boolean canWrite = true;
    private boolean isVersionList = false; // true if the Directory really represents the list of
                                           // versions a file has.
    private String fileSep; // File/Directory separator used for this directory.
    private boolean iterated = false;

    private int badElementCnt = 0;

    /**
     * Creates an ArcMoverDirectory based on a parent directory and directory name.
     */
    private ArcMoverDirectory(final AbstractProfileBase profile, final ArcMoverDirectory parent,
            final String dirName, final FileMetadata attrs, final StorageAdapter storageAdapter) {
        super(profile, parent, dirName, attrs);
        fileSep = parent.getFileSep();
        this.storageAdapter = storageAdapter;
    }

    /**
     * Creates a Root ArcMoverDirectory based on the profile and root directory name
     */
    private ArcMoverDirectory(final AbstractProfileBase profile, final String dirName, final FileMetadata attrs,
            final String dirSepChar, final StorageAdapter storageAdapter) {
        super(profile, dirName, attrs);
        fileSep = "" + dirSepChar;
        fileSep = fileSep.intern();
        this.storageAdapter = storageAdapter;
    }

    /**
     * Return the ArcMoverDirectory for given profile & path
     * 
     * @param profile
     * @param path
     *            Path of the directory for which you want to create an ArcMoverDirectory
     * @param storageAdapter
     *            May be null. If not null this object is used to iteratively callect File objects
     *            from the returned directory object when the getNextFileBatch method of the
     *            ArcMoverDirectory object is called. If this param is null then the
     *            getNextFileBatch method cannot be used for the returned object.
     *
     * @todo Find out if null can be allowed. If not, there should be a way to pass a non-null value
     *       in the current code that uses this getinstance method that does not have an adapter.
     *
     * @return the ArcMoverDirectory for given profile & path
     */
    public static ArcMoverDirectory getDirInstance(AbstractProfileBase profile, String path,
            StorageAdapter storageAdapter) {
        if (profile == null)
            throw new IllegalArgumentException("Parameter 'AbstractProfileBase profile' must not be null");
        if (path == null)
            throw new IllegalArgumentException("Parameter 'String path' must not be null");

        ArcMoverDirectory dir = null;
        String dirSep = profile.getPathSeparator();
        assert (dirSep != null);

        // Convert to canonical forward-slash form and split on that
        String dirPath = FileUtil.converWindowsPathToUnix(path, dirSep);
        String[] dirParts = dirPath.split("/");

        if (dirParts.length < 1) {
            // Root Path that has 0 parts. Create a root dir.
            dir = new ArcMoverDirectory(profile, "", null, dirSep, storageAdapter);
        } else {
            // Iterate everything but the filename and create directories
            ArcMoverDirectory parentDir = null;
            for (int i = 0; i < dirParts.length; i++) {
                if (parentDir == null) {
                    dir = new ArcMoverDirectory(profile, dirParts[i], null, dirSep, storageAdapter);
                } else {
                    dir = new ArcMoverDirectory(profile, parentDir, dirParts[i], null, storageAdapter);
                }
                parentDir = dir;
            }
        }

        return dir;
    }

    public static ArcMoverDirectory getFileVersions(AbstractProfileBase profile, String path,
            StorageAdapter storageAdapter) {

        if (profile == null)
            throw new IllegalArgumentException("Parameter 'AbstractProfileBase profile' must not be null");
        if (path == null)
            throw new IllegalArgumentException("Parameter 'String path' must not be null");

        ArcMoverDirectory dir = getDirInstance(profile, path, storageAdapter);
        dir.setVersionList(true);
        return dir;
    }

    /**
     * @param parent
     * @param filename
     * @param attrs
     * @param storageAdapter
     *            May be null. If not null this object is used to iteratively callect File objects
     *            from the returned directory object when the getNextFileBatch method of the
     *            ArcMoverDirectory object is called. If this param is null then the
     *            getNextFileBatch method cannot be used for the returned object.
     *
     * @todo Find out if null can be allowed. If not, there should be a way to pass a non-null value
     *       in the current code that uses this getinstance method that does not have an adapter.
     *
     * @return
     */
    public static ArcMoverDirectory getDirInstance(final ArcMoverDirectory parent, final String filename,
            final FileMetadata attrs, StorageAdapter storageAdapter) {
        if (storageAdapter == null)
            throw new IllegalArgumentException("Parameter 'StorageAdapter storageAdapter' must not be null");
        if (parent == null)
            throw new IllegalArgumentException("Parameter 'ArcMoverDirectory parent' must not be null");
        if (filename == null)
            throw new IllegalArgumentException("Parameter 'String filename' must not be null");

        ArcMoverDirectory dir = new ArcMoverDirectory(storageAdapter.getProfile(), parent, filename, attrs,
                storageAdapter);
        return dir;
    }

    /**
     * Return an iterator over the items in the directory.
     * <P>
     * 
     * @param includeDeleted
     *            -- include deleted directories
     * @param supportsVersioning
     *            -- directory supports versioning
     * @return
     * @throws StorageAdapterException
     *             on fatal error
     */
    public Iterator<ArcMoverFile> getFileListIterator(boolean includeDeleted, boolean supportsVersioning)
            throws StorageAdapterException {
        return storageAdapter.getFileListIterator(this, includeDeleted, supportsVersioning);
    }

    public List<ArcMoverFile> getFileList(int maxFiles) throws StorageAdapterException, JobException {
        badElementCnt = 0;
        int count = 0;
        ArrayList<ArcMoverFile> files = new ArrayList<ArcMoverFile>();
        Iterator<ArcMoverFile> iter = getFileListIterator(true, profile.supportsVersioning());

        while (iter.hasNext() && count++ < maxFiles) {
            try {
                ArcMoverFile f = iter.next();
                assert (f != null); // Expecting the iterator to throw NoSuchElementException
                                    // instead of returning null;
                files.add(f);
            } catch (NoSuchElementException e) {
                // decrement count
                --count;
                // This can happen if the adapter sees things it can't deal with, e.g., symlinks on
                // a LFS.
                LOG.log(Level.FINEST, "Unsupported object encountered, skipping.", e);
            } catch (BadElementException bee) {
                // we will not include this element, but other elements should be included
                --count;
                badElementCnt++;
                LOG.log(Level.FINEST, "Bad object encountered, skipping.", bee);
            }
        }

        return files;
    }

    /**
     * @return the number of BadElementExceptions that were encountered during the last call to
     *         getFileList(int maxFiles);
     */
    public int getFileListBadElementCnt() {
        return badElementCnt;
    }

    public AbstractProfileBase getProfile() {
        return this.profile;
    }

    public String getPath() {
        String path = null;
        if (getParent() != null) {
            assert (getParent() != this);
            path = getParent().getPath();
        }

        String filename = getFileName();
        if (filename == null) {
            filename = "";
        }
        if (path == null) {
            path = filename;
        } else {
            path = FileUtil.resolvePath(path, filename, getFileSep());
        }

        // Directory paths should end in a separator. Let the GUI's strip it off if they don't want
        // to display it.
        if (!path.endsWith(getFileSep()) && !this.isVersionList()) {
            path = path + getFileSep();
        }
        return path;
    }

    public long getSize() {
        long size = 0;
        if (files != null) {
            size = files.size();
        }
        return size;
    }

    public String getFileSep() {
        return fileSep;
    }

    public void abortASAP() {
        storageAdapter.abortASAP();
    }

    public boolean isFile() {
        return false;
    }

    public boolean isDirectory() {
        return true;
    }

    public boolean canRead() {
        return canRead;
    }

    public boolean isVersionList() {
        return isVersionList;
    }

    public void setVersionList(final boolean versionList) {
        isVersionList = versionList;
    }

    public boolean equals(final Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        final ArcMoverDirectory that = (ArcMoverDirectory) o;

        if (filename != null ? !filename.equals(that.filename) : that.filename != null)
            return false;
        if (parent != null ? !parent.equals(that.parent) : that.parent != null)
            return false;
        if (!profile.equals(that.profile))
            return false;

        return true;
    }

    public int hashCode() {
        int result;
        result = (filename != null ? filename.hashCode() : 0);
        result = 31 * result + (parent != null ? parent.hashCode() : 0);
        result = 31 * result + profile.hashCode();
        return result;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("ArcMoverDirectory");
        sb.append("{name=").append(getFileName());
        sb.append(", path=").append(getPath());
        sb.append(", isVersionList=").append(isVersionList());
        sb.append('}');
        return sb.toString();
    }

    @Override
    public String toDetailString() {
        final StringBuilder sb = new StringBuilder();
        sb.append("ArcMoverDirectory");
        sb.append("{").append(super.toDetailString());
        sb.append(", path=").append(getPath());
        sb.append(", isVersionList=").append(isVersionList());
        sb.append('}');
        sb.append(", files: ");
        return sb.toString();
    }
}