/* * Sonar C# Plugin :: Gendarme * Copyright (C) 2010 Jose Chillan, Alexandre Victoor and SonarSource * dev@sonar.codehaus.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02 */ package org.sonar.plugins.csharp.gendarme.results; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.InputStreamReader; import javax.xml.stream.XMLStreamException; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.codehaus.staxmate.SMInputFactory; import org.codehaus.staxmate.in.SMEvent; import org.codehaus.staxmate.in.SMHierarchicCursor; import org.codehaus.staxmate.in.SMInputCursor; import org.sonar.api.BatchExtension; import org.sonar.api.rules.Rule; import org.sonar.api.rules.RuleFinder; import org.sonar.api.rules.RuleQuery; import org.sonar.api.utils.SonarException; import org.sonar.dotnet.tools.commons.utils.AbstractStaxParser; import org.sonar.plugins.csharp.gendarme.GendarmeConstants; /** * Parses the reports generated by a Gendarme analysis. */ public class GendarmeResultParser extends AbstractStaxParser implements BatchExtension { private RuleFinder ruleFinder; private GendarmeViolationMaker gendarmeViolationMaker; /** * Constructs a @link{GendarmeResultParser}. * * @param project * @param context * @param rulesManager * @param profile */ public GendarmeResultParser(RuleFinder ruleFinder, GendarmeViolationMaker gendarmeViolationMaker) { super(); this.ruleFinder = ruleFinder; this.gendarmeViolationMaker = gendarmeViolationMaker; } /** * Parses a processed violation file. * * @param file * the file to parse */ public void parse(File file) { SMInputFactory inputFactory = initStax(); FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(file); SMHierarchicCursor cursor = inputFactory.rootElementCursor(new InputStreamReader(fileInputStream, getEncoding())); SMInputCursor rulesCursor = cursor.advance().descendantElementCursor("rule"); parseRuleBlocs(rulesCursor); cursor.getStreamReader().closeCompletely(); } catch (XMLStreamException e) { throw new SonarException("Error while reading Gendarme result file: " + file.getAbsolutePath(), e); } catch (FileNotFoundException e) { throw new SonarException("Cannot find Gendarme result file: " + file.getAbsolutePath(), e); } finally { IOUtils.closeQuietly(fileInputStream); } } private void parseRuleBlocs(SMInputCursor cursor) throws XMLStreamException { RuleQuery ruleQuery = RuleQuery.create().withRepositoryKey(GendarmeConstants.REPOSITORY_KEY); // Cursor is on <rule> while (cursor.getNext() != null) { if (cursor.getCurrEvent().equals(SMEvent.START_ELEMENT)) { Rule currentRule = ruleFinder.find(ruleQuery.withKey(cursor.getAttrValue("Name"))); if (currentRule != null) { String type = cursor.getAttrValue("Type"); if (StringUtils.isEmpty(type)) { parseRuleDefects(cursor, currentRule); } else { gendarmeViolationMaker.registerRuleType(currentRule, type); } } } } } private void parseRuleDefects(SMInputCursor cursor, Rule currentRule) throws XMLStreamException { gendarmeViolationMaker.setCurrentRule(currentRule); gendarmeViolationMaker.setCurrentDefaultViolationMessage(""); SMInputCursor childCursor = cursor.childElementCursor(); while (childCursor.getNext() != null) { if ("problem".equals(childCursor.getQName().getLocalPart())) { gendarmeViolationMaker.setCurrentDefaultViolationMessage(childCursor.collectDescendantText().trim()); } else if ("target".equals(childCursor.getQName().getLocalPart())) { parseTargetBloc(childCursor); } } } private void parseTargetBloc(SMInputCursor cursor) throws XMLStreamException { // Cursor is on <target> gendarmeViolationMaker.setCurrentTargetName(cursor.getAttrValue("Name")); gendarmeViolationMaker.setCurrentTargetAssembly(cursor.getAttrValue("Assembly")); SMInputCursor defectCursor = cursor.childElementCursor(); while (defectCursor.getNext() != null) { // Cursor is on <defect> gendarmeViolationMaker.setCurrentLocation(defectCursor.getAttrValue("Location")); gendarmeViolationMaker.setCurrentSource(defectCursor.getAttrValue("Source")); gendarmeViolationMaker.setCurrentMessage(defectCursor.collectDescendantText().trim()); gendarmeViolationMaker.createViolation(); } } }