refactoring
This commit is contained in:
parent
d1451e9889
commit
9823461435
3 changed files with 123 additions and 150 deletions
|
@ -1,115 +0,0 @@
|
|||
package net.osmand.plus.server;
|
||||
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static fi.iki.elonen.NanoHTTPD.newFixedLengthResponse;
|
||||
|
||||
public class ApiRouter {
|
||||
private static final String FOLDER_NAME = "server";
|
||||
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(ApiRouter.class);
|
||||
private final Map<String, ApiEndpoint> endpoints = new HashMap<>();
|
||||
private OsmandApplication application;
|
||||
|
||||
public OsmandApplication getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public void setApplication(OsmandApplication application) {
|
||||
this.application = application;
|
||||
for (String s : endpoints.keySet()) {
|
||||
endpoints.get(s).setApplication(application);
|
||||
}
|
||||
}
|
||||
|
||||
public NanoHTTPD.Response getStatic(String uri) {
|
||||
InputStream is;
|
||||
String mimeType = parseMimeType(uri);
|
||||
if (application != null) {
|
||||
try {
|
||||
is = application.getAssets().open(FOLDER_NAME + uri);
|
||||
if (is.available() == 0) {
|
||||
return ErrorResponses.response404;
|
||||
}
|
||||
return newFixedLengthResponse(
|
||||
NanoHTTPD.Response.Status.OK,
|
||||
mimeType,
|
||||
is,
|
||||
is.available());
|
||||
} catch (IOException e) {
|
||||
return ErrorResponses.response404;
|
||||
}
|
||||
}
|
||||
return ErrorResponses.response500;
|
||||
}
|
||||
|
||||
public NanoHTTPD.Response route(NanoHTTPD.IHTTPSession session) {
|
||||
Log.d("SERVER", "URI: " + session.getUri());
|
||||
String uri = session.getUri();
|
||||
if (uri.equals("/")) {
|
||||
return getStatic("/go.html");
|
||||
}
|
||||
if (isApiUrl(uri)) {
|
||||
return routeApi(session);
|
||||
}
|
||||
return getStatic(uri);
|
||||
}
|
||||
|
||||
public void register(String path, ApiEndpoint endpoint) {
|
||||
endpoint.setApplication(application);
|
||||
endpoints.put(path, endpoint);
|
||||
}
|
||||
|
||||
private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) {
|
||||
String uri = session.getUri();
|
||||
int pathEnd = uri.indexOf("/", 1);
|
||||
if (pathEnd != -1) {
|
||||
uri = uri.substring(0, pathEnd);
|
||||
}
|
||||
ApiEndpoint endpoint = endpoints.get(uri);
|
||||
if (endpoint != null) {
|
||||
return endpoint.process(session);
|
||||
}
|
||||
return ErrorResponses.response404;
|
||||
}
|
||||
|
||||
private boolean isApiUrl(String uri) {
|
||||
for (String endpoint : endpoints.keySet()) {
|
||||
int stringLength = endpoint.length();
|
||||
if (uri.startsWith(endpoint) &&
|
||||
(uri.length() == endpoint.length() || uri.charAt(stringLength) == '/')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private String parseMimeType(String url) {
|
||||
String type = "text/plain";
|
||||
if (url.endsWith(".js")) return "text/javascript";
|
||||
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
||||
if (extension != null) {
|
||||
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static class ErrorResponses {
|
||||
public static NanoHTTPD.Response response404 =
|
||||
newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND,
|
||||
NanoHTTPD.MIME_PLAINTEXT, "404 Not Found");
|
||||
|
||||
public static NanoHTTPD.Response response500 =
|
||||
newFixedLengthResponse(NanoHTTPD.Response.Status.INTERNAL_ERROR,
|
||||
NanoHTTPD.MIME_PLAINTEXT, "500 Internal Server Error");
|
||||
}
|
||||
}
|
|
@ -1,15 +1,23 @@
|
|||
package net.osmand.plus.server;
|
||||
|
||||
import android.util.Log;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import fi.iki.elonen.NanoHTTPD;
|
||||
import net.osmand.PlatformUtil;
|
||||
import net.osmand.plus.OsmandApplication;
|
||||
import net.osmand.plus.server.endpoints.TileEndpoint;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class OsmAndHttpServer extends NanoHTTPD {
|
||||
public static int PORT = 24990;
|
||||
private static final String FOLDER_NAME = "server";
|
||||
private static final org.apache.commons.logging.Log LOG = PlatformUtil.getLog(OsmAndHttpServer.class);
|
||||
public static final int PORT = 24990;
|
||||
public static String HOSTNAME = "0.0.0.0";
|
||||
private final ApiRouter router = new ApiRouter();
|
||||
private final Map<String, ApiEndpoint> endpoints = new HashMap<>();
|
||||
private OsmandApplication application;
|
||||
|
||||
public OsmAndHttpServer() throws IOException {
|
||||
|
@ -24,15 +32,95 @@ public class OsmAndHttpServer extends NanoHTTPD {
|
|||
|
||||
public void setApplication(OsmandApplication application) {
|
||||
this.application = application;
|
||||
router.setApplication(application);
|
||||
}
|
||||
|
||||
private void registerEndpoints() {
|
||||
router.register("/tile", new TileEndpoint(application));
|
||||
for (String s : endpoints.keySet()) {
|
||||
endpoints.get(s).setApplication(application);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response serve(IHTTPSession session) {
|
||||
return router.route(session);
|
||||
Log.d("SERVER", "URI: " + session.getUri());
|
||||
String uri = session.getUri();
|
||||
if (uri.equals("/")) {
|
||||
return getStatic("/go.html");
|
||||
}
|
||||
if (isApiUrl(uri)) {
|
||||
return routeApi(session);
|
||||
}
|
||||
return getStatic(uri);
|
||||
}
|
||||
|
||||
private NanoHTTPD.Response routeApi(NanoHTTPD.IHTTPSession session) {
|
||||
String uri = session.getUri();
|
||||
int pathEnd = uri.indexOf("/", 1);
|
||||
if (pathEnd != -1) {
|
||||
uri = uri.substring(0, pathEnd);
|
||||
}
|
||||
ApiEndpoint endpoint = endpoints.get(uri);
|
||||
if (endpoint != null) {
|
||||
return endpoint.process(session);
|
||||
}
|
||||
return ErrorResponses.response404;
|
||||
}
|
||||
|
||||
private boolean isApiUrl(String uri) {
|
||||
for (String endpoint : endpoints.keySet()) {
|
||||
int stringLength = endpoint.length();
|
||||
if (uri.startsWith(endpoint) &&
|
||||
(uri.length() == endpoint.length() || uri.charAt(stringLength) == '/')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void registerEndpoints() {
|
||||
register("/tile", new TileEndpoint(application));
|
||||
}
|
||||
|
||||
private void register(String path, ApiEndpoint endpoint) {
|
||||
endpoint.setApplication(application);
|
||||
endpoints.put(path, endpoint);
|
||||
}
|
||||
|
||||
private NanoHTTPD.Response getStatic(String uri) {
|
||||
InputStream is;
|
||||
String mimeType = parseMimeType(uri);
|
||||
if (application != null) {
|
||||
try {
|
||||
is = application.getAssets().open(FOLDER_NAME + uri);
|
||||
if (is.available() == 0) {
|
||||
return ErrorResponses.response404;
|
||||
}
|
||||
return newFixedLengthResponse(
|
||||
NanoHTTPD.Response.Status.OK,
|
||||
mimeType,
|
||||
is,
|
||||
is.available());
|
||||
} catch (IOException e) {
|
||||
return ErrorResponses.response404;
|
||||
}
|
||||
}
|
||||
return ErrorResponses.response500;
|
||||
}
|
||||
|
||||
private String parseMimeType(String url) {
|
||||
String type = "text/plain";
|
||||
if (url.endsWith(".js")) return "text/javascript";
|
||||
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
|
||||
if (extension != null) {
|
||||
type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static class ErrorResponses {
|
||||
public static NanoHTTPD.Response response404 =
|
||||
newFixedLengthResponse(NanoHTTPD.Response.Status.NOT_FOUND,
|
||||
NanoHTTPD.MIME_PLAINTEXT, "404 Not Found");
|
||||
|
||||
public static NanoHTTPD.Response response500 =
|
||||
newFixedLengthResponse(NanoHTTPD.Response.Status.INTERNAL_ERROR,
|
||||
NanoHTTPD.MIME_PLAINTEXT, "500 Internal Server Error");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ import net.osmand.plus.OsmandApplication;
|
|||
import net.osmand.plus.render.MapRenderRepositories;
|
||||
import net.osmand.plus.resources.AsyncLoadingThread;
|
||||
import net.osmand.plus.server.ApiEndpoint;
|
||||
import net.osmand.plus.server.ApiRouter;
|
||||
import net.osmand.plus.server.OsmAndHttpServer;
|
||||
import org.apache.commons.logging.Log;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
|
@ -35,20 +35,6 @@ public class TileEndpoint implements ApiEndpoint {
|
|||
|
||||
@Override
|
||||
public NanoHTTPD.Response process(NanoHTTPD.IHTTPSession session) {
|
||||
try {
|
||||
return tileApiCall(session);
|
||||
} catch (Exception e) {
|
||||
LOG.error("Exception", e);
|
||||
}
|
||||
return ApiRouter.ErrorResponses.response500;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplication(OsmandApplication application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
private synchronized NanoHTTPD.Response tileApiCall(NanoHTTPD.IHTTPSession session) {
|
||||
int zoom;
|
||||
double lat;
|
||||
double lon;
|
||||
|
@ -57,6 +43,27 @@ public class TileEndpoint implements ApiEndpoint {
|
|||
zoom = s.nextInt();
|
||||
lat = s.nextDouble();
|
||||
lon = s.nextDouble();
|
||||
Bitmap bitmap = requestTile(lat, lon, zoom);
|
||||
if (bitmap == null) {
|
||||
return OsmAndHttpServer.ErrorResponses.response500;
|
||||
}
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
byte[] byteArray = stream.toByteArray();
|
||||
ByteArrayInputStream str = new ByteArrayInputStream(byteArray);
|
||||
return newFixedLengthResponse(
|
||||
NanoHTTPD.Response.Status.OK,
|
||||
"image/png",
|
||||
str,
|
||||
str.available());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplication(OsmandApplication application) {
|
||||
this.application = application;
|
||||
}
|
||||
|
||||
private synchronized Bitmap requestTile(double lat, double lon, int zoom) {
|
||||
Future<Pair<RotatedTileBox, Bitmap>> future;
|
||||
final RotatedTileBox rotatedTileBox = new RotatedTileBox.RotatedTileBoxBuilder()
|
||||
.setLocation(lat, lon)
|
||||
|
@ -67,8 +74,10 @@ public class TileEndpoint implements ApiEndpoint {
|
|||
@Override
|
||||
public Pair<RotatedTileBox, Bitmap> call() throws Exception {
|
||||
Bitmap bmp;
|
||||
int sleepTime = 500;
|
||||
while ((bmp = map.get(rotatedTileBox)) == null) {
|
||||
Thread.sleep(500);
|
||||
Thread.sleep(sleepTime);
|
||||
sleepTime += 500;
|
||||
}
|
||||
return Pair.create(rotatedTileBox, bmp);
|
||||
}
|
||||
|
@ -82,21 +91,12 @@ public class TileEndpoint implements ApiEndpoint {
|
|||
try {
|
||||
Pair<RotatedTileBox, Bitmap> pair = future.get();
|
||||
Bitmap bitmap = pair.second;
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
|
||||
byte[] byteArray = stream.toByteArray();
|
||||
ByteArrayInputStream str = new ByteArrayInputStream(byteArray);
|
||||
return newFixedLengthResponse(
|
||||
NanoHTTPD.Response.Status.OK,
|
||||
"image/png",
|
||||
str,
|
||||
str.available());
|
||||
return bitmap;
|
||||
} catch (ExecutionException e) {
|
||||
LOG.error("Execution exception", e);
|
||||
return ApiRouter.ErrorResponses.response500;
|
||||
} catch (InterruptedException e) {
|
||||
LOG.error("Interrupted exception", e);
|
||||
return ApiRouter.ErrorResponses.response500;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue