/* * Sonar W3C Markup Validation Plugin * Copyright (C) 2010 Matthijs Galesloot * dev@sonar.codehaus.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.sonar.plugins.web.markup.validation; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.lang.BooleanUtils; import org.apache.commons.lang.math.NumberUtils; import org.apache.log4j.Logger; import org.apache.xerces.parsers.DOMParser; import org.sonar.api.utils.SonarException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.NodeList; import org.xml.sax.InputSource; import org.xml.sax.SAXException; /** * Parser for the W3C Validation Soap Report * * @author Matthijs Galesloot * @since 1.0 */ public final class MarkupReport { private static final Logger LOG = Logger.getLogger(MarkupReport.class); /** * Create a report from W3C Markup Validation Soap message. */ public static MarkupReport fromXml(File reportFile) { MarkupReport markupReport = new MarkupReport(); markupReport.parse(reportFile); return markupReport; } private final List<MarkupMessage> errors = new ArrayList<MarkupMessage>(); private File reportFile; private boolean valid; private final List<MarkupMessage> warnings = new ArrayList<MarkupMessage>(); private MarkupMessage createMessage(Element element) { MarkupMessage message = new MarkupMessage(); message.setLine(getInteger(element, "m:line")); message.setMessageId(getString(element, "m:messageid")); message.setMessage(getString(element, "m:message")); return message; } /** * Get all the errors from the report. */ public List<MarkupMessage> getErrors() { return errors; } private Integer getInteger(Element element, String elementName) { NodeList nodeList = element.getElementsByTagName(elementName); if (nodeList.getLength() > 0) { return NumberUtils.toInt(nodeList.item(0).getTextContent(), -1); } else { return -1; } } /** * Get report file. */ public File getReportFile() { return reportFile; } private String getString(Element element, String elementName) { NodeList nodeList = element.getElementsByTagName(elementName); if (nodeList.getLength() > 0) { return nodeList.item(0).getTextContent(); } else { return null; } } /** * Get warnings. */ public List<MarkupMessage> getWarnings() { return warnings; } public boolean isValid() { return valid; } /** * Parse report, read errors and warnings. */ private void parse(File reportFile) { this.reportFile = reportFile; if ( !reportFile.exists()) { throw new SonarException("File does not exist: " + reportFile.getPath()); } Document document = parseSoapMessage(reportFile); if (document != null) { NodeList nodeList = document.getElementsByTagName("m:validity"); for (int i = 0; i < nodeList.getLength(); i++) { valid = BooleanUtils.toBoolean(nodeList.item(i).getTextContent()); } nodeList = document.getElementsByTagName("m:error"); for (int i = 0; i < nodeList.getLength(); i++) { Element element = (Element) nodeList.item(i); errors.add(createMessage(element)); } nodeList = document.getElementsByTagName("m:warning"); for (int i = 0; i < nodeList.getLength(); i++) { Element element = (Element) nodeList.item(i); warnings.add(createMessage(element)); } } } private Document parseSoapMessage(File file) { DOMParser parser = new DOMParser(); try { parser.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", false); parser.parse(new InputSource(new FileReader(file))); } catch (SAXException se) { LOG.error("Failed to parse " + file.getPath()); return null; } catch (IOException ioe) { LOG.error("Failed to parse " + file.getPath()); return null; } return parser.getDocument(); } }