
org.oscim.theme.rule.RuleBuilder Maven / Gradle / Ivy
/*
* Copyright 2014 Hannes Janetzek
* Copyright 2016-2017 devemux86
*
* 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.theme.IRenderTheme.ThemeException;
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.StyleBuilder;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class RuleBuilder {
private final static String[] EMPTY_KV = {};
public enum RuleType {
POSITIVE,
NEGATIVE,
EXCLUDE
}
public String cat;
int zoom;
int element;
int selector;
RuleType type;
String keys[];
String values[];
ArrayList renderStyles = new ArrayList<>(4);
ArrayList subRules = new ArrayList<>(4);
StyleBuilder>[] styleBuilder;
private static final String STRING_NEGATION = "~";
private static final String STRING_EXCLUSIVE = "-";
private static final String SEPARATOR = "\\|";
//private static final String STRING_WILDCARD = "*";
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.keys = keys;
this.values = values;
}
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(String k, String v) {
String[] keys = EMPTY_KV;
String[] values = EMPTY_KV;
RuleType type = RuleType.POSITIVE;
if (v != null) {
String[] split = v.split(SEPARATOR);
List valueList = new ArrayList<>(Arrays.asList(split));
if (valueList.remove(STRING_NEGATION)) {
type = RuleType.NEGATIVE;
values = valueList.toArray(new String[valueList.size()]);
} else if (valueList.remove(STRING_EXCLUSIVE)) {
type = RuleType.EXCLUDE;
values = valueList.toArray(new String[valueList.size()]);
} else {
values = split;
}
}
if (k != null) {
keys = k.split(SEPARATOR);
}
if (type != RuleType.POSITIVE) {
if (keys == null || keys.length == 0)
throw new ThemeException("negative rule requires key");
}
return new RuleBuilder(type, keys, values);
}
public RuleBuilder zoom(byte zoomMin, byte zoomMax) {
// zoom-level bitmask
zoom = 0;
for (int z = zoomMin; z <= zoomMax && z < 32; z++)
zoom |= (1 << z);
return this;
}
public Rule onComplete(int[] level) {
RenderStyle[] styles = null;
Rule[] rules = null;
if (styleBuilder != null)
for (StyleBuilder> style : styleBuilder) {
renderStyles.add(style.level(level[0]).build());
level[0] += 2;
}
if (renderStyles.size() > 0) {
styles = new RenderStyle[renderStyles.size()];
renderStyles.toArray(styles);
}
if (subRules.size() > 0) {
rules = new Rule[subRules.size()];
for (int i = 0; i < rules.length; i++)
rules[i] = subRules.get(i).onComplete(level);
}
int numKeys = keys.length;
int numVals = values.length;
if (numKeys == 0 && numVals == 0)
return new Rule(element, zoom, selector, rules, styles)
.setCat(cat);
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)
return new NegativeRule(type, element, zoom, selector, keys, values, rules, styles)
.setCat(cat);
if (numKeys == 1 && numVals == 0)
return new PositiveRuleK(element, zoom, selector, keys[0], rules, styles)
.setCat(cat);
if (numKeys == 0 && numVals == 1)
return new PositiveRuleV(element, zoom, selector, values[0], rules, styles)
.setCat(cat);
if (numKeys == 1 && numVals == 1)
return new PositiveRuleKV(element, zoom, selector, keys[0], values[0], rules, styles)
.setCat(cat);
return new PositiveRuleMultiKV(element, zoom, selector, keys, values, rules, styles)
.setCat(cat);
}
public RuleBuilder addStyle(RenderStyle style) {
renderStyles.add(style);
return this;
}
public RuleBuilder addSubRule(RuleBuilder rule) {
subRules.add(rule);
return this;
}
public RuleBuilder style(StyleBuilder>... styles) {
styleBuilder = styles;
return this;
}
public RuleBuilder rules(RuleBuilder... rules) {
Collections.addAll(subRules, rules);
return this;
}
public RuleBuilder select(int selector) {
this.selector = selector;
return this;
}
public RuleBuilder zoom(int zoom) {
this.zoom = zoom;
return this;
}
public RuleBuilder element(int element) {
this.element = element;
return this;
}
public RuleBuilder cat(String cat) {
this.cat = cat;
return this;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy