package org.jboss.fresh.vfs.impl.disk;
import org.jboss.fresh.vfs.FileInfo;
import org.jboss.fresh.vfs.FileName;
import org.jboss.fresh.vfs.VFSException;
import org.jboss.fresh.vfs.VFSMeta;
import org.jboss.fresh.vfs.VFSMetaCacheUpdater;
import org.apache.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
public class DiskVFSMeta implements VFSMeta {
private String rootpath;
private FileName root;
private File fsroot;
private VFSMetaCacheUpdater cup;
private int rootlen;
private HashMap tags = new HashMap();
private static Logger log = Logger.getLogger(DiskVFSMeta.class);
public DiskVFSMeta(String rootpath) throws Exception {
fsroot = new File(rootpath);
String rp = fsroot.getPath();// toURL().getPath();
rootlen = rp.endsWith("/") ? rp.length()-1 : rp.length();
// just check that path exists
if(!fsroot.isDirectory())
throw new RuntimeException("Root directory does not exist: " + rootpath);
root = new FileName("/");
}
public void setCacheUpdater(VFSMetaCacheUpdater updater) {
cup = updater;
}
public VFSMetaCacheUpdater getCacheUpdater() {
return cup;
}
private FileInfo fileToFileInfo(File file) throws VFSException {
try {
FileInfo inf = new FileInfo(file.getPath().substring(rootlen));
//FileInfo inf = new FileInfo(file.toURL().getPath().substring(rootlen));
inf.setCreateDate(new Date(file.lastModified()));
inf.setFileType(file.isFile() ? FileInfo.TYPE_FILE : FileInfo.TYPE_DIR);
inf.setLastModified(new Date(file.lastModified()));
inf.setLength(file.length());
inf.setMime("application/octet-stream");
String tag = (String) tags.get(file);
inf.setTag(tag == null ? String.valueOf(inf.getLastModified().getTime()) : tag);
return inf;
} catch(IOException ex) {
log.info("Exception while getting file information: ", ex);
return null;
}
}
/** Name must be valid FileName object.
*/
public boolean exists(FileName name) throws Exception {
// absolutize on root
// append to fsroot
FileName adjusted = root.absolutize(name);
File thefile = new File(fsroot, adjusted.toString());
return thefile.exists();
}
/** Path must be valid FileName object.
*/
public int countChildren(FileName path) throws Exception {
FileName adjusted = root.absolutize(path);
File thefile = new File(fsroot, adjusted.toString());
return thefile.list().length;
}
/** Path must point to existing file or dir and must not be null.
*/
public List resolvePath(FileName path) throws Exception {
LinkedList ls = new LinkedList();
if(path == null) {
ls.add(new FileName("/"));
return ls;
}
FileName adjusted = root.absolutize(path);
File thefile = new File(fsroot, adjusted.toString());
//ls.add(new FileName(thefile.toURL().getPath().substring(rootlen)));
ls.add(new FileName(thefile.getPath().substring(rootlen)));
return ls;
}
public FileInfo getFileInfo(FileName name) throws Exception {
// Convert to CompositeName
// get FileInfo
// return null if no info for name
FileName adjusted = root.absolutize(name);
File thefile = new File(fsroot, adjusted.toString());
return fileToFileInfo(thefile);
}
public List list(FileName path) throws Exception {
FileName adjusted = root.absolutize(path);
File thefile = new File(fsroot, adjusted.toString());
File [] fs = thefile.listFiles();
List l = new LinkedList();
for(int i=0; i<fs.length; i++) {
File f = (File) fs[i];
l.add(fileToFileInfo(f));
}
return l;
}
public Collection getLinks(FileName target) throws Exception {
// return all fileinfos that link to this one
// why would we need that?
// it means we need to keep reverse references - a pain
throw new RuntimeException("Not implemented");
}
public void create(FileInfo fi) throws Exception {
FileName adjusted = root.absolutize(fi.getFileName().toString());
File thefile = new File(fsroot, adjusted.toString());
tags.put(thefile, fi.getTag());
if(fi.getFileType() == FileInfo.TYPE_DIR) {
if(thefile.isDirectory()) {
throw new VFSException("Directory exists already: " + fi.getFileName());
} if(thefile.exists()) {
throw new VFSException("File exists already (is not a directory): " + fi.getFileName());
}
if(!thefile.mkdir())
throw new VFSException("Could not create directory: " + fi.getFileName());
} else if(!thefile.createNewFile()) {
throw new VFSException("Could not create file: " + fi.getFileName());
}
}
public void update(FileInfo fi) throws Exception {
// look up info for CompositeName
// apply new info to it
FileName adjusted = root.absolutize(fi.getFileName().toString());
File thefile = new File(fsroot, adjusted.toString());
tags.put(thefile, fi.getTag());
}
// ko klices getInt na result setu, pa da je ta int nastavljen na NULL, dobis nazaj 0! Zato ne sme biti noben index 0!
public void remove(FileName name) throws Exception {
FileName adjusted = root.absolutize(name.toString());
File thefile = new File(fsroot, adjusted.toString());
if(!thefile.exists())
throw new VFSException("File does not exist: " + name);
if(!thefile.delete())
throw new VFSException("File could no be deleted: " + name);
}
public void rename(FileName oldPath, FileName newPath) throws Exception {
FileName adjusted = root.absolutize(oldPath.toString());
File thefile = new File(fsroot, adjusted.toString());
if(!thefile.exists())
throw new VFSException("File does not exist: " + oldPath);
FileName adjNu = root.absolutize(newPath.toString());
File newFile = new File(fsroot, adjNu.toString());
thefile.renameTo(newFile);
}
public float moveBefore(FileName currFile, FileName nextFile) throws Exception {
// this operation moves a file whithin it's parent. Native FSs usually don't support this
throw new RuntimeException("Method not implemented");
}
}