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