161 | | private void checkRoles(Relation n, LinkedList<Role> allroles, HashMap<String, RoleInfo> map) { |
162 | | List<String> done = new LinkedList<>(); |
163 | | // Remove empty roles if several exist (like in route=hiking, see #9844) |
164 | | List<Role> emptyRoles = new LinkedList<>(); |
165 | | for (Role r : allroles) { |
166 | | if ("".equals(r.key)) { |
167 | | emptyRoles.add(r); |
| 163 | private boolean checkMemberType(Role r, RelationMember member) { |
| 164 | if (r.types != null) { |
| 165 | for (TaggingPresetType type: r.types) { |
| 166 | if (type.equals(TaggingPresetType.CLOSEDWAY) && member.isWay() && member.getWay().isClosed()) { |
| 167 | return true; |
| 168 | } |
| 169 | if(type.equals(TaggingPresetType.NODE) && member.isNode()) { |
| 170 | return true; |
| 171 | } |
| 172 | if(type.equals(TaggingPresetType.RELATION) && member.isRelation()) { |
| 173 | return true; |
| 174 | } |
| 175 | if(type.equals(TaggingPresetType.WAY) && member.isWay()) { |
| 176 | return true; |
| 177 | } |
170 | | if (emptyRoles.size() > 1) { |
171 | | allroles.removeAll(emptyRoles); |
| 183 | // if no match is found, then test failed |
| 184 | return false; |
| 185 | } |
| 186 | |
| 187 | // get all role definition for specified key and check, if some definition matches |
| 188 | private boolean checkMemberExpressionAndType(RolePreset rolePreset, RelationMember member, Relation n) { |
| 189 | TestError possibleMatchError = null; |
| 190 | if (rolePreset == null || rolePreset.roles == null) { |
| 191 | // no restrictions on role types |
| 192 | return true; |
173 | | for (Role r : allroles) { |
174 | | done.add(r.key); |
175 | | String keyname = r.key; |
176 | | if ("".equals(keyname)) { |
177 | | keyname = tr("<empty>"); |
178 | | } |
179 | | RoleInfo ri = map.get(r.key); |
180 | | checkRoleCounts(n, r, keyname, ri); |
181 | | if (ri != null) { |
182 | | if (r.types != null) { |
183 | | checkRoleTypes(n, r, keyname, ri); |
184 | | } |
| 194 | for (Role r: rolePreset.roles) { |
| 195 | if (checkMemberType(r, member)) { |
186 | | checkRoleMemberExpressions(n, r, keyname, ri); |
| 197 | OsmPrimitive primitive = member.getMember(); |
| 198 | if(primitive.isUsable()) { |
| 199 | if(r.memberExpression.match(primitive)) { |
| 200 | return true; |
| 201 | } else { |
| 202 | // possible match error |
| 203 | String s = marktr("Role member didn''t match expression {0} in template {1}"); |
| 204 | possibleMatchError = new TestError(this, Severity.WARNING, ROLE_VERIF_PROBLEM_MSG, |
| 205 | tr(s, r.memberExpression, rolePreset.name), s, WRONG_TYPE, |
| 206 | member.getMember().isUsable() ? member.getMember() : n); |
| 207 | |
| 208 | } |
| 209 | } else { |
| 210 | // if it is not usable, we can't verify memberExpression |
| 211 | return true; |
| 212 | } |
| 213 | } else { |
| 214 | return true; |
| 215 | } |
| 216 | } else { |
| 217 | |
| 218 | } |
| 219 | } |
| 220 | if( possibleMatchError != null) { |
| 221 | errors.add(possibleMatchError); |
| 222 | } else { |
| 223 | String s = marktr("Role member type {0} didn''t match accepted list of {1} in template {2}"); |
| 224 | Set<Enum<TaggingPresetType>> types = new HashSet<>(); |
| 225 | for (Role r: rolePreset.roles) { |
| 226 | types.addAll(r.types); |
| 227 | } |
| 228 | errors.add(new TestError(this, Severity.WARNING, ROLE_VERIF_PROBLEM_MSG, |
| 229 | tr(s, member.getType(), types, rolePreset.name), s, WRONG_TYPE, |
| 230 | member.getMember().isUsable() ? member.getMember() : n)); |
| 231 | } |
| 232 | return false; |
| 233 | } |
| 234 | |
| 235 | |
| 236 | private void checkRoles(Relation n, HashMap<String, RolePreset> allroles, HashMap<String, RoleInfo> map) { |
| 237 | Set<String> done = new HashSet<>(); |
| 238 | |
| 239 | // go through all members of relation |
| 240 | for (RelationMember member: n.getMembers()) { |
| 241 | String role = member.getRole(); |
| 242 | done.add(role); |
| 243 | |
| 244 | // error reporting done inside |
| 245 | checkMemberExpressionAndType(allroles.get(role), member, n); |
| 246 | } |
| 247 | |
| 248 | // verify role counts based on whole role sets |
| 249 | for(RolePreset rp: allroles.values()) { |
| 250 | for (Role r: rp.roles) { |
| 251 | String keyname = r.key; |
| 252 | if ("".equals(keyname)) { |
| 253 | keyname = tr("<empty>"); |
205 | | private void checkRoleMemberExpressions(Relation n, Role r, String keyname, RoleInfo ri) { |
206 | | Set<OsmPrimitive> notMatching = new HashSet<>(); |
207 | | Collection<OsmPrimitive> allPrimitives = new ArrayList<>(); |
208 | | allPrimitives.addAll(ri.nodes); |
209 | | allPrimitives.addAll(ri.ways); |
210 | | allPrimitives.addAll(ri.relations); |
211 | | for (OsmPrimitive p : allPrimitives) { |
212 | | if (p.isUsable() && !r.memberExpression.match(p)) { |
213 | | notMatching.add(p); |
214 | | } |
215 | | } |
216 | | if (!notMatching.isEmpty()) { |
217 | | String s = marktr("Member for role ''{0}'' does not match ''{1}''"); |
218 | | LinkedList<OsmPrimitive> highlight = new LinkedList<>(notMatching); |
219 | | highlight.addFirst(n); |
220 | | errors.add(new TestError(this, Severity.WARNING, ROLE_VERIF_PROBLEM_MSG, |
221 | | tr(s, keyname, r.memberExpression), MessageFormat.format(s, keyname, r.memberExpression), WRONG_TYPE, |
222 | | highlight, notMatching)); |
223 | | } |
224 | | } |
225 | | |
226 | | private void checkRoleTypes(Relation n, Role r, String keyname, RoleInfo ri) { |
227 | | Set<OsmPrimitive> wrongTypes = new HashSet<>(); |
228 | | if (!r.types.contains(TaggingPresetType.WAY)) { |
229 | | wrongTypes.addAll(r.types.contains(TaggingPresetType.CLOSEDWAY) ? ri.openways : ri.ways); |
230 | | } |
231 | | if (!r.types.contains(TaggingPresetType.NODE)) { |
232 | | wrongTypes.addAll(ri.nodes); |
233 | | } |
234 | | if (!r.types.contains(TaggingPresetType.RELATION)) { |
235 | | wrongTypes.addAll(ri.relations); |
236 | | } |
237 | | if (!wrongTypes.isEmpty()) { |
238 | | String s = marktr("Member for role {0} of wrong type"); |
239 | | LinkedList<OsmPrimitive> highlight = new LinkedList<>(wrongTypes); |
240 | | highlight.addFirst(n); |
241 | | errors.add(new TestError(this, Severity.WARNING, ROLE_VERIF_PROBLEM_MSG, |
242 | | tr(s, keyname), MessageFormat.format(s, keyname), WRONG_TYPE, |
243 | | highlight, wrongTypes)); |
244 | | } |
245 | | } |