/*
* Copyright 2011 Uwe Krueger.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.mandelsoft.mand.scan;
import com.mandelsoft.mand.QualifiedMandelName;
import java.io.IOException;
import java.util.HashMap;
import com.mandelsoft.mand.MandelData;
import com.mandelsoft.io.AbstractFile;
import com.mandelsoft.mand.ColormapName;
import com.mandelsoft.mand.MandelFileName;
import com.mandelsoft.mand.MandelHeader;
import com.mandelsoft.mand.MandelInfo;
import com.mandelsoft.mand.cm.Colormap;
import com.mandelsoft.mand.scan.MandelScanner.Filter;
/**
*
* @author Uwe Krueger
*/
public abstract class CachedFolderMandelScannerSupport extends FolderMandelScannerSupport {
static public boolean debug=false;
protected HashMap<AbstractFile,MandelInfo> infos=
new HashMap<AbstractFile,MandelInfo>();
protected HashMap<AbstractFile,MandelData> colormaps=
new HashMap<AbstractFile,MandelData>();
protected boolean initial=true;
public CachedFolderMandelScannerSupport(Filter filter, boolean setup)
{
super(filter, setup);
}
public CachedFolderMandelScannerSupport(Filter filter)
{
super(filter);
}
public CachedFolderMandelScannerSupport()
{
}
abstract protected MandelFolderCache getCache();
//////////////////////////////////////////////////////////////////////////
private class MyMandelHandle extends DefaultMandelHandle {
public MyMandelHandle(AbstractFile file, QualifiedMandelName name,
MandelHeader header)
{
super(file,name,header);
}
@Override
public MandelData getInfo() throws IOException
{
MandelInfo info=infos.get(getFile());
if (info==null) {
// info data omitted in cache; read directly
try {
MandelData md=super.getInfo();
if (md!=null) infos.put(getFile(), info);
return md;
}
catch (IOException io) {
System.err.println("cannot read "+getFile()+": "+io);
throw io;
}
}
else {
return new MandelData(info,getHeader(),getFile());
}
}
}
@Override
protected MandelHandle create(AbstractFile f, QualifiedMandelName n,
MandelHeader h)
{
return new MyMandelHandle(f, n, h);
}
//////////////////////////////////////////////////////////////////////////
private class MyColormapHandle extends DefaultColormapHandle {
public MyColormapHandle(AbstractFile file, ColormapName name,
MandelHeader header)
{
super(file,name,header);
}
@Override
public MandelData getData() throws IOException
{
MandelData data=colormaps.get(getFile());
if (data==null) {
// info data omitted in cache; read directly
try {
MandelData md=super.getData();
if (md!=null) colormaps.put(getFile(), md);
return md;
}
catch (IOException io) {
System.err.println("cannot read "+getFile()+": "+io);
throw io;
}
}
else {
return data;
}
}
}
@Override
protected ColormapHandle create(AbstractFile f, ColormapName n,
MandelHeader h)
{
return new MyColormapHandle(f, n, h);
}
//////////////////////////////////////////////////////////////////////////
@Override
protected void clear()
{
if (debug) System.out.println("clear folder scanner");
initial=true;
infos.clear();
colormaps.clear();
super.clear();
}
@Override
protected void add(MandelHandle h)
{
infos.remove(h.getFile());
super.add(h);
}
@Override
protected void add(ColormapHandle h)
{
colormaps.remove(h.getFile());
super.add(h);
}
@Override
protected void remove(AbstractFile f)
{
infos.remove(f);
colormaps.remove(f);
super.remove(f);
}
//
// cache handling
//
private MandelHeader createMandelHeader(MandelFolderCache.Entry e)
throws IOException
{
return new MandelHeader(e.getType());
}
abstract protected AbstractFile createAbstractFile(MandelFolderCache.Entry e)
throws IOException;
protected void add(MandelFolderCache.Entry e)
{
//System.out.println("add "+e);
try {
String base=e.getFilename();
int ix=base.lastIndexOf('.');
if (ix>0) base=base.substring(0,ix);
MandelFileName n=null;
try {
MandelHeader h=createMandelHeader(e);
AbstractFile af;
if (h!=null && filter(h)) {
if (h.isColormap()) {
add(create(createAbstractFile(e),new ColormapName(base), h));
}
else {
n=MandelFileName.create(e.getFilename());
if (n==null) return;
add(create(af=createAbstractFile(e),n.getQualifiedName(), h));
if (h.hasInfo()) infos.put(af,e.getInfo());
}
//System.out.println(" used");
}
}
catch (IOException io) {
// System.out.println(" no mandel: "+f);
}
}
catch (IllegalArgumentException ex) {
//ignore
}
}
//
// file handling
//
public void rescan(boolean verbose)
{
rescan(verbose,true);
}
protected abstract boolean rescanNonCached(boolean verbose, boolean read);
protected boolean rescanCached(MandelFolderCache cache,
boolean verbose, boolean read)
{
boolean updated=true;
// System.out.println("using cache");
if (read) try {
updated=cache.update();
}
catch (IOException ex) {
System.err.println("cannot read cache: "+ex);
}
if (updated || initial) {
clear();
for (MandelFolderCache.Entry e:cache) {
add(e);
}
}
return updated;
}
protected void rescan(boolean verbose, boolean read)
{ boolean updated=true;
lock();
startUpdate();
try {
MandelFolderCache mcache=getCache();
if (mcache!=null) {
updated=rescanCached(mcache,verbose,read);
}
else {
updated=rescanNonCached(verbose, read);
}
}
finally {
releaseLock();
initial=false;
finishUpdate();
//if (debug) dump();
}
}
protected abstract void lock();
protected abstract void releaseLock();
}