package org.jboss.fresh.vfs.impl;
import org.jboss.fresh.cache.HierarchicalCache;
import org.jboss.fresh.naming.PathExpression;
import org.jboss.fresh.vfs.FileInfo;
import org.jboss.fresh.vfs.FileName;
import org.jboss.fresh.vfs.VFSMetaCacheUpdater;
import org.jboss.fresh.vfs.VFSStoreCacheUpdater;
import org.apache.log4j.Logger;
import java.io.Serializable;
import java.util.*;
public class VFSCacheWrapper implements VFSMetaCacheUpdater, VFSStoreCacheUpdater {
private static Logger log = Logger.getLogger("org.jboss.fresh.vfs.impl.VFSCacheWrapper");
public HierarchicalCache cache;
public VFSCacheWrapper(HierarchicalCache cache) {
this.cache = cache;
}
public void onExists(FileName pe, boolean result) {
// System.out.println( "[VFSCacheWrapper] [onExists()] " +pe );
VFSCacheItem item = getCachedItem(pe);
if (!result) {
item.setFileInfo(null);
item.setListComplete(false);
item.setContent(null);
item.setChildrenCount(null);
}
item.setExists(new Boolean(result));
}
public void onCountChildren(FileName pe, int count) {
// System.out.println( "[VFSCacheWrapper] [onCountChildren()] " +pe );
VFSCacheItem item = getCachedItem(pe);
item.setChildrenCount(new Integer(count));
item.setExists(new Boolean(true));
}
public void onGetFileInfo(FileName pe, FileInfo fileinfo) {
// System.out.println( "[VFSCacheWrapper] [onGetFileInfo()] FileInfo " +pe+ " cached." );
// log.trace("/vfs/cache", "FileInfo " + pe + " cached.");
VFSCacheItem item = getCachedItem(pe);
item.setFileInfo(fileinfo);
item.setExists(new Boolean(true));
}
public void onList(FileName pe, List links) {
// System.out.println( "[VFSCacheWrapper] [onList()] " +pe );
VFSCacheItem item = getCachedItem(pe);
item.setListComplete(true);
item.setExists(new Boolean(true));
Iterator it = links.iterator();
while (it.hasNext()) {
FileInfo fi = (FileInfo) it.next();
onGetFileInfo(fi.getFileName(), fi);
}
}
public void onCreate(FileInfo fi) {
// System.out.println( "[VFSCacheWrapper] [onCreate()] " +fi.getFileName() );
FileName pe = fi.getFileName();
VFSCacheItem item = new VFSCacheItem();
cache.put(pe, item);
item.setFileInfo(fi);
item.setExists(new Boolean(true));
item.setChildrenCount(new Integer(0));
item.setContent(new Boolean(false));
}
public void onUpdate(FileInfo fi) {
// System.out.println( "[VFSCacheWrapper] [onUpdate()] " + fi.getFileName() );
FileName pe = fi.getFileName();
VFSCacheItem item = getCachedItem(pe);
item.setFileInfo(fi);
item.setExists(new Boolean(true));
}
public void onRemove(FileName pe, boolean recursive) {
// System.out.println( "[VFSCacheWrapper] [onRemove()] " +pe );
VFSCacheItem item = (VFSCacheItem) cache.remove(pe);
}
public void onRename(FileName pe, FileName newpe) {
// System.out.println( "[VFSCacheWrapper] [onRename] " +pe );
// log.trace("/vfs/cache", "[onRename] " + pe);
VFSCacheItem item = (VFSCacheItem) cache.remove(pe);
item.getFileInfo().setFileName(newpe);
cache.put(newpe, item);
}
public void onMoveBefore(FileName pe, float idx) {
// System.out.println( "[VFSCacheWrapper] [onMoveBefore] " +pe );
VFSCacheItem item = (VFSCacheItem) cache.get(pe);
if (item != null && item.getFileInfo() != null)
item.getFileInfo().setOrderIndex(idx);
}
public void onHasContent(FileName fn, boolean result) {
// System.out.println( "[VFSCacheWrapper] [onHasContent()] " +fn );
VFSCacheItem item = getCachedItem(fn);
item.setContent(new Boolean(result));
}
public void onWriteContent(FileName fn) {
// System.out.println( "[VFSCacheWrapper] [onWriteContent()] " +fn );
VFSCacheItem item = getCachedItem(fn);
item.setContent(new Boolean(true));
}
public void onRemoveContent(FileName fn) {
// System.out.println( "[VFSCacheWrapper] [onRemoveContent()] " +fn );
VFSCacheItem item = getCachedItem(fn);
item.setContent(new Boolean(false));
}
public void onRenameContent(FileName fn) {
// System.out.println( "[VFSCacheWrapper] [onRenameContent()] " +fn );
// log.trace("/vfs/cache", "[onRenameContent()] " + fn);
onRemoveContent(fn);
}
public List[] resolve(FileName pe, boolean faster) {
// System.out.println( "[VFSCacheWrapper] [resolve()] File " +pe+ ", faster = " +faster );
// log.trace("/vfs/cache", "[resolve()] File " + pe + ", faster = " + faster);
List res = new ArrayList();
List[] result = new List[]{res};
res.add(pe);
Iterator it = pe.iterateTokens();
FileName path = new FileName(new Vector(), true);
int i = 0;
while (it.hasNext()) {
i++;
Object token = it.next();
path = path.absolutize((String) token);
// System.out.println( "[VFSCacheWrapper] [resolve()] Step = " +path );
// log.trace("/vfs/cache", "Step = " + path);
// System.out.println( "[VFSCacheWrapper] [resolve()] tokens = " +path );
// log.trace("/vfs/cache", "tokens = " + path);
FileInfo[] fromCache = getFileInfo(path);
FileInfo fi;
// if not cached
// and not cached as inexisting
if (fromCache != null && fromCache[0] != null)
fi = fromCache[0];
else {
// ce pa imamo slucajno cachirano, da ne obstaja potem je resolve success!
boolean[] existsFromCache = exists(path);
if (existsFromCache != null && existsFromCache[0] == false) {
res.add(path);
break;
}
result = null;
break;
}
if (fi.isLink()) {
path = fi.getTarget();
if (!faster) {
FileName tmp = path;
for (int j = i; j < pe.getTokens().size(); j++)
tmp.absolutize((String) pe.getTokens().get(j));
res.add(tmp);
}
}
}
if (faster)
res.add(path);
if (result != null) {
// System.out.println( "[VFSCacheWrapper] [resolve()] File " +pe+ " resolved to " +result[0].get(result[0].size()-1)+ " using cache." );
// log.trace("/vfs/cache", "File " + pe + " resolved to " + result[0].get(result[0].size() - 1) + " using cache.");
} else {
// System.out.println( "[VFSCacheWrapper] [resolve()] Could not resolve " +pe+ " using cache." );
// log.trace("/vfs/cache", "Could not resolve " + pe + " using cache.");
}
return result;
}
public boolean[] exists(FileName pe) {
boolean[] result = null;
VFSCacheItem item = (VFSCacheItem) cache.get(pe);
if (item != null && item.exists() != null) {
result = new boolean[]{item.exists().booleanValue()};
// System.out.println( "[VFSCacheWrapper] [exists()] " +pe+ " using cache." );
}
return result;
}
public int[] countChildren(FileName pe) {
int[] result = null;
VFSCacheItem item = (VFSCacheItem) cache.get(pe);
if (item != null && item.countChildren() != null) {
result = new int[]{item.countChildren().intValue()};
// System.out.println( "[VFSCacheWrapper] [countChildren()] " +pe+ " using cache." );
}
return result;
}
public FileInfo[] getFileInfo(FileName pe) {
// System.out.println( "[WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW] Loading FileInfo for " +pe+ "." );
FileInfo[] result = null;
VFSCacheItem item = (VFSCacheItem) cache.get(pe);
// System.out.println( "[WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW] item = " + item );
// System.out.println( "[WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW]");
if (item != null && item.getFileInfo() != null)
result = new FileInfo[]{item.getFileInfo()};
else if (item != null && !item.exists().booleanValue())
result = new FileInfo[]{null};
//System.out.println( "[WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW] result = " +result );
/*
if ( result != null ) {
System.out.println( "[VFSCacheWrapper] [getFileInfo()] FileInfo for " +pe+ " loaded using cache." );
System.out.println( result[0] );
}
*/
return result;
}
public List[] list(FileName pe) {
List[] result = null;
VFSCacheItem item = (VFSCacheItem) cache.get(pe);
Collection c = cache.childrenVals(pe);
if (item != null && item.listComplete) {
List l = new ArrayList();
Iterator it = c.iterator();
while (it.hasNext()) {
item = (VFSCacheItem) it.next();
if (item.exists() != null && item.exists().booleanValue())
l.add(item.getFileInfo());
}
Collections.sort(l, new Comparator() {
public int compare(Object o1, Object o2) {
float fnum1 = ((FileInfo) o1).getOrderIndex();
float fnum2 = ((FileInfo) o2).getOrderIndex();
if (fnum1 > fnum2)
return 1;
else if (fnum1 < fnum2)
return -1;
else
return 0;
}
public boolean equals(Object o) {
return false;
}
});
result = new List[]{l};
// System.out.println( "[VFSCacheWrapper] [list()] " +pe+ " using cache." );
}
return result;
}
public boolean[] hasContent(FileName pe) {
boolean[] result = null;
VFSCacheItem item = (VFSCacheItem) cache.get(pe);
if (item != null && item.getFileInfo() != null) {
result = new boolean[]{item.hasContent().booleanValue()};
// System.out.println( "[VFSCacheWrapper] [hasContent()] " +pe+ " using cache." );
}
return result;
}
private VFSCacheItem getCachedItem(PathExpression pe) {
VFSCacheItem item = (VFSCacheItem) cache.get(pe);
if (item == null)
cache.put(pe, (item = new VFSCacheItem()));
return item;
}
static class VFSCacheItem implements Serializable {
private FileInfo fileinfo;
private Boolean exists;
private boolean listComplete;
private Boolean content;
private Integer childrenCount;
public FileInfo getFileInfo() {
return fileinfo;
}
public Boolean exists() {
return exists;
}
public boolean isListComplete() {
return listComplete;
}
public Boolean hasContent() {
return content;
}
public Integer countChildren() {
return childrenCount;
}
public void setFileInfo(FileInfo fi) {
fileinfo = fi;
}
public void setExists(Boolean exists) {
VFSCacheItem.this.exists = exists;
}
public void setListComplete(boolean lc) {
listComplete = lc;
}
public void setContent(Boolean con) {
content = con;
}
public void setChildrenCount(Integer i) {
childrenCount = i;
}
public String toString() {
StringBuffer buf = new StringBuffer();
buf.append("fileinfo = " + fileinfo);
buf.append("\nexists = " + exists);
buf.append("\nlistCmp = " + listComplete);
buf.append("\ncontent = " + content);
buf.append("\nchildCnt = " + childrenCount + "\n");
return buf.toString();
}
}
}