package net.sourceforge.javautil.common.io.impl;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import javax.swing.Icon;
import javax.swing.filechooser.FileSystemView;
import bsh.commands.dir;
import net.sourceforge.javautil.common.FileUtil;
import net.sourceforge.javautil.common.exception.ThrowableManagerRegistry;
import net.sourceforge.javautil.common.io.IVirtualArtifact;
import net.sourceforge.javautil.common.io.VirtualArtifactAbstract;
import net.sourceforge.javautil.common.io.VirtualArtifactException;
import net.sourceforge.javautil.common.io.VirtualArtifactNotFoundException;
import net.sourceforge.javautil.common.io.IVirtualDirectory;
import net.sourceforge.javautil.common.io.VirtualDirectoryAbstract;
import net.sourceforge.javautil.common.io.IVirtualFile;
import net.sourceforge.javautil.common.io.IVirtualPath;
import net.sourceforge.javautil.common.xml.annotation.XmlTag;
import net.sourceforge.javautil.common.xml.annotation.XmlTag.ElementType;
/**
* An implementation encompassing {@link File}'s that are directories.
*
* @author elponderador
* @author $Author: ponderator $
* @version $Id: SystemDirectory.java 2706 2010-12-31 00:09:22Z ponderator $
*/
@XmlTag(elementType=ElementType.Simple)
public class SystemDirectory extends VirtualDirectoryAbstract implements IVirtualDirectory, ISystemArtifact<IVirtualDirectory> {
private static FileSystemView FILE_SYSTEM;
protected static FileSystemView getFileSystemView () {
if (FILE_SYSTEM == null) {
synchronized (SystemDirectory.class) {
if (FILE_SYSTEM == null) {
FILE_SYSTEM = FileSystemView.getFileSystemView();
}
}
}
return FILE_SYSTEM;
}
protected File directory;
protected SystemDirectory parent;
public SystemDirectory(String directoryPath) {
this(new File(directoryPath));
}
public SystemDirectory(File directory) {
try {
String name = directory.getName();
if ("".equals(name)) name = directory.getPath();
this.directory = ("".equals(name) ? (directory.getParent() != null ? new File(directory.getParent()) : directory) : directory.getCanonicalFile());
} catch (IOException e) {
throw ThrowableManagerRegistry.caught(e);
}
}
public SystemDirectory(SystemDirectory parent, File directory) {
this(directory);
this.parent = parent;
}
public String getDisplayName() {
return directory.exists() ? getFileSystemView().getSystemDisplayName(directory) : directory.getName();
}
public Icon getSystemIcon() {
return getFileSystemView().getSystemIcon(directory);
}
public String getTypeDescription() {
return getFileSystemView().getSystemTypeDescription(directory);
}
public boolean isDrive() {
return getFileSystemView().isDrive(directory);
}
/**
* @return The drive related to this directory
*/
public SystemDrive getDrive () {
if (getFileSystemView().isDrive(directory)) {
return new SystemDrive(directory);
} else {
SystemDirectory dir = this;
while (dir.getOwner() != null) {
if (dir.getOwner() instanceof SystemDrive) {
return (SystemDrive) dir.getOwner();
} else {
dir = dir.getOwner();
}
}
return null;
}
}
public boolean isReadOnly() {
return !this.directory.canWrite();
}
public void rename(String newName) {
File newDirectory = new File(this.directory.getParentFile(), newName);
if (this.directory.renameTo(newDirectory)) {
this.directory = newDirectory;
} else {
throw new VirtualArtifactException(this, "Could not rename to: " + newName);
}
}
public long getLength() { return this.directory.length(); }
public URL getURL() {
try {
return directory.toURI().toURL();
} catch (MalformedURLException e) {
throw ThrowableManagerRegistry.caught(new VirtualArtifactException(this, e));
}
}
public long getLastModified() { return directory.lastModified(); }
public ISystemArtifact getArtifact(IVirtualPath path) {
File file = new File(directory, path.toString("/"));
if (!file.exists())
throw new VirtualArtifactNotFoundException(this, path.toString("/") + " does not exist in " + this);
return file.isDirectory() ? new SystemDirectory(file) : new SystemFile(file);
}
public IVirtualArtifact getArtifact(String name) {
File artifact = new File(directory, name);
return artifact.exists() ? (artifact.isFile() ? new SystemFile(artifact) : new SystemDirectory(artifact)) : null;
}
public File getRealArtifact() { return this.directory; }
public boolean isDirectory() { return true; }
public boolean isFile() { return false; }
public SystemDirectory createDirectory(String name) {
File newdir = new File(directory, name);
if (!newdir.exists() && !newdir.mkdirs()) throw new VirtualArtifactException(this, "Could not create directory " + name + " in " + this);
return new SystemDirectory( newdir );
}
public SystemFile createFile(String name) {
File newFile = new File(directory, name);
if (newFile.exists()) throw new VirtualArtifactException(this, "A file by this name already exists: " + name);
return new SystemFile( newFile );
}
public boolean makeDirectories() {
return directory.mkdirs();
}
public boolean makeDirectory() {
return directory.mkdir();
}
public boolean remove(String name) {
try {
FileUtil.delete(new File(directory, name));
return true;
} catch (Exception e) {
return false;
}
}
public Iterator<IVirtualArtifact> getArtifacts() {
List<IVirtualArtifact> files = new ArrayList<IVirtualArtifact>();
File[] fileList = directory.listFiles();
if (fileList != null)
for (File file : fileList) {
if (file.isFile()) files.add(new SystemFile(this, file));
else files.add(new SystemDirectory(this, file));
}
return files.iterator();
}
public String getName() {
return "".equals(directory.getName()) ? directory.getPath().replaceAll("[\\\\/]", "") : directory.getName();
}
public SystemDirectory getOwner() {
if (parent == null && directory.getParentFile() != null) {
File pfile = directory.getParentFile();
if (getFileSystemView().isDrive(pfile)) {
this.parent = new SystemDrive(pfile);
} else {
this.parent = new SystemDirectory(pfile);
}
}
return parent;
}
public boolean remove() { if (this.directory.exists()) return FileUtil.delete(this.directory); else return false; }
public boolean isExists() { return directory.exists(); }
public String toString () { return "SystemDirectory[" + this.directory + "]"; }
}