1 package net.sourceforge.pmd;
2
3 import net.sourceforge.pmd.swingui.Constants;
4 import org.xml.sax.Attributes;
5 import org.xml.sax.InputSource;
6 import org.xml.sax.SAXException;
7 import org.xml.sax.helpers.DefaultHandler;
8
9 import javax.xml.parsers.SAXParser;
10 import javax.xml.parsers.SAXParserFactory;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.text.MessageFormat;
14
15 /***
16 * Reads an XML file containing information about a rule set and each rule within the rule set.
17 * <p>
18 * The SAXParser is used to parse the file.
19 *
20 * @author Donald A. Leckie
21 * @since August 30, 2002
22 * @version $Revision: 1.18 $, $Date: 2003/04/17 14:58:09 $
23 */
24 public class RuleSetReader implements Constants {
25
26 private RuleSet m_ruleSet;
27 private boolean m_onlyIfIncluded;
28
29 // Constants
30 private final String REJECT_NOT_INCLUDED = "Reject not included";
31
32 /***
33 *****************************************************************************
34 *
35 */
36 public RuleSetReader() {
37 }
38
39 /***
40 *****************************************************************************
41 *
42 * @param inputStream
43 * @param ruleSetFileName
44 *
45 * @return
46 */
47 public RuleSet read(InputStream inputStream, String ruleSetFileName) throws PMDException {
48 return read(inputStream, ruleSetFileName, false);
49 }
50
51 /***
52 *****************************************************************************
53 *
54 * @param inputStream
55 * @param ruleSetFileName
56 * @param onlyIfIncluded
57 *
58 * @return
59 */
60 public RuleSet read(InputStream inputStream, String ruleSetFileName, boolean onlyIfIncluded) throws PMDException {
61 if (inputStream == null) {
62 String message = "Missing input stream.";
63 PMDException pmdException = new PMDException(message);
64 pmdException.fillInStackTrace();
65 throw pmdException;
66 }
67
68 if (ruleSetFileName == null) {
69 String message = "Missing rule set file name.";
70 PMDException pmdException = new PMDException(message);
71 pmdException.fillInStackTrace();
72 throw pmdException;
73 }
74
75 m_onlyIfIncluded = onlyIfIncluded;
76
77 try {
78 InputSource inputSource;
79 MainContentHandler mainContentHandler;
80 SAXParser parser;
81
82 inputSource = new InputSource(inputStream);
83 mainContentHandler = new MainContentHandler();
84
85 SAXParserFactory factory = SAXParserFactory.newInstance();
86 factory.setFeature("http://xml.org/sax/features/namespace-prefixes", true);
87 factory.setFeature("http://xml.org/sax/features/namespaces", false);
88
89 parser = factory.newSAXParser();
90
91 parser.parse(inputSource, mainContentHandler);
92 m_ruleSet.setFileName(ruleSetFileName);
93
94 return m_ruleSet;
95 } catch (IOException exception) {
96 PMDException pmdException = new PMDException("IOException was thrown.", exception);
97 pmdException.fillInStackTrace();
98 throw pmdException;
99 } catch (SAXException exception) {
100 if (exception.getMessage() == REJECT_NOT_INCLUDED) {
101 // Return a null rule set to indicate that it should not be included.
102 return null;
103 }
104
105 Throwable originalException = exception.getException();
106
107 if (originalException instanceof PMDException) {
108 throw (PMDException) originalException;
109 }
110
111 String message = "SAXException was thrown.";
112 PMDException pmdException = new PMDException(message, exception);
113 pmdException.fillInStackTrace();
114 throw pmdException;
115 } catch (Exception exception) {
116 PMDException pmdException = new PMDException("Uncaught exception was thrown.", exception);
117 pmdException.fillInStackTrace();
118 throw pmdException;
119 }
120 }
121
122 /***
123 *****************************************************************************
124 *****************************************************************************
125 *****************************************************************************
126 */
127 private class MainContentHandler extends DefaultHandler {
128
129 private StringBuffer m_buffer = new StringBuffer(500);
130 private Rule m_rule;
131
132 /***
133 *************************************************************************
134 */
135 private MainContentHandler() {
136 super();
137 }
138
139 /***
140 *************************************************************************
141 *
142 * @param namespace
143 * @param localName
144 * @param qualifiedName
145 * @param attributes
146 *
147 * @throws SAXException
148 */
149 public void startElement(String namespace, String localName, String qualifiedName, Attributes attributes) throws SAXException {
150 m_buffer.setLength(0);
151
152 if (qualifiedName.equalsIgnoreCase("ruleset")) {
153 String name;
154 String include;
155
156 m_ruleSet = new RuleSet();
157 name = attributes.getValue("name");
158 name = (name == null) ? "Unknown" : name.trim();
159 include = attributes.getValue("include");
160 include = (include == null) ? "true" : include.trim();
161
162 m_ruleSet.setName(name);
163 m_ruleSet.setInclude(include.equalsIgnoreCase("true"));
164 } else if (qualifiedName.equalsIgnoreCase("rule")) {
165 String ruleName;
166 String message;
167 String className;
168 String includeText;
169 boolean include;
170
171 ruleName = attributes.getValue("name");
172 message = attributes.getValue("message");
173 className = attributes.getValue("class");
174 includeText = attributes.getValue("include");
175 ruleName = (ruleName == null) ? "Unknown" : ruleName.trim();
176 message = (message == null) ? EMPTY_STRING : message.trim();
177 className = (className == null) ? EMPTY_STRING : className.trim();
178 includeText = (includeText == null) ? "true" : includeText.trim();
179 include = includeText.equalsIgnoreCase("true");
180
181 if (m_onlyIfIncluded && (include == false)) {
182 SAXException exception = new SAXException(REJECT_NOT_INCLUDED);
183 throw exception;
184 }
185
186 if (className.length() == 0) {
187 String template = "Missing class name for rule \"{0}\" in rule set \"{1}\".";
188 Object[] args = {ruleName, m_ruleSet.getName()};
189 String msg = MessageFormat.format(template, args);
190 PMDException pmdException = new PMDException(msg);
191 SAXException saxException = new SAXException(EMPTY_STRING, pmdException.getReason());
192 pmdException.fillInStackTrace();
193 throw saxException;
194 }
195
196 try {
197 Class ruleClass;
198
199 ruleClass = Class.forName(className);
200 m_rule = (Rule) ruleClass.newInstance();
201 } catch (ClassNotFoundException classNotFoundException) {
202 try {
203 Class ruleClass;
204 className = "net.sourceforge.pmd.UndefinedRule";
205 ruleClass = Class.forName(className);
206 m_rule = (Rule) ruleClass.newInstance();
207 } catch (Exception exception) {
208 String template = "Cannot find class \"{0}\" on the classpath.";
209 Object[] args = {className};
210 String msg = MessageFormat.format(template, args);
211 PMDException pmdException = new PMDException(msg, exception);
212 SAXException saxException = new SAXException(EMPTY_STRING, pmdException);
213 pmdException.fillInStackTrace();
214 throw saxException;
215 }
216 } catch (IllegalAccessException exception) {
217 String template = "Illegal access to class \"{0}\" for rule \"{1}\" in rule set \"{2}\".";
218 Object[] args = {className, ruleName, m_ruleSet.getName()};
219 String msg = MessageFormat.format(template, args);
220 PMDException pmdException = new PMDException(msg, exception);
221 SAXException saxException = new SAXException(EMPTY_STRING, pmdException);
222 pmdException.fillInStackTrace();
223 throw saxException;
224 } catch (InstantiationException exception) {
225 String template = "Cannot instantiate class \"{0}\" for rule \"{1}\" in rule set \"{2}\".";
226 Object[] args = {className, ruleName, m_ruleSet.getName()};
227 String msg = MessageFormat.format(template, args);
228 PMDException pmdException = new PMDException(msg, exception);
229 SAXException saxException = new SAXException(EMPTY_STRING, pmdException);
230 pmdException.fillInStackTrace();
231 throw saxException;
232 }
233
234 m_rule.setName(ruleName);
235 m_rule.setMessage(message);
236 m_rule.setInclude(include);
237 m_ruleSet.addRule(m_rule);
238 } else if (qualifiedName.equalsIgnoreCase("property")) {
239 String name = attributes.getValue("name");
240 String value = attributes.getValue("value");
241 String type = attributes.getValue("type");
242
243 name = (name == null) ? EMPTY_STRING : name.trim();
244 value = (value == null) ? EMPTY_STRING : value;
245 type = (type == null) ? EMPTY_STRING : type;
246
247 if (name.length() > 0) {
248 m_rule.getProperties().setValue(name, value);
249 m_rule.getProperties().setValueType(name, type);
250 }
251 }
252 }
253
254 /***
255 *************************************************************************
256 *
257 * @param chars
258 * @param beginIndex
259 * @param length
260 *
261 * @throws PMDException
262 */
263 public void characters(char[] chars, int beginIndex, int length) {
264 m_buffer.append(chars, beginIndex, length);
265 }
266
267 /***
268 *************************************************************************
269 *
270 * @param namespace
271 * @param localName
272 * @param qualifiedName
273 *
274 * @throws SAXException
275 */
276 public void endElement(String namespace, String localName, String qualifiedName) throws SAXException {
277 if (qualifiedName.equalsIgnoreCase("description")) {
278 if (m_rule == null) {
279 m_ruleSet.setDescription(trim(m_buffer));
280 } else {
281 m_rule.setDescription(trim(m_buffer));
282 }
283 } else if (qualifiedName.equalsIgnoreCase("message")) {
284 m_rule.setMessage(trim(m_buffer));
285 } else if (qualifiedName.equalsIgnoreCase("example")) {
286 m_rule.setExample(trimExample(m_buffer));
287 } else if (qualifiedName.equals("priority")) {
288 int priority;
289
290 try {
291 priority = Integer.parseInt(trim(m_buffer));
292 } catch (NumberFormatException exception) {
293 priority = Rule.LOWEST_PRIORITY;
294 }
295
296 m_rule.setPriority(priority);
297 } else if (qualifiedName.equalsIgnoreCase("rule")) {
298 m_rule = null;
299 }
300 }
301
302 /***
303 ***************************************************************************
304 */
305 private String trim(StringBuffer buffer) {
306 if (buffer.length() > 0) {
307 for (int n = buffer.length() - 1; n >= 0; n--) {
308 if (buffer.charAt(n) == '\n') {
309 buffer.setCharAt(n, ' ');
310 }
311
312 char theChar = buffer.charAt(n);
313
314 if (theChar == ' ') {
315 if (n == buffer.length() - 1) {
316 buffer.deleteCharAt(n);
317 } else if (buffer.charAt(n + 1) == ' ') {
318 buffer.deleteCharAt(n);
319 } else if (n == 0) {
320 buffer.deleteCharAt(n);
321 }
322 }
323 }
324 }
325
326 return buffer.toString();
327 }
328
329 /***
330 ***************************************************************************
331 */
332 private String trimExample(StringBuffer buffer) {
333 while ((buffer.length() > 0) && ((buffer.charAt(0) == '\n') || (buffer.charAt(0) == ' '))) {
334 buffer.deleteCharAt(0);
335 }
336
337 for (int n = buffer.length() - 1; n >= 0; n--) {
338 if ((buffer.charAt(n) != '\n') && (buffer.charAt(n) != ' ')) {
339 buffer.setLength(n + 1);
340 break;
341 }
342 }
343
344 return buffer.toString();
345 }
346 }
347 }
This page was automatically generated by Maven