com.github.stephenc.javaisotools.iso9660.ISO9660Directory Maven / Gradle / Ivy
/*
* Copyright (c) 2010. Stephen Connolly.
* Copyright (C) 2007. Jens Hatlak
*
* 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 com.github.stephenc.javaisotools.iso9660;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import com.github.stephenc.javaisotools.sabre.HandlerException;
public class ISO9660Directory implements ISO9660HierarchyObject {
private String name;
private int level;
private List files;
private List directories;
private ISO9660Directory parent;
private ISO9660RootDirectory root;
private long lastModified;
private boolean sorted;
private Object id;
ISO9660DirectoryIterator sortedIterator, unsortedIterator;
/**
* Create directory
*
* @param name Name of the directory
*/
public ISO9660Directory(String name) {
init();
this.name = name;
}
/**
* Create directory
*
* @param file Directory
*
* @throws HandlerException Not a directory
*/
public ISO9660Directory(File file) throws HandlerException {
init();
if (file.isDirectory()) {
this.name = file.getName();
this.lastModified = file.lastModified();
} else {
throw new HandlerException("Not a directory: " + file);
}
}
private void init() {
this.files = new ArrayList();
this.directories = new ArrayList();
this.level = 1;
this.parent = this;
this.name = "";
this.lastModified = (new Date()).getTime();
this.sorted = false;
this.id = new Object();
}
public void setName(String name) {
this.name = name;
if (parent != this) {
// Force sort of parent only if is contains this directory
parent.forceSort();
}
}
public String getName() {
return name;
}
private void setLevel(int level) {
this.level = level;
}
/**
* Returns this directory's level of the directory hierarchy
*
* @return Directory's level
*/
public int getLevel() {
return this.level;
}
void setRoot(ISO9660RootDirectory root) {
this.root = root;
}
public ISO9660RootDirectory getRoot() {
return root;
}
public ISO9660Directory getParentDirectory() {
return parent;
}
void setParentDirectory(ISO9660Directory parent) {
this.parent = parent;
}
/**
* Returns a Vector of the directory's files
*
* @return Vector containing ISO9660File objects
*/
public List getFiles() {
if (!sorted) {
sort();
}
return files;
}
/**
* Returns a Vector of the directory's subdirectories
*
* @return Vector containing ISO9660Directory objects
*/
public List getDirectories() {
if (!sorted) {
sort();
}
return directories;
}
/**
* Returns whether this directory contains subdirectories
*
* @return Whether the directory contains subdirectories
*/
public boolean hasSubDirs() {
return (directories.size() > 0);
}
public String getISOPath() {
StringBuffer buf = new StringBuffer();
getISOPath(buf);
return buf.toString();
}
private void getISOPath(StringBuffer buf) {
ISO9660Directory parent = getParentDirectory();
if (parent == this) {
// Root reached
return;
}
// Depth-first recursion
parent.getISOPath(buf);
// Append path component separator
buf.append(File.separator);
// Append name of current directory
buf.append(getName());
}
int deepLevelCount() {
int count = level;
for (ISO9660Directory dir : directories) {
count = Math.max(count, dir.deepLevelCount());
}
return count;
}
int deepFileCount() {
int count = files.size();
for (ISO9660Directory dir : directories) {
count += dir.deepFileCount();
}
return count;
}
int deepDirCount() {
int count = directories.size();
for (ISO9660Directory dir : directories) {
count += dir.deepDirCount();
}
return count;
}
/**
* Add directory
*
* @param dir Directory to be added
*
* @return Added directory
*/
public ISO9660Directory addDirectory(ISO9660Directory dir) {
dir.setLevel(level + 1);
dir.setParentDirectory(this);
dir.setRoot(root);
updateSubdirectories(dir);
directories.add(dir);
sorted = false;
return dir;
}
/**
* Update subdirectories info (level, root) based on dir info.
*
* @param dir Directory whose subdirectories will be updated
*/
private void updateSubdirectories(ISO9660Directory dir) {
List subdirectories = dir.getDirectories();
Iterator iter = subdirectories.iterator();
while (iter.hasNext()) {
ISO9660Directory subdir = (ISO9660Directory) iter.next();
subdir.setLevel(dir.getLevel() + 1);
subdir.setRoot(dir.getRoot());
updateSubdirectories(subdir);
}
}
/**
* Add directory
*
* @param file Directory to be added
*
* @return Added directory
*
* @throws com.github.stephenc.javaisotools.sabre.HandlerException Not a directory
*/
public ISO9660Directory addDirectory(File file) throws HandlerException {
ISO9660Directory dir = new ISO9660Directory(file);
return addDirectory(dir);
}
/**
* Add directory
*
* @param name Name of the directory to created and added
*
* @return Added directory
*/
public ISO9660Directory addDirectory(String name) {
ISO9660Directory dir = new ISO9660Directory(name);
return addDirectory(dir);
}
/**
* Add path
*
* @param path Filesystem-specific path to be added recursively
*
* @return Topmost added directory
* @throws com.github.stephenc.javaisotools.sabre.HandlerException
*/
public ISO9660Directory addPath(String path) throws HandlerException {
ISO9660Directory dir;
if (path.indexOf(File.separator) == -1) {
// Path is a directory - add it if not already listed
return checkDirectory(path);
}
// Add path recursively
int frontSeparatorIndex = path.indexOf(File.separator);
String dirName = path.substring(0, frontSeparatorIndex);
dir = checkDirectory(dirName);
String rest = path.substring(frontSeparatorIndex + 1);
dir = dir.addPath(rest);
return dir;
}
private ISO9660Directory checkDirectory(String name) throws HandlerException {
for (ISO9660Directory dir : directories) {
if (dir.getName().equals(name)) {
return dir;
}
}
// Not listed -> create a new one and add it to the hierarchy
return addDirectory(name);
}
/**
* Force a sort of this directory's files and subdirectories
*/
public void forceSort() {
sorted = false;
}
private void sort() {
Collections.sort(files);
Collections.sort(directories);
sorted = true;
}
/**
* Add file
*
* @param file File to be added
*/
public void addFile(ISO9660File file) {
file.setParentDirectory(this);
files.add(file);
sorted = false;
}
/**
* Add file
*
* @param file File to be added
* @param version File version
*
* @throws HandlerException Problems converting to ISO9660File
*/
public void addFile(File file, int version) throws HandlerException {
addFile(new ISO9660File(file, version));
}
/**
* Add file
*
* @param file File to be added
*
* @throws com.github.stephenc.javaisotools.sabre.HandlerException Problems converting to ISO9660File
*/
public void addFile(File file) throws HandlerException {
addFile(new ISO9660File(file));
}
/**
* Add file
*
* @param pathname File to be added
* @param version File version
*
* @throws com.github.stephenc.javaisotools.sabre.HandlerException Problems converting to ISO9660File
*/
public void addFile(String pathname, int version) throws HandlerException {
addFile(new ISO9660File(pathname, version));
}
/**
* Add file
*
* @param pathname File to be added
*
* @throws HandlerException Problems converting to ISO9660File
*/
public void addFile(String pathname) throws HandlerException {
addFile(new ISO9660File(pathname));
}
/**
* Add file or directory recursively
*
* @param file File or directory to be added recursively
*
* @throws HandlerException Problems converting to ISO9660File
*/
public void addRecursively(File file) throws HandlerException {
addRecursively(file, true, this);
}
/**
* Add contents of directory recursively
*
* @param file Directory the contents of which are to be added recursively
*
* @throws HandlerException Problems converting to ISO9660File
*/
public void addContentsRecursively(File file) throws HandlerException {
addRecursively(file, false, this);
}
private void addRecursively(File file, boolean addItself, ISO9660Directory parent) throws HandlerException {
if (!file.isDirectory() && addItself) {
// Add file
parent.addFile(file);
return;
}
ISO9660Directory dir = parent;
if (addItself) {
// Add directory itself
dir = parent.addDirectory(file);
}
// Add directory contents recursively
for (File childFile : file.listFiles()) {
addRecursively(childFile, true, dir);
}
}
public int compareTo(Object object) throws ClassCastException, NullPointerException {
// Alphanumerical case-insensitive sort (according to ISO9660 needs)
if (object == null) {
throw new NullPointerException();
} else if (object.equals(this)) {
return 0;
} else if (object instanceof ISO9660Directory) {
ISO9660Directory dir = (ISO9660Directory) object;
return getName().toUpperCase().compareTo(dir.getName().toUpperCase());
} else if (object instanceof ISO9660File) {
ISO9660File file = (ISO9660File) object;
return getName().toUpperCase().compareTo(file.getFullName().toUpperCase());
} else {
throw new ClassCastException();
}
}
/**
* Returns date of last modification
*
* @return Date of last modification
*/
public long lastModified() {
return lastModified;
}
public boolean isDirectory() {
return true;
}
/**
* Returns whether this directory has been relocated
*
* @return Whether this is a relocated directory
*/
public boolean isMoved() {
return parent == root.getMovedDirectoriesStore();
}
/**
* Relocate directory
*
* @return Old parent directory
*/
public ISO9660Directory relocate() {
ISO9660Directory movedDirectoriesStore = root.getMovedDirectoriesStore();
ISO9660Directory oldParent = parent;
int oldLevel = level;
// Relocate directory (updates level and parent pointer)
movedDirectoriesStore.addDirectory(this);
// Update level of all subdirectories
int difference = oldLevel - getLevel();
Iterator it = unsortedIterator();
while (it.hasNext()) {
ISO9660Directory subdir = (ISO9660Directory) it.next();
subdir.setLevel(subdir.getLevel() - difference);
}
return oldParent;
}
public Object getID() {
// Identification of the ISO9660Directory, survives cloning
return id;
}
public Object clone() {
ISO9660Directory clone = null;
try {
clone = (ISO9660Directory) super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
clone.level = level;
clone.directories = new ArrayList();
clone.files = new ArrayList();
clone.id = id;
clone.sortedIterator = null;
clone.sorted = false;
for (ISO9660Directory subdir : directories) {
ISO9660Directory subdirClone = (ISO9660Directory) subdir.clone();
subdirClone.setParentDirectory(clone);
subdirClone.setLevel(level + 1);
subdirClone.id = subdir.id;
subdirClone.sortedIterator = null;
subdirClone.sorted = false;
clone.directories.add(subdirClone);
}
for (ISO9660File file : files) {
ISO9660File fileClone = (ISO9660File) file.clone();
fileClone.setParentDirectory(clone);
clone.files.add(fileClone);
}
return clone;
}
/**
* Returns a directory iterator to traverse the directory hierarchy according to the needs of ISO 9660 (sort order
* of Path Tables and Directory Records)
*
* @return Iterator
*/
public Iterator sortedIterator() {
if (sortedIterator == null) {
sortedIterator = new ISO9660DirectoryIterator(this, true);
}
sortedIterator.reset();
return sortedIterator;
}
/**
* Returns a directory iterator to traverse the directory hierarchy using a recursive method
*
* @return Iterator
*/
public Iterator unsortedIterator() {
if (unsortedIterator == null) {
unsortedIterator = new ISO9660DirectoryIterator(this, false);
}
unsortedIterator.reset();
return unsortedIterator;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy