// Copyright (C) 2003-2009 by Object Mentor, Inc. All rights reserved.
// Released under the terms of the CPL Common Public License version 1.0.
package fitnesse.wiki;
import java.lang.ref.SoftReference;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import util.TimeMeasurement;
public abstract class CachingPage extends CommitingPage {
private static final long serialVersionUID = 1L;
public static int cacheTime = 3000;
protected Map<String, WikiPage> children = new HashMap<String, WikiPage>();
private transient SoftReference<PageData> cachedData;
private transient TimeMeasurement cachedTime;
public CachingPage(String name, WikiPage parent) {
super(name, parent);
addExtention(new VirtualCouplingExtension(this));
}
public abstract boolean hasChildPage(String pageName);
protected abstract WikiPage createChildPage(String name);
protected abstract void loadChildren();
protected abstract PageData makePageData();
public WikiPage addChildPage(String name) {
WikiPage page = createChildPage(name);
children.put(name, page);
return page;
}
@Override
public List<WikiPage> getNormalChildren() {
loadChildren();
return getCachedChildren();
}
public List<WikiPage> getCachedChildren() {
return new ArrayList<WikiPage>(children.values());
}
public void removeChildPage(String name) {
if (hasCachedSubpage(name))
children.remove(name);
}
@Override
public WikiPage getNormalChildPage(String name) {
if (hasCachedSubpage(name) || hasChildPage(name))
return children.get(name);
else
return null;
}
protected boolean hasCachedSubpage(String name) {
return children.containsKey(name);
}
public PageData getData() {
if (cachedDataExpired()) {
ReloadCache();
}
return new PageData(getCachedData());
}
private void ReloadCache() {
//if (getCachedData() == null) System.out.println("cache null " + (getName() != null ? getName() : "?"));
//else if (cachedTime.elapsed() >= cacheTime) System.out.println("cache expired " + (getName() != null ? getName() : "?"));
PageData data = makePageData();
//System.out.println("reload " + getName() + " " + data.getContent().length());
setCachedData(data);
}
public ReadOnlyPageData readOnlyData() {
if (getCachedData() == null) {
ReloadCache();
}
return getCachedData();
}
private boolean cachedDataExpired() {
return getCachedData() == null || cachedTime.elapsed() >= cacheTime;
}
public void dumpExpiredCachedData() {
if (cachedDataExpired())
clearCache();
}
@Override
public VersionInfo commit(PageData data) {
VersionInfo versionInfo = super.commit(data);
setCachedData(makePageData());
return versionInfo;
}
private void setCachedData(PageData data) {
if (cachedData != null)
cachedData.clear();
cachedData = new SoftReference<PageData>(data);
cachedTime = new TimeMeasurement().start();
}
public PageData getCachedData() {
if (cachedData != null)
return cachedData.get();
else
return null;
}
public void clearCache() {
cachedData.clear();
cachedData = null;
}
}