001 // License: GPL. For details, see LICENSE file.
002 package org.openstreetmap.josm.gui.mappaint.mapcss;
003
004 import java.util.Arrays;
005
006 import org.openstreetmap.josm.gui.mappaint.Cascade;
007 import org.openstreetmap.josm.gui.mappaint.Environment;
008 import org.openstreetmap.josm.gui.mappaint.Keyword;
009 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
010 import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.IconReference;
011 import org.openstreetmap.josm.gui.mappaint.StyleKeys;
012
013 abstract public class Instruction implements StyleKeys {
014
015 public abstract void execute(Environment env);
016
017 public static class RelativeFloat {
018 public final float val;
019
020 public RelativeFloat(float val) {
021 this.val = val;
022 }
023
024 @Override
025 public String toString() {
026 return "RelativeFloat{" + "val=" + val + '}';
027 }
028 }
029
030 public static class AssignmentInstruction extends Instruction {
031 public final String key;
032 public final Object val;
033
034 public AssignmentInstruction(String key, Object val) {
035 this.key = key;
036 if (val instanceof Expression.LiteralExpression) {
037 Object litValue = ((Expression.LiteralExpression) val).evaluate(null);
038 if (key.equals(TEXT)) {
039 /* Special case for declaration 'text: ...'
040 *
041 * - Treat the value 'auto' as keyword.
042 * - Treat any other literal value 'litval' as as reference to tag with key 'litval'
043 *
044 * - Accept function expressions as is. This allows for
045 * tag(a_tag_name) value of a tag
046 * eval("a static text") a static text
047 * parent_tag(a_tag_name) value of a tag of a parent relation
048 */
049 if (litValue.equals(Keyword.AUTO)) {
050 this.val = Keyword.AUTO;
051 } else {
052 String s = Cascade.convertTo(litValue, String.class);
053 if (s != null) {
054 this.val = new MapPaintStyles.TagKeyReference(s);
055 } else {
056 this.val = litValue;
057 }
058 }
059 } else {
060 this.val = litValue;
061 }
062 } else {
063 this.val = val;
064 }
065 }
066
067 @Override
068 public void execute(Environment env) {
069 Object value = null;
070 if (val instanceof Expression) {
071 value = ((Expression) val).evaluate(env);
072 } else {
073 value = val;
074 }
075 if (key.equals(ICON_IMAGE) || key.equals(FILL_IMAGE) || key.equals("pattern-image")) {
076 if (value instanceof String) {
077 value = new IconReference((String) value, env.source);
078 }
079 }
080 env.mc.getOrCreateCascade(env.layer).putOrClear(key, value);
081 }
082
083 @Override
084 public String toString() {
085 return key + ':' + (val instanceof float[] ? Arrays.toString((float[]) val) : val) + ';';
086 }
087 }
088 }