Render theme xml pull parser, fix #431
This commit is contained in:
parent
804c8c4603
commit
661bc08bbf
@ -5,6 +5,7 @@
|
|||||||
- Android: scoped storage example [#785](https://github.com/mapsforge/vtm/pull/785)
|
- Android: scoped storage example [#785](https://github.com/mapsforge/vtm/pull/785)
|
||||||
- Mapsforge: map stream support [#784](https://github.com/mapsforge/vtm/pull/784)
|
- Mapsforge: map stream support [#784](https://github.com/mapsforge/vtm/pull/784)
|
||||||
- Render theme from Android content providers [#783](https://github.com/mapsforge/vtm/pull/783)
|
- Render theme from Android content providers [#783](https://github.com/mapsforge/vtm/pull/783)
|
||||||
|
- Render theme xml pull parser [#786](https://github.com/mapsforge/vtm/pull/786)
|
||||||
- Many other minor improvements and bug fixes
|
- Many other minor improvements and bug fixes
|
||||||
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.15.0)
|
- [Solved issues](https://github.com/mapsforge/vtm/issues?q=is%3Aclosed+milestone%3A0.15.0)
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ Current version is [ {
|
public boolean accept(File file) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
|
ThemeLoader.load(file.getAbsolutePath());
|
||||||
DefaultHandler renderThemeHandler = new XmlThemeBuilder(theme);
|
|
||||||
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
|
||||||
xmlReader.setContentHandler(renderThemeHandler);
|
|
||||||
xmlReader.parse(new InputSource(theme.getRenderThemeAsStream()));
|
|
||||||
mOpenResult = OpenResult.SUCCESS;
|
mOpenResult = OpenResult.SUCCESS;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
mOpenResult = new OpenResult(e.getMessage());
|
mOpenResult = new OpenResult(e.getMessage());
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012 mapsforge.org
|
||||||
* Copyright 2016 devemux86
|
* Copyright 2016-2020 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
|
||||||
@ -15,40 +15,30 @@
|
|||||||
*/
|
*/
|
||||||
package org.oscim.app.filefilter;
|
package org.oscim.app.filefilter;
|
||||||
|
|
||||||
import org.oscim.theme.ExternalRenderTheme;
|
import org.oscim.theme.ThemeLoader;
|
||||||
import org.oscim.theme.ThemeFile;
|
|
||||||
import org.oscim.theme.XmlThemeBuilder;
|
|
||||||
import org.oscim.tiling.TileSource.OpenResult;
|
import org.oscim.tiling.TileSource.OpenResult;
|
||||||
import org.xml.sax.InputSource;
|
|
||||||
import org.xml.sax.XMLReader;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
import javax.xml.parsers.SAXParserFactory;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts all valid render theme XML files.
|
* Accepts all valid render theme XML files.
|
||||||
*/
|
*/
|
||||||
public final class ValidRenderTheme implements ValidFileFilter {
|
public final class ValidRenderTheme implements ValidFileFilter {
|
||||||
private OpenResult openResult;
|
private OpenResult mOpenResult;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File file) {
|
public boolean accept(File file) {
|
||||||
try {
|
try {
|
||||||
ThemeFile theme = new ExternalRenderTheme(file.getAbsolutePath());
|
ThemeLoader.load(file.getAbsolutePath());
|
||||||
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme);
|
mOpenResult = OpenResult.SUCCESS;
|
||||||
XMLReader xmlReader = SAXParserFactory.newInstance().newSAXParser().getXMLReader();
|
|
||||||
xmlReader.setContentHandler(renderThemeHandler);
|
|
||||||
xmlReader.parse(new InputSource(theme.getRenderThemeAsStream()));
|
|
||||||
this.openResult = OpenResult.SUCCESS;
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
this.openResult = new OpenResult(e.getMessage());
|
mOpenResult = new OpenResult(e.getMessage());
|
||||||
}
|
}
|
||||||
return this.openResult.isSuccess();
|
return mOpenResult.isSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public OpenResult getFileOpenResult() {
|
public OpenResult getFileOpenResult() {
|
||||||
return this.openResult;
|
return mOpenResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
1124
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlPullParser.java
Normal file
1124
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlPullParser.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,76 @@
|
|||||||
|
/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
|
||||||
|
// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
|
||||||
|
|
||||||
|
package org.xmlpull.v1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is thrown to signal XML Pull Parser related faults.
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
|
||||||
|
*/
|
||||||
|
public class XmlPullParserException extends Exception {
|
||||||
|
protected Throwable detail;
|
||||||
|
protected int row = -1;
|
||||||
|
protected int column = -1;
|
||||||
|
|
||||||
|
/* public XmlPullParserException() {
|
||||||
|
}*/
|
||||||
|
|
||||||
|
public XmlPullParserException(String s) {
|
||||||
|
super(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
public XmlPullParserException(String s, Throwable thrwble) {
|
||||||
|
super(s);
|
||||||
|
this.detail = thrwble;
|
||||||
|
}
|
||||||
|
|
||||||
|
public XmlPullParserException(String s, int row, int column) {
|
||||||
|
super(s);
|
||||||
|
this.row = row;
|
||||||
|
this.column = column;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
public XmlPullParserException(String msg, XmlPullParser parser, Throwable chain) {
|
||||||
|
super ((msg == null ? "" : msg+" ")
|
||||||
|
+ (parser == null ? "" : "(position:"+parser.getPositionDescription()+") ")
|
||||||
|
+ (chain == null ? "" : "caused by: "+chain));
|
||||||
|
|
||||||
|
if (parser != null) {
|
||||||
|
this.row = parser.getLineNumber();
|
||||||
|
this.column = parser.getColumnNumber();
|
||||||
|
}
|
||||||
|
this.detail = chain;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Throwable getDetail() { return detail; }
|
||||||
|
// public void setDetail(Throwable cause) { this.detail = cause; }
|
||||||
|
public int getLineNumber() { return row; }
|
||||||
|
public int getColumnNumber() { return column; }
|
||||||
|
|
||||||
|
/*
|
||||||
|
public String getMessage() {
|
||||||
|
if(detail == null)
|
||||||
|
return super.getMessage();
|
||||||
|
else
|
||||||
|
return super.getMessage() + "; nested exception is: \n\t"
|
||||||
|
+ detail.getMessage();
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
//NOTE: code that prints this and detail is difficult in J2ME
|
||||||
|
public void printStackTrace() {
|
||||||
|
if (detail == null) {
|
||||||
|
super.printStackTrace();
|
||||||
|
} else {
|
||||||
|
synchronized(System.err) {
|
||||||
|
System.err.println(super.getMessage() + "; nested exception is:");
|
||||||
|
detail.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,237 @@
|
|||||||
|
/* -*- c-basic-offset: 4; indent-tabs-mode: nil; -*- //------100-columns-wide------>|*/
|
||||||
|
// for license please see accompanying LICENSE.txt file (available also at http://www.xmlpull.org/)
|
||||||
|
|
||||||
|
package org.xmlpull.v1;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class is used to create implementations of XML Pull Parser defined in XMPULL V1 API.
|
||||||
|
*
|
||||||
|
* @see XmlPullParser
|
||||||
|
*
|
||||||
|
* @author <a href="http://www.extreme.indiana.edu/~aslom/">Aleksander Slominski</a>
|
||||||
|
* @author Stefan Haustein
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class XmlPullParserFactory {
|
||||||
|
|
||||||
|
public static final String PROPERTY_NAME = "org.xmlpull.v1.XmlPullParserFactory";
|
||||||
|
protected ArrayList parserClasses;
|
||||||
|
protected ArrayList serializerClasses;
|
||||||
|
|
||||||
|
/** Unused, but we have to keep it because it's public API. */
|
||||||
|
protected String classNamesLocation = null;
|
||||||
|
|
||||||
|
// features are kept there
|
||||||
|
// TODO: This can't be made final because it's a public API.
|
||||||
|
protected HashMap<String, Boolean> features = new HashMap<String, Boolean>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Protected constructor to be called by factory implementations.
|
||||||
|
*/
|
||||||
|
protected XmlPullParserFactory() {
|
||||||
|
parserClasses = new ArrayList<String>();
|
||||||
|
serializerClasses = new ArrayList<String>();
|
||||||
|
|
||||||
|
// GWT
|
||||||
|
/*try {
|
||||||
|
parserClasses.add(Class.forName("com.android.org.kxml2.io.KXmlParser"));
|
||||||
|
serializerClasses.add(Class.forName("com.android.org.kxml2.io.KXmlSerializer"));
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the features to be set when XML Pull Parser is created by this factory.
|
||||||
|
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
|
||||||
|
*
|
||||||
|
* @param name string with URI identifying feature
|
||||||
|
* @param state if true feature will be set; if false will be ignored
|
||||||
|
*/
|
||||||
|
public void setFeature(String name, boolean state) throws XmlPullParserException {
|
||||||
|
features.put(name, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current value of the feature with given name.
|
||||||
|
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
|
||||||
|
*
|
||||||
|
* @param name The name of feature to be retrieved.
|
||||||
|
* @return The value of named feature.
|
||||||
|
* Unknown features are <string>always</strong> returned as false
|
||||||
|
*/
|
||||||
|
public boolean getFeature(String name) {
|
||||||
|
Boolean value = features.get(name);
|
||||||
|
return value != null ? value.booleanValue() : false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that the parser produced by this factory will provide
|
||||||
|
* support for XML namespaces.
|
||||||
|
* By default the value of this is set to false.
|
||||||
|
*
|
||||||
|
* @param awareness true if the parser produced by this code
|
||||||
|
* will provide support for XML namespaces; false otherwise.
|
||||||
|
*/
|
||||||
|
public void setNamespaceAware(boolean awareness) {
|
||||||
|
features.put (XmlPullParser.FEATURE_PROCESS_NAMESPACES, awareness);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the factory is configured to produce
|
||||||
|
* parsers which are namespace aware
|
||||||
|
* (it simply set feature XmlPullParser.FEATURE_PROCESS_NAMESPACES to true or false).
|
||||||
|
*
|
||||||
|
* @return true if the factory is configured to produce parsers
|
||||||
|
* which are namespace aware; false otherwise.
|
||||||
|
*/
|
||||||
|
public boolean isNamespaceAware() {
|
||||||
|
return getFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specifies that the parser produced by this factory will be validating
|
||||||
|
* (it simply set feature XmlPullParser.FEATURE_VALIDATION to true or false).
|
||||||
|
*
|
||||||
|
* By default the value of this is set to false.
|
||||||
|
*
|
||||||
|
* @param validating - if true the parsers created by this factory must be validating.
|
||||||
|
*/
|
||||||
|
public void setValidating(boolean validating) {
|
||||||
|
features.put(XmlPullParser.FEATURE_VALIDATION, validating);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates whether or not the factory is configured to produce parsers
|
||||||
|
* which validate the XML content during parse.
|
||||||
|
*
|
||||||
|
* @return true if the factory is configured to produce parsers
|
||||||
|
* which validate the XML content during parse; false otherwise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public boolean isValidating() {
|
||||||
|
return getFeature(XmlPullParser.FEATURE_VALIDATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a XML Pull Parser
|
||||||
|
* using the currently configured factory features.
|
||||||
|
*
|
||||||
|
* @return A new instance of a XML Pull Parser.
|
||||||
|
*/
|
||||||
|
public XmlPullParser newPullParser() throws XmlPullParserException {
|
||||||
|
final XmlPullParser pp = getParserInstance();
|
||||||
|
for (Map.Entry<String, Boolean> entry : features.entrySet()) {
|
||||||
|
// NOTE: This test is needed for compatibility reasons. We guarantee
|
||||||
|
// that we only set a feature on a parser if its value is true.
|
||||||
|
if (entry.getValue()) {
|
||||||
|
pp.setFeature(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pp;
|
||||||
|
}
|
||||||
|
|
||||||
|
private XmlPullParser getParserInstance() throws XmlPullParserException {
|
||||||
|
ArrayList<Exception> exceptions = null;
|
||||||
|
|
||||||
|
if (parserClasses != null && !parserClasses.isEmpty()) {
|
||||||
|
exceptions = new ArrayList<Exception>();
|
||||||
|
for (Object o : parserClasses) {
|
||||||
|
// GWT
|
||||||
|
/*try {
|
||||||
|
if (o != null) {
|
||||||
|
Class<?> parserClass = (Class<?>) o;
|
||||||
|
return (XmlPullParser) parserClass.newInstance();
|
||||||
|
}
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw newInstantiationException("Invalid parser class list", exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private XmlSerializer getSerializerInstance() throws XmlPullParserException {
|
||||||
|
ArrayList<Exception> exceptions = null;
|
||||||
|
|
||||||
|
if (serializerClasses != null && !serializerClasses.isEmpty()) {
|
||||||
|
exceptions = new ArrayList<Exception>();
|
||||||
|
for (Object o : serializerClasses) {
|
||||||
|
// GWT
|
||||||
|
/*try {
|
||||||
|
if (o != null) {
|
||||||
|
Class<?> serializerClass = (Class<?>) o;
|
||||||
|
return (XmlSerializer) serializerClass.newInstance();
|
||||||
|
}
|
||||||
|
} catch (InstantiationException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (IllegalAccessException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
} catch (ClassCastException e) {
|
||||||
|
exceptions.add(e);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw newInstantiationException("Invalid serializer class list", exceptions);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static XmlPullParserException newInstantiationException(String message,
|
||||||
|
ArrayList<Exception> exceptions) {
|
||||||
|
if (exceptions == null || exceptions.isEmpty()) {
|
||||||
|
return new XmlPullParserException(message);
|
||||||
|
} else {
|
||||||
|
XmlPullParserException exception = new XmlPullParserException(message);
|
||||||
|
for (Exception ex : exceptions) {
|
||||||
|
exception.addSuppressed(ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exception;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a XML Serializer.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> factory features are not used for XML Serializer.
|
||||||
|
*
|
||||||
|
* @return A new instance of a XML Serializer.
|
||||||
|
* @throws XmlPullParserException if a parser cannot be created which satisfies the
|
||||||
|
* requested configuration.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public XmlSerializer newSerializer() throws XmlPullParserException {
|
||||||
|
return getSerializerInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new instance of a PullParserFactory that can be used
|
||||||
|
* to create XML pull parsers. The factory will always return instances
|
||||||
|
* of Android's built-in {@link XmlPullParser} and {@link XmlSerializer}.
|
||||||
|
*/
|
||||||
|
public static XmlPullParserFactory newInstance () throws XmlPullParserException {
|
||||||
|
return new XmlPullParserFactory();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a factory that always returns instances of Android's built-in
|
||||||
|
* {@link XmlPullParser} and {@link XmlSerializer} implementation. This
|
||||||
|
* <b>does not</b> support factories capable of creating arbitrary parser
|
||||||
|
* and serializer implementations. Both arguments to this method are unused.
|
||||||
|
*/
|
||||||
|
public static XmlPullParserFactory newInstance (String unused, Class unused2)
|
||||||
|
throws XmlPullParserException {
|
||||||
|
return newInstance();
|
||||||
|
}
|
||||||
|
}
|
325
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlSerializer.java
Normal file
325
vtm-web/src/org/oscim/gdx/emu/org/xmlpull/v1/XmlSerializer.java
Normal file
@ -0,0 +1,325 @@
|
|||||||
|
package org.xmlpull.v1;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.io.Writer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define an interface to serialization of XML Infoset.
|
||||||
|
* This interface abstracts away if serialized XML is XML 1.0 compatible text or
|
||||||
|
* other formats of XML 1.0 serializations (such as binary XML for example with WBXML).
|
||||||
|
*
|
||||||
|
* <p><b>PLEASE NOTE:</b> This interface will be part of XmlPull 1.2 API.
|
||||||
|
* It is included as basis for discussion. It may change in any way.
|
||||||
|
*
|
||||||
|
* <p>Exceptions that may be thrown are: IOException or runtime exception
|
||||||
|
* (more runtime exceptions can be thrown but are not declared and as such
|
||||||
|
* have no semantics defined for this interface):
|
||||||
|
* <ul>
|
||||||
|
* <li><em>IllegalArgumentException</em> - for almost all methods to signal that
|
||||||
|
* argument is illegal
|
||||||
|
* <li><em>IllegalStateException</em> - to signal that call has good arguments but
|
||||||
|
* is not expected here (violation of contract) and for features/properties
|
||||||
|
* when requesting setting unimplemented feature/property
|
||||||
|
* (UnsupportedOperationException would be better but it is not in MIDP)
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> writing CDSECT, ENTITY_REF, IGNORABLE_WHITESPACE,
|
||||||
|
* PROCESSING_INSTRUCTION, COMMENT, and DOCDECL in some implementations
|
||||||
|
* may not be supported (for example when serializing to WBXML).
|
||||||
|
* In such case IllegalStateException will be thrown and it is recommended
|
||||||
|
* to use an optional feature to signal that implementation is not
|
||||||
|
* supporting this kind of output.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface XmlSerializer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set feature identified by name (recommended to be URI for uniqueness).
|
||||||
|
* Some well known optional features are defined in
|
||||||
|
* <a href="http://www.xmlpull.org/v1/doc/features.html">
|
||||||
|
* http://www.xmlpull.org/v1/doc/features.html</a>.
|
||||||
|
*
|
||||||
|
* If feature is not recognized or can not be set
|
||||||
|
* then IllegalStateException MUST be thrown.
|
||||||
|
*
|
||||||
|
* @exception IllegalStateException If the feature is not supported or can not be set
|
||||||
|
*/
|
||||||
|
void setFeature(String name,
|
||||||
|
boolean state)
|
||||||
|
throws IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current value of the feature with given name.
|
||||||
|
* <p><strong>NOTE:</strong> unknown properties are <strong>always</strong> returned as null
|
||||||
|
*
|
||||||
|
* @param name The name of feature to be retrieved.
|
||||||
|
* @return The value of named feature.
|
||||||
|
* @exception IllegalArgumentException if feature string is null
|
||||||
|
*/
|
||||||
|
boolean getFeature(String name);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value of a property.
|
||||||
|
* (the property name is recommended to be URI for uniqueness).
|
||||||
|
* Some well known optional properties are defined in
|
||||||
|
* <a href="http://www.xmlpull.org/v1/doc/properties.html">
|
||||||
|
* http://www.xmlpull.org/v1/doc/properties.html</a>.
|
||||||
|
*
|
||||||
|
* If property is not recognized or can not be set
|
||||||
|
* then IllegalStateException MUST be thrown.
|
||||||
|
*
|
||||||
|
* @exception IllegalStateException if the property is not supported or can not be set
|
||||||
|
*/
|
||||||
|
void setProperty(String name,
|
||||||
|
Object value)
|
||||||
|
throws IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Look up the value of a property.
|
||||||
|
*
|
||||||
|
* The property name is any fully-qualified URI. I
|
||||||
|
* <p><strong>NOTE:</strong> unknown properties are <string>always</strong> returned as null
|
||||||
|
*
|
||||||
|
* @param name The name of property to be retrieved.
|
||||||
|
* @return The value of named property.
|
||||||
|
*/
|
||||||
|
Object getProperty(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set to use binary output stream with given encoding.
|
||||||
|
*/
|
||||||
|
void setOutput (OutputStream os, String encoding)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the output to the given writer.
|
||||||
|
* <p><b>WARNING</b> no information about encoding is available!
|
||||||
|
*/
|
||||||
|
void setOutput (Writer writer)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write <?xml declaration with encoding (if encoding not null)
|
||||||
|
* and standalone flag (if standalone not null)
|
||||||
|
* This method can only be called just after setOutput.
|
||||||
|
*/
|
||||||
|
void startDocument (String encoding, Boolean standalone)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finish writing. All unclosed start tags will be closed and output
|
||||||
|
* will be flushed. After calling this method no more output can be
|
||||||
|
* serialized until next call to setOutput()
|
||||||
|
*/
|
||||||
|
void endDocument ()
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Binds the given prefix to the given namespace.
|
||||||
|
* This call is valid for the next element including child elements.
|
||||||
|
* The prefix and namespace MUST be always declared even if prefix
|
||||||
|
* is not used in element (startTag() or attribute()) - for XML 1.0
|
||||||
|
* it must result in declaring <code>xmlns:prefix='namespace'</code>
|
||||||
|
* (or <code>xmlns:prefix="namespace"</code> depending what character is used
|
||||||
|
* to quote attribute value).
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> this method MUST be called directly before startTag()
|
||||||
|
* and if anything but startTag() or setPrefix() is called next there will be exception.
|
||||||
|
* <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
|
||||||
|
* and can not be redefined see:
|
||||||
|
* <a href="http://www.w3.org/XML/xml-names-19990114-errata#NE05">Namespaces in XML Errata</a>.
|
||||||
|
* <p><b>NOTE:</b> to set default namespace use as prefix empty string.
|
||||||
|
*
|
||||||
|
* @param prefix must be not null (or IllegalArgumentException is thrown)
|
||||||
|
* @param namespace must be not null
|
||||||
|
*/
|
||||||
|
void setPrefix (String prefix, String namespace)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return namespace that corresponds to given prefix
|
||||||
|
* If there is no prefix bound to this namespace return null
|
||||||
|
* but if generatePrefix is false then return generated prefix.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> if the prefix is empty string "" and default namespace is bound
|
||||||
|
* to this prefix then empty string ("") is returned.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> prefixes "xml" and "xmlns" are already bound
|
||||||
|
* will have values as defined
|
||||||
|
* <a href="http://www.w3.org/TR/REC-xml-names/">Namespaces in XML specification</a>
|
||||||
|
*/
|
||||||
|
String getPrefix (String namespace, boolean generatePrefix)
|
||||||
|
throws IllegalArgumentException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the current depth of the element.
|
||||||
|
* Outside the root element, the depth is 0. The
|
||||||
|
* depth is incremented by 1 when startTag() is called.
|
||||||
|
* The depth is decremented after the call to endTag()
|
||||||
|
* event was observed.
|
||||||
|
*
|
||||||
|
* <pre>
|
||||||
|
* <!-- outside --> 0
|
||||||
|
* <root> 1
|
||||||
|
* sometext 1
|
||||||
|
* <foobar> 2
|
||||||
|
* </foobar> 2
|
||||||
|
* </root> 1
|
||||||
|
* <!-- outside --> 0
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
int getDepth();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the namespace URI of the current element as set by startTag().
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> that means in particular that: <ul>
|
||||||
|
* <li>if there was startTag("", ...) then getNamespace() returns ""
|
||||||
|
* <li>if there was startTag(null, ...) then getNamespace() returns null
|
||||||
|
* </ul>
|
||||||
|
*
|
||||||
|
* @return namespace set by startTag() that is currently in scope
|
||||||
|
*/
|
||||||
|
String getNamespace ();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the name of the current element as set by startTag().
|
||||||
|
* It can only be null before first call to startTag()
|
||||||
|
* or when last endTag() is called to close first startTag().
|
||||||
|
*
|
||||||
|
* @return namespace set by startTag() that is currently in scope
|
||||||
|
*/
|
||||||
|
String getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a start tag with the given namespace and name.
|
||||||
|
* If there is no prefix defined for the given namespace,
|
||||||
|
* a prefix will be defined automatically.
|
||||||
|
* The explicit prefixes for namespaces can be established by calling setPrefix()
|
||||||
|
* immediately before this method.
|
||||||
|
* If namespace is null no namespace prefix is printed but just name.
|
||||||
|
* If namespace is empty string then serializer will make sure that
|
||||||
|
* default empty namespace is declared (in XML 1.0 xmlns='')
|
||||||
|
* or throw IllegalStateException if default namespace is already bound
|
||||||
|
* to non-empty string.
|
||||||
|
*/
|
||||||
|
XmlSerializer startTag (String namespace, String name)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write an attribute. Calls to attribute() MUST follow a call to
|
||||||
|
* startTag() immediately. If there is no prefix defined for the
|
||||||
|
* given namespace, a prefix will be defined automatically.
|
||||||
|
* If namespace is null or empty string
|
||||||
|
* no namespace prefix is printed but just name.
|
||||||
|
*/
|
||||||
|
XmlSerializer attribute (String namespace, String name, String value)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write end tag. Repetition of namespace and name is just for avoiding errors.
|
||||||
|
* <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
|
||||||
|
* very difficult to find...
|
||||||
|
* If namespace is null no namespace prefix is printed but just name.
|
||||||
|
* If namespace is empty string then serializer will make sure that
|
||||||
|
* default empty namespace is declared (in XML 1.0 xmlns='').
|
||||||
|
*/
|
||||||
|
XmlSerializer endTag (String namespace, String name)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
|
||||||
|
// /**
|
||||||
|
// * Writes a start tag with the given namespace and name.
|
||||||
|
// * <br />If there is no prefix defined (prefix == null) for the given namespace,
|
||||||
|
// * a prefix will be defined automatically.
|
||||||
|
// * <br />If explicit prefixes is passed (prefix != null) then it will be used
|
||||||
|
// *and namespace declared if not already declared or
|
||||||
|
// * throw IllegalStateException the same prefix was already set on this
|
||||||
|
// * element (setPrefix()) and was bound to different namespace.
|
||||||
|
// * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
|
||||||
|
// * <br />If namespace is null then no namespace prefix is printed but just name.
|
||||||
|
// * <br />If namespace is empty string then serializer will make sure that
|
||||||
|
// * default empty namespace is declared (in XML 1.0 xmlns='')
|
||||||
|
// * or throw IllegalStateException if default namespace is already bound
|
||||||
|
// * to non-empty string.
|
||||||
|
// */
|
||||||
|
// XmlSerializer startTag (String prefix, String namespace, String name)
|
||||||
|
// throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Write an attribute. Calls to attribute() MUST follow a call to
|
||||||
|
// * startTag() immediately.
|
||||||
|
// * <br />If there is no prefix defined (prefix == null) for the given namespace,
|
||||||
|
// * a prefix will be defined automatically.
|
||||||
|
// * <br />If explicit prefixes is passed (prefix != null) then it will be used
|
||||||
|
// * and namespace declared if not already declared or
|
||||||
|
// * throw IllegalStateException the same prefix was already set on this
|
||||||
|
// * element (setPrefix()) and was bound to different namespace.
|
||||||
|
// * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
|
||||||
|
// * <br />If namespace is null then no namespace prefix is printed but just name.
|
||||||
|
// * <br />If namespace is empty string then serializer will make sure that
|
||||||
|
// * default empty namespace is declared (in XML 1.0 xmlns='')
|
||||||
|
// * or throw IllegalStateException if default namespace is already bound
|
||||||
|
// * to non-empty string.
|
||||||
|
// */
|
||||||
|
// XmlSerializer attribute (String prefix, String namespace, String name, String value)
|
||||||
|
// throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
//
|
||||||
|
// /**
|
||||||
|
// * Write end tag. Repetition of namespace, prefix, and name is just for avoiding errors.
|
||||||
|
// * <br />If namespace or name arguments are different from corresponding startTag call
|
||||||
|
// * then IllegalArgumentException is thrown, if prefix argument is not null and is different
|
||||||
|
// * from corresponding starTag then IllegalArgumentException is thrown.
|
||||||
|
// * <br />If namespace is null then prefix must be null too or IllegalStateException is thrown.
|
||||||
|
// * <br />If namespace is null then no namespace prefix is printed but just name.
|
||||||
|
// * <br />If namespace is empty string then serializer will make sure that
|
||||||
|
// * default empty namespace is declared (in XML 1.0 xmlns='').
|
||||||
|
// * <p><b>Background:</b> in kXML endTag had no arguments, and non matching tags were
|
||||||
|
// * very difficult to find...</p>
|
||||||
|
// */
|
||||||
|
// ALEK: This is really optional as prefix in end tag MUST correspond to start tag but good for error checking
|
||||||
|
// XmlSerializer endTag (String prefix, String namespace, String name)
|
||||||
|
// throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes text, where special XML chars are escaped automatically
|
||||||
|
*/
|
||||||
|
XmlSerializer text (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes text, where special XML chars are escaped automatically
|
||||||
|
*/
|
||||||
|
XmlSerializer text (char [] buf, int start, int len)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
void cdsect (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void entityRef (String text) throws IOException,
|
||||||
|
IllegalArgumentException, IllegalStateException;
|
||||||
|
void processingInstruction (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void comment (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void docdecl (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
void ignorableWhitespace (String text)
|
||||||
|
throws IOException, IllegalArgumentException, IllegalStateException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write all pending output to the stream.
|
||||||
|
* If method startTag() or attribute() was called then start tag is closed (final >)
|
||||||
|
* before flush() is called on underlying output stream.
|
||||||
|
*
|
||||||
|
* <p><b>NOTE:</b> if there is need to close start tag
|
||||||
|
* (so no more attribute() calls are allowed) but without flushing output
|
||||||
|
* call method text() with empty string (text("")).
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void flush ()
|
||||||
|
throws IOException;
|
||||||
|
|
||||||
|
}
|
@ -2,6 +2,7 @@ apply plugin: 'java-library'
|
|||||||
apply plugin: 'maven'
|
apply plugin: 'maven'
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
api 'net.sf.kxml:kxml2:2.3.0'
|
||||||
api "org.slf4j:slf4j-api:$slf4jVersion"
|
api "org.slf4j:slf4j-api:$slf4jVersion"
|
||||||
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
|
compileOnly 'com.google.code.findbugs:jsr305:3.0.2'
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2017 Longri
|
* Copyright 2017 Longri
|
||||||
* Copyright 2017-2018 devemux86
|
* Copyright 2017-2020 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
|
||||||
@ -17,7 +17,6 @@ package org.oscim.theme;
|
|||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.Platform;
|
import org.oscim.backend.Platform;
|
||||||
import org.oscim.backend.XMLReaderAdapter;
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.renderer.atlas.TextureAtlas;
|
import org.oscim.renderer.atlas.TextureAtlas;
|
||||||
import org.oscim.renderer.atlas.TextureRegion;
|
import org.oscim.renderer.atlas.TextureRegion;
|
||||||
@ -26,8 +25,11 @@ import org.oscim.theme.rule.Rule;
|
|||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.theme.styles.SymbolStyle;
|
import org.oscim.theme.styles.SymbolStyle;
|
||||||
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
import org.oscim.utils.TextureAtlasUtils;
|
import org.oscim.utils.TextureAtlasUtils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -51,20 +53,23 @@ public class XmlAtlasThemeBuilder extends XmlThemeBuilder {
|
|||||||
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
||||||
*/
|
*/
|
||||||
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
||||||
Map<Object, TextureRegion> outputMap = new HashMap<>();
|
InputStream inputStream = null;
|
||||||
List<TextureAtlas> atlasList = new ArrayList<>();
|
|
||||||
XmlAtlasThemeBuilder renderThemeHandler = new XmlAtlasThemeBuilder(theme, themeCallback, outputMap, atlasList);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new XMLReaderAdapter().parse(renderThemeHandler, theme.getRenderThemeAsStream());
|
XmlPullParser pullParser = getXmlPullParserFactory().newPullParser();
|
||||||
|
Map<Object, TextureRegion> outputMap = new HashMap<>();
|
||||||
|
List<TextureAtlas> atlasList = new ArrayList<>();
|
||||||
|
XmlAtlasThemeBuilder renderThemeHandler = new XmlAtlasThemeBuilder(theme, pullParser, themeCallback, outputMap, atlasList);
|
||||||
|
inputStream = theme.getRenderThemeAsStream();
|
||||||
|
pullParser.setInput(inputStream, null);
|
||||||
|
renderThemeHandler.processRenderTheme();
|
||||||
|
TextureAtlasUtils.createTextureRegions(renderThemeHandler.bitmapMap, outputMap, atlasList,
|
||||||
|
true, CanvasAdapter.platform == Platform.IOS);
|
||||||
|
return replaceThemeSymbols(renderThemeHandler.mRenderTheme, outputMap);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ThemeException(e.getMessage());
|
throw new ThemeException(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(inputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
TextureAtlasUtils.createTextureRegions(renderThemeHandler.bitmapMap, outputMap, atlasList,
|
|
||||||
true, CanvasAdapter.platform == Platform.IOS);
|
|
||||||
|
|
||||||
return replaceThemeSymbols(renderThemeHandler.mRenderTheme, outputMap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IRenderTheme replaceThemeSymbols(RenderTheme renderTheme, Map<Object, TextureRegion> regionMap) {
|
private static IRenderTheme replaceThemeSymbols(RenderTheme renderTheme, Map<Object, TextureRegion> regionMap) {
|
||||||
@ -98,14 +103,14 @@ public class XmlAtlasThemeBuilder extends XmlThemeBuilder {
|
|||||||
|
|
||||||
private final Map<Object, Bitmap> bitmapMap = new HashMap<>();
|
private final Map<Object, Bitmap> bitmapMap = new HashMap<>();
|
||||||
|
|
||||||
public XmlAtlasThemeBuilder(ThemeFile theme,
|
public XmlAtlasThemeBuilder(ThemeFile theme, XmlPullParser pullParser,
|
||||||
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
||||||
this(theme, null, regionMap, atlasList);
|
this(theme, pullParser, null, regionMap, atlasList);
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlAtlasThemeBuilder(ThemeFile theme, ThemeCallback themeCallback,
|
public XmlAtlasThemeBuilder(ThemeFile theme, XmlPullParser pullParser, ThemeCallback themeCallback,
|
||||||
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
Map<Object, TextureRegion> regionMap, List<TextureAtlas> atlasList) {
|
||||||
super(theme, themeCallback);
|
super(theme, pullParser, themeCallback);
|
||||||
this.regionMap = regionMap;
|
this.regionMap = regionMap;
|
||||||
this.atlasList = atlasList;
|
this.atlasList = atlasList;
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, 2011, 2012 mapsforge.org
|
* Copyright 2010, 2011, 2012, 2013 mapsforge.org
|
||||||
* Copyright 2013 Hannes Janetzek
|
* Copyright 2013 Hannes Janetzek
|
||||||
* Copyright 2016-2019 devemux86
|
* Copyright 2014 Ludwig M Brinckmann
|
||||||
|
* Copyright 2016-2020 devemux86
|
||||||
* Copyright 2016-2017 Longri
|
* Copyright 2016-2017 Longri
|
||||||
* Copyright 2016-2020 Andrey Novikov
|
* Copyright 2016-2020 Andrey Novikov
|
||||||
* Copyright 2018-2019 Gustl22
|
* Copyright 2018-2019 Gustl22
|
||||||
@ -24,7 +25,6 @@
|
|||||||
package org.oscim.theme;
|
package org.oscim.theme;
|
||||||
|
|
||||||
import org.oscim.backend.CanvasAdapter;
|
import org.oscim.backend.CanvasAdapter;
|
||||||
import org.oscim.backend.XMLReaderAdapter;
|
|
||||||
import org.oscim.backend.canvas.Bitmap;
|
import org.oscim.backend.canvas.Bitmap;
|
||||||
import org.oscim.backend.canvas.Canvas;
|
import org.oscim.backend.canvas.Canvas;
|
||||||
import org.oscim.backend.canvas.Color;
|
import org.oscim.backend.canvas.Color;
|
||||||
@ -49,27 +49,29 @@ import org.oscim.theme.styles.LineStyle.LineBuilder;
|
|||||||
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
import org.oscim.theme.styles.SymbolStyle.SymbolBuilder;
|
||||||
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
import org.oscim.theme.styles.TextStyle.TextBuilder;
|
||||||
import org.oscim.utils.FastMath;
|
import org.oscim.utils.FastMath;
|
||||||
|
import org.oscim.utils.IOUtils;
|
||||||
import org.oscim.utils.Utils;
|
import org.oscim.utils.Utils;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.xml.sax.Attributes;
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
import org.xml.sax.SAXException;
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
import org.xml.sax.SAXParseException;
|
import org.xmlpull.v1.XmlPullParserFactory;
|
||||||
import org.xml.sax.helpers.DefaultHandler;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static java.lang.Boolean.parseBoolean;
|
import static java.lang.Boolean.parseBoolean;
|
||||||
import static java.lang.Float.parseFloat;
|
import static java.lang.Float.parseFloat;
|
||||||
import static java.lang.Integer.parseInt;
|
import static java.lang.Integer.parseInt;
|
||||||
|
|
||||||
public class XmlThemeBuilder extends DefaultHandler {
|
public class XmlThemeBuilder {
|
||||||
|
|
||||||
private static final Logger log = LoggerFactory.getLogger(XmlThemeBuilder.class);
|
private static final Logger log = LoggerFactory.getLogger(XmlThemeBuilder.class);
|
||||||
|
|
||||||
private static final int RENDER_THEME_VERSION_MAPSFORGE = 6;
|
private static final int RENDER_THEME_VERSION_MAPSFORGE = 6;
|
||||||
private static final int RENDER_THEME_VERSION_VTM = 1;
|
private static final int RENDER_THEME_VERSION_VTM = 1;
|
||||||
|
private static XmlPullParserFactory xmlPullParserFactory = null;
|
||||||
|
|
||||||
private enum Element {
|
private enum Element {
|
||||||
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RECT, RENDERING_STYLE, TAG_TRANSFORM
|
RENDER_THEME, RENDERING_INSTRUCTION, RULE, STYLE, ATLAS, RECT, RENDERING_STYLE, TAG_TRANSFORM
|
||||||
@ -109,15 +111,30 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
* @throws ThemeException if an error occurs while parsing the render theme XML.
|
||||||
*/
|
*/
|
||||||
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
public static IRenderTheme read(ThemeFile theme, ThemeCallback themeCallback) throws ThemeException {
|
||||||
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme, themeCallback);
|
InputStream inputStream = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
new XMLReaderAdapter().parse(renderThemeHandler, theme.getRenderThemeAsStream());
|
XmlPullParser pullParser = getXmlPullParserFactory().newPullParser();
|
||||||
|
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(theme, pullParser, themeCallback);
|
||||||
|
inputStream = theme.getRenderThemeAsStream();
|
||||||
|
pullParser.setInput(inputStream, null);
|
||||||
|
renderThemeHandler.processRenderTheme();
|
||||||
|
return renderThemeHandler.mRenderTheme;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
throw new ThemeException(e.getMessage());
|
throw new ThemeException(e.getMessage());
|
||||||
|
} finally {
|
||||||
|
IOUtils.closeQuietly(inputStream);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return renderThemeHandler.mRenderTheme;
|
public static XmlPullParserFactory getXmlPullParserFactory() throws XmlPullParserException {
|
||||||
|
if (xmlPullParserFactory == null) {
|
||||||
|
xmlPullParserFactory = XmlPullParserFactory.newInstance();
|
||||||
|
}
|
||||||
|
return xmlPullParserFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setXmlPullParserFactory(XmlPullParserFactory xmlPullParserFactory) {
|
||||||
|
XmlThemeBuilder.xmlPullParserFactory = xmlPullParserFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -128,19 +145,17 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param value the XML attribute value.
|
* @param value the XML attribute value.
|
||||||
* @param attributeIndex the XML attribute index position.
|
* @param attributeIndex the XML attribute index position.
|
||||||
*/
|
*/
|
||||||
private static void logUnknownAttribute(String element, String name,
|
private static void logUnknownAttribute(String element, String name, String value, int attributeIndex) {
|
||||||
String value, int attributeIndex) {
|
log.debug("unknown attribute in element {} {} : {} = {}", element, attributeIndex, name, value);
|
||||||
log.debug("unknown attribute in element {} () : {} = {}",
|
|
||||||
element, attributeIndex, name, value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private final ArrayList<RuleBuilder> mRulesList = new ArrayList<>();
|
private final ArrayList<RuleBuilder> mRulesList = new ArrayList<>();
|
||||||
private final Stack<Element> mElementStack = new Stack<>();
|
private final Stack<Element> mElementStack = new Stack<>();
|
||||||
private final Stack<RuleBuilder> mRuleStack = new Stack<>();
|
private final Stack<RuleBuilder> mRuleStack = new Stack<>();
|
||||||
private final HashMap<String, RenderStyle> mStyles = new HashMap<>(10);
|
private final Map<String, RenderStyle<?>> mStyles = new HashMap<>(10);
|
||||||
|
|
||||||
private final HashMap<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10);
|
private final Map<String, TextStyle.TextBuilder<?>> mTextStyles = new HashMap<>(10);
|
||||||
private final HashMap<String, SymbolStyle.SymbolBuilder<?>> mSymbolStyles = new HashMap<>(10);
|
private final Map<String, SymbolStyle.SymbolBuilder<?>> mSymbolStyles = new HashMap<>(10);
|
||||||
|
|
||||||
private final AreaBuilder<?> mAreaBuilder = AreaStyle.builder();
|
private final AreaBuilder<?> mAreaBuilder = AreaStyle.builder();
|
||||||
private final CircleBuilder<?> mCircleBuilder = CircleStyle.builder();
|
private final CircleBuilder<?> mCircleBuilder = CircleStyle.builder();
|
||||||
@ -157,6 +172,8 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
private float mStrokeScale = 1;
|
private float mStrokeScale = 1;
|
||||||
float mTextScale = 1;
|
float mTextScale = 1;
|
||||||
|
|
||||||
|
private final XmlPullParser mPullParser;
|
||||||
|
private String qName;
|
||||||
final ThemeFile mTheme;
|
final ThemeFile mTheme;
|
||||||
private final ThemeCallback mThemeCallback;
|
private final ThemeCallback mThemeCallback;
|
||||||
RenderTheme mRenderTheme;
|
RenderTheme mRenderTheme;
|
||||||
@ -168,21 +185,38 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
private XmlRenderThemeStyleLayer mCurrentLayer;
|
private XmlRenderThemeStyleLayer mCurrentLayer;
|
||||||
private XmlRenderThemeStyleMenu mRenderThemeStyleMenu;
|
private XmlRenderThemeStyleMenu mRenderThemeStyleMenu;
|
||||||
|
|
||||||
private Map<String, String> mTransformKeyMap = new HashMap<>();
|
private final Map<String, String> mTransformKeyMap = new HashMap<>();
|
||||||
private Map<Tag, Tag> mTransformTagMap = new HashMap<>();
|
private final Map<Tag, Tag> mTransformTagMap = new HashMap<>();
|
||||||
|
|
||||||
public XmlThemeBuilder(ThemeFile theme) {
|
public XmlThemeBuilder(ThemeFile theme, XmlPullParser pullParser) {
|
||||||
this(theme, null);
|
this(theme, pullParser, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public XmlThemeBuilder(ThemeFile theme, ThemeCallback themeCallback) {
|
public XmlThemeBuilder(ThemeFile theme, XmlPullParser pullParser, ThemeCallback themeCallback) {
|
||||||
mTheme = theme;
|
mTheme = theme;
|
||||||
|
mPullParser = pullParser;
|
||||||
mThemeCallback = themeCallback;
|
mThemeCallback = themeCallback;
|
||||||
mMapsforgeTheme = theme.isMapsforgeTheme();
|
mMapsforgeTheme = theme.isMapsforgeTheme();
|
||||||
mScale = CanvasAdapter.getScale();
|
mScale = CanvasAdapter.getScale();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void processRenderTheme() throws XmlPullParserException, IOException {
|
||||||
|
int eventType = mPullParser.getEventType();
|
||||||
|
do {
|
||||||
|
if (eventType == XmlPullParser.START_DOCUMENT) {
|
||||||
|
// no-op
|
||||||
|
} else if (eventType == XmlPullParser.START_TAG) {
|
||||||
|
startElement();
|
||||||
|
} else if (eventType == XmlPullParser.END_TAG) {
|
||||||
|
endElement();
|
||||||
|
} else if (eventType == XmlPullParser.TEXT) {
|
||||||
|
// not implemented
|
||||||
|
}
|
||||||
|
eventType = mPullParser.next();
|
||||||
|
} while (eventType != XmlPullParser.END_DOCUMENT);
|
||||||
|
endDocument();
|
||||||
|
}
|
||||||
|
|
||||||
public void endDocument() {
|
public void endDocument() {
|
||||||
if (mMapsforgeTheme) {
|
if (mMapsforgeTheme) {
|
||||||
// Building rule for Mapsforge themes
|
// Building rule for Mapsforge themes
|
||||||
@ -209,11 +243,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mTransformKeyMap, mTransformTagMap, mMapsforgeTheme);
|
return new RenderTheme(mMapBackground, mTextScale, rules, mLevels, mTransformKeyMap, mTransformTagMap, mMapsforgeTheme);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void endElement() {
|
||||||
public void endElement(String uri, String localName, String qName) {
|
qName = mPullParser.getName();
|
||||||
|
|
||||||
mElementStack.pop();
|
mElementStack.pop();
|
||||||
|
|
||||||
if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(localName) || ELEMENT_NAME_MATCH_VTM.equals(localName)) {
|
if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(qName) || ELEMENT_NAME_MATCH_VTM.equals(qName)) {
|
||||||
mRuleStack.pop();
|
mRuleStack.pop();
|
||||||
if (mRuleStack.empty()) {
|
if (mRuleStack.empty()) {
|
||||||
if (isVisible(mCurrentRule)) {
|
if (isVisible(mCurrentRule)) {
|
||||||
@ -222,7 +257,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
} else {
|
} else {
|
||||||
mCurrentRule = mRuleStack.peek();
|
mCurrentRule = mRuleStack.peek();
|
||||||
}
|
}
|
||||||
} else if (ELEMENT_NAME_STYLE_MENU.equals(localName)) {
|
} else if (ELEMENT_NAME_STYLE_MENU.equals(qName)) {
|
||||||
// when we are finished parsing the menu part of the file, we can get the
|
// when we are finished parsing the menu part of the file, we can get the
|
||||||
// categories to render from the initiator. This allows the creating action
|
// categories to render from the initiator. This allows the creating action
|
||||||
// to select which of the menu options to choose
|
// to select which of the menu options to choose
|
||||||
@ -233,118 +268,108 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void startElement() throws ThemeException {
|
||||||
public void error(SAXParseException exception) {
|
qName = mPullParser.getName();
|
||||||
log.debug(exception.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void warning(SAXParseException exception) {
|
|
||||||
log.debug(exception.getMessage());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void startElement(String uri, String localName, String qName,
|
|
||||||
Attributes attributes) throws ThemeException {
|
|
||||||
try {
|
try {
|
||||||
if (ELEMENT_NAME_RENDER_THEME.equals(localName)) {
|
if (ELEMENT_NAME_RENDER_THEME.equals(qName)) {
|
||||||
checkState(localName, Element.RENDER_THEME);
|
checkState(qName, Element.RENDER_THEME);
|
||||||
createRenderTheme(localName, attributes);
|
createRenderTheme(qName);
|
||||||
|
|
||||||
} else if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(localName) || ELEMENT_NAME_MATCH_VTM.equals(localName)) {
|
} else if (ELEMENT_NAME_MATCH_MAPSFORGE.equals(qName) || ELEMENT_NAME_MATCH_VTM.equals(qName)) {
|
||||||
checkState(localName, Element.RULE);
|
checkState(qName, Element.RULE);
|
||||||
RuleBuilder rule = createRule(localName, attributes);
|
RuleBuilder rule = createRule(qName);
|
||||||
if (!mRuleStack.empty() && isVisible(rule)) {
|
if (!mRuleStack.empty() && isVisible(rule)) {
|
||||||
mCurrentRule.addSubRule(rule);
|
mCurrentRule.addSubRule(rule);
|
||||||
}
|
}
|
||||||
mCurrentRule = rule;
|
mCurrentRule = rule;
|
||||||
mRuleStack.push(mCurrentRule);
|
mRuleStack.push(mCurrentRule);
|
||||||
|
|
||||||
} else if ("style-text".equals(localName)) {
|
} else if ("style-text".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleTextElement(localName, attributes, true, false);
|
handleTextElement(qName, true, false);
|
||||||
|
|
||||||
} else if ("style-symbol".equals(localName)) {
|
} else if ("style-symbol".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleSymbolElement(localName, attributes, true);
|
handleSymbolElement(qName, true);
|
||||||
|
|
||||||
} else if ("style-area".equals(localName)) {
|
} else if ("style-area".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleAreaElement(localName, attributes, true);
|
handleAreaElement(qName, true);
|
||||||
|
|
||||||
} else if ("style-line".equals(localName)) {
|
} else if ("style-line".equals(qName)) {
|
||||||
checkState(localName, Element.STYLE);
|
checkState(qName, Element.STYLE);
|
||||||
handleLineElement(localName, attributes, true, false);
|
handleLineElement(qName, true, false);
|
||||||
|
|
||||||
} else if ("outline-layer".equals(localName)) {
|
} else if ("outline-layer".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
LineStyle line = createLine(null, localName, attributes, mLevels++, true, false);
|
LineStyle line = createLine(null, qName, mLevels++, true, false);
|
||||||
mStyles.put(OUTLINE_STYLE + line.style, line);
|
mStyles.put(OUTLINE_STYLE + line.style, line);
|
||||||
|
|
||||||
} else if ("area".equals(localName)) {
|
} else if ("area".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleAreaElement(localName, attributes, false);
|
handleAreaElement(qName, false);
|
||||||
|
|
||||||
} else if ("caption".equals(localName)) {
|
} else if ("caption".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleTextElement(localName, attributes, false, true);
|
handleTextElement(qName, false, true);
|
||||||
|
|
||||||
} else if ("circle".equals(localName)) {
|
} else if ("circle".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
CircleStyle circle = createCircle(localName, attributes, mLevels++);
|
CircleStyle circle = createCircle(qName, mLevels++);
|
||||||
if (isVisible(circle))
|
if (isVisible(circle))
|
||||||
mCurrentRule.addStyle(circle);
|
mCurrentRule.addStyle(circle);
|
||||||
|
|
||||||
} else if ("line".equals(localName)) {
|
} else if ("line".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleLineElement(localName, attributes, false, false);
|
handleLineElement(qName, false, false);
|
||||||
|
|
||||||
} else if ("text".equals(localName) || "pathText".equals(localName)) {
|
} else if ("text".equals(qName) || "pathText".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleTextElement(localName, attributes, false, false);
|
handleTextElement(qName, false, false);
|
||||||
|
|
||||||
} else if ("symbol".equals(localName)) {
|
} else if ("symbol".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleSymbolElement(localName, attributes, false);
|
handleSymbolElement(qName, false);
|
||||||
|
|
||||||
} else if ("outline".equals(localName)) {
|
} else if ("outline".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
LineStyle outline = createOutline(attributes.getValue("use"), attributes);
|
LineStyle outline = createOutline(getStringAttribute("use"));
|
||||||
if (outline != null && isVisible(outline))
|
if (outline != null && isVisible(outline))
|
||||||
mCurrentRule.addStyle(outline);
|
mCurrentRule.addStyle(outline);
|
||||||
|
|
||||||
} else if ("extrusion".equals(localName)) {
|
} else if ("extrusion".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
ExtrusionStyle extrusion = createExtrusion(localName, attributes, mLevels++);
|
ExtrusionStyle extrusion = createExtrusion(qName, mLevels++);
|
||||||
if (isVisible(extrusion))
|
if (isVisible(extrusion))
|
||||||
mCurrentRule.addStyle(extrusion);
|
mCurrentRule.addStyle(extrusion);
|
||||||
|
|
||||||
} else if ("lineSymbol".equals(localName)) {
|
} else if ("lineSymbol".equals(qName)) {
|
||||||
checkState(localName, Element.RENDERING_INSTRUCTION);
|
checkState(qName, Element.RENDERING_INSTRUCTION);
|
||||||
handleLineElement(localName, attributes, false, true);
|
handleLineElement(qName, false, true);
|
||||||
|
|
||||||
} else if ("atlas".equals(localName)) {
|
} else if ("atlas".equals(qName)) {
|
||||||
checkState(localName, Element.ATLAS);
|
checkState(qName, Element.ATLAS);
|
||||||
createAtlas(localName, attributes);
|
createAtlas(qName);
|
||||||
|
|
||||||
} else if ("rect".equals(localName)) {
|
} else if ("rect".equals(qName)) {
|
||||||
checkState(localName, Element.RECT);
|
checkState(qName, Element.RECT);
|
||||||
createTextureRegion(localName, attributes);
|
createTextureRegion(qName);
|
||||||
|
|
||||||
} else if ("cat".equals(localName)) {
|
} else if ("cat".equals(qName)) {
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
mCurrentLayer.addCategory(getStringAttribute(attributes, "id"));
|
mCurrentLayer.addCategory(getStringAttribute("id"));
|
||||||
|
|
||||||
} else if ("layer".equals(localName)) {
|
} else if ("layer".equals(qName)) {
|
||||||
// render theme menu layer
|
// render theme menu layer
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
boolean enabled = false;
|
boolean enabled = false;
|
||||||
if (getStringAttribute(attributes, "enabled") != null) {
|
if (getStringAttribute("enabled") != null) {
|
||||||
enabled = Boolean.valueOf(getStringAttribute(attributes, "enabled"));
|
enabled = Boolean.parseBoolean(getStringAttribute("enabled"));
|
||||||
}
|
}
|
||||||
boolean visible = Boolean.valueOf(getStringAttribute(attributes, "visible"));
|
boolean visible = Boolean.parseBoolean(getStringAttribute("visible"));
|
||||||
mCurrentLayer = mRenderThemeStyleMenu.createLayer(getStringAttribute(attributes, "id"), visible, enabled);
|
mCurrentLayer = mRenderThemeStyleMenu.createLayer(getStringAttribute("id"), visible, enabled);
|
||||||
String parent = getStringAttribute(attributes, "parent");
|
String parent = getStringAttribute("parent");
|
||||||
if (null != parent) {
|
if (null != parent) {
|
||||||
XmlRenderThemeStyleLayer parentEntry = mRenderThemeStyleMenu.getLayer(parent);
|
XmlRenderThemeStyleLayer parentEntry = mRenderThemeStyleMenu.getLayer(parent);
|
||||||
if (null != parentEntry) {
|
if (null != parentEntry) {
|
||||||
@ -357,40 +382,38 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ("name".equals(localName)) {
|
} else if ("name".equals(qName)) {
|
||||||
// render theme menu name
|
// render theme menu name
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
mCurrentLayer.addTranslation(getStringAttribute(attributes, "lang"), getStringAttribute(attributes, "value"));
|
mCurrentLayer.addTranslation(getStringAttribute("lang"), getStringAttribute("value"));
|
||||||
|
|
||||||
} else if ("overlay".equals(localName)) {
|
} else if ("overlay".equals(qName)) {
|
||||||
// render theme menu overlay
|
// render theme menu overlay
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
XmlRenderThemeStyleLayer overlay = mRenderThemeStyleMenu.getLayer(getStringAttribute(attributes, "id"));
|
XmlRenderThemeStyleLayer overlay = mRenderThemeStyleMenu.getLayer(getStringAttribute("id"));
|
||||||
if (overlay != null) {
|
if (overlay != null) {
|
||||||
mCurrentLayer.addOverlay(overlay);
|
mCurrentLayer.addOverlay(overlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if ("stylemenu".equals(localName)) {
|
} else if ("stylemenu".equals(qName)) {
|
||||||
checkState(qName, Element.RENDERING_STYLE);
|
checkState(qName, Element.RENDERING_STYLE);
|
||||||
mRenderThemeStyleMenu = new XmlRenderThemeStyleMenu(getStringAttribute(attributes, "id"),
|
mRenderThemeStyleMenu = new XmlRenderThemeStyleMenu(getStringAttribute("id"),
|
||||||
getStringAttribute(attributes, "defaultlang"), getStringAttribute(attributes, "defaultvalue"));
|
getStringAttribute("defaultlang"), getStringAttribute("defaultvalue"));
|
||||||
|
|
||||||
} else if ("tag-transform".equals(localName)) {
|
} else if ("tag-transform".equals(qName)) {
|
||||||
checkState(qName, Element.TAG_TRANSFORM);
|
checkState(qName, Element.TAG_TRANSFORM);
|
||||||
tagTransform(localName, attributes);
|
tagTransform(qName);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
log.error("unknown element: {}", localName);
|
log.error("unknown element: {}", qName);
|
||||||
throw new SAXException("unknown element: " + localName);
|
throw new XmlPullParserException("unknown element: " + qName);
|
||||||
}
|
}
|
||||||
} catch (SAXException e) {
|
} catch (XmlPullParserException | IOException e) {
|
||||||
throw new ThemeException(e.getMessage());
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new ThemeException(e.getMessage());
|
throw new ThemeException(e.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RuleBuilder createRule(String localName, Attributes attributes) {
|
private RuleBuilder createRule(String qName) {
|
||||||
String cat = null;
|
String cat = null;
|
||||||
int element = Rule.Element.ANY;
|
int element = Rule.Element.ANY;
|
||||||
int closed = Closed.ANY;
|
int closed = Closed.ANY;
|
||||||
@ -400,9 +423,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
byte zoomMax = Byte.MAX_VALUE;
|
byte zoomMax = Byte.MAX_VALUE;
|
||||||
int selector = 0;
|
int selector = 0;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("e".equals(name)) {
|
if ("e".equals(name)) {
|
||||||
String val = value.toUpperCase(Locale.ENGLISH);
|
String val = value.toUpperCase(Locale.ENGLISH);
|
||||||
@ -440,7 +463,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
if ("when-matched".equals(value))
|
if ("when-matched".equals(value))
|
||||||
selector |= Selector.WHEN_MATCHED;
|
selector |= Selector.WHEN_MATCHED;
|
||||||
} else {
|
} else {
|
||||||
logUnknownAttribute(localName, name, value, i);
|
logUnknownAttribute(qName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,10 +497,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleLineElement(String localName, Attributes attributes, boolean isStyle, boolean hasSymbol)
|
private void handleLineElement(String qName, boolean isStyle, boolean hasSymbol) {
|
||||||
throws SAXException {
|
|
||||||
|
|
||||||
String use = attributes.getValue("use");
|
String use = getStringAttribute("use");
|
||||||
LineStyle style = null;
|
LineStyle style = null;
|
||||||
|
|
||||||
if (use != null) {
|
if (use != null) {
|
||||||
@ -488,7 +510,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LineStyle line = createLine(style, localName, attributes, mLevels++, false, hasSymbol);
|
LineStyle line = createLine(style, qName, mLevels++, false, hasSymbol);
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(LINE_STYLE + line.style, line);
|
mStyles.put(LINE_STYLE + line.style, line);
|
||||||
@ -497,9 +519,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mCurrentRule.addStyle(line);
|
mCurrentRule.addStyle(line);
|
||||||
/* Note 'outline' will not be inherited, it's just a
|
/* Note 'outline' will not be inherited, it's just a
|
||||||
* shortcut to add the outline RenderInstruction. */
|
* shortcut to add the outline RenderInstruction. */
|
||||||
String outlineValue = attributes.getValue("outline");
|
String outlineValue = getStringAttribute("outline");
|
||||||
if (outlineValue != null) {
|
if (outlineValue != null) {
|
||||||
LineStyle outline = createOutline(outlineValue, attributes);
|
LineStyle outline = createOutline(outlineValue);
|
||||||
if (outline != null)
|
if (outline != null)
|
||||||
mCurrentRule.addStyle(outline);
|
mCurrentRule.addStyle(outline);
|
||||||
}
|
}
|
||||||
@ -513,17 +535,16 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param isOutline is outline layer
|
* @param isOutline is outline layer
|
||||||
* @return a new Line with the given rendering attributes.
|
* @return a new Line with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private LineStyle createLine(LineStyle line, String elementName, Attributes attributes,
|
private LineStyle createLine(LineStyle line, String elementName, int level, boolean isOutline, boolean hasSymbol) {
|
||||||
int level, boolean isOutline, boolean hasSymbol) {
|
|
||||||
LineBuilder<?> b = mLineBuilder.set(line);
|
LineBuilder<?> b = mLineBuilder.set(line);
|
||||||
b.isOutline(isOutline);
|
b.isOutline(isOutline);
|
||||||
b.level(level);
|
b.level(level);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
String src = null;
|
String src = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@ -671,10 +692,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleAreaElement(String localName, Attributes attributes, boolean isStyle)
|
private void handleAreaElement(String qName, boolean isStyle) {
|
||||||
throws SAXException {
|
|
||||||
|
|
||||||
String use = attributes.getValue("use");
|
String use = getStringAttribute("use");
|
||||||
AreaStyle style = null;
|
AreaStyle style = null;
|
||||||
|
|
||||||
if (use != null) {
|
if (use != null) {
|
||||||
@ -685,7 +705,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AreaStyle area = createArea(style, localName, attributes, mLevels++);
|
AreaStyle area = createArea(style, qName, mLevels++);
|
||||||
|
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
mStyles.put(AREA_STYLE + area.style, area);
|
mStyles.put(AREA_STYLE + area.style, area);
|
||||||
@ -698,16 +718,15 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* @return a new Area with the given rendering attributes.
|
* @return a new Area with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private AreaStyle createArea(AreaStyle area, String elementName, Attributes attributes,
|
private AreaStyle createArea(AreaStyle area, String elementName, int level) {
|
||||||
int level) {
|
|
||||||
AreaBuilder<?> b = mAreaBuilder.set(area);
|
AreaBuilder<?> b = mAreaBuilder.set(area);
|
||||||
b.level(level);
|
b.level(level);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
String src = null;
|
String src = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@ -766,15 +785,15 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private LineStyle createOutline(String style, Attributes attributes) {
|
private LineStyle createOutline(String style) {
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style);
|
LineStyle line = (LineStyle) mStyles.get(OUTLINE_STYLE + style);
|
||||||
if (line != null && line.outline) {
|
if (line != null && line.outline) {
|
||||||
String cat = null;
|
String cat = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("cat".equals(name)) {
|
if ("cat".equals(name)) {
|
||||||
cat = value;
|
cat = value;
|
||||||
@ -790,12 +809,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAtlas(String elementName, Attributes attributes) throws IOException {
|
private void createAtlas(String elementName) throws IOException {
|
||||||
String img = null;
|
String img = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("img".equals(name)) {
|
if ("img".equals(name)) {
|
||||||
img = value;
|
img = value;
|
||||||
@ -810,16 +829,16 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mTextureAtlas = new TextureAtlas(bitmap);
|
mTextureAtlas = new TextureAtlas(bitmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createTextureRegion(String elementName, Attributes attributes) {
|
private void createTextureRegion(String elementName) {
|
||||||
if (mTextureAtlas == null)
|
if (mTextureAtlas == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String regionName = null;
|
String regionName = null;
|
||||||
Rect r = null;
|
Rect r = null;
|
||||||
|
|
||||||
for (int i = 0, n = attributes.getLength(); i < n; i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name)) {
|
if ("id".equals(name)) {
|
||||||
regionName = value;
|
regionName = value;
|
||||||
@ -841,12 +860,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mTextureAtlas.addTextureRegion(regionName.intern(), r);
|
mTextureAtlas.addTextureRegion(regionName.intern(), r);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkElement(String elementName, Element element) throws SAXException {
|
private void checkElement(String elementName, Element element) throws XmlPullParserException {
|
||||||
Element parentElement;
|
Element parentElement;
|
||||||
switch (element) {
|
switch (element) {
|
||||||
case RENDER_THEME:
|
case RENDER_THEME:
|
||||||
if (!mElementStack.empty()) {
|
if (!mElementStack.empty()) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_STACK_NOT_EMPTY + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_STACK_NOT_EMPTY + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -854,34 +873,34 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME
|
if (parentElement != Element.RENDER_THEME
|
||||||
&& parentElement != Element.RULE) {
|
&& parentElement != Element.RULE) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_RULE_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_RULE_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case STYLE:
|
case STYLE:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME) {
|
if (parentElement != Element.RENDER_THEME) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_STYLE_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_STYLE_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RENDERING_INSTRUCTION:
|
case RENDERING_INSTRUCTION:
|
||||||
if (mElementStack.peek() != Element.RULE) {
|
if (mElementStack.peek() != Element.RULE) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_RENDERING_INSTRUCTION_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_RENDERING_INSTRUCTION_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case ATLAS:
|
case ATLAS:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME) {
|
if (parentElement != Element.RENDER_THEME) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_ATLAS_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_ATLAS_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case RECT:
|
case RECT:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.ATLAS) {
|
if (parentElement != Element.ATLAS) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_RECT_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_RECT_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -891,28 +910,28 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
case TAG_TRANSFORM:
|
case TAG_TRANSFORM:
|
||||||
parentElement = mElementStack.peek();
|
parentElement = mElementStack.peek();
|
||||||
if (parentElement != Element.RENDER_THEME) {
|
if (parentElement != Element.RENDER_THEME) {
|
||||||
throw new SAXException(UNEXPECTED_ELEMENT_TAG_TRANSFORM_PARENT_ELEMENT_MISMATCH + elementName);
|
throw new XmlPullParserException(UNEXPECTED_ELEMENT_TAG_TRANSFORM_PARENT_ELEMENT_MISMATCH + elementName);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new SAXException("unknown enum value: " + element);
|
throw new XmlPullParserException("unknown enum value: " + element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkState(String elementName, Element element) throws SAXException {
|
private void checkState(String elementName, Element element) throws XmlPullParserException {
|
||||||
checkElement(elementName, element);
|
checkElement(elementName, element);
|
||||||
mElementStack.push(element);
|
mElementStack.push(element);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createRenderTheme(String elementName, Attributes attributes) {
|
private void createRenderTheme(String elementName) {
|
||||||
Integer version = null;
|
Integer version = null;
|
||||||
int mapBackground = Color.WHITE;
|
int mapBackground = Color.WHITE;
|
||||||
float baseStrokeWidth = 1;
|
float baseStrokeWidth = 1;
|
||||||
float baseTextScale = 1;
|
float baseTextScale = 1;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("schemaLocation".equals(name))
|
if ("schemaLocation".equals(name))
|
||||||
continue;
|
continue;
|
||||||
@ -950,10 +969,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
mTextScale = baseTextScale;
|
mTextScale = baseTextScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleTextElement(String localName, Attributes attributes, boolean isStyle,
|
private void handleTextElement(String qName, boolean isStyle, boolean isCaption) {
|
||||||
boolean isCaption) throws SAXException {
|
|
||||||
|
|
||||||
String style = attributes.getValue("use");
|
String style = getStringAttribute("use");
|
||||||
TextBuilder<?> pt = null;
|
TextBuilder<?> pt = null;
|
||||||
|
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
@ -964,7 +982,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
TextBuilder<?> b = createText(localName, attributes, isCaption, pt);
|
TextBuilder<?> b = createText(qName, isCaption, pt);
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
log.debug("put style {}", b.style);
|
log.debug("put style {}", b.style);
|
||||||
mTextStyles.put(b.style, TextStyle.builder().from(b));
|
mTextStyles.put(b.style, TextStyle.builder().from(b));
|
||||||
@ -979,8 +997,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param caption ...
|
* @param caption ...
|
||||||
* @return a new Text with the given rendering attributes.
|
* @return a new Text with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private TextBuilder<?> createText(String elementName, Attributes attributes,
|
private TextBuilder<?> createText(String elementName, boolean caption, TextBuilder<?> style) {
|
||||||
boolean caption, TextBuilder<?> style) {
|
|
||||||
TextBuilder<?> b;
|
TextBuilder<?> b;
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
b = mTextBuilder.reset();
|
b = mTextBuilder.reset();
|
||||||
@ -995,9 +1012,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
b.priority = DEFAULT_PRIORITY;
|
b.priority = DEFAULT_PRIORITY;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@ -1101,14 +1118,14 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* @param level the drawing level of this instruction.
|
* @param level the drawing level of this instruction.
|
||||||
* @return a new Circle with the given rendering attributes.
|
* @return a new Circle with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private CircleStyle createCircle(String elementName, Attributes attributes, int level) {
|
private CircleStyle createCircle(String elementName, int level) {
|
||||||
CircleBuilder<?> b = mCircleBuilder.reset();
|
CircleBuilder<?> b = mCircleBuilder.reset();
|
||||||
b.level(level);
|
b.level(level);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("r".equals(name) || "radius".equals(name))
|
if ("r".equals(name) || "radius".equals(name))
|
||||||
b.radius(Float.parseFloat(value) * mScale * mStrokeScale);
|
b.radius(Float.parseFloat(value) * mScale * mStrokeScale);
|
||||||
@ -1139,10 +1156,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void handleSymbolElement(String localName, Attributes attributes, boolean isStyle)
|
private void handleSymbolElement(String qName, boolean isStyle) {
|
||||||
throws SAXException {
|
|
||||||
|
|
||||||
String style = attributes.getValue("use");
|
String style = getStringAttribute("use");
|
||||||
SymbolBuilder<?> ps = null;
|
SymbolBuilder<?> ps = null;
|
||||||
|
|
||||||
if (style != null) {
|
if (style != null) {
|
||||||
@ -1153,7 +1169,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SymbolBuilder<?> b = createSymbol(localName, attributes, ps);
|
SymbolBuilder<?> b = createSymbol(qName, ps);
|
||||||
if (isStyle) {
|
if (isStyle) {
|
||||||
log.debug("put style {}", b.style);
|
log.debug("put style {}", b.style);
|
||||||
mSymbolStyles.put(b.style, SymbolStyle.builder().from(b));
|
mSymbolStyles.put(b.style, SymbolStyle.builder().from(b));
|
||||||
@ -1167,8 +1183,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
/**
|
/**
|
||||||
* @return a new Symbol with the given rendering attributes.
|
* @return a new Symbol with the given rendering attributes.
|
||||||
*/
|
*/
|
||||||
private SymbolBuilder<?> createSymbol(String elementName, Attributes attributes,
|
private SymbolBuilder<?> createSymbol(String elementName, SymbolBuilder<?> style) {
|
||||||
SymbolBuilder<?> style) {
|
|
||||||
SymbolBuilder<?> b;
|
SymbolBuilder<?> b;
|
||||||
if (style == null)
|
if (style == null)
|
||||||
b = mSymbolBuilder.reset();
|
b = mSymbolBuilder.reset();
|
||||||
@ -1176,9 +1191,9 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
b = mSymbolBuilder.from(style);
|
b = mSymbolBuilder.from(style);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("id".equals(name))
|
if ("id".equals(name))
|
||||||
b.style = value;
|
b.style = value;
|
||||||
@ -1247,14 +1262,14 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.bitmap(bitmap).build();
|
return b.bitmap(bitmap).build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExtrusionStyle createExtrusion(String elementName, Attributes attributes, int level) {
|
private ExtrusionStyle createExtrusion(String elementName, int level) {
|
||||||
ExtrusionBuilder<?> b = mExtrusionBuilder.reset();
|
ExtrusionBuilder<?> b = mExtrusionBuilder.reset();
|
||||||
b.level(level);
|
b.level(level);
|
||||||
b.themeCallback(mThemeCallback);
|
b.themeCallback(mThemeCallback);
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
if ("cat".equals(name))
|
if ("cat".equals(name))
|
||||||
b.cat(value);
|
b.cat(value);
|
||||||
@ -1287,10 +1302,11 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return b.build();
|
return b.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getStringAttribute(Attributes attributes, String name) {
|
private String getStringAttribute(String name) {
|
||||||
for (int i = 0; i < attributes.getLength(); ++i) {
|
int n = mPullParser.getAttributeCount();
|
||||||
if (attributes.getLocalName(i).equals(name)) {
|
for (int i = 0; i < n; i++) {
|
||||||
return attributes.getValue(i);
|
if (mPullParser.getAttributeName(i).equals(name)) {
|
||||||
|
return mPullParser.getAttributeValue(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
@ -1300,7 +1316,7 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
* A style is visible if categories is not set or the style has no category
|
* A style is visible if categories is not set or the style has no category
|
||||||
* or the categories contain the style's category.
|
* or the categories contain the style's category.
|
||||||
*/
|
*/
|
||||||
private boolean isVisible(RenderStyle renderStyle) {
|
private boolean isVisible(RenderStyle<?> renderStyle) {
|
||||||
return mCategories == null || renderStyle.cat == null || mCategories.contains(renderStyle.cat);
|
return mCategories == null || renderStyle.cat == null || mCategories.contains(renderStyle.cat);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1321,13 +1337,13 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
return dashIntervals;
|
return dashIntervals;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void tagTransform(String localName, Attributes attributes) {
|
private void tagTransform(String qName) {
|
||||||
String k, v, libK, libV;
|
String k, v, libK, libV;
|
||||||
k = v = libK = libV = null;
|
k = v = libK = libV = null;
|
||||||
|
|
||||||
for (int i = 0; i < attributes.getLength(); i++) {
|
for (int i = 0, n = mPullParser.getAttributeCount(); i < n; ++i) {
|
||||||
String name = attributes.getLocalName(i);
|
String name = mPullParser.getAttributeName(i);
|
||||||
String value = attributes.getValue(i);
|
String value = mPullParser.getAttributeValue(i);
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case "k":
|
case "k":
|
||||||
@ -1343,12 +1359,12 @@ public class XmlThemeBuilder extends DefaultHandler {
|
|||||||
libV = value;
|
libV = value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
logUnknownAttribute(localName, name, value, i);
|
logUnknownAttribute(qName, name, value, i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (k == null || k.isEmpty() || libK == null || libK.isEmpty()) {
|
if (k == null || k.isEmpty() || libK == null || libK.isEmpty()) {
|
||||||
log.debug("empty key in element " + localName);
|
log.debug("empty key in element " + qName);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user