source: josm/trunk/src/org/openstreetmap/josm/tools/template_engine/ContextSwitchTemplate.java@ 11057

Last change on this file since 11057 was 10659, checked in by Don-vip, 8 years ago

see #12472 - fix more warnings, increase maximum number of reported warnings from 100 to 1000

  • Property svn:eol-style set to native
File size: 10.4 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.tools.template_engine;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.ArrayList;
7import java.util.Collection;
8import java.util.Collections;
9import java.util.List;
10
11import org.openstreetmap.josm.actions.search.SearchCompiler.And;
12import org.openstreetmap.josm.actions.search.SearchCompiler.Child;
13import org.openstreetmap.josm.actions.search.SearchCompiler.Match;
14import org.openstreetmap.josm.actions.search.SearchCompiler.Not;
15import org.openstreetmap.josm.actions.search.SearchCompiler.Or;
16import org.openstreetmap.josm.actions.search.SearchCompiler.Parent;
17import org.openstreetmap.josm.data.osm.Node;
18import org.openstreetmap.josm.data.osm.OsmPrimitive;
19import org.openstreetmap.josm.data.osm.Relation;
20import org.openstreetmap.josm.data.osm.RelationMember;
21import org.openstreetmap.josm.data.osm.Way;
22
23public class ContextSwitchTemplate implements TemplateEntry {
24
25 private static final TemplateEngineDataProvider EMTPY_PROVIDER = new TemplateEngineDataProvider() {
26 @Override
27 public Object getTemplateValue(String name, boolean special) {
28 return null;
29 }
30
31 @Override
32 public Collection<String> getTemplateKeys() {
33 return Collections.emptyList();
34 }
35
36 @Override
37 public boolean evaluateCondition(Match condition) {
38 return false;
39 }
40 };
41
42 private abstract static class ContextProvider extends Match {
43 protected Match condition;
44
45 abstract List<OsmPrimitive> getPrimitives(OsmPrimitive root);
46 }
47
48 private static class ParentSet extends ContextProvider {
49 private final Match childCondition;
50
51 ParentSet(Match child) {
52 this.childCondition = child;
53 }
54
55 @Override
56 public boolean match(OsmPrimitive osm) {
57 throw new UnsupportedOperationException();
58 }
59
60 @Override
61 List<OsmPrimitive> getPrimitives(OsmPrimitive root) {
62 List<OsmPrimitive> children;
63 if (childCondition instanceof ContextProvider) {
64 children = ((ContextProvider) childCondition).getPrimitives(root);
65 } else if (childCondition.match(root)) {
66 children = Collections.singletonList(root);
67 } else {
68 children = Collections.emptyList();
69 }
70
71 List<OsmPrimitive> result = new ArrayList<>();
72 for (OsmPrimitive child: children) {
73 for (OsmPrimitive parent: child.getReferrers(true)) {
74 if (condition == null || condition.match(parent)) {
75 result.add(parent);
76 }
77 }
78 }
79 return result;
80 }
81 }
82
83 private static class ChildSet extends ContextProvider {
84 private final Match parentCondition;
85
86 ChildSet(Match parentCondition) {
87 this.parentCondition = parentCondition;
88 }
89
90 @Override
91 public boolean match(OsmPrimitive osm) {
92 throw new UnsupportedOperationException();
93 }
94
95 @Override
96 List<OsmPrimitive> getPrimitives(OsmPrimitive root) {
97 List<OsmPrimitive> parents;
98 if (parentCondition instanceof ContextProvider) {
99 parents = ((ContextProvider) parentCondition).getPrimitives(root);
100 } else if (parentCondition.match(root)) {
101 parents = Collections.singletonList(root);
102 } else {
103 parents = Collections.emptyList();
104 }
105 List<OsmPrimitive> result = new ArrayList<>();
106 for (OsmPrimitive p: parents) {
107 if (p instanceof Way) {
108 for (Node n: ((Way) p).getNodes()) {
109 if (condition != null && condition.match(n)) {
110 result.add(n);
111 }
112 result.add(n);
113 }
114 } else if (p instanceof Relation) {
115 for (RelationMember rm: ((Relation) p).getMembers()) {
116 if (condition != null && condition.match(rm.getMember())) {
117 result.add(rm.getMember());
118 }
119 }
120 }
121 }
122 return result;
123 }
124 }
125
126 private static class OrSet extends ContextProvider {
127 private final ContextProvider lhs;
128 private final ContextProvider rhs;
129
130 OrSet(ContextProvider lhs, ContextProvider rhs) {
131 this.lhs = lhs;
132 this.rhs = rhs;
133 }
134
135 @Override
136 public boolean match(OsmPrimitive osm) {
137 throw new UnsupportedOperationException();
138 }
139
140 @Override
141 List<OsmPrimitive> getPrimitives(OsmPrimitive root) {
142 List<OsmPrimitive> result = new ArrayList<>();
143 for (OsmPrimitive o: lhs.getPrimitives(root)) {
144 if (condition == null || condition.match(o)) {
145 result.add(o);
146 }
147 }
148 for (OsmPrimitive o: rhs.getPrimitives(root)) {
149 if (condition == null || (condition.match(o) && !result.contains(o))) {
150 result.add(o);
151 }
152 }
153 return result;
154 }
155 }
156
157 private static class AndSet extends ContextProvider {
158 private final ContextProvider lhs;
159 private final ContextProvider rhs;
160
161 AndSet(ContextProvider lhs, ContextProvider rhs) {
162 this.lhs = lhs;
163 this.rhs = rhs;
164 }
165
166 @Override
167 public boolean match(OsmPrimitive osm) {
168 throw new UnsupportedOperationException();
169 }
170
171 @Override
172 List<OsmPrimitive> getPrimitives(OsmPrimitive root) {
173 List<OsmPrimitive> result = new ArrayList<>();
174 List<OsmPrimitive> lhsList = lhs.getPrimitives(root);
175 for (OsmPrimitive o: rhs.getPrimitives(root)) {
176 if (lhsList.contains(o) && (condition == null || condition.match(o))) {
177 result.add(o);
178 }
179 }
180 return result;
181 }
182 }
183
184 private final ContextProvider context;
185 private final TemplateEntry template;
186
187 private static Match transform(Match m, int searchExpressionPosition) throws ParseError {
188 if (m instanceof Parent) {
189 Match child = transform(((Parent) m).getOperand(), searchExpressionPosition);
190 return new ParentSet(child);
191 } else if (m instanceof Child) {
192 Match parent = transform(((Child) m).getOperand(), searchExpressionPosition);
193 return new ChildSet(parent);
194 } else if (m instanceof And) {
195 Match lhs = transform(((And) m).getLhs(), searchExpressionPosition);
196 Match rhs = transform(((And) m).getRhs(), searchExpressionPosition);
197
198 if (lhs instanceof ContextProvider && rhs instanceof ContextProvider)
199 return new AndSet((ContextProvider) lhs, (ContextProvider) rhs);
200 else if (lhs instanceof ContextProvider) {
201 ContextProvider cp = (ContextProvider) lhs;
202 if (cp.condition == null) {
203 cp.condition = rhs;
204 } else {
205 cp.condition = new And(cp.condition, rhs);
206 }
207 return cp;
208 } else if (rhs instanceof ContextProvider) {
209 ContextProvider cp = (ContextProvider) rhs;
210 if (cp.condition == null) {
211 cp.condition = lhs;
212 } else {
213 cp.condition = new And(lhs, cp.condition);
214 }
215 return cp;
216 } else
217 return m;
218 } else if (m instanceof Or) {
219 Match lhs = transform(((Or) m).getLhs(), searchExpressionPosition);
220 Match rhs = transform(((Or) m).getRhs(), searchExpressionPosition);
221
222 if (lhs instanceof ContextProvider && rhs instanceof ContextProvider)
223 return new OrSet((ContextProvider) lhs, (ContextProvider) rhs);
224 else if (lhs instanceof ContextProvider)
225 throw new ParseError(
226 tr("Error in search expression on position {0} - right side of or(|) expression must return set of primitives",
227 searchExpressionPosition));
228 else if (rhs instanceof ContextProvider)
229 throw new ParseError(
230 tr("Error in search expression on position {0} - left side of or(|) expression must return set of primitives",
231 searchExpressionPosition));
232 else
233 return m;
234 } else if (m instanceof Not) {
235 Match match = transform(((Not) m).getMatch(), searchExpressionPosition);
236 if (match instanceof ContextProvider)
237 throw new ParseError(
238 tr("Error in search expression on position {0} - not(-) cannot be used in this context",
239 searchExpressionPosition));
240 else
241 return m;
242 } else
243 return m;
244 }
245
246 public ContextSwitchTemplate(Match match, TemplateEntry template, int searchExpressionPosition) throws ParseError {
247 Match m = transform(match, searchExpressionPosition);
248 if (!(m instanceof ContextProvider))
249 throw new ParseError(
250 tr("Error in search expression on position {0} - expression must return different then current primitive",
251 searchExpressionPosition));
252 else {
253 context = (ContextProvider) m;
254 }
255 this.template = template;
256 }
257
258 @Override
259 public void appendText(StringBuilder result, TemplateEngineDataProvider dataProvider) {
260 List<OsmPrimitive> primitives = context.getPrimitives((OsmPrimitive) dataProvider);
261 if (primitives != null && !primitives.isEmpty()) {
262 template.appendText(result, primitives.get(0));
263 } else {
264 template.appendText(result, EMTPY_PROVIDER);
265 }
266 }
267
268 @Override
269 public boolean isValid(TemplateEngineDataProvider dataProvider) {
270 List<OsmPrimitive> primitives = context.getPrimitives((OsmPrimitive) dataProvider);
271 if (primitives != null && !primitives.isEmpty())
272 return template.isValid(primitives.get(0));
273 else
274 return false;
275 }
276
277}
Note: See TracBrowser for help on using the repository browser.