--- /dev/null
+package tim.prune.function.cache;
+
+import java.io.File;
+import java.util.ArrayList;
+
+import tim.prune.gui.map.MapSource;
+import tim.prune.gui.map.MapSourceLibrary;
+
+/**
+ * Class to obtain and hold information about the current
+ * tile cache including its subdirectories
+ */
+public class TileCacheModel
+{
+ /** Cache directory */
+ private File _cacheDir = null;
+ /** Array of tilesets */
+ private ArrayList<TileSet> _tileSets = null;
+ /** Summary information */
+ private RowInfo _summaryRow = null;
+ /** Cancelled flag */
+ private boolean _cancelled = false;
+
+
+ /**
+ * Constructor
+ * @param inDir start directory
+ */
+ public TileCacheModel(File inDir)
+ {
+ if (inDir != null && inDir.exists() && inDir.isDirectory() && inDir.canRead()) {
+ _cacheDir = inDir;
+ }
+ _cancelled = false;
+ }
+
+ /**
+ * Build the tilesets by searching recursively
+ */
+ public void buildTileSets()
+ {
+ if (_cacheDir == null) return;
+
+ _tileSets = new ArrayList<TileSet>();
+ // go through subdirectories, if any
+ File[] subdirs = _cacheDir.listFiles();
+ for (File subdir : subdirs)
+ {
+ if (subdir != null && subdir.isDirectory() && subdir.exists() && subdir.canRead()
+ && !_cancelled)
+ {
+ getTileSets(subdir, null, _tileSets);
+ }
+ }
+ // Loop over found tile sets and create summary rowinfo
+ _summaryRow = new RowInfo();
+ for (TileSet ts : _tileSets)
+ {
+ _summaryRow.addRow(ts.getRowInfo());
+ }
+ }
+
+ /**
+ * Get all the tilesets from the given directory
+ * @param inDir directory to search
+ * @return array of TileSet objects
+ */
+ private static void getTileSets(File inDir, String inParentPath, ArrayList<TileSet> inTsList)
+ {
+ final String wholePath = (inParentPath == null ? "" : inParentPath)
+ + inDir.getName() + File.separator;
+ // See if any configured backgrounds use this directory
+ // or if the directories match OSM structure
+ String usedByDesc = matchConfig(wholePath);
+ boolean tsFound = false;
+ if (usedByDesc != null || looksLikeCacheDir(inDir))
+ {
+ TileSet ts = new TileSet(inDir, wholePath, usedByDesc);
+ if (usedByDesc != null || ts.getRowInfo().getNumTiles() > 0)
+ {
+ tsFound = true;
+ inTsList.add(ts);
+ }
+ }
+ // If a tileset wasn't found, look through subdirectories
+ if (!tsFound)
+ {
+ // Go through subdirectories and look at each of them too
+ File[] subdirs = inDir.listFiles();
+ if (subdirs != null) {
+ for (File subdir : subdirs)
+ {
+ if (subdir != null && subdir.exists() && subdir.isDirectory()
+ && subdir.canRead())
+ {
+ getTileSets(subdir, wholePath, inTsList);
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * Match the given directory name to find the configs which use it
+ * @param inName name of directory to match
+ * @return null if not used, otherwise comma-separated list of background names
+ */
+ private static String matchConfig(String inName)
+ {
+ if (inName == null || inName.equals(""))
+ return null;
+ String usedBy = null;
+ for (int i=0; i<MapSourceLibrary.getNumSources(); i++)
+ {
+ MapSource ms = MapSourceLibrary.getSource(i);
+ for (int l=0; l<2; l++)
+ {
+ String msdir = ms.getSiteName(l);
+ if (msdir != null && msdir.equals(inName))
+ {
+ if (usedBy == null)
+ usedBy = ms.getName();
+ else
+ usedBy = usedBy + ", " + ms.getName();
+ }
+ }
+ }
+ return usedBy;
+ }
+
+ /**
+ * @param inDir directory to test
+ * @return true if the subdirectories meet the normal osm layout
+ */
+ private static boolean looksLikeCacheDir(File inDir)
+ {
+ // look for at least one numeric directory, nothing else
+ boolean numFound = false;
+ if (inDir != null && inDir.exists() && inDir.isDirectory() && inDir.canRead())
+ {
+ for (File subdir : inDir.listFiles())
+ {
+ // Only consider readable things which exist
+ if (subdir != null && subdir.exists() && subdir.canRead())
+ {
+ // subdirectories should have numeric names (for the zoom levels)
+ if (subdir.isDirectory() && TileSet.isNumeric(subdir.getName())
+ && subdir.getName().length() < 3)
+ {
+ numFound = true;
+ }
+ else return false; // either a file or non-numeric directory
+ }
+ }
+ }
+ return numFound;
+ }
+
+ /**
+ * @return cache directory
+ */
+ public File getCacheDir() {
+ return _cacheDir;
+ }
+
+ /**
+ * @return number of tile sets
+ */
+ public int getNumTileSets()
+ {
+ if (_tileSets == null) return 0;
+ return _tileSets.size();
+ }
+
+ /**
+ * @return the total number of tile images found
+ */
+ public int getTotalTiles()
+ {
+ return _summaryRow.getNumTiles();
+ }
+
+ /**
+ * @return the total number of bytes taken up with tile images
+ */
+ public long getTotalBytes()
+ {
+ return _summaryRow.getTotalSize();
+ }
+
+ /**
+ * @param inIndex index of tileset
+ * @return requested tileset
+ */
+ public TileSet getTileSet(int inIndex)
+ {
+ if (inIndex >= 0 && inIndex < getNumTileSets()) {
+ return _tileSets.get(inIndex);
+ }
+ return null;
+ }
+
+ /**
+ * Cancel the search
+ */
+ public void cancel() {
+ _cancelled = true;
+ }
+
+ /**
+ * @return true if search was cancelled
+ */
+ public boolean isAborted() {
+ return _cancelled;
+ }
+}