merge Positive/NegativeRule into Rule
This commit is contained in:
parent
211ba90108
commit
191e94c670
@ -22,8 +22,8 @@ import java.util.List;
|
|||||||
|
|
||||||
import org.oscim.core.GeometryBuffer.GeometryType;
|
import org.oscim.core.GeometryBuffer.GeometryType;
|
||||||
import org.oscim.core.TagSet;
|
import org.oscim.core.TagSet;
|
||||||
import org.oscim.theme.rule.Element;
|
|
||||||
import org.oscim.theme.rule.Rule;
|
import org.oscim.theme.rule.Rule;
|
||||||
|
import org.oscim.theme.rule.Rule.Element;
|
||||||
import org.oscim.theme.rule.Rule.RuleVisitor;
|
import org.oscim.theme.rule.Rule.RuleVisitor;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
import org.oscim.utils.LRUCache;
|
import org.oscim.utils.LRUCache;
|
||||||
|
|||||||
@ -1,25 +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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.theme.rule;
|
|
||||||
|
|
||||||
public final class Closed {
|
|
||||||
public static final int NO = 1 << 0;
|
|
||||||
public static final int YES = 1 << 1;
|
|
||||||
public static final int ANY = NO | YES;
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,24 +0,0 @@
|
|||||||
/* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.theme.rule;
|
|
||||||
|
|
||||||
public final class Element {
|
|
||||||
public static final int NODE = 1 << 0;
|
|
||||||
public static final int LINE = 1 << 1;
|
|
||||||
public static final int POLY = 1 << 2;
|
|
||||||
public static final int WAY = LINE | POLY;
|
|
||||||
public static final int ANY = NODE | WAY;
|
|
||||||
}
|
|
||||||
@ -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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
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 {
|
|
||||||
|
|
||||||
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 <m k="a"><m k=a v="-|b|c">...</m></m>)
|
|
||||||
*
|
|
||||||
* (~) '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);
|
|
||||||
|
|
||||||
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
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,167 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package org.oscim.theme.rule;
|
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
|
||||||
|
|
||||||
class PositiveRule {
|
|
||||||
|
|
||||||
static class PositiveRuleK extends Rule {
|
|
||||||
private final String mKey;
|
|
||||||
|
|
||||||
PositiveRuleK(int element, int zoom, int selector, String key,
|
|
||||||
Rule[] subRules, RenderStyle[] styles) {
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -19,9 +19,30 @@ package org.oscim.theme.rule;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.oscim.core.Tag;
|
import org.oscim.core.Tag;
|
||||||
|
import org.oscim.theme.rule.RuleBuilder.RuleType;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
|
||||||
public class Rule {
|
public class Rule {
|
||||||
|
public final class Element {
|
||||||
|
public static final int NODE = 1 << 0;
|
||||||
|
public static final int LINE = 1 << 1;
|
||||||
|
public static final int POLY = 1 << 2;
|
||||||
|
public static final int WAY = LINE | POLY;
|
||||||
|
public static final int ANY = NODE | WAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Closed {
|
||||||
|
public static final int NO = 1 << 0;
|
||||||
|
public static final int YES = 1 << 1;
|
||||||
|
public static final int ANY = NO | YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class Selector {
|
||||||
|
public static final int ANY = 0;
|
||||||
|
public static final int FIRST = 1 << 0;
|
||||||
|
public static final int WHEN_MATCHED = 1 << 1;
|
||||||
|
}
|
||||||
|
|
||||||
public final static RenderStyle[] EMPTY_STYLE = new RenderStyle[0];
|
public final static RenderStyle[] EMPTY_STYLE = new RenderStyle[0];
|
||||||
public final static Rule[] EMPTY_RULES = new Rule[0];
|
public final static Rule[] EMPTY_RULES = new Rule[0];
|
||||||
|
|
||||||
@ -49,49 +70,45 @@ public class Rule {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean matchElement(int type, Tag[] tags, int zoomLevel, List<RenderStyle> result) {
|
public boolean matchElement(int type, Tag[] tags, int zoomLevel, List<RenderStyle> result) {
|
||||||
|
if (((element & type) == 0) || ((zoom & zoomLevel) == 0) || !matchesTags(tags))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (((element & type) != 0) && ((zoom & zoomLevel) != 0) && (matchesTags(tags))) {
|
boolean matched = false;
|
||||||
boolean matched = false;
|
if (subRules != EMPTY_RULES) {
|
||||||
|
if (selectFirstMatch) {
|
||||||
|
/* only add first matching rule and when-matched rules iff a
|
||||||
|
* previous rule matched */
|
||||||
|
for (Rule r : subRules) {
|
||||||
|
/* continue if matched xor selectWhenMatch */
|
||||||
|
if (matched ^ r.selectWhenMatched)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (subRules != EMPTY_RULES) {
|
if (r.matchElement(type, tags, zoomLevel, result))
|
||||||
if (selectFirstMatch) {
|
matched = true;
|
||||||
/* only add first matching rule and when-matched rules iff a
|
}
|
||||||
* previous rule matched */
|
} else {
|
||||||
for (Rule r : subRules) {
|
/* add all rules and when-matched rules iff a previous rule
|
||||||
/* continue if matched xor selectWhenMatch */
|
* matched */
|
||||||
if (matched ^ r.selectWhenMatched)
|
for (Rule r : subRules) {
|
||||||
continue;
|
if (r.selectWhenMatched && !matched)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (r.matchElement(type, tags, zoomLevel, result))
|
if (r.matchElement(type, tags, zoomLevel, result))
|
||||||
matched = true;
|
matched = true;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* add all rules and when-matched rules iff a previous rule
|
|
||||||
* matched */
|
|
||||||
for (Rule r : subRules) {
|
|
||||||
if (r.selectWhenMatched && !matched)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (r.matchElement(type, tags, zoomLevel, result))
|
|
||||||
matched = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (styles == EMPTY_STYLE)
|
|
||||||
/* matched if styles where added */
|
|
||||||
return matched;
|
|
||||||
|
|
||||||
/* add instructions for this rule */
|
|
||||||
for (RenderStyle ri : styles)
|
|
||||||
result.add(ri);
|
|
||||||
|
|
||||||
/* this rule did not match */
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* this rule did not match */
|
if (styles == EMPTY_STYLE)
|
||||||
return false;
|
/* matched if styles where added */
|
||||||
|
return matched;
|
||||||
|
|
||||||
|
/* add instructions for this rule */
|
||||||
|
for (RenderStyle ri : styles)
|
||||||
|
result.add(ri);
|
||||||
|
|
||||||
|
/* this rule did match */
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void dispose() {
|
public void dispose() {
|
||||||
@ -152,4 +169,163 @@ public class Rule {
|
|||||||
public void apply(RuleVisitor v) {
|
public void apply(RuleVisitor v) {
|
||||||
v.apply(this);
|
v.apply(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class PositiveRuleK extends Rule {
|
||||||
|
private final String mKey;
|
||||||
|
|
||||||
|
PositiveRuleK(int element, int zoom, int selector, String key,
|
||||||
|
Rule[] subRules, RenderStyle[] styles) {
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
mKeys = keys;
|
||||||
|
|
||||||
|
if (values.length == 0)
|
||||||
|
mValues = null;
|
||||||
|
else
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static class NegativeRule extends Rule {
|
||||||
|
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 <m k="a"><m k=a v="-|b|c">...</m></m>)
|
||||||
|
*
|
||||||
|
* (~) '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);
|
||||||
|
|
||||||
|
this.keys = keys;
|
||||||
|
this.values = values;
|
||||||
|
this.exclusive = type == RuleType.EXCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean matchesTags(Tag[] tags) {
|
||||||
|
if (!containsKeys(tags))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
for (Tag tag : tags)
|
||||||
|
for (String value : values)
|
||||||
|
if (value == tag.value)
|
||||||
|
return !exclusive;
|
||||||
|
|
||||||
|
return exclusive;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean containsKeys(Tag[] tags) {
|
||||||
|
for (Tag tag : tags)
|
||||||
|
for (String key : keys)
|
||||||
|
if (key == tag.key)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,15 @@ import java.util.Stack;
|
|||||||
|
|
||||||
import org.oscim.theme.IRenderTheme.ThemeException;
|
import org.oscim.theme.IRenderTheme.ThemeException;
|
||||||
import org.oscim.theme.XmlThemeBuilder;
|
import org.oscim.theme.XmlThemeBuilder;
|
||||||
|
import org.oscim.theme.rule.Rule.Closed;
|
||||||
|
import org.oscim.theme.rule.Rule.Element;
|
||||||
|
import org.oscim.theme.rule.Rule.NegativeRule;
|
||||||
|
import org.oscim.theme.rule.Rule.PositiveRuleK;
|
||||||
|
import org.oscim.theme.rule.Rule.PositiveRuleKV;
|
||||||
|
import org.oscim.theme.rule.Rule.PositiveRuleMultiKV;
|
||||||
|
import org.oscim.theme.rule.Rule.PositiveRuleV;
|
||||||
import org.oscim.theme.styles.RenderStyle;
|
import org.oscim.theme.styles.RenderStyle;
|
||||||
|
import org.oscim.theme.styles.RenderStyle.StyleBuilder;
|
||||||
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;
|
||||||
@ -93,9 +101,8 @@ public class RuleBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (type != RuleType.POSITIVE) {
|
if (type != RuleType.POSITIVE) {
|
||||||
if (keyList == null || keyList.length == 0) {
|
if (keyList == null || keyList.length == 0)
|
||||||
throw new ThemeException("negative rule requires key");
|
throw new ThemeException("negative rule requires key");
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RuleBuilder(type, keyList, valueList);
|
return new RuleBuilder(type, keyList, valueList);
|
||||||
@ -191,12 +198,39 @@ public class RuleBuilder {
|
|||||||
rules[i] = subRules.get(i).onComplete();
|
rules[i] = subRules.get(i).onComplete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int numKeys = keys.length;
|
||||||
|
int numVals = values.length;
|
||||||
|
|
||||||
|
if (numKeys == 0 && numVals == 0)
|
||||||
|
return new Rule(element, zoom, selector, rules, 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 (type != RuleType.POSITIVE)
|
if (type != RuleType.POSITIVE)
|
||||||
return new NegativeRule(type, element, zoom, selector,
|
return new NegativeRule(type, element, zoom, selector,
|
||||||
keys, values, rules, styles);
|
keys, values, rules, styles);
|
||||||
else
|
|
||||||
return PositiveRule.create(element, zoom, selector,
|
if (numKeys == 1 && numKeys == 0) {
|
||||||
keys, values, rules, styles);
|
return new PositiveRuleK(element, zoom, selector, keys[0],
|
||||||
|
rules, styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numKeys == 0 && numVals == 1) {
|
||||||
|
return new PositiveRuleV(element, zoom, selector, values[0],
|
||||||
|
rules, styles);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (numKeys == 1 && numVals == 1)
|
||||||
|
return new PositiveRuleKV(element, zoom, selector,
|
||||||
|
keys[0], values[0], rules, styles);
|
||||||
|
|
||||||
|
return new PositiveRuleMultiKV(element, zoom, selector,
|
||||||
|
keys, values, rules, styles);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addStyle(RenderStyle style) {
|
public void addStyle(RenderStyle style) {
|
||||||
|
|||||||
@ -1,8 +0,0 @@
|
|||||||
package org.oscim.theme.rule;
|
|
||||||
|
|
||||||
public class Selector {
|
|
||||||
|
|
||||||
public static final int ANY = 0;
|
|
||||||
public static final int FIRST = 1 << 0;
|
|
||||||
public static final int WHEN_MATCHED = 1 << 1;
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user