source: josm/trunk/src/org/openstreetmap/josm/io/ValidatorErrorWriter.java@ 12687

Last change on this file since 12687 was 12668, checked in by Don-vip, 7 years ago

see #14704 - PMD

File size: 6.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.io;
3
4import java.io.BufferedWriter;
5import java.io.OutputStream;
6import java.io.OutputStreamWriter;
7import java.io.PrintWriter;
8import java.nio.charset.StandardCharsets;
9import java.util.ArrayList;
10import java.util.Collection;
11import java.util.Date;
12import java.util.HashMap;
13import java.util.List;
14import java.util.Map;
15import java.util.Map.Entry;
16import java.util.Set;
17import java.util.TreeSet;
18import java.util.stream.Collectors;
19
20import org.openstreetmap.josm.command.AddPrimitivesCommand;
21import org.openstreetmap.josm.command.ChangePropertyCommand;
22import org.openstreetmap.josm.command.ChangePropertyKeyCommand;
23import org.openstreetmap.josm.command.Command;
24import org.openstreetmap.josm.command.DeleteCommand;
25import org.openstreetmap.josm.data.coor.LatLon;
26import org.openstreetmap.josm.data.osm.OsmPrimitive;
27import org.openstreetmap.josm.data.validation.OsmValidator;
28import org.openstreetmap.josm.data.validation.Severity;
29import org.openstreetmap.josm.data.validation.Test;
30import org.openstreetmap.josm.data.validation.TestError;
31import org.openstreetmap.josm.tools.LanguageInfo;
32import org.openstreetmap.josm.tools.Logging;
33import org.openstreetmap.josm.tools.date.DateUtils;
34
35/**
36 * Class to write a collection of validator errors out to XML.
37 * The format is inspired by the
38 * <a href="https://wiki.openstreetmap.org/wiki/Osmose#Issues_file_format">Osmose API issues file format</a>
39 * @since 12667
40 */
41public class ValidatorErrorWriter extends XmlWriter {
42
43 /**
44 * Constructs a new {@code ValidatorErrorWriter} that will write to the given {@link PrintWriter}.
45 * @param out PrintWriter to write XML to
46 */
47 public ValidatorErrorWriter(PrintWriter out) {
48 super(out);
49 }
50
51 /**
52 * Constructs a new {@code ValidatorErrorWriter} that will write to a given {@link OutputStream}.
53 * @param out OutputStream to write XML to
54 */
55 public ValidatorErrorWriter(OutputStream out) {
56 super(new PrintWriter(new BufferedWriter(new OutputStreamWriter(out, StandardCharsets.UTF_8))));
57 }
58
59 /**
60 * Write validator errors to designated output target
61 * @param validationErrors Test error collection to write
62 */
63 public void write(Collection<TestError> validationErrors) {
64 Set<Test> analysers = validationErrors.stream().map(TestError::getTester).collect(Collectors.toCollection(TreeSet::new));
65 String timestamp = DateUtils.fromDate(new Date());
66
67 out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
68 out.println("<analysers generator='JOSM' timestamp=\""+timestamp+"\">");
69
70 OsmWriter osmWriter = OsmWriterFactory.createOsmWriter(out, true, OsmChangeBuilder.DEFAULT_API_VERSION);
71 String lang = LanguageInfo.getJOSMLocaleCode();
72
73 for (Test test : analysers) {
74 out.println(" <analyser timestamp=\""+timestamp+"\" name=\""+test.getName()+"\">");
75 // Build map of test error classes for the current test
76 Map<ErrorClass, List<TestError>> map = new HashMap<>();
77 for (Entry<Severity, Map<String, Map<String, List<TestError>>>> e1 :
78 OsmValidator.getErrorsBySeverityMessageDescription(validationErrors, e -> e.getTester() == test).entrySet()) {
79 for (Entry<String, Map<String, List<TestError>>> e2 : e1.getValue().entrySet()) {
80 ErrorClass errorClass = new ErrorClass(e1.getKey(), e2.getKey());
81 List<TestError> list = map.get(errorClass);
82 if (list == null) {
83 list = new ArrayList<>();
84 map.put(errorClass, list);
85 }
86 e2.getValue().values().stream().forEach(list::addAll);
87 }
88 }
89 // Write classes
90 for (ErrorClass ec : map.keySet()) {
91 out.println(" <class id=\""+ec.id+"\" level=\""+ec.severity.getLevel()+"\">");
92 out.println(" <classtext lang=\""+lang+"\" title=\""+ec.message+"\"/>");
93 out.println(" </class>");
94 }
95
96 // Write errors
97 for (Entry<ErrorClass, List<TestError>> entry : map.entrySet()) {
98 for (TestError error : entry.getValue()) {
99 LatLon ll = error.getPrimitives().iterator().next().getBBox().getCenter();
100 out.println(" <error class=\""+entry.getKey().id+"\">");
101 out.println(" <location lat=\""+ll.lat()+"\" lon=\""+ll.lon()+"\">");
102 for (OsmPrimitive p : error.getPrimitives()) {
103 p.accept(osmWriter);
104 }
105 out.println(" <text lang=\""+lang+"\" value=\""+error.getDescription()+"\">");
106 if (error.isFixable()) {
107 out.println(" <fixes>");
108 Command fix = error.getFix();
109 if (fix instanceof AddPrimitivesCommand) {
110 Logging.info("TODO: {0}", fix);
111 } else if (fix instanceof DeleteCommand) {
112 Logging.info("TODO: {0}", fix);
113 } else if (fix instanceof ChangePropertyCommand) {
114 Logging.info("TODO: {0}", fix);
115 } else if (fix instanceof ChangePropertyKeyCommand) {
116 Logging.info("TODO: {0}", fix);
117 } else {
118 Logging.warn("Unsupported command type: {0}", fix);
119 }
120 out.println(" </fixes>");
121 }
122 out.println(" </error>");
123 }
124 }
125
126 out.println(" </analyser>");
127 }
128
129 out.println("</analysers>");
130 out.flush();
131 }
132
133 private static class ErrorClass {
134 static int idCounter;
135 final Severity severity;
136 final String message;
137 final int id;
138
139 ErrorClass(Severity severity, String message) {
140 this.severity = severity;
141 this.message = message;
142 this.id = ++idCounter;
143 }
144 }
145}
Note: See TracBrowser for help on using the repository browser.