diff --git a/vtm/src/org/oscim/theme/rule/AnyMatcher.java b/vtm/src/org/oscim/theme/rule/AnyMatcher.java
deleted file mode 100644
index c0130570..00000000
--- a/vtm/src/org/oscim/theme/rule/AnyMatcher.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import org.oscim.core.Tag;
-
-final class AnyMatcher implements AttributeMatcher {
- private static final AnyMatcher INSTANCE = new AnyMatcher();
-
- static AnyMatcher getInstance() {
- return INSTANCE;
- }
-
- /**
- * Private constructor to prevent instantiation from other classes.
- */
- private AnyMatcher() {
- // do nothing
- }
-
- @Override
- public boolean isCoveredBy(AttributeMatcher attributeMatcher) {
- return attributeMatcher == this;
- }
-
- @Override
- public boolean matches(Tag[] tags) {
- return true;
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/AttributeMatcher.java b/vtm/src/org/oscim/theme/rule/AttributeMatcher.java
deleted file mode 100644
index 4f02ce68..00000000
--- a/vtm/src/org/oscim/theme/rule/AttributeMatcher.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import org.oscim.core.Tag;
-
-interface AttributeMatcher {
- boolean isCoveredBy(AttributeMatcher attributeMatcher);
-
- boolean matches(Tag[] tags);
-}
diff --git a/vtm/src/org/oscim/theme/rule/MultiKeyMatcher.java b/vtm/src/org/oscim/theme/rule/MultiKeyMatcher.java
deleted file mode 100644
index 1389e84e..00000000
--- a/vtm/src/org/oscim/theme/rule/MultiKeyMatcher.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import java.util.List;
-
-import org.oscim.core.Tag;
-
-class MultiKeyMatcher implements AttributeMatcher {
- private final String[] mKeys;
-
- MultiKeyMatcher(List keys) {
- mKeys = new String[keys.size()];
- for (int i = 0, n = mKeys.length; i < n; ++i) {
- mKeys[i] = keys.get(i).intern();
- }
- }
-
- @Override
- public boolean isCoveredBy(AttributeMatcher attributeMatcher) {
- if (attributeMatcher == this) {
- return true;
- }
-
- Tag[] tags = new Tag[mKeys.length];
- int i = 0;
- for (String key : mKeys) {
- tags[i++] = new Tag(key, null);
- }
- return attributeMatcher.matches(tags);
- }
-
- @Override
- public boolean matches(Tag[] tags) {
- for (Tag tag : tags)
- for (String key : mKeys)
- if (key == tag.key)
- return true;
-
- return false;
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/MultiValueMatcher.java b/vtm/src/org/oscim/theme/rule/MultiValueMatcher.java
deleted file mode 100644
index 821d1269..00000000
--- a/vtm/src/org/oscim/theme/rule/MultiValueMatcher.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import java.util.List;
-
-import org.oscim.core.Tag;
-
-class MultiValueMatcher implements AttributeMatcher {
- private final String[] mValues;
-
- MultiValueMatcher(List values) {
- mValues = new String[values.size()];
- for (int i = 0, n = mValues.length; i < n; ++i) {
- mValues[i] = values.get(i).intern();
- }
- }
-
- @Override
- public boolean isCoveredBy(AttributeMatcher attributeMatcher) {
- if (attributeMatcher == this) {
- return true;
- }
- Tag[] tags = new Tag[mValues.length];
-
- int i = 0;
- for (String val : mValues) {
- tags[i++] = new Tag(null, val);
- }
- return attributeMatcher.matches(tags);
- }
-
- @Override
- public boolean matches(Tag[] tags) {
- for (Tag tag : tags)
- for (String val : mValues)
- if (val == tag.value)
- return true;
-
- return false;
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/NegativeMatcher.java b/vtm/src/org/oscim/theme/rule/NegativeMatcher.java
deleted file mode 100644
index d859bd4e..00000000
--- a/vtm/src/org/oscim/theme/rule/NegativeMatcher.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import java.util.List;
-
-import org.oscim.core.Tag;
-
-class NegativeMatcher implements AttributeMatcher {
- private final String[] mKeyList;
- private final String[] mValueList;
-
- // (-) 'exclusive negation' matches when either KEY is not present
- // or KEY is present and any VALUE is NOT present
- //
- // (\) 'except negation' matches when KEY is present
- // none items of VALUE is present (TODO).
- // (can be emulated by ...)
- //
- // (~) 'non-exclusive negation' matches when either KEY is not present
- // or KEY is present and any VALUE is present
- //
- private final boolean mExclusive;
-
- NegativeMatcher(List keyList, List valueList, boolean exclusive) {
- mKeyList = new String[keyList.size()];
- for (int i = 0; i < mKeyList.length; i++)
- mKeyList[i] = keyList.get(i).intern();
-
- mValueList = new String[valueList.size()];
- for (int i = 0; i < mValueList.length; i++)
- mValueList[i] = valueList.get(i).intern();
-
- mExclusive = exclusive;
- }
-
- @Override
- public boolean isCoveredBy(AttributeMatcher attributeMatcher) {
- return false;
- }
-
- @Override
- public boolean matches(Tag[] tags) {
- if (keyListDoesNotContainKeys(tags))
- return true;
-
- for (Tag tag : tags)
- for (String value : mValueList)
- if (value == tag.value)
- return !mExclusive;
-
- return mExclusive;
- }
-
- private boolean keyListDoesNotContainKeys(Tag[] tags) {
- for (Tag tag : tags)
- for (String key : mKeyList)
- if (key == tag.key)
- return false;
-
- return true;
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/NegativeRule.java b/vtm/src/org/oscim/theme/rule/NegativeRule.java
index ce750aaa..9454a009 100644
--- a/vtm/src/org/oscim/theme/rule/NegativeRule.java
+++ b/vtm/src/org/oscim/theme/rule/NegativeRule.java
@@ -18,20 +18,61 @@
package org.oscim.theme.rule;
import org.oscim.core.Tag;
+import org.oscim.theme.rule.RuleBuilder.RuleType;
import org.oscim.theme.styles.RenderStyle;
class NegativeRule extends Rule {
- final AttributeMatcher mAttributeMatcher;
- NegativeRule(int element, int zoom, int selector, AttributeMatcher attributeMatcher,
+ public final String[] keys;
+ public final String[] values;
+
+ /* (-) 'exclusive negation' matches when either KEY is not present
+ * or KEY is present and any VALUE is NOT present
+ *
+ * (\) 'except negation' matches when KEY is present
+ * none items of VALUE is present (TODO).
+ * (can be emulated by ...)
+ *
+ * (~) 'non-exclusive negation' matches when either KEY is not present
+ * or KEY is present and any VALUE is present */
+
+ public final boolean exclusive;
+
+ NegativeRule(RuleType type, int element, int zoom, int selector,
+ String[] keys, String[] values,
Rule[] subRules, RenderStyle[] styles) {
super(element, zoom, selector, subRules, styles);
- mAttributeMatcher = attributeMatcher;
+ for (int i = 0; i < keys.length; i++)
+ keys[i] = keys[i].intern();
+
+ for (int i = 0; i < values.length; i++)
+ values[i] = values[i].intern();
+
+ this.keys = keys;
+ this.values = values;
+ this.exclusive = type == RuleType.EXCLUDE;
}
@Override
- boolean matchesTags(Tag[] tags) {
- return mAttributeMatcher.matches(tags);
+ public boolean matchesTags(Tag[] tags) {
+ if (keyListDoesNotContainKeys(tags))
+ return true;
+
+ for (Tag tag : tags)
+ for (String value : values)
+ if (value == tag.value)
+ return !exclusive;
+
+ return exclusive;
+ }
+
+ private boolean keyListDoesNotContainKeys(Tag[] tags) {
+ for (Tag tag : tags)
+ for (String key : keys)
+ if (key == tag.key)
+ return false;
+
+ return true;
}
}
diff --git a/vtm/src/org/oscim/theme/rule/PositiveRule.java b/vtm/src/org/oscim/theme/rule/PositiveRule.java
index 370bcb24..59ecb111 100644
--- a/vtm/src/org/oscim/theme/rule/PositiveRule.java
+++ b/vtm/src/org/oscim/theme/rule/PositiveRule.java
@@ -1,5 +1,4 @@
/*
- * Copyright 2010, 2011, 2012 mapsforge.org
* Copyright 2013 Hannes Janetzek
*
* This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
@@ -20,28 +19,149 @@ package org.oscim.theme.rule;
import org.oscim.core.Tag;
import org.oscim.theme.styles.RenderStyle;
-class PositiveRule extends Rule {
- final AttributeMatcher mKeyMatcher;
- final AttributeMatcher mValueMatcher;
+class PositiveRule {
- PositiveRule(int element, int zoom, int selector, AttributeMatcher keyMatcher,
- AttributeMatcher valueMatcher, Rule[] subRules, RenderStyle[] styles) {
- super(element, zoom, selector, subRules, styles);
+ static class PositiveRuleK extends Rule {
+ private final String mKey;
- if (keyMatcher instanceof AnyMatcher)
- mKeyMatcher = null;
- else
- mKeyMatcher = keyMatcher;
+ PositiveRuleK(int element, int zoom, int selector, String key,
+ Rule[] subRules, RenderStyle[] styles) {
- if (valueMatcher instanceof AnyMatcher)
- mValueMatcher = null;
- else
- mValueMatcher = valueMatcher;
+ super(element, zoom, selector, subRules, styles);
+ mKey = key;
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ for (Tag tag : tags)
+ if (mKey == tag.key)
+ return true;
+
+ return false;
+ }
}
- @Override
- boolean matchesTags(Tag[] tags) {
- return (mKeyMatcher == null || mKeyMatcher.matches(tags))
- && (mValueMatcher == null || mValueMatcher.matches(tags));
+ static class PositiveRuleV extends Rule {
+ private final String mValue;
+
+ PositiveRuleV(int element, int zoom, int selector, String value,
+ Rule[] subRules, RenderStyle[] styles) {
+
+ super(element, zoom, selector, subRules, styles);
+ mValue = value;
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ for (Tag tag : tags)
+ if (mValue == tag.value)
+ return true;
+
+ return false;
+ }
+ }
+
+ static class PositiveRuleKV extends Rule {
+ private final String mKey;
+ private final String mValue;
+
+ PositiveRuleKV(int element, int zoom, int selector, String key, String value,
+ Rule[] subRules, RenderStyle[] styles) {
+
+ super(element, zoom, selector, subRules, styles);
+ mKey = key;
+ mValue = value;
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ for (Tag tag : tags)
+ if (mKey == tag.key)
+ return (mValue == tag.value);
+
+ return false;
+ }
+ }
+
+ static class PositiveRuleMultiKV extends Rule {
+ private final String mKeys[];
+ private final String mValues[];
+
+ PositiveRuleMultiKV(int element, int zoom, int selector, String keys[], String values[],
+ Rule[] subRules, RenderStyle[] styles) {
+
+ super(element, zoom, selector, subRules, styles);
+ if (keys.length == 0) {
+ mKeys = null;
+ } else {
+ for (int i = 0; i < keys.length; i++)
+ keys[i] = keys[i].intern();
+ mKeys = keys;
+ }
+
+ if (values.length == 0) {
+ mValues = null;
+ } else {
+ for (int i = 0; i < values.length; i++)
+ values[i] = values[i].intern();
+ mValues = values;
+ }
+ }
+
+ @Override
+ boolean matchesTags(Tag[] tags) {
+ if (mKeys == null) {
+ for (Tag tag : tags) {
+ for (String value : mValues) {
+ if (value == tag.value)
+ return true;
+ }
+ }
+ return false;
+ }
+
+ for (Tag tag : tags)
+ for (String key : mKeys) {
+ if (key == tag.key) {
+ if (mValues == null)
+ return true;
+
+ for (String value : mValues) {
+ if (value == tag.value)
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ }
+
+ public static Rule create(int element, int zoom, int selector,
+ String[] keys, String values[], Rule[] subRules, RenderStyle[] styles) {
+ int numKeys = keys.length;
+ int numVals = values.length;
+
+ if (numKeys == 0 && numVals == 0)
+ return new Rule(element, zoom, selector, subRules, styles);
+
+ for (int i = 0; i < numVals; i++)
+ values[i] = values[i].intern();
+
+ for (int i = 0; i < numKeys; i++)
+ keys[i] = keys[i].intern();
+
+ if (numKeys == 1 && numKeys == 0) {
+ return new PositiveRuleK(element, zoom, selector, keys[0], subRules, styles);
+ }
+
+ if (numKeys == 0 && numVals == 1) {
+ return new PositiveRuleV(element, zoom, selector, values[0], subRules, styles);
+ }
+
+ if (numKeys == 1 && numVals == 1)
+ return new PositiveRuleKV(element, zoom, selector, keys[0], values[0], subRules, styles);
+
+ return new PositiveRuleMultiKV(element, zoom, selector, keys, values, subRules, styles);
+
}
}
diff --git a/vtm/src/org/oscim/theme/rule/Rule.java b/vtm/src/org/oscim/theme/rule/Rule.java
index 31756ca2..347792ca 100644
--- a/vtm/src/org/oscim/theme/rule/Rule.java
+++ b/vtm/src/org/oscim/theme/rule/Rule.java
@@ -21,7 +21,7 @@ import java.util.List;
import org.oscim.core.Tag;
import org.oscim.theme.styles.RenderStyle;
-public abstract class Rule {
+public class Rule {
public final static RenderStyle[] EMPTY_STYLE = new RenderStyle[0];
public final static Rule[] EMPTY_RULES = new Rule[0];
@@ -44,7 +44,9 @@ public abstract class Rule {
selectWhenMatched = (selector & Selector.WHEN_MATCHED) != 0;
}
- abstract boolean matchesTags(Tag[] tags);
+ boolean matchesTags(Tag[] tags) {
+ return true;
+ }
public boolean matchElement(int type, Tag[] tags, int zoomLevel, List result) {
diff --git a/vtm/src/org/oscim/theme/rule/RuleBuilder.java b/vtm/src/org/oscim/theme/rule/RuleBuilder.java
index 00c3cca0..968679e5 100644
--- a/vtm/src/org/oscim/theme/rule/RuleBuilder.java
+++ b/vtm/src/org/oscim/theme/rule/RuleBuilder.java
@@ -1,139 +1,104 @@
package org.oscim.theme.rule;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
import java.util.Stack;
import org.oscim.theme.IRenderTheme.ThemeException;
import org.oscim.theme.XmlThemeBuilder;
import org.oscim.theme.styles.RenderStyle;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xml.sax.Attributes;
public class RuleBuilder {
- boolean positiveRule;
+ final static Logger log = LoggerFactory.getLogger(RuleBuilder.class);
+
+ private final static String[] EMPTY_KV = {};
+
+ public enum RuleType {
+ POSITIVE,
+ NEGATIVE,
+ EXCLUDE
+ }
int zoom;
int element;
int selector;
+ RuleType type;
- AttributeMatcher keyMatcher;
- AttributeMatcher valueMatcher;
+ String keys[];
+ String values[];
ArrayList renderStyles = new ArrayList(4);
ArrayList subRules = new ArrayList(4);
- private static final Map, AttributeMatcher> MATCHERS_CACHE_KEY =
- new HashMap, AttributeMatcher>();
- private static final Map, AttributeMatcher> MATCHERS_CACHE_VALUE =
- new HashMap, AttributeMatcher>();
-
private static final String STRING_NEGATION = "~";
private static final String STRING_EXCLUSIVE = "-";
- private static final String STRING_WILDCARD = "*";
+ private static final String SEPARATOR = "\\|";
+ //private static final String STRING_WILDCARD = "*";
private static final int SELECT_FIRST = 1 << 0;
private static final int SELECT_WHEN_MATCHED = 1 << 1;
- public RuleBuilder(boolean positive, int element, int zoom, int selector,
- AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
- this.positiveRule = positive;
+ public RuleBuilder(RuleType type, int element, int zoom, int selector,
+ String[] keys, String[] values) {
+ this.type = type;
this.element = element;
this.zoom = zoom;
this.selector = selector;
- this.keyMatcher = keyMatcher;
- this.valueMatcher = valueMatcher;
+ this.keys = keys;
+ this.values = values;
}
- public RuleBuilder(boolean positive, AttributeMatcher keyMatcher, AttributeMatcher valueMatcher) {
- this.positiveRule = positive;
- this.keyMatcher = keyMatcher;
- this.valueMatcher = valueMatcher;
+ public RuleBuilder(RuleType type, String[] keys, String[] values) {
+ this.element = Element.ANY;
+ this.zoom = ~0;
+ this.type = type;
+ this.keys = keys;
+ this.values = values;
+ }
+
+ public RuleBuilder() {
+ this.type = RuleType.POSITIVE;
+ this.element = Element.ANY;
+ this.zoom = ~0;
+ this.keys = EMPTY_KV;
+ this.values = EMPTY_KV;
}
public static RuleBuilder create(Stack ruleStack, String keys, String values) {
- List keyList = null, valueList = null;
- boolean negativeRule = false;
- boolean exclusionRule = false;
+ String[] keyList = EMPTY_KV;
+ String[] valueList = EMPTY_KV;
+ RuleType type = RuleType.POSITIVE;
- AttributeMatcher keyMatcher, valueMatcher = null;
-
- if (values == null) {
- valueMatcher = AnyMatcher.getInstance();
- } else {
- valueList = new ArrayList(Arrays.asList(values.split("\\|")));
- if (valueList.remove(STRING_NEGATION))
- negativeRule = true;
- else if (valueList.remove(STRING_EXCLUSIVE))
- exclusionRule = true;
- else {
- valueMatcher = getValueMatcher(valueList);
- valueMatcher = RuleOptimizer.optimize(valueMatcher, ruleStack);
+ if (values != null) {
+ if (values.startsWith(STRING_NEGATION)) {
+ type = RuleType.NEGATIVE;
+ if (values.length() > 2)
+ valueList = values.substring(2)
+ .split(SEPARATOR);
+ } else if (values.startsWith(STRING_EXCLUSIVE)) {
+ type = RuleType.EXCLUDE;
+ if (values.length() > 2)
+ valueList = values.substring(2)
+ .split(SEPARATOR);
+ } else {
+ valueList = values.split(SEPARATOR);
}
}
- if (keys == null) {
- if (negativeRule || exclusionRule) {
+ if (keys != null) {
+ keyList = keys.split("\\|");
+ }
+
+ if (type != RuleType.POSITIVE) {
+ if (keyList == null || keyList.length == 0) {
throw new ThemeException("negative rule requires key");
}
- keyMatcher = AnyMatcher.getInstance();
- } else {
- keyList = new ArrayList(Arrays.asList(keys.split("\\|")));
- keyMatcher = getKeyMatcher(keyList);
-
- if ((keyMatcher instanceof AnyMatcher) && (negativeRule || exclusionRule)) {
- throw new ThemeException("negative rule requires key");
- }
-
- if (negativeRule) {
- AttributeMatcher m = new NegativeMatcher(keyList, valueList, false);
- return new RuleBuilder(false, m, null);
- } else if (exclusionRule) {
- AttributeMatcher m = new NegativeMatcher(keyList, valueList, true);
- return new RuleBuilder(false, m, null);
- }
-
- keyMatcher = RuleOptimizer.optimize(keyMatcher, ruleStack);
}
- return new RuleBuilder(true, keyMatcher, valueMatcher);
- }
-
- private static AttributeMatcher getKeyMatcher(List keyList) {
- if (STRING_WILDCARD.equals(keyList.get(0))) {
- return AnyMatcher.getInstance();
- }
-
- AttributeMatcher attributeMatcher = MATCHERS_CACHE_KEY.get(keyList);
- if (attributeMatcher == null) {
- if (keyList.size() == 1) {
- attributeMatcher = new SingleKeyMatcher(keyList.get(0));
- } else {
- attributeMatcher = new MultiKeyMatcher(keyList);
- }
- MATCHERS_CACHE_KEY.put(keyList, attributeMatcher);
- }
- return attributeMatcher;
- }
-
- private static AttributeMatcher getValueMatcher(List valueList) {
- if (STRING_WILDCARD.equals(valueList.get(0))) {
- return AnyMatcher.getInstance();
- }
-
- AttributeMatcher attributeMatcher = MATCHERS_CACHE_VALUE.get(valueList);
- if (attributeMatcher == null) {
- if (valueList.size() == 1) {
- attributeMatcher = new SingleValueMatcher(valueList.get(0));
- } else {
- attributeMatcher = new MultiValueMatcher(valueList);
- }
- MATCHERS_CACHE_VALUE.put(valueList, attributeMatcher);
- }
- return attributeMatcher;
+ return new RuleBuilder(type, keyList, valueList);
}
private static void validate(byte zoomMin, byte zoomMax) {
@@ -211,8 +176,6 @@ public class RuleBuilder {
}
public Rule onComplete() {
- MATCHERS_CACHE_KEY.clear();
- MATCHERS_CACHE_VALUE.clear();
RenderStyle[] styles = null;
Rule[] rules = null;
@@ -228,12 +191,12 @@ public class RuleBuilder {
rules[i] = subRules.get(i).onComplete();
}
- if (positiveRule)
- return new PositiveRule(element, zoom, selector, keyMatcher,
- valueMatcher, rules, styles);
+ if (type != RuleType.POSITIVE)
+ return new NegativeRule(type, element, zoom, selector,
+ keys, values, rules, styles);
else
- return new NegativeRule(element, zoom, selector, keyMatcher,
- rules, styles);
+ return PositiveRule.create(element, zoom, selector,
+ keys, values, rules, styles);
}
public void addStyle(RenderStyle style) {
diff --git a/vtm/src/org/oscim/theme/rule/RuleOptimizer.java b/vtm/src/org/oscim/theme/rule/RuleOptimizer.java
deleted file mode 100644
index 5b74f873..00000000
--- a/vtm/src/org/oscim/theme/rule/RuleOptimizer.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import java.util.Stack;
-
-final class RuleOptimizer {
-
- private static AttributeMatcher optimizeKeyMatcher(AttributeMatcher attributeMatcher,
- Stack ruleStack) {
- for (int i = 0, n = ruleStack.size(); i < n; ++i) {
- if (ruleStack.get(i).positiveRule) {
- RuleBuilder positiveRule = ruleStack.get(i);
-
- if (positiveRule.keyMatcher != null
- && positiveRule.keyMatcher.isCoveredBy(attributeMatcher)) {
- return null;
- }
- }
- }
-
- return attributeMatcher;
- }
-
- private static AttributeMatcher optimizeValueMatcher(
- AttributeMatcher attributeMatcher, Stack ruleStack) {
- for (int i = 0, n = ruleStack.size(); i < n; ++i) {
- if (ruleStack.get(i).positiveRule) {
- RuleBuilder positiveRule = ruleStack.get(i);
-
- if (positiveRule.valueMatcher != null
- && positiveRule.valueMatcher.isCoveredBy(attributeMatcher)) {
- return null;
- }
- }
- }
-
- return attributeMatcher;
- }
-
- static AttributeMatcher optimize(AttributeMatcher attributeMatcher,
- Stack ruleStack) {
- if (attributeMatcher instanceof AnyMatcher)
- return attributeMatcher;// return null;
- else if (attributeMatcher instanceof NegativeMatcher) {
- return attributeMatcher;
- } else if (attributeMatcher instanceof SingleKeyMatcher) {
- return optimizeKeyMatcher(attributeMatcher, ruleStack);
- } else if (attributeMatcher instanceof SingleValueMatcher) {
- return optimizeValueMatcher(attributeMatcher, ruleStack);
- } else if (attributeMatcher instanceof MultiKeyMatcher) {
- return optimizeKeyMatcher(attributeMatcher, ruleStack);
- } else if (attributeMatcher instanceof MultiValueMatcher) {
- return optimizeValueMatcher(attributeMatcher, ruleStack);
- }
- throw new IllegalArgumentException("unknown AttributeMatcher: "
- + attributeMatcher);
- }
-
- // static ClosedMatcher optimize(ClosedMatcher closedMatcher, Stack ruleStack) {
- // if (closedMatcher == null) {
- // return null;
- // }
- //
- // if (closedMatcher instanceof AnyMatcher) {
- // return null;
- // }
- //
- // for (int i = 0, n = ruleStack.size(); i < n; ++i) {
- // ClosedMatcher matcher = ruleStack.get(i).mClosedMatcher;
- // if (matcher == null)
- // return null;
- //
- // if (matcher.isCoveredBy(closedMatcher)) {
- // return null; // AnyMatcher.getInstance();
- //
- // } else if (!closedMatcher.isCoveredBy(ruleStack.get(i).mClosedMatcher)) {
- // LOG.warning("unreachable rule (closed)");
- // }
- // }
- //
- // return closedMatcher;
- // }
- //
- // static ElementMatcher optimize(ElementMatcher elementMatcher, Stack ruleStack) {
- //
- // if (elementMatcher == null) {
- // return null;
- // }
- //
- // if (elementMatcher instanceof AnyMatcher) {
- // return null;
- // }
- //
- // for (int i = 0, n = ruleStack.size(); i < n; ++i) {
- // ElementMatcher matcher = ruleStack.get(i).mElementMatcher;
- //
- // if (matcher == null)
- // return null;
- //
- // if (matcher.isCoveredBy(elementMatcher)) {
- // return null; // AnyMatcher.getInstance();
- //
- // } else if (!elementMatcher.isCoveredBy(ruleStack.get(i).mElementMatcher)) {
- // LOG.warning("unreachable rule (e)");
- // }
- // }
- //
- // return elementMatcher;
- // }
-
- /**
- * Private constructor to prevent instantiation from other classes.
- */
- private RuleOptimizer() {
- // do nothing
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/SingleKeyMatcher.java b/vtm/src/org/oscim/theme/rule/SingleKeyMatcher.java
deleted file mode 100644
index 90b26088..00000000
--- a/vtm/src/org/oscim/theme/rule/SingleKeyMatcher.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import org.oscim.core.Tag;
-
-public class SingleKeyMatcher implements AttributeMatcher {
- private final String mKey;
-
- public SingleKeyMatcher(String key) {
- mKey = key.intern();
- }
-
- @Override
- public boolean isCoveredBy(AttributeMatcher attributeMatcher) {
- Tag[] tags = { new Tag(mKey, null) };
-
- return attributeMatcher == this || attributeMatcher.matches(tags);
- }
-
- @Override
- public boolean matches(Tag[] tags) {
- for (Tag tag : tags)
- if (mKey == tag.key)
- return true;
-
- return false;
- }
-}
diff --git a/vtm/src/org/oscim/theme/rule/SingleValueMatcher.java b/vtm/src/org/oscim/theme/rule/SingleValueMatcher.java
deleted file mode 100644
index 8dc3ef7b..00000000
--- a/vtm/src/org/oscim/theme/rule/SingleValueMatcher.java
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright 2010, 2011, 2012 mapsforge.org
- * Copyright 2013 Hannes Janetzek
- *
- * This file is part of the OpenScienceMap project (http://www.opensciencemap.org).
- *
- * 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
- * Foundation, either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT ANY
- * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
- * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License along with
- * this program. If not, see .
- */
-package org.oscim.theme.rule;
-
-import org.oscim.core.Tag;
-
-public class SingleValueMatcher implements AttributeMatcher {
- private final String mValue;
-
- public SingleValueMatcher(String value) {
- mValue = value.intern();
- }
-
- @Override
- public boolean isCoveredBy(AttributeMatcher attributeMatcher) {
- Tag[] tags = { new Tag(null, mValue) };
-
- return attributeMatcher == this || attributeMatcher.matches(tags);
- }
-
- @Override
- public boolean matches(Tag[] tags) {
- for (Tag tag : tags)
- if (mValue == tag.value)
- return true;
-
- return false;
- }
-}