cleanup: XmlThemeBuilder:

- rename from -> read
- cleanup theme attribute validation
This commit is contained in:
Hannes Janetzek 2014-03-09 02:04:34 +01:00
parent abade416df
commit a4cd4ad767
2 changed files with 61 additions and 113 deletions

View File

@ -45,7 +45,7 @@ public class ThemeLoader {
InputStream inputStream = null; InputStream inputStream = null;
try { try {
inputStream = theme.getRenderThemeAsStream(); inputStream = theme.getRenderThemeAsStream();
IRenderTheme t = XmlThemeBuilder.from(inputStream); IRenderTheme t = XmlThemeBuilder.read(inputStream);
if (t != null) if (t != null)
t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f); t.scaleTextSize(CanvasAdapter.textScale + (CanvasAdapter.dpi / 240 - 1) * 0.5f);

View File

@ -45,6 +45,7 @@ import org.oscim.theme.styles.LineSymbol;
import org.oscim.theme.styles.RenderStyle; import org.oscim.theme.styles.RenderStyle;
import org.oscim.theme.styles.Symbol; import org.oscim.theme.styles.Symbol;
import org.oscim.theme.styles.Text; import org.oscim.theme.styles.Text;
import org.oscim.theme.styles.Text.TextBuilder;
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;
@ -83,7 +84,7 @@ public class XmlThemeBuilder extends DefaultHandler {
* @throws IOException * @throws IOException
* if an I/O error occurs while reading from the input stream. * if an I/O error occurs while reading from the input stream.
*/ */
public static IRenderTheme from(InputStream inputStream) public static IRenderTheme read(InputStream inputStream)
throws SAXException, IOException { throws SAXException, IOException {
XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder(); XmlThemeBuilder renderThemeHandler = new XmlThemeBuilder();
@ -119,14 +120,15 @@ public class XmlThemeBuilder extends DefaultHandler {
log.debug(sb.toString()); log.debug(sb.toString());
} }
private ArrayList<RuleBuilder> mRulesList = new ArrayList<RuleBuilder>(); private final ArrayList<RuleBuilder> mRulesList = new ArrayList<RuleBuilder>();
private RuleBuilder mCurrentRule; private final Stack<Element> mElementStack = new Stack<Element>();
private final Stack<RuleBuilder> mRuleStack = new Stack<RuleBuilder>();
private Stack<Element> mElementStack = new Stack<Element>(); private final HashMap<String, RenderStyle> mStyles =
private Stack<RuleBuilder> mRuleStack = new Stack<RuleBuilder>();
private HashMap<String, RenderStyle> mStyles =
new HashMap<String, RenderStyle>(10); new HashMap<String, RenderStyle>(10);
private final TextBuilder mTextBuilder = new TextBuilder();
private RuleBuilder mCurrentRule;
private TextureAtlas mTextureAtlas; private TextureAtlas mTextureAtlas;
private int mLevels = 0; private int mLevels = 0;
@ -149,10 +151,6 @@ public class XmlThemeBuilder extends DefaultHandler {
mRuleStack.clear(); mRuleStack.clear();
mElementStack.clear(); mElementStack.clear();
mStyles = null;
mRuleStack = null;
mRulesList = null;
mElementStack = null;
mTextureAtlas = null; mTextureAtlas = null;
} }
@ -325,10 +323,6 @@ public class XmlThemeBuilder extends DefaultHandler {
/** /**
* @param line * @param line
* optional: line style defaults * optional: line style defaults
* @param elementName
* the name of the XML element.
* @param attributes
* the attributes of the XML element.
* @param level * @param level
* the drawing level of this instruction. * the drawing level of this instruction.
* @param isOutline * @param isOutline
@ -430,7 +424,7 @@ public class XmlThemeBuilder extends DefaultHandler {
width = 1; width = 1;
} else if (!isOutline) { } else if (!isOutline) {
validateLine(width); validateNonNegative("width", width);
} }
return new Line(level, style, color, width, cap, fixed, return new Line(level, style, color, width, cap, fixed,
@ -438,11 +432,6 @@ public class XmlThemeBuilder extends DefaultHandler {
fade, blur, isOutline); fade, blur, isOutline);
} }
private static void validateLine(float strokeWidth) {
if (strokeWidth < 0)
throw new ThemeException("width must not be negative: " + strokeWidth);
}
private void handleAreaElement(String localName, Attributes attributes, boolean isStyle) private void handleAreaElement(String localName, Attributes attributes, boolean isStyle)
throws SAXException { throws SAXException {
@ -468,12 +457,6 @@ public class XmlThemeBuilder extends DefaultHandler {
} }
/** /**
* @param elementName
* the name of the XML element.
* @param attributes
* the attributes of the XML element.
* @param level
* the drawing level of this instruction.
* @return a new Area with the given rendering attributes. * @return a new Area with the given rendering attributes.
*/ */
private static Area createArea(Area area, String elementName, Attributes attributes, int level) { private static Area createArea(Area area, String elementName, Attributes attributes, int level) {
@ -535,8 +518,7 @@ public class XmlThemeBuilder extends DefaultHandler {
else else
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
validateNonNegative("stroke-width", strokeWidth);
validateLine(strokeWidth);
if (src != null) { if (src != null) {
try { try {
@ -574,8 +556,7 @@ public class XmlThemeBuilder extends DefaultHandler {
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i); XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
} }
} }
if (img == null) validateExists("img", img, elementName);
throw new ThemeException("missing attribute 'img' for element: " + elementName);
Bitmap bitmap = CanvasAdapter.g.loadBitmapAsset(IMG_PATH + img); Bitmap bitmap = CanvasAdapter.g.loadBitmapAsset(IMG_PATH + img);
mTextureAtlas = new TextureAtlas(bitmap); mTextureAtlas = new TextureAtlas(bitmap);
@ -603,9 +584,8 @@ public class XmlThemeBuilder extends DefaultHandler {
XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i); XmlThemeBuilder.logUnknownAttribute(elementName, name, value, i);
} }
} }
if (regionName == null || r == null) validateExists("id", regionName, elementName);
throw new ThemeException("missing attribute 'id' or 'rect' for element: " validateExists("pos", r, elementName);
+ elementName);
mTextureAtlas.addTextureRegion(regionName.intern(), r); mTextureAtlas.addTextureRegion(regionName.intern(), r);
} }
@ -687,107 +667,82 @@ public class XmlThemeBuilder extends DefaultHandler {
} }
if (version == null) validateExists("version", version, elementName);
throw new ThemeException("missing attribute version for element:" + elementName);
else if (version.intValue() != RENDER_THEME_VERSION) if (version.intValue() != RENDER_THEME_VERSION)
throw new ThemeException("invalid render theme version:" + version); throw new ThemeException("invalid render theme version:"
else if (baseStrokeWidth < 0) + version);
throw new ThemeException("base-stroke-width must not be negative: " + baseStrokeWidth);
else if (baseTextSize < 0) validateNonNegative("base-stroke-width", baseStrokeWidth);
throw new ThemeException("base-text-size must not be negative: " + baseTextSize); validateNonNegative("base-test-size", baseTextSize);
mMapBackground = mapBackground; mMapBackground = mapBackground;
mBaseTextSize = baseTextSize; mBaseTextSize = baseTextSize;
} }
/** /**
* @param elementName
* the name of the XML element.
* @param attributes
* the attributes of the XML element.
* @param caption * @param caption
* ... * ...
* @return a new Text with the given rendering attributes. * @return a new Text with the given rendering attributes.
*/ */
private Text createText(String elementName, Attributes attributes, boolean caption) { private Text createText(String elementName, Attributes attributes, boolean caption) {
String textKey = null; TextBuilder b = mTextBuilder.reset();
FontFamily fontFamily = FontFamily.DEFAULT;
FontStyle fontStyle = FontStyle.NORMAL; b.caption = caption;
float fontSize = 0;
int fill = Color.BLACK;
int stroke = Color.BLACK;
float strokeWidth = 0;
String style = null;
float dy = 0;
int priority = Integer.MAX_VALUE;
TextureRegion symbol = null;
for (int i = 0; i < attributes.getLength(); ++i) { for (int i = 0; i < attributes.getLength(); ++i) {
String name = attributes.getLocalName(i); String name = attributes.getLocalName(i);
String value = attributes.getValue(i); String value = attributes.getValue(i);
if ("id".equals(name)) if ("id".equals(name))
style = value; b.style = value;
else if ("k".equals(name)) else if ("k".equals(name))
textKey = value.intern(); b.textKey = value.intern();
else if ("font-family".equals(name)) else if ("font-family".equals(name))
fontFamily = FontFamily.valueOf(value.toUpperCase()); b.fontFamily = FontFamily.valueOf(value.toUpperCase());
else if ("style".equals(name)) else if ("style".equals(name))
fontStyle = FontStyle.valueOf(value.toUpperCase()); b.fontStyle = FontStyle.valueOf(value.toUpperCase());
else if ("size".equals(name)) else if ("size".equals(name))
fontSize = Float.parseFloat(value); b.fontSize = Float.parseFloat(value);
else if ("fill".equals(name)) else if ("fill".equals(name))
fill = Color.parseColor(value); b.color = Color.parseColor(value);
else if ("stroke".equals(name)) else if ("stroke".equals(name))
stroke = Color.parseColor(value); b.stroke = Color.parseColor(value);
else if ("stroke-width".equals(name)) else if ("stroke-width".equals(name))
strokeWidth = Float.parseFloat(value); b.strokeWidth = Float.parseFloat(value);
else if ("caption".equals(name)) else if ("caption".equals(name))
caption = Boolean.parseBoolean(value); b.caption = Boolean.parseBoolean(value);
else if ("priority".equals(name)) else if ("priority".equals(name))
priority = Integer.parseInt(value); b.priority = Integer.parseInt(value);
else if ("dy".equals(name)) else if ("dy".equals(name))
dy = Float.parseFloat(value); // NB: minus..
b.dy = -Float.parseFloat(value);
else if ("symbol".equals(name)) else if ("symbol".equals(name))
symbol = getAtlasRegion(value); b.texture = getAtlasRegion(value);
else else
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
validateText(elementName, textKey, fontSize, strokeWidth); validateExists("k", b.textKey, elementName);
validateNonNegative("size", b.fontSize);
validateNonNegative("stroke-width", b.strokeWidth);
return new Text(style, textKey, fontFamily, fontStyle, fontSize, fill, stroke, strokeWidth, return b.buildInternal();
dy, caption, symbol, priority);
}
private static void validateText(String elementName, String textKey, float fontSize,
float strokeWidth) {
if (textKey == null)
throw new ThemeException("missing attribute k for element: " + elementName);
else if (fontSize < 0)
throw new ThemeException("font-size must not be negative: " + fontSize);
else if (strokeWidth < 0)
throw new ThemeException("stroke-width must not be negative: " + strokeWidth);
} }
/** /**
* @param elementName
* the name of the XML element.
* @param attributes
* the attributes of the XML element.
* @param level * @param level
* the drawing level of this instruction. * the drawing level of this instruction.
* @return a new Circle with the given rendering attributes. * @return a new Circle with the given rendering attributes.
@ -822,24 +777,14 @@ public class XmlThemeBuilder extends DefaultHandler {
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
validateCircle(elementName, radius, strokeWidth); validateExists("r", radius, elementName);
validateNonNegative("radius", radius);
validateNonNegative("stroke-width", strokeWidth);
return new Circle(radius, scaleRadius, fill, stroke, strokeWidth, level); return new Circle(radius, scaleRadius, fill, stroke, strokeWidth, level);
} }
private static void validateCircle(String elementName, Float radius, float strokeWidth) {
if (radius == null)
throw new ThemeException("missing attribute r for element: " + elementName);
else if (radius.floatValue() < 0)
throw new ThemeException("radius must not be negative: " + radius);
else if (strokeWidth < 0)
throw new ThemeException("stroke-width must not be negative: " + strokeWidth);
}
/** /**
* @param elementName
* the name of the XML element.
* @param attributes
* the attributes of the XML element.
* @return a new LineSymbol with the given rendering attributes. * @return a new LineSymbol with the given rendering attributes.
*/ */
private static LineSymbol createLineSymbol(String elementName, Attributes attributes) { private static LineSymbol createLineSymbol(String elementName, Attributes attributes) {
@ -864,15 +809,11 @@ public class XmlThemeBuilder extends DefaultHandler {
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
validateSymbol(elementName, src); validateExists("src", src, elementName);
return new LineSymbol(src, alignCenter, repeat); return new LineSymbol(src, alignCenter, repeat);
} }
/** /**
* @param elementName
* the name of the XML element.
* @param attributes
* the attributes of the XML element.
* @return a new Symbol with the given rendering attributes. * @return a new Symbol with the given rendering attributes.
*/ */
private Symbol createSymbol(String elementName, Attributes attributes) { private Symbol createSymbol(String elementName, Attributes attributes) {
@ -888,16 +829,11 @@ public class XmlThemeBuilder extends DefaultHandler {
logUnknownAttribute(elementName, name, value, i); logUnknownAttribute(elementName, name, value, i);
} }
validateSymbol(elementName, src); validateExists("src", src, elementName);
return new Symbol(getAtlasRegion(src)); return new Symbol(getAtlasRegion(src));
} }
private static void validateSymbol(String elementName, String src) {
if (src == null)
throw new ThemeException("missing attribute src for element: " + elementName);
}
private Extrusion createExtrusion(String elementName, Attributes attributes, int level) { private Extrusion createExtrusion(String elementName, Attributes attributes, int level) {
int colorSide = 0; int colorSide = 0;
int colorTop = 0; int colorTop = 0;
@ -926,4 +862,16 @@ public class XmlThemeBuilder extends DefaultHandler {
return new Extrusion(level, colorSide, colorTop, colorLine, defaultHeight); return new Extrusion(level, colorSide, colorTop, colorLine, defaultHeight);
} }
private static void validateNonNegative(String name, float value) {
if (value < 0)
throw new ThemeException(name + " must not be negative: "
+ value);
}
private static void validateExists(String name, Object obj, String elementName) {
if (obj == null)
throw new ThemeException("missing attribute " + name
+ " for element: " + elementName);
}
} }