1 package org.codehaus.plexus.compiler.eclipse;
2
3 import javax.xml.stream.XMLInputFactory;
4 import javax.xml.stream.XMLStreamConstants;
5 import javax.xml.stream.XMLStreamReader;
6
7 import java.io.BufferedReader;
8 import java.io.File;
9 import java.io.FileInputStream;
10 import java.io.IOException;
11 import java.io.InputStreamReader;
12 import java.io.Reader;
13 import java.util.ArrayList;
14 import java.util.List;
15
16 import org.codehaus.plexus.compiler.CompilerMessage;
17 import org.codehaus.plexus.compiler.CompilerMessage.Kind;
18
19
20
21
22
23 public class EcjResponseParser {
24
25
26
27
28 private static final XMLInputFactory FACTORY = getStreamFactory();
29
30 private static XMLInputFactory getStreamFactory() {
31 XMLInputFactory xmlif = XMLInputFactory.newInstance();
32 xmlif.setProperty(XMLInputFactory.IS_VALIDATING, Boolean.FALSE);
33 xmlif.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES, Boolean.FALSE);
34 xmlif.setProperty(XMLInputFactory.SUPPORT_DTD, Boolean.FALSE);
35 return xmlif;
36 }
37
38
39
40
41
42
43 public List<CompilerMessage> parse(File xmltf, boolean errorsAsWarnings) throws Exception {
44
45
46
47 List<CompilerMessage> list = new ArrayList<>();
48
49 try (Reader src = new BufferedReader(new InputStreamReader(new FileInputStream(xmltf), "utf-8"))) {
50 XMLStreamReader xsr = FACTORY.createXMLStreamReader(src);
51
52
53 while (xsr.hasNext()) {
54 int type = xsr.next();
55 if (type == XMLStreamConstants.START_ELEMENT && "source".equals(xsr.getLocalName())) {
56 decodeSourceElement(list, xsr, errorsAsWarnings);
57 }
58 }
59 }
60 return list;
61 }
62
63 private void decodeSourceElement(List<CompilerMessage> list, XMLStreamReader xsr, boolean errorsAsWarnings)
64 throws Exception {
65 String filename = xsr.getAttributeValue(null, "path");
66
67
68 File path = new File(filename).getCanonicalFile();
69 while (xsr.hasNext()) {
70 int type = xsr.nextTag();
71 if (type == XMLStreamConstants.START_ELEMENT) {
72 if ("problems".equals(xsr.getLocalName())) {
73 decodeProblems(list, path.toString(), xsr, errorsAsWarnings);
74 } else {
75 ignoreTillEnd(xsr);
76 }
77 } else if (type == XMLStreamConstants.END_ELEMENT) {
78 return;
79 }
80 }
81 }
82
83
84
85
86 private void decodeProblems(
87 List<CompilerMessage> list, String sourcePath, XMLStreamReader xsr, boolean errorsAsWarnings)
88 throws Exception {
89 while (xsr.hasNext()) {
90 int type = xsr.nextTag();
91 if (type == XMLStreamConstants.START_ELEMENT) {
92 if ("problem".equals(xsr.getLocalName())) {
93 decodeProblem(list, sourcePath, xsr, errorsAsWarnings);
94 } else {
95 ignoreTillEnd(xsr);
96 }
97
98 } else if (type == XMLStreamConstants.END_ELEMENT) {
99 return;
100 }
101 }
102 }
103
104 private void decodeProblem(
105 List<CompilerMessage> list, String sourcePath, XMLStreamReader xsr, boolean errorsAsWarnings)
106 throws Exception {
107 String id = xsr.getAttributeValue(null, "optionKey");
108 int startline = getInt(xsr, "line");
109 int column = getInt(xsr, "charStart");
110 int endCol = getInt(xsr, "charEnd");
111 String sev = xsr.getAttributeValue(null, "severity");
112 String message = "Unknown message?";
113
114
115 while (xsr.hasNext()) {
116 int type = xsr.nextTag();
117 if (type == XMLStreamConstants.START_ELEMENT) {
118 if ("message".equals(xsr.getLocalName())) {
119 message = xsr.getAttributeValue(null, "value");
120 }
121 ignoreTillEnd(xsr);
122
123 } else if (type == XMLStreamConstants.END_ELEMENT) {
124 break;
125 }
126 }
127
128 Kind msgtype;
129 if ("warning".equalsIgnoreCase(sev)) {
130 msgtype = Kind.WARNING;
131 } else if ("error".equalsIgnoreCase(sev)) {
132 msgtype = errorsAsWarnings ? Kind.WARNING : Kind.ERROR;
133 } else if ("info".equalsIgnoreCase(sev)) {
134 msgtype = Kind.NOTE;
135 } else {
136 msgtype = Kind.OTHER;
137 }
138
139 CompilerMessage cm = new CompilerMessage(sourcePath, msgtype, startline, column, startline, endCol, message);
140 list.add(cm);
141 }
142
143 private static void ignoreTillEnd(XMLStreamReader xsr) throws Exception {
144 int depth = 1;
145 while (xsr.hasNext()) {
146 int type = xsr.next();
147 if (type == XMLStreamConstants.START_ELEMENT) {
148 depth++;
149 } else if (type == XMLStreamConstants.END_ELEMENT) {
150 depth--;
151 if (depth == 0) {
152 return;
153 }
154 }
155 }
156 }
157
158 private static int getInt(XMLStreamReader xsr, String name) throws IOException {
159 String v = xsr.getAttributeValue(null, name);
160 if (null == v) {
161 return -1;
162 }
163 try {
164 return Integer.parseInt(v.trim());
165 } catch (Exception x) {
166 throw new IOException("Illegal integer value '" + v + "' in attribute " + name);
167 }
168 }
169 }