All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.osmdroid.mtp.download.DownloadManager Maven / Gradle / Ivy

// Created by plusminus on 9:34:16 PM - Mar 5, 2009
package org.osmdroid.mtp.download;

import org.osmdroid.mtp.adt.OSMTileInfo;
import org.osmdroid.tileprovider.util.StreamUtils;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.Queue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class DownloadManager {
    // ===========================================================
    // Constants
    // ===========================================================

    // ===========================================================
    // Fields
    // ===========================================================

    private final ExecutorService mThreadPool;

    private final Queue mQueue = new LinkedBlockingQueue();

    private final String mBaseURL;
    private final String mDestinationURL;

    // ===========================================================
    // Constructors
    // ===========================================================

    public DownloadManager(final String pBaseURL, final String pDestinationURL, final int mThreads) {
        this.mBaseURL = pBaseURL;
        this.mDestinationURL = pDestinationURL;
        this.mThreadPool = Executors.newFixedThreadPool(mThreads);
    }

    // ===========================================================
    // Getter & Setter
    // ===========================================================

    public synchronized void add(final OSMTileInfo pTileInfo) {
        this.mQueue.add(pTileInfo);
        spawnNewThread();
    }

    private synchronized OSMTileInfo getNext() {
        final OSMTileInfo tile = this.mQueue.poll();

        final int remaining = this.mQueue.size();
        if (remaining % 10 == 0 && remaining > 0) {
            System.out.print("(" + remaining + ")");
        } else {
            System.out.print(".");
        }

        this.notify();
        return tile;
    }

    public synchronized void waitEmpty() throws InterruptedException {
        while (this.mQueue.size() > 0) {
            this.wait();
        }
    }

    public void waitFinished() throws InterruptedException {
        waitEmpty();
        this.mThreadPool.shutdown();
        this.mThreadPool.awaitTermination(6, TimeUnit.HOURS);
    }

    // ===========================================================
    // Methods from SuperClass/Interfaces
    // ===========================================================

    // ===========================================================
    // Methods
    // ===========================================================

    private void spawnNewThread() {
        this.mThreadPool.execute(new DownloadRunner());
    }

    // ===========================================================
    // Inner and Anonymous Classes
    // ===========================================================


    private class DownloadRunner implements Runnable {

        private OSMTileInfo mTileInfo;
        private File mDestinationFile;

        public DownloadRunner() {
        }

        private void init(final OSMTileInfo pTileInfo) {
            this.mTileInfo = pTileInfo;
            /* Create destination file. */
            final String filename = String.format(DownloadManager.this.mDestinationURL, this.mTileInfo.zoom, this.mTileInfo.x, this.mTileInfo.y);
            this.mDestinationFile = new File(filename);

            final File parent = this.mDestinationFile.getParentFile();
            parent.mkdirs();
        }

        @Override
        public void run() {
            InputStream in = null;
            OutputStream out = null;

            init(DownloadManager.this.getNext());

            if (mDestinationFile.exists()) {
                return; // TODO issue 70 - make this an option
            }

            final String finalURL = String.format(DownloadManager.this.mBaseURL, this.mTileInfo.zoom, this.mTileInfo.x, this.mTileInfo.y);

            try {
                in = new BufferedInputStream(new URL(finalURL).openStream(), StreamUtils.IO_BUFFER_SIZE);

                final FileOutputStream fileOut = new FileOutputStream(this.mDestinationFile);
                out = new BufferedOutputStream(fileOut, StreamUtils.IO_BUFFER_SIZE);

                StreamUtils.copy(in, out);

                out.flush();
            } catch (final Exception e) {
                System.err.println("Error downloading: '" + this.mTileInfo + "' from URL: " + finalURL + " : " + e);
                DownloadManager.this.add(this.mTileInfo); // try again later
            } finally {
                StreamUtils.closeStream(in);
                StreamUtils.closeStream(out);
            }
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy