Mapsforge themes compatibility improvements #100, fix #392

This commit is contained in:
Emux
2017-09-05 13:29:22 +03:00
parent eddfa5a896
commit 07138f3240
6 changed files with 42 additions and 45 deletions

View File

@@ -1,6 +1,6 @@
/* /*
* Copyright 2010, 2011, 2012 mapsforge.org * Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2016 devemux86 * Copyright 2016-2017 devemux86
* Copyright 2017 Longri * Copyright 2017 Longri
* *
* This program is free software: you can redistribute it and/or modify it under the * This program is free software: you can redistribute it and/or modify it under the
@@ -27,7 +27,6 @@ import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import java.io.File; import java.io.File;
import java.io.FileInputStream;
import javax.xml.parsers.SAXParserFactory; import javax.xml.parsers.SAXParserFactory;
@@ -43,7 +42,7 @@ public final class ValidRenderTheme implements ValidFileFilter {
try { try {
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath()); ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
DefaultHandler renderThemeHandler; DefaultHandler renderThemeHandler;
if (ThemeUtils.isMapsforgeTheme(new FileInputStream(file))) if (ThemeUtils.isMapsforgeTheme(theme))
renderThemeHandler = new XmlMapsforgeThemeBuilder(theme); renderThemeHandler = new XmlMapsforgeThemeBuilder(theme);
else else
renderThemeHandler = new XmlThemeBuilder(theme); renderThemeHandler = new XmlThemeBuilder(theme);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2016 devemux86 * Copyright 2016-2017 devemux86
* *
* This program is free software: you can redistribute it and/or modify it under the * This program is free software: you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software * terms of the GNU Lesser General Public License as published by the Free Software
@@ -58,7 +58,7 @@ public class MapsforgeStyleActivity extends MapsforgeMapActivity {
@Override @Override
protected void loadTheme(final String styleId) { protected void loadTheme(final String styleId) {
mMap.setTheme(new AssetsRenderTheme(this, "", "vtm/stylemenu.xml", new XmlRenderThemeMenuCallback() { mMap.setTheme(new AssetsRenderTheme(getAssets(), "", "vtm/stylemenu.xml", new XmlRenderThemeMenuCallback() {
@Override @Override
public Set<String> getCategories(XmlRenderThemeStyleMenu renderThemeStyleMenu) { public Set<String> getCategories(XmlRenderThemeStyleMenu renderThemeStyleMenu) {
// Use the selected style or the default // Use the selected style or the default

View File

@@ -15,7 +15,7 @@
*/ */
package org.oscim.android.theme; package org.oscim.android.theme;
import android.content.Context; import android.content.res.AssetManager;
import android.text.TextUtils; import android.text.TextUtils;
import org.oscim.theme.IRenderTheme.ThemeException; import org.oscim.theme.IRenderTheme.ThemeException;
@@ -33,36 +33,33 @@ import java.io.InputStream;
public class AssetsRenderTheme implements ThemeFile { public class AssetsRenderTheme implements ThemeFile {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
private final InputStream mInputStream; private final AssetManager mAssetManager;
private final String mFileName;
private XmlRenderThemeMenuCallback mMenuCallback; private XmlRenderThemeMenuCallback mMenuCallback;
private final String mRelativePathPrefix; private final String mRelativePathPrefix;
/** /**
* @param context the Android context. * @param assetManager the Android asset manager.
* @param relativePathPrefix the prefix for all relative resource paths. * @param relativePathPrefix the prefix for all relative resource paths.
* @param fileName the path to the XML render theme file. * @param fileName the path to the XML render theme file.
* @throws ThemeException if an error occurs while reading the render theme XML. * @throws ThemeException if an error occurs while reading the render theme XML.
*/ */
public AssetsRenderTheme(Context context, String relativePathPrefix, String fileName) throws ThemeException { public AssetsRenderTheme(AssetManager assetManager, String relativePathPrefix, String fileName) throws ThemeException {
this(context, relativePathPrefix, fileName, null); this(assetManager, relativePathPrefix, fileName, null);
} }
/** /**
* @param context the Android context. * @param assetManager the Android asset manager.
* @param relativePathPrefix the prefix for all relative resource paths. * @param relativePathPrefix the prefix for all relative resource paths.
* @param fileName the path to the XML render theme file. * @param fileName the path to the XML render theme file.
* @param menuCallback the interface callback to create a settings menu on the fly. * @param menuCallback the interface callback to create a settings menu on the fly.
* @throws ThemeException if an error occurs while reading the render theme XML. * @throws ThemeException if an error occurs while reading the render theme XML.
*/ */
public AssetsRenderTheme(Context context, String relativePathPrefix, String fileName, XmlRenderThemeMenuCallback menuCallback) throws ThemeException { public AssetsRenderTheme(AssetManager assetManager, String relativePathPrefix, String fileName, XmlRenderThemeMenuCallback menuCallback) throws ThemeException {
mAssetManager = assetManager;
mRelativePathPrefix = relativePathPrefix; mRelativePathPrefix = relativePathPrefix;
mFileName = fileName;
mMenuCallback = menuCallback; mMenuCallback = menuCallback;
try {
mInputStream = context.getAssets().open((TextUtils.isEmpty(mRelativePathPrefix) ? "" : mRelativePathPrefix) + fileName);
} catch (IOException e) {
throw new ThemeException(e.getMessage());
}
} }
@Override @Override
@@ -73,7 +70,7 @@ public class AssetsRenderTheme implements ThemeFile {
return false; return false;
} }
AssetsRenderTheme other = (AssetsRenderTheme) obj; AssetsRenderTheme other = (AssetsRenderTheme) obj;
if (mInputStream != other.mInputStream) { if (getRenderThemeAsStream() != other.getRenderThemeAsStream()) {
return false; return false;
} }
if (!Utils.equals(mRelativePathPrefix, other.mRelativePathPrefix)) { if (!Utils.equals(mRelativePathPrefix, other.mRelativePathPrefix)) {
@@ -94,7 +91,11 @@ public class AssetsRenderTheme implements ThemeFile {
@Override @Override
public InputStream getRenderThemeAsStream() throws ThemeException { public InputStream getRenderThemeAsStream() throws ThemeException {
return mInputStream; try {
return mAssetManager.open((TextUtils.isEmpty(mRelativePathPrefix) ? "" : mRelativePathPrefix) + mFileName);
} catch (IOException e) {
throw new ThemeException(e.getMessage());
}
} }
@Override @Override

View File

@@ -17,6 +17,8 @@ package org.oscim.theme;
import org.oscim.theme.IRenderTheme.ThemeException; import org.oscim.theme.IRenderTheme.ThemeException;
import org.oscim.utils.Utils; import org.oscim.utils.Utils;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
/** /**
@@ -45,7 +47,8 @@ public class StreamRenderTheme implements ThemeFile {
*/ */
public StreamRenderTheme(String relativePathPrefix, InputStream inputStream, XmlRenderThemeMenuCallback menuCallback) { public StreamRenderTheme(String relativePathPrefix, InputStream inputStream, XmlRenderThemeMenuCallback menuCallback) {
mRelativePathPrefix = relativePathPrefix; mRelativePathPrefix = relativePathPrefix;
mInputStream = inputStream; mInputStream = new BufferedInputStream(inputStream);
mInputStream.mark(0);
mMenuCallback = menuCallback; mMenuCallback = menuCallback;
} }
@@ -78,6 +81,11 @@ public class StreamRenderTheme implements ThemeFile {
@Override @Override
public InputStream getRenderThemeAsStream() throws ThemeException { public InputStream getRenderThemeAsStream() throws ThemeException {
try {
mInputStream.reset();
} catch (IOException e) {
throw new ThemeException(e.getMessage());
}
return mInputStream; return mInputStream;
} }

View File

@@ -48,7 +48,7 @@ public class ThemeLoader {
public static IRenderTheme load(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException { public static IRenderTheme load(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
IRenderTheme t; IRenderTheme t;
if (ThemeUtils.isMapsforgeTheme(theme.getRenderThemeAsStream())) if (ThemeUtils.isMapsforgeTheme(theme))
t = USE_ATLAS ? XmlMapsforgeAtlasThemeBuilder.read(theme, themeCallback) : XmlMapsforgeThemeBuilder.read(theme, themeCallback); t = USE_ATLAS ? XmlMapsforgeAtlasThemeBuilder.read(theme, themeCallback) : XmlMapsforgeThemeBuilder.read(theme, themeCallback);
else else
t = USE_ATLAS ? XmlAtlasThemeBuilder.read(theme, themeCallback) : XmlThemeBuilder.read(theme, themeCallback); t = USE_ATLAS ? XmlAtlasThemeBuilder.read(theme, themeCallback) : XmlThemeBuilder.read(theme, themeCallback);

View File

@@ -15,20 +15,15 @@
*/ */
package org.oscim.theme; package org.oscim.theme;
import org.oscim.utils.IOUtils; import org.oscim.backend.XMLReaderAdapter;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes; import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException; import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler; import org.xml.sax.helpers.DefaultHandler;
import java.io.InputStream;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import javax.xml.parsers.SAXParserFactory;
/** /**
* A utility class with theme specific helper methods. * A utility class with theme specific helper methods.
*/ */
@@ -37,25 +32,21 @@ public final class ThemeUtils {
private static final Logger log = LoggerFactory.getLogger(ThemeUtils.class); private static final Logger log = LoggerFactory.getLogger(ThemeUtils.class);
/** /**
* Check if the given InputStream is a Mapsforge render theme. * Check if the given theme is a Mapsforge one.
*/ */
public static boolean isMapsforgeTheme(InputStream is) { public static boolean isMapsforgeTheme(ThemeFile theme) {
try { try {
final AtomicBoolean isMapsforgeTheme = new AtomicBoolean(false); final AtomicBoolean isMapsforgeTheme = new AtomicBoolean(false);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setNamespaceAware(true);
XMLReader xmlReader = factory.newSAXParser().getXMLReader();
xmlReader.setContentHandler(new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals("rendertheme")) {
isMapsforgeTheme.set(uri.equals("http://mapsforge.org/renderTheme"));
// We have all info, break parsing
throw new SAXTerminationException();
}
}
});
try { try {
xmlReader.parse(new InputSource(is)); new XMLReaderAdapter().parse(new DefaultHandler() {
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
if (localName.equals("rendertheme")) {
isMapsforgeTheme.set(uri.equals("http://mapsforge.org/renderTheme"));
// We have all info, break parsing
throw new SAXTerminationException();
}
}
}, theme.getRenderThemeAsStream());
} catch (SAXTerminationException e) { } catch (SAXTerminationException e) {
// Do nothing // Do nothing
} }
@@ -63,8 +54,6 @@ public final class ThemeUtils {
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
return false; return false;
} finally {
IOUtils.closeQuietly(is);
} }
} }