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 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 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 (litValue instanceof Keyword && "none".equals(((Keyword) litValue).val)) { 041 this.val = null; 042 } else if (TEXT.equals(key)) { 043 /* Special case for declaration 'text: ...' 044 * 045 * - Treat the value 'auto' as keyword. 046 * - Treat any other literal value 'litval' as as reference to tag with key 'litval' 047 * 048 * - Accept function expressions as is. This allows for 049 * tag(a_tag_name) value of a tag 050 * eval("a static text") a static text 051 * parent_tag(a_tag_name) value of a tag of a parent relation 052 */ 053 if (litValue.equals(Keyword.AUTO)) { 054 this.val = Keyword.AUTO; 055 } else { 056 String s = Cascade.convertTo(litValue, String.class); 057 if (s != null) { 058 this.val = new MapPaintStyles.TagKeyReference(s); 059 } else { 060 this.val = litValue; 061 } 062 } 063 } else { 064 this.val = litValue; 065 } 066 } else { 067 this.val = val; 068 } 069 } 070 071 @Override 072 public void execute(Environment env) { 073 Object value = null; 074 if (val instanceof Expression) { 075 value = ((Expression) val).evaluate(env); 076 } else { 077 value = val; 078 } 079 if (ICON_IMAGE.equals(key) || FILL_IMAGE.equals(key) || REPEAT_IMAGE.equals(key)) { 080 if (value instanceof String) { 081 value = new IconReference((String) value, env.source); 082 } 083 } 084 env.mc.getOrCreateCascade(env.layer).putOrClear(key, value); 085 } 086 087 @Override 088 public String toString() { 089 return key + ": " + (val instanceof float[] ? Arrays.toString((float[]) val) : 090 val instanceof String ? "String<"+val+'>' : val) + ';'; 091 } 092 } 093}