/* * 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 java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import com.mandelsoft.io.AbstractFile; import com.mandelsoft.io.FileAbstractFile; import com.mandelsoft.mand.ColormapName; import com.mandelsoft.mand.MandelFileName; import com.mandelsoft.mand.MandelHeader; import com.mandelsoft.mand.MandelName; import com.mandelsoft.mand.QualifiedMandelName; import com.mandelsoft.mand.scan.MandelScanner.Filter; import com.mandelsoft.mand.util.MandUtils; /** * * @author Uwe Krüger */ /* * generally caching the relevant folder contents in memory */ public abstract class FolderMandelScannerSupport extends MandelScannerSupport { public static boolean debug=false; private Map<MandelName, Map<AbstractFile,MandelHandle>> mandels; private Map<ColormapName,Map<AbstractFile,ColormapHandle>> colmaps; private Map<AbstractFile,ElementHandle<?>> files; protected FolderMandelScannerSupport() { this(MandelScanner.HAS_IMAGEDATA); } protected FolderMandelScannerSupport(Filter filter) { this(filter,true); } protected FolderMandelScannerSupport(Filter filter, boolean setup) { super(filter); mandels=new HashMap<MandelName,Map<AbstractFile,MandelHandle>>(); colmaps=new HashMap<ColormapName,Map<AbstractFile,ColormapHandle>>(); files=new HashMap<AbstractFile,ElementHandle<?>>(); } ////////////////////////////////////////////////////////////////////////// // basic methods to be implemented for MandelScannerSupport ////////////////////////////////////////////////////////////////////////// protected Set<MandelName> _getMandelNames() { if (debug) System.out.println(this+" lookup mandel names "); return (mandels.keySet()); } protected Set<MandelHandle> _getMandelHandles(MandelName name) { if (debug) System.out.println(this+" lookup headers "+name); return valueSet(mandels, name); } protected Set<ColormapName> _getColormapNames() { if (debug) System.out.println(this+" lookup colmaps"); return (colmaps.keySet()); } protected Set<ColormapHandle> _getColormapHandles(ColormapName name) { if (debug) System.out.println(this+" lookup "+name); return valueSet(colmaps, name); } //////////////////////////////////////////////////////////////////////// // optimized implementations //////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // avoid unneccessary copy of set, beacuse it is already copied // @Override synchronized public Set<MandelHandle> getMandelHandles(MandelName name) { return _getMandelHandles(name); } @Override synchronized public Set<ColormapHandle> getColormapHandles(ColormapName name) { return _getColormapHandles(name); } ////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////// // optimized implementation for support class @Override synchronized public MandelHandle getMandelInfo(MandelName name) { if (debug) System.out.println(this+" lookup info "+name); Map<AbstractFile, MandelHandle> sub=mandels.get(name); if (sub==null) return null; Set<AbstractFile> set=new HashSet<AbstractFile>(sub.keySet()); while (!set.isEmpty()) { MandelHandle best=null; for (AbstractFile f:set) { MandelHandle h=sub.get(f); if (h.getHeader().hasInfo()) { best=MandUtils.better(best, h); } } if (best!=null) { try { return new CachedMandelHandle(best).assertInfo(); } catch (IOException ex) { set.remove(best.getFile()); } } else break; } return null; } @Override synchronized public MandelHandle getMandelData(MandelName name) { if (debug) System.out.println(this+" lookup data "+name); Map<AbstractFile, MandelHandle> sub=mandels.get(name); if (sub==null) return null; Set<AbstractFile> set=new HashSet<AbstractFile>(sub.keySet()); while (!set.isEmpty()) { MandelHandle best=null; for (AbstractFile f:set) { MandelHandle h=sub.get(f); if (h.getHeader().hasInfo()) { best=MandUtils.better(best, h); } } if (best!=null) { try { return new CachedMandelHandle(best).assertData(); } catch (IOException ex) { // just try next set.remove(best.getFile()); } } else break; } return null; } // // utilities // protected void clear() { if (debug) System.out.println("clearing "+this); startUpdate(true); mandels.clear(); files.clear(); colmaps.clear(); finishUpdate(); } protected <K,H> Set<H> valueSet(Map<K, Map<AbstractFile,H>> map, K name) { Set<H> set; Map<AbstractFile,H> sub=map.get(name); if (sub==null) set=new HashSet<H>(); else set=new HashSet<H>(sub.values()); return set; } @Override synchronized public String toString() { String id=super.toString(); int ix=id.lastIndexOf('@'); if (ix>=0) id=id.substring(ix); else id=""; return files.size()+"/"+mandels.size()+"/"+colmaps.size()+id; } protected void dump() { System.out.println(toString()+":"); dump(mandels); } //////////////////////////////////////////////////////////////////////////// // generic map util protected <K,H> void dump(Map<K,Map<AbstractFile,H>> map) { for (K n: map.keySet()) { System.out.println(" "+n); } } protected <K,H extends ElementHandle<?>> void add(Map<K,Map<AbstractFile,H>> map, K name, H h) { Map<AbstractFile,H> sub=map.get(name); if (sub==null) { sub=new HashMap<AbstractFile,H>(); map.put(name, sub); } sub.put(h.getFile(), h); } protected <K,H> H remove(Map<K,Map<AbstractFile,H>> map, K name, AbstractFile f) { H h=null; Map<AbstractFile,H> sub=map.get(name); if (sub!=null) { h=sub.remove(f); if (sub.isEmpty()) { map.remove(name); } if (debug) { if (h==null) { if (debug) { System.out.println(" no sub entry found for "+f); for (AbstractFile n:sub.keySet()) { System.out.println(" "+n); } } } } } else { if (debug) { System.out.println(" no entry found for "+name); dump(map); } } return h; } //////////////////////////////////////////////////////////////////////////// // type specific handling protected void add(MandelHandle h) { //System.out.println(" adding mandel "+h.getFile()); add(mandels,h.getName().getMandelName(),h); files.put(h.getFile(), h); notifyAddMandelFile(h); } protected void add(ColormapHandle h) { //System.out.println(" adding colormap "+h.getFile()); add(colmaps,h.getName(),h); notifyAddColormap(h); } protected MandelHandle create(AbstractFile f, QualifiedMandelName n, MandelHeader h) { return new DefaultMandelHandle(f,n,h); } protected ColormapHandle create(AbstractFile f, ColormapName n, MandelHeader h) { return new DefaultColormapHandle(f,n,h); } //////////////////////////////////////////////////////////////////////////// // file handling protected void add(File f) { try { String base=f.getName(); int ix=base.lastIndexOf('.'); if (ix>0) base=base.substring(0,ix); MandelFileName n=null; boolean namedone=false; if (!providesColormaps()) { namedone=true; n=MandelFileName.create(f); } try { MandelHeader h=MandelHeader.getHeader(f); AbstractFile af=new FileAbstractFile(f); //System.out.println(" "+f.getMandelName()+" is mandel "+h+"("+h.getType()+")"); if (filter(h)) { if (h.isColormap()) { add(create(af,new ColormapName(base),h)); } else { if (n==null) { if (namedone) return; n=MandelFileName.create(f); } add(create(af,n.getQualifiedName(),h)); } //System.out.println(" used"); } } catch (IOException io) { // System.out.println(" no mandel: "+f); } } catch (IllegalArgumentException ex) { //ignore } } protected void remove(AbstractFile f) { Map<AbstractFile,MandelHeader> m; MandelHandle mh; ColormapHandle ch; try { String base=f.getName(); int ix=base.lastIndexOf('.'); if (ix>0) base=base.substring(0,ix); MandelFileName n=MandelFileName.create(f); if (debug) System.out.println(toString()+": remove mandel file "+f+": "+n); if (files.remove(f)==null) { if (debug) System.out.println(" file not registered"); } if (n!=null) { mh=remove(mandels,n.getQualifiedName().getMandelName(),f); if (mh!=null) { notifyRemoveMandelFile(mh); } else { if (debug) System.out.println(" header not registered"); } } ColormapName cn=new ColormapName(base); ch=remove(colmaps, cn, f); if (ch!=null) { notifyRemoveColormap(ch); } else { if (debug) System.out.println(" colormap not registerd"); } } catch (IllegalArgumentException ex) { //ignore } } }