diff --git a/vtm/build.gradle b/vtm/build.gradle index 45747427..adb2f2b0 100644 --- a/vtm/build.gradle +++ b/vtm/build.gradle @@ -5,11 +5,16 @@ configurations { providedCompile } dependencies { compile 'org.slf4j:slf4j-api:1.7.6' + compile 'com.squareup.okhttp:okhttp:1.5.2' providedCompile 'com.google.code.findbugs:annotations:2.0.1' + testCompile 'junit:junit:4.11' + testCompile 'org.mockito:mockito-all:1.9.5' + testCompile 'org.easytesting:fest-assert-core:2.0M10' } sourceSets { main.java.srcDirs = ['src'] + test.java.srcDirs = ['test'] main.resources.srcDirs = ['resources'] main.compileClasspath += configurations.providedCompile } diff --git a/vtm/src/org/oscim/tiling/source/HttpEngine.java b/vtm/src/org/oscim/tiling/source/HttpEngine.java new file mode 100644 index 00000000..bf3f3240 --- /dev/null +++ b/vtm/src/org/oscim/tiling/source/HttpEngine.java @@ -0,0 +1,19 @@ +package org.oscim.tiling.source; + +import org.oscim.core.Tile; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +public interface HttpEngine { + InputStream read() throws IOException; + + boolean sendRequest(UrlTileSource tileSource, Tile tile) throws IOException; + + void close(); + + void setCache(OutputStream os); + + boolean requestCompleted(boolean success); +} diff --git a/vtm/src/org/oscim/tiling/source/LwHttp.java b/vtm/src/org/oscim/tiling/source/LwHttp.java index 385a4bdf..8f3978ff 100644 --- a/vtm/src/org/oscim/tiling/source/LwHttp.java +++ b/vtm/src/org/oscim/tiling/source/LwHttp.java @@ -36,11 +36,8 @@ import org.slf4j.LoggerFactory; /** * Lightweight HTTP connection for tile loading. Does not do redirects, * https, full header parsing or stuff. - * - * TODO extract API interface to be used by UrlTileSource so that one - * could also use HttpUrlConnection, etc. */ -public class LwHttp { +public class LwHttp implements HttpEngine { static final Logger log = LoggerFactory.getLogger(LwHttp.class); static final boolean dbg = false; @@ -332,6 +329,7 @@ public class LwHttp { return is; } + @Override public boolean sendRequest(UrlTileSource tileSource, Tile tile) throws IOException { if (mSocket != null) { @@ -405,6 +403,7 @@ public class LwHttp { return true; } + @Override public void close() { if (mSocket == null) return; @@ -415,6 +414,7 @@ public class LwHttp { mResponseStream = null; } + @Override public void setCache(OutputStream os) { if (mResponseStream == null) return; @@ -422,6 +422,7 @@ public class LwHttp { mResponseStream.setCache(os); } + @Override public boolean requestCompleted(boolean success) { if (mResponseStream == null) return false; diff --git a/vtm/src/org/oscim/tiling/source/OkHttpEngine.java b/vtm/src/org/oscim/tiling/source/OkHttpEngine.java new file mode 100644 index 00000000..e68d31a0 --- /dev/null +++ b/vtm/src/org/oscim/tiling/source/OkHttpEngine.java @@ -0,0 +1,70 @@ +package org.oscim.tiling.source; + +import com.squareup.okhttp.OkHttpClient; + +import org.oscim.core.Tile; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.HttpURLConnection; +import java.net.URL; + +public class OkHttpEngine implements HttpEngine { + private final URL baseUrl; + private final OkHttpClient client; + private InputStream inputStream; + + public OkHttpEngine(URL baseUrl) { + this.baseUrl = baseUrl; + this.client = new OkHttpClient(); + } + + @Override + public InputStream read() throws IOException { + return inputStream; + } + + @Override + public boolean sendRequest(UrlTileSource tileSource, Tile tile) throws IOException { + final URL requestUrl = new URL(baseUrl.toString() + + "/" + + Byte.toString(tile.zoomLevel) + + "/" + + tile.tileX + + "/" + + tile.tileY + + ".vtm"); + + final HttpURLConnection connection = client.open(requestUrl); + + try { + inputStream = connection.getInputStream(); + } catch (Exception e) { + e.printStackTrace(); + } + + return true; + } + + @Override + public void close() { + if (inputStream != null) { + try { + inputStream.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + @Override + public void setCache(OutputStream os) { + // TODO: Evaluate OkHttp response cache and determine if additional caching is required. + } + + @Override + public boolean requestCompleted(boolean success) { + return true; + } +} diff --git a/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java b/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java index f26c90c0..a97272c3 100644 --- a/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java +++ b/vtm/src/org/oscim/tiling/source/UrlTileDataSource.java @@ -38,12 +38,12 @@ import org.slf4j.LoggerFactory; public class UrlTileDataSource implements ITileDataSource { static final Logger log = LoggerFactory.getLogger(UrlTileDataSource.class); - protected final LwHttp mConn; + protected final HttpEngine mConn; protected final ITileDecoder mTileDecoder; protected final UrlTileSource mTileSource; protected final boolean mUseCache; - public UrlTileDataSource(UrlTileSource tileSource, ITileDecoder tileDecoder, LwHttp conn) { + public UrlTileDataSource(UrlTileSource tileSource, ITileDecoder tileDecoder, HttpEngine conn) { mTileDecoder = tileDecoder; mTileSource = tileSource; mUseCache = (tileSource.tileCache != null); diff --git a/vtm/src/org/oscim/tiling/source/UrlTileSource.java b/vtm/src/org/oscim/tiling/source/UrlTileSource.java index 89515d14..d6ff2b99 100644 --- a/vtm/src/org/oscim/tiling/source/UrlTileSource.java +++ b/vtm/src/org/oscim/tiling/source/UrlTileSource.java @@ -26,6 +26,7 @@ public abstract class UrlTileSource extends TileSource { private final URL mUrl; private byte[] mExt; + private HttpEngine httpEngine; public UrlTileSource(String urlString) { URL url = null; @@ -107,4 +108,16 @@ public abstract class UrlTileSource extends TileSource { public URL getUrl() { return mUrl; } + + public void setHttpEngine(HttpEngine httpEngine) { + this.httpEngine = httpEngine; + } + + public HttpEngine getHttpEngine() { + if (httpEngine == null) { + httpEngine = new LwHttp(getUrl()); + } + + return httpEngine; + } } diff --git a/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java b/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java index 92a718de..40197f63 100644 --- a/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java +++ b/vtm/src/org/oscim/tiling/source/bitmap/BitmapTileSource.java @@ -32,7 +32,7 @@ public class BitmapTileSource extends UrlTileSource { @Override public ITileDataSource getDataSource() { - return new UrlTileDataSource(this, new BitmapTileDecoder(), new LwHttp(getUrl())); + return new UrlTileDataSource(this, new BitmapTileDecoder(), getHttpEngine()); } public class BitmapTileDecoder implements ITileDecoder { diff --git a/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java b/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java index b5dbc5a8..3d2788a7 100644 --- a/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java +++ b/vtm/src/org/oscim/tiling/source/oscimap4/OSciMap4TileSource.java @@ -17,7 +17,6 @@ package org.oscim.tiling.source.oscimap4; import org.oscim.tiling.ITileDataSource; -import org.oscim.tiling.source.LwHttp; import org.oscim.tiling.source.UrlTileDataSource; import org.oscim.tiling.source.UrlTileSource; @@ -34,6 +33,6 @@ public class OSciMap4TileSource extends UrlTileSource { @Override public ITileDataSource getDataSource() { - return new UrlTileDataSource(this, new TileDecoder(), new LwHttp(getUrl())); + return new UrlTileDataSource(this, new TileDecoder(), getHttpEngine()); } } diff --git a/vtm/test/org/oscim/tiling/source/UrlTileSourceTest.java b/vtm/test/org/oscim/tiling/source/UrlTileSourceTest.java new file mode 100644 index 00000000..b708cb40 --- /dev/null +++ b/vtm/test/org/oscim/tiling/source/UrlTileSourceTest.java @@ -0,0 +1,58 @@ +package org.oscim.tiling.source; + +import com.squareup.okhttp.OkHttpClient; + +import org.junit.Before; +import org.junit.Test; +import org.oscim.tiling.ITileDataSource; + +import static org.fest.assertions.api.Assertions.assertThat; + +public class UrlTileSourceTest { + private UrlTileSource tileSource; + + @Before + public void setUp() throws Exception { + tileSource = new TestTileSource("http://example.org/tiles/vtm"); + } + + @Test + public void shouldNotBeNull() throws Exception { + assertThat(tileSource).isNotNull(); + } + + @Test + public void shouldUseDefaultHttpEngine() throws Exception { + TestTileDataSource dataSource = (TestTileDataSource) tileSource.getDataSource(); + assertThat(dataSource.getConnection()).isInstanceOf(LwHttp.class); + } + + @Test + public void shouldUseCustomHttpEngine() throws Exception { + tileSource.setHttpEngine(new OkHttpEngine(tileSource.getUrl())); + TestTileDataSource dataSource = (TestTileDataSource) tileSource.getDataSource(); + assertThat(dataSource.getConnection()).isInstanceOf(OkHttpEngine.class); + } + + class TestTileSource extends UrlTileSource { + public TestTileSource(String urlString) { + super(urlString); + } + + @Override + public ITileDataSource getDataSource() { + return new TestTileDataSource(this, null, getHttpEngine()); + } + } + + class TestTileDataSource extends UrlTileDataSource { + public TestTileDataSource(UrlTileSource tileSource, ITileDecoder tileDecoder, + HttpEngine conn) { + super(tileSource, tileDecoder, conn); + } + + public HttpEngine getConnection() { + return mConn; + } + } +} diff --git a/vtm/test/org/oscim/tiling/source/bitmap/BitmapTileSourceTest.java b/vtm/test/org/oscim/tiling/source/bitmap/BitmapTileSourceTest.java new file mode 100644 index 00000000..8fde2545 --- /dev/null +++ b/vtm/test/org/oscim/tiling/source/bitmap/BitmapTileSourceTest.java @@ -0,0 +1,48 @@ +package org.oscim.tiling.source.bitmap; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.oscim.tiling.ITileDataSource; +import org.oscim.tiling.source.LwHttp; +import org.oscim.tiling.source.OkHttpEngine; + +import static org.fest.assertions.api.Assertions.assertThat; + +public class BitmapTileSourceTest { + private BitmapTileSource tileSource; + + @Before + public void setUp() throws Exception { + tileSource = new TestBitmapTileSource("http://tile.openstreetmap.org", 0, 18); + } + + @Test + public void shouldNotBeNull() throws Exception { + assertThat(tileSource).isNotNull(); + } + + @Test + public void shouldUseLwHttp() throws Exception { + LwHttp lwHttp = Mockito.mock(LwHttp.class); + tileSource.setHttpEngine(lwHttp); + ITileDataSource dataSource = tileSource.getDataSource(); + dataSource.destroy(); + Mockito.verify(lwHttp).close(); + } + + @Test + public void shouldUseOkHttp() throws Exception { + OkHttpEngine okHttp = Mockito.mock(OkHttpEngine.class); + tileSource.setHttpEngine(okHttp); + ITileDataSource dataSource = tileSource.getDataSource(); + dataSource.destroy(); + Mockito.verify(okHttp).close(); + } + + class TestBitmapTileSource extends BitmapTileSource { + public TestBitmapTileSource(String url, int zoomMin, int zoomMax) { + super(url, zoomMin, zoomMax); + } + } +} diff --git a/vtm/test/org/oscim/tiling/source/oscimap4/OSciMap4TileSourceTest.java b/vtm/test/org/oscim/tiling/source/oscimap4/OSciMap4TileSourceTest.java new file mode 100644 index 00000000..711cd310 --- /dev/null +++ b/vtm/test/org/oscim/tiling/source/oscimap4/OSciMap4TileSourceTest.java @@ -0,0 +1,42 @@ +package org.oscim.tiling.source.oscimap4; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.oscim.tiling.ITileDataSource; +import org.oscim.tiling.source.LwHttp; +import org.oscim.tiling.source.OkHttpEngine; + +import static org.fest.assertions.api.Assertions.assertThat; + +public class OSciMap4TileSourceTest { + private OSciMap4TileSource tileSource; + + @Before + public void setUp() throws Exception { + tileSource = new OSciMap4TileSource("http://www.example.org/tiles/vtm"); + } + + @Test + public void shouldNotBeNull() throws Exception { + assertThat(tileSource).isNotNull(); + } + + @Test + public void shouldUseLwHttp() throws Exception { + LwHttp lwHttp = Mockito.mock(LwHttp.class); + tileSource.setHttpEngine(lwHttp); + ITileDataSource dataSource = tileSource.getDataSource(); + dataSource.destroy(); + Mockito.verify(lwHttp).close(); + } + + @Test + public void shouldUseOkHttp() throws Exception { + OkHttpEngine okHttp = Mockito.mock(OkHttpEngine.class); + tileSource.setHttpEngine(okHttp); + ITileDataSource dataSource = tileSource.getDataSource(); + dataSource.destroy(); + Mockito.verify(okHttp).close(); + } +}