Java tutorial
// 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(); } }