001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.gui.mappaint.mapcss; 003 004import java.util.List; 005import java.util.Objects; 006 007import org.openstreetmap.josm.gui.mappaint.Environment; 008import org.openstreetmap.josm.gui.mappaint.StyleSource; 009import org.openstreetmap.josm.tools.Utils; 010 011/** 012 * A MapCSS rule. 013 * 014 * A MapCSS style is simply a list of MapCSS rules. Each rule has a selector 015 * and a declaration. Whenever the selector matches the primitive, the 016 * declaration block is executed for this primitive. 017 */ 018public class MapCSSRule implements Comparable<MapCSSRule> { 019 020 /** 021 * The selector. If it matches, this rule should be applied 022 */ 023 public final Selector selector; 024 /** 025 * The instructions for this selector 026 */ 027 public final Declaration declaration; 028 029 /** 030 * A declaration is a set of {@link Instruction}s 031 */ 032 public static class Declaration { 033 /** 034 * The instructions in this declaration 035 */ 036 public final List<Instruction> instructions; 037 /** 038 * The index of this declaration 039 * <p> 040 * declarations in the StyleSource are numbered consecutively 041 */ 042 public final int idx; 043 044 /** 045 * Create a new {@link Declaration} 046 * @param instructions The instructions for this dectlaration 047 * @param idx The index in the {@link StyleSource} 048 */ 049 public Declaration(List<Instruction> instructions, int idx) { 050 this.instructions = instructions; 051 this.idx = idx; 052 } 053 054 /** 055 * <p>Executes the instructions against the environment {@code env}</p> 056 * 057 * @param env the environment 058 */ 059 public void execute(Environment env) { 060 for (Instruction i : instructions) { 061 i.execute(env); 062 } 063 } 064 065 @Override 066 public int hashCode() { 067 return Objects.hash(instructions, idx); 068 } 069 070 @Override 071 public boolean equals(Object obj) { 072 if (this == obj) return true; 073 if (obj == null || getClass() != obj.getClass()) return false; 074 Declaration that = (Declaration) obj; 075 return idx == that.idx && 076 Objects.equals(instructions, that.instructions); 077 } 078 079 @Override 080 public String toString() { 081 return "Declaration [instructions=" + instructions + ", idx=" + idx + ']'; 082 } 083 } 084 085 /** 086 * Constructs a new {@code MapCSSRule}. 087 * @param selector The selector 088 * @param declaration The declaration 089 */ 090 public MapCSSRule(Selector selector, Declaration declaration) { 091 this.selector = selector; 092 this.declaration = declaration; 093 } 094 095 /** 096 * <p>Executes the instructions against the environment {@code env}</p> 097 * 098 * @param env the environment 099 */ 100 public void execute(Environment env) { 101 declaration.execute(env); 102 } 103 104 @Override 105 public int compareTo(MapCSSRule o) { 106 return declaration.idx - o.declaration.idx; 107 } 108 109 @Override 110 public String toString() { 111 return selector + " {\n " + Utils.join("\n ", declaration.instructions) + "\n}"; 112 } 113} 114