package com.nutiteq.task; import java.util.Vector; import com.nutiteq.cache.Cache; import com.nutiteq.components.MapTile; import com.nutiteq.io.StreamedTileRetriever; import com.nutiteq.io.UnstreamedTileRetriever; import com.nutiteq.maps.GeoMap; import com.nutiteq.maps.MapTilesRequestor; import com.nutiteq.maps.StoredMap; import com.nutiteq.maps.StreamedMap; import com.nutiteq.maps.UnstreamedMap; public class MapTileSearchTask implements Task { private final MapTilesRequestor tilesRequestor; private final GeoMap[] tileSearchStrategy; private final TasksRunner taskRunner; private final int strategyIndex; private MapTile[] toRetrieve; public MapTileSearchTask(final MapTilesRequestor tilesRequestor, final GeoMap[] tileSearchStrategy, final TasksRunner taskRunner) { this(tilesRequestor, tileSearchStrategy, taskRunner, 0, new MapTile[0]); } public MapTileSearchTask(final MapTilesRequestor tilesRequestor, final GeoMap[] tileSearchStrategy, final TasksRunner taskRunner, final int strategyIndex, final MapTile[] toRetrieve) { this.tilesRequestor = tilesRequestor; this.tileSearchStrategy = tileSearchStrategy; this.taskRunner = taskRunner; this.strategyIndex = strategyIndex; this.toRetrieve = toRetrieve; } public void execute() { if (strategyIndex == tileSearchStrategy.length) { finishRetrieval(toRetrieve); //start next search retrieveSuccess(); return; } final GeoMap map = tileSearchStrategy[strategyIndex]; if (strategyIndex == 0) { toRetrieve = appendTiles(toRetrieve, pullNeededTiles(map, tilesRequestor)); } if (toRetrieve.length == 0) { return; } if (map instanceof StoredMap) { //TODO jaanus : try to megre this with unstreamed/streamed implementation final StoredMap sMap = (StoredMap) map; if (sMap.isInitializeConf()) { sMap.initializeConfigUsingFs(taskRunner.getFileSystem()); } taskRunner.enqueue(new ReadStoredMapTileTask(this, toRetrieve, sMap, taskRunner .getFileSystem())); } else if (map instanceof UnstreamedMap) { taskRunner.enqueueDownload( new UnstreamedTileRetriever(this, toRetrieve, (UnstreamedMap) map), Cache.CACHE_LEVEL_NONE); } else if (map instanceof StreamedMap) { toRetrieve = findStreamedFromCache(toRetrieve, (StreamedMap) map, taskRunner .getNetworkCache()); if (toRetrieve.length == 0) { //TODO jaanus : check this retrieveSuccess(); return; } taskRunner.enqueueDownload(new StreamedTileRetriever(this, toRetrieve, (StreamedMap) map), Cache.CACHE_LEVEL_NONE); } } private MapTile[] findStreamedFromCache(final MapTile[] tiles, final StreamedMap map, final Cache networkCache) { if (networkCache == null) { return tiles; } final Vector uncached = new Vector(); for (int i = 0; i < tiles.length; i++) { final MapTile t = tiles[i]; if (networkCache.contains(t.getIDString())) { final byte[] tc = networkCache.get(t.getIDString()); if (tc != null) { t.setImagesData(new byte[][] { tc }); } else { // file not found from cache uncached.addElement(t); } } else { uncached.addElement(t); } } final MapTile[] result = new MapTile[uncached.size()]; uncached.copyInto(result); return result; } private MapTile[] appendTiles(final MapTile[] toRetrieve, final MapTile[] additionalTiles) { final int titalSize = toRetrieve.length + additionalTiles.length; final MapTile[] result = new MapTile[titalSize]; System.arraycopy(toRetrieve, 0, result, 0, toRetrieve.length); System.arraycopy(additionalTiles, 0, result, toRetrieve.length, additionalTiles.length); return result; } private MapTile[] pullNeededTiles(final GeoMap map, final MapTilesRequestor tilesRequestor) { MapTile[] result = new MapTile[0]; if (map instanceof UnstreamedMap) { final MapTile required = tilesRequestor.getRequiredTile(); if (required != null) { result = new MapTile[] { required }; } } else { result = tilesRequestor.getAllRequiredTiles(); } return result; } private void finishRetrieval(final MapTile[] failedTiles) { for (int i = 0; i < failedTiles.length; i++) { failedTiles[i].notifyError(); } } public void retrieveErrorFor(final MapTile[] errorTiles) { taskRunner.enqueue(new MapTileSearchTask(tilesRequestor, tileSearchStrategy, taskRunner, strategyIndex + 1, errorTiles)); } public void retrieveSuccess() { taskRunner.enqueue(new MapTileSearchTask(tilesRequestor, tileSearchStrategy, taskRunner)); } }