package org.jboss.fresh.vfs.impl.mem;
import org.jboss.fresh.vfs.FileInfo;
import org.jboss.fresh.vfs.FileName;
import org.jboss.fresh.vfs.FileOpInfo;
import org.jboss.fresh.vfs.FileReadInfo;
import org.jboss.fresh.vfs.VFSException;
import org.jboss.fresh.vfs.VFSMeta;
import org.jboss.fresh.vfs.VFSStore;
import org.jboss.fresh.vfs.VFSStoreCacheUpdater;
import org.jboss.fresh.registry.RegistryContext;
import org.apache.log4j.Logger;
import javax.naming.Context;
import javax.naming.NameNotFoundException;
import javax.naming.NamingException;
import java.util.Date;
public class MemVFSStore implements VFSStore {
private VFSMeta meta;
private VFSStoreCacheUpdater cup;
RegistryContext fsroot;
private static Logger log = Logger.getLogger("org.jboss.fresh.vfs.impl.mem.MemVFSStore");
public MemVFSStore(VFSMeta meta, String fsname) throws Exception {
this.meta = meta;
fsroot = new RegistryContext(fsname);
}
public void setCacheUpdater(VFSStoreCacheUpdater updater) {
cup = updater;
}
public VFSStoreCacheUpdater getCacheUpdater() {
return cup;
}
public Object getResolvedNode(String name) throws VFSException, NamingException {
Object node = null;
for(int i=0; i<256; i++) {
node = fsroot.lookup(name);
if(node instanceof FNode) {
FNode fnode = (FNode) node;
if(fnode.getType() == FNode.LINK) {
name = fnode.getLinkRef();
} else {
return node;
}
} else {
return node;
}
}
throw new VFSException("Link resolution infinitely looped: " + name);
}
/** FileName must not be null, it can point to inexisting file.
*/
public boolean hasContent(FileName filename) throws Exception {
// lookup if it is a file
Object node = null;
try {
node = getResolvedNode(filename.toString());
} catch(NameNotFoundException ex) {
}
if(node == null)
return false;
if(node instanceof FNode) {
return ((FNode) node).getLength() > 0;
} else if(node instanceof Context) {
return false;
} else {
throw new RuntimeException("Internal error: child of illegal type: " + node.getClass().getName());
}
}
/** Writes a chunk of content data.
* FileOpInfo must be filled filename (file doesn't need to exist), filepos, and len.
*/
public void writeContent(FileOpInfo info) throws Exception {
try {
Object node = null;
try {
node = getResolvedNode(info.filename.toString());
} catch(NameNotFoundException ex) {
}
if(node == null) {
// file doesn't exist
// create it
FileInfo finf = new FileInfo(info.filename);
finf.setCreateDate(new Date());
finf.setLastModified(new Date());
finf.setFileType(FileInfo.TYPE_FILE);
finf.setLength(0);
finf.setMime("application/octet-stream");
meta.create(finf);
node = getResolvedNode(info.filename.toString());
}
RAF raf = null;
if(node instanceof FNode) {
raf = ((FNode) node).getFileContent().getRAF();
} else if(node instanceof Context) {
throw new VFSException(info.filename.toString() + " is a directory.");
}
if(info.append) {
raf.seek(raf.getLength());
} else {
raf.seek(info.offset);
}
raf.write(info.buf, 0, info.buf.length);
raf.close();
} catch (Exception e) {
log.error("Could not write content", e);
throw e;
}
}
/** Reads a chunk of content data and returns it as FileRetInfo object.
* FileOpInfo must be filled filename (file must exist), filepos and buf.
*/
public FileReadInfo readContent(FileOpInfo info) throws Exception {
FileReadInfo result = new FileReadInfo();
long count;
Object node = null;
try {
node = getResolvedNode(info.filename.toString());
} catch(NameNotFoundException ex) {
}
if(node == null) throw new VFSException("File not found: " + info.filename);
RAF raf = null;
if(node instanceof FNode) {
raf = ((FNode) node).getFileContent().getRAF();
} else if(node instanceof Context) {
throw new VFSException(info.filename.toString() + " is a directory.");
}
raf.seek(info.offset);
int size = 8192;
int togo = (int) (raf.getLength() - info.offset);
if(togo <= 0) {
result.buf = new byte[] {};
result.more = false;
} else if( togo > 0 && togo <= size) {
result.buf = new byte[togo];
result.more = false;
} else {
result.buf = new byte[size];
result.more = true;
}
raf.read(result.buf);
return result;
}
/** Removes content data for specified file from persistence.
*/
public void removeContent(FileName name) throws Exception {
// ves content je v podatkovni strukturi, ki bo odstranjena
// skupaj z metainfom
}
public void rename(FileName oldPath, FileName newPath) throws Exception {
// v content delu ni ni� za postoriti na to temo
}
}