![JAR search and dependency download from the Maven repository](/logo.png)
org.sonar.plugins.csharp.fxcop.FxCopResultParser Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of sonar-csharp-fxcop-plugin
Show all versions of sonar-csharp-fxcop-plugin
Plugin that runs FxCop analyses to check C# sources against rule violations.
/*
* Sonar C# Plugin :: FxCop
* Copyright (C) 2010 Jose Chillan, Alexandre Victoor and SonarSource
* [email protected]
*
* 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.fxcop;
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.codehaus.staxmate.SMInputFactory;
import org.codehaus.staxmate.in.SMEvent;
import org.codehaus.staxmate.in.SMHierarchicCursor;
import org.codehaus.staxmate.in.SMInputCursor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.sonar.api.BatchExtension;
import org.sonar.api.batch.SensorContext;
import org.sonar.api.resources.Project;
import org.sonar.api.resources.Resource;
import org.sonar.api.rules.Rule;
import org.sonar.api.rules.RuleFinder;
import org.sonar.api.rules.RuleQuery;
import org.sonar.api.rules.Violation;
import org.sonar.api.utils.SonarException;
import org.sonar.plugins.csharp.api.CSharpResourcesBridge;
import org.sonar.plugins.csharp.core.AbstractStaxParser;
/**
* Parses the reports generated by a FXCop analysis.
*/
public class FxCopResultParser extends AbstractStaxParser implements BatchExtension {
private static final Logger LOG = LoggerFactory.getLogger(FxCopResultParser.class);
private static final String NAMESPACE = "Namespace";
private static final String NAMESPACES = "Namespaces";
private static final String TARGETS = "Targets";
private static final String MESSAGE = "Message";
private static final String MESSAGES = "Messages";
private static final String MODULE = "Module";
private static final String NAME = "Name";
private static final String TYPENAME = "TypeName";
private static final String LINE = "Line";
private Project project;
private SensorContext context;
private RuleFinder ruleFinder;
private CSharpResourcesBridge resourcesBridge;
/**
* Constructs a @link{FxCopResultParser}.
*
* @param project
* @param context
* @param rulesManager
* @param profile
*/
public FxCopResultParser(Project project, SensorContext context, RuleFinder ruleFinder, CSharpResourcesBridge resourcesBridge) {
super();
this.project = project;
this.context = context;
this.ruleFinder = ruleFinder;
this.resourcesBridge = resourcesBridge;
}
/**
* 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 mainCursor = cursor.advance().childElementCursor();
while (mainCursor.getNext() != null) {
if (NAMESPACES.equals(mainCursor.getQName().getLocalPart())) {
parseNamespacesBloc(mainCursor);
} else if (TARGETS.equals(mainCursor.getQName().getLocalPart())) {
parseTargetsBloc(mainCursor);
}
}
cursor.getStreamReader().closeCompletely();
} catch (XMLStreamException e) {
throw new SonarException("Error while reading FxCop result file: " + file.getAbsolutePath(), e);
} catch (FileNotFoundException e) {
throw new SonarException("Cannot find FxCop result file: " + file.getAbsolutePath(), e);
} finally {
IOUtils.closeQuietly(fileInputStream);
}
}
private void parseNamespacesBloc(SMInputCursor cursor) throws XMLStreamException {
// Cursor in on
SMInputCursor namespacesCursor = cursor.childElementCursor(NAMESPACE);
while (namespacesCursor.getNext() != null) {
SMInputCursor messagesCursor = namespacesCursor.descendantElementCursor(MESSAGE);
while (messagesCursor.getNext() != null) {
createViolationFromMessageAtProjectLevel(messagesCursor);
}
}
}
private void parseTargetsBloc(SMInputCursor cursor) throws XMLStreamException {
// Cursor on
SMInputCursor modulesCursor = cursor.descendantElementCursor(MODULE);
while (modulesCursor.getNext() != null) {
parseModuleMessagesBloc(modulesCursor);
}
}
private void parseModuleMessagesBloc(SMInputCursor cursor) throws XMLStreamException {
// Cursor on
SMInputCursor moduleChildrenCursor = cursor.childElementCursor();
while (moduleChildrenCursor.getNext() != null) {
if (MESSAGES.equals(moduleChildrenCursor.getQName().getLocalPart())) {
// We are on , look for
SMInputCursor messagesCursor = moduleChildrenCursor.childElementCursor(MESSAGE);
while (messagesCursor.getNext() != null) {
createViolationFromMessageAtProjectLevel(messagesCursor);
}
} else if (NAMESPACES.equals(moduleChildrenCursor.getQName().getLocalPart())) {
// We are on , get
SMInputCursor namespaceCursor = moduleChildrenCursor.childElementCursor();
while (namespaceCursor.getNext() != null) {
String namespaceName = namespaceCursor.getAttrValue(NAME);
SMInputCursor typeCursor = namespaceCursor.childElementCursor().advance().childElementCursor();
while (typeCursor.getNext() != null) {
parseTypeBloc(namespaceName, typeCursor);
}
}
}
}
}
private void parseTypeBloc(String namespaceName, SMInputCursor cursor) throws XMLStreamException {
// Cursor on
String typeName = cursor.getAttrValue(NAME);
Resource> resource = resourcesBridge.getFromTypeName(namespaceName, typeName);
SMInputCursor messagesCursor = cursor.descendantElementCursor(MESSAGE);
while (messagesCursor.getNext() != null) {
// Cursor on
if (messagesCursor.getCurrEvent() == SMEvent.START_ELEMENT) {
Rule currentRule = ruleFinder.find(RuleQuery.create().withRepositoryKey(FxCopConstants.REPOSITORY_KEY)
.withKey(messagesCursor.getAttrValue(TYPENAME)));
if (currentRule != null) {
// look for all potential issues
SMInputCursor issueCursor = messagesCursor.childElementCursor();
while (issueCursor.getNext() != null) {
// Cursor on Issue
Violation violation = Violation.create(currentRule, resource);
String lineNumber = issueCursor.getAttrValue(LINE);
if (lineNumber != null) {
violation.setLineId(Integer.parseInt(lineNumber));
}
violation.setMessage(issueCursor.collectDescendantText().trim());
violation.setSeverity(currentRule.getSeverity());
context.saveViolation(violation);
}
} else {
LOG.warn("Could not find the following rule in the FxCop rule repository: " + messagesCursor.getAttrValue(TYPENAME));
}
}
}
}
private void createViolationFromMessageAtProjectLevel(SMInputCursor messagesCursor) throws XMLStreamException {
Rule currentRule = ruleFinder.find(RuleQuery.create().withRepositoryKey(FxCopConstants.REPOSITORY_KEY)
.withKey(messagesCursor.getAttrValue(TYPENAME)));
if (currentRule != null) {
// the violation is saved at project level, not on a specific resource
Violation violation = Violation.create(currentRule, project);
violation.setMessage(messagesCursor.collectDescendantText().trim());
violation.setSeverity(currentRule.getSeverity());
context.saveViolation(violation);
} else {
LOG.debug("Could not find the following rule in the FxCop rule repository: " + messagesCursor.getAttrValue(TYPENAME));
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy