Skip to content

Commit 38995df

Browse files
Handling new way of creating repositories and rules for SQ9
1 parent d0b8cda commit 38995df

File tree

4 files changed

+103
-335
lines changed

4 files changed

+103
-335
lines changed

src/main/java/fr/cnes/sonar/plugins/icode/languages/ICodeQualityProfiles.java

Lines changed: 17 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,15 @@
2323
import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition;
2424
import org.sonar.api.utils.log.Logger;
2525
import org.sonar.api.utils.log.Loggers;
26+
import org.sonar.api.server.rule.RulesDefinition.NewRule;
27+
28+
import java.util.ArrayList;
29+
import java.util.List;
2630

2731
import java.io.InputStream;
2832

2933
/**
30-
* Built-in quality profile format since SonarQube 6.6.
34+
* Built-in quality profile format since SonarQube 9.9
3135
*/
3236
public final class ICodeQualityProfiles implements BuiltInQualityProfilesDefinition {
3337

@@ -44,45 +48,29 @@ public final class ICodeQualityProfiles implements BuiltInQualityProfilesDefinit
4448
*/
4549
@Override
4650
public void define(final Context context) {
47-
NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile("F 77", "f77");
48-
profile.setDefault(true);
49-
50-
NewBuiltInActiveRule data_array = profile.activateRule("f77-rules", "F77.DATA.Array");
51-
profile.done();
52-
53-
NewBuiltInQualityProfile profile2 = context.createBuiltInQualityProfile("F 90", "f90");
54-
profile2.setDefault(true);
55-
profile2.done();
56-
//createBuiltInProfile(context, Fortran77Language.KEY, ICodeRulesDefinition.PATH_TO_F77_RULES_XML);
57-
//reateBuiltInProfile(context, Fortran90Language.KEY, ICodeRulesDefinition.PATH_TO_F90_RULES_XML);
51+
createBuiltInProfile(context, ICodeRulesDefinition.FORTRAN77_REPOSITORY, Fortran77Language.KEY, ICodeRulesDefinition.f77Rules);
52+
createBuiltInProfile(context, ICodeRulesDefinition.FORTRAN90_REPOSITORY, Fortran90Language.KEY, ICodeRulesDefinition.f90Rules);
5853
}
5954

6055
/**
6156
* Create a built in quality profile for a specific language.
6257
*
6358
* @param context SonarQube context in which create the profile.
59+
* @param repository Rules' repository.
6460
* @param language Language key of the associated profile.
65-
* @param path Path to the xml definition of all rules.
61+
* @param rules Rules to activate.
6662
*/
67-
private void createBuiltInProfile(final Context context, final String language, final String path) {
63+
private void createBuiltInProfile(final Context context, final String repository, final String languageKey, final List<NewRule> rules) {
6864
// Create a builder for the rules' repository.
69-
final NewBuiltInQualityProfile defaultProfile =
70-
context.createBuiltInQualityProfile(I_CODE_RULES_PROFILE_NAME, language);
71-
72-
// Retrieve all defined rules.
73-
final InputStream stream = getClass().getResourceAsStream(path);
74-
final RulesDefinition rules = (RulesDefinition) XmlHandler.unmarshal(stream, RulesDefinition.class);
75-
final String repositoryKey = ICodeRulesDefinition.getRepositoryKeyForLanguage(language);
65+
NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile(I_CODE_RULES_PROFILE_NAME, languageKey);
7666

7767
// Activate all i-Code CNES rules.
78-
for(final Rule rule : rules.getRules()) {
79-
defaultProfile.activateRule(repositoryKey, rule.getKey());
80-
LOGGER.debug(String.format("Rule %s added to repository %s.", rule.getKey(), repositoryKey));
68+
for (NewRule rule : rules) {
69+
profile.activateRule(repository, rule.key());
70+
LOGGER.info(String.format("Rule %s added to repository %s.", rule.key(), repository));
8171
}
82-
LOGGER.debug(String.format("%s rules are activated.", defaultProfile.activeRules().size()));
83-
84-
// Save the default profile.
85-
defaultProfile.setDefault(true);
86-
defaultProfile.done();
72+
profile.setDefault(true);
73+
profile.done();
74+
LOGGER.info(String.format("%s rules are activated for the repository %s.", profile.activeRules().size(), repository));
8775
}
8876
}

src/main/java/fr/cnes/sonar/plugins/icode/rules/ICodeRulesDefinition.java

Lines changed: 85 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -22,77 +22,122 @@
2222
import org.sonar.api.rules.RuleType;
2323
import org.sonar.api.server.rule.RulesDefinition;
2424

25+
import org.sonar.api.utils.log.Logger;
26+
import org.sonar.api.utils.log.Loggers;
27+
2528
import fr.cnes.sonar.plugins.icode.languages.Fortran77Language;
2629
import fr.cnes.sonar.plugins.icode.languages.Fortran90Language;
2730
import fr.cnes.sonar.plugins.icode.settings.ICodePluginProperties;
2831

2932
import java.io.InputStream;
3033
import java.nio.charset.StandardCharsets;
34+
import java.util.ArrayList;
35+
import java.util.List;
36+
37+
import java.io.File;
38+
import javax.xml.parsers.DocumentBuilderFactory;
39+
import javax.xml.parsers.DocumentBuilder;
40+
import org.w3c.dom.Document;
41+
import org.w3c.dom.NodeList;
42+
import org.w3c.dom.Node;
43+
import org.w3c.dom.Element;
3144

3245
/**
3346
* Specific i-Code rules definition provided by resource file.
3447
*/
3548
public class ICodeRulesDefinition implements RulesDefinition {
3649

37-
public static final String REPOSITORY = "f77-rules";
38-
public static final String FORTRAN_LANGUAGE = "f77";
39-
public static final RuleKey F77_DATA_ARRAY = RuleKey.of(REPOSITORY, "F77.DATA.Array");
50+
/** Logger for this class. **/
51+
private static final Logger LOGGER = Loggers.get(ICodeRulesDefinition.class);
4052

4153
/** Partial key for repository. **/
4254
private static final String REPO_KEY_SUFFIX = "-rules";
4355

56+
public static final String FORTRAN77_LANGUAGE = Fortran77Language.KEY;
57+
public static final String FORTRAN90_LANGUAGE = Fortran90Language.KEY;
58+
59+
public static final String FORTRAN77_REPOSITORY = FORTRAN77_LANGUAGE + REPO_KEY_SUFFIX;
60+
public static final String FORTRAN90_REPOSITORY = FORTRAN90_LANGUAGE + REPO_KEY_SUFFIX;
4461

4562
/** Path to xml file in resources tree (fortran 77 rules). **/
4663
public static final String PATH_TO_F77_RULES_XML = "/rules/icode-f77-rules.xml";
4764

4865
/** Path to xml file in resources tree (fortran 90 rules). **/
4966
public static final String PATH_TO_F90_RULES_XML = "/rules/icode-f90-rules.xml";
5067

68+
public static List<NewRule> f77Rules;
69+
public static List<NewRule> f90Rules;
70+
5171
/**
5272
* Define i-Code rules in SonarQube thanks to xml configuration files.
5373
*
5474
* @param context SonarQube context.
5575
*/
5676
@Override
5777
public void define(final Context context) {
58-
// createRepository(context, Fortran77Language.KEY);
59-
//createRepository(context, Fortran90Language.KEY);
60-
NewRepository repository = context.createRepository(REPOSITORY, FORTRAN_LANGUAGE).setName(ICodePluginProperties.ICODE_NAME);
61-
62-
NewRule f77DataArray = repository.createRule(F77_DATA_ARRAY.rule())
63-
.setName("F77.DATA.Array")
64-
.setInternalKey("*")
65-
.setHtmlDescription("Arrays dimension should be declared explicitly. The use of * is tolerated for the last one if justified with a comment.")
66-
.setSeverity(Severity.MAJOR)
67-
.setStatus(RuleStatus.READY)
68-
.setType(RuleType.CODE_SMELL);
69-
70-
f77DataArray.setDebtRemediationFunction(f77DataArray.debtRemediationFunctions().constantPerIssue("30min"));
71-
72-
repository.done();
78+
this.f77Rules = createFortranRepository(context, FORTRAN77_LANGUAGE, FORTRAN77_REPOSITORY, PATH_TO_F77_RULES_XML);
79+
this.f90Rules = createFortranRepository(context, FORTRAN90_LANGUAGE, FORTRAN90_REPOSITORY, PATH_TO_F90_RULES_XML);
7380
}
7481

75-
// /**
76-
// * Create repositories for each language.
77-
// *
78-
// * @param context SonarQube context.
79-
// * @param language Key of the language.
80-
// */
81-
// protected void createRepository(final Context context, final String language) {
82-
// // Create a repository to put rules inside.
83-
// final NewRepository repository = context
84-
// .createRepository(getRepositoryKeyForLanguage(language), language)
85-
// .setName(getRepositoryName());
86-
87-
// // Get XML file describing rules for language.
88-
// final InputStream rulesXml = this.getClass().getResourceAsStream(rulesDefinitionFilePath(language));
89-
// // Add rules in repository.
90-
// if (rulesXml != null) {
91-
// final RulesDefinitionXmlLoader rulesLoader = new RulesDefinitionXmlLoader();
92-
// rulesLoader.load(repository, rulesXml, StandardCharsets.UTF_8.name());
93-
// }
94-
// repository.done();
95-
// }
82+
/**
83+
* Create repositories for each language f77 and f90
84+
*
85+
* @param context SonarQube context.
86+
* @param language Key of the language.
87+
* @param repositoryName Key of the repository.
88+
* @param pathToRulesXml Path to the xml file containing the rules.
89+
*/
90+
protected List<NewRule> createFortranRepository(final Context context, final String language, final String repositoryName, final String pathToRulesXml) {
91+
// Create the repository
92+
NewRepository repository = context.createRepository(repositoryName, language)
93+
.setName(ICodePluginProperties.ICODE_NAME);
94+
95+
List<NewRule> rules = new ArrayList<>();
96+
97+
try {
98+
InputStream inputFile = this.getClass().getResourceAsStream(pathToRulesXml);
99+
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
100+
Document doc = dbFactory.newDocumentBuilder().parse(inputFile);
101+
doc.getDocumentElement().normalize();
102+
103+
NodeList nodeList = doc.getElementsByTagName("rule");
104+
105+
for (int i = 0; i < nodeList.getLength(); i++) {
106+
Node node = nodeList.item(i);
107+
108+
if (node.getNodeType() == Node.ELEMENT_NODE) {
109+
Element element = (Element) node;
110+
111+
String key = element.getElementsByTagName("key").item(0).getTextContent();
112+
String name = element.getElementsByTagName("name").item(0).getTextContent();
113+
String internalKey = element.getElementsByTagName("internalKey").item(0).getTextContent();
114+
String description = element.getElementsByTagName("description").item(0).getTextContent();
115+
String severity = element.getElementsByTagName("severity").item(0).getTextContent();
116+
RuleStatus status = RuleStatus.valueOf(element.getElementsByTagName("status").item(0).getTextContent());
117+
RuleType type = RuleType.valueOf(element.getElementsByTagName("type").item(0).getTextContent());
118+
String remediationFunctionBaseEffort = element.getElementsByTagName("remediationFunctionBaseEffort").item(0).getTextContent();
119+
120+
RuleKey ruleKey = RuleKey.of(repositoryName, key);
121+
122+
NewRule rule = repository.createRule(ruleKey.rule())
123+
.setName(name)
124+
.setInternalKey(internalKey)
125+
.setHtmlDescription(description)
126+
.setSeverity(severity)
127+
.setStatus(status)
128+
.setType(type);
129+
130+
rule.setDebtRemediationFunction(rule.debtRemediationFunctions().constantPerIssue(remediationFunctionBaseEffort));
131+
rules.add(rule);
132+
LOGGER.info(String.format("Rule %s created.", rule.toString()));
133+
}
134+
}
135+
repository.done();
136+
} catch (Exception e) {
137+
e.printStackTrace();
138+
}
139+
return rules;
140+
}
96141

97142
/**
98143
* Getter for repository key.
@@ -103,26 +148,4 @@ public void define(final Context context) {
103148
public static String getRepositoryKeyForLanguage(final String language) {
104149
return language + REPO_KEY_SUFFIX;
105150
}
106-
107-
/**
108-
* Getter for the path to rules file.
109-
*
110-
* @param language Key of the language.
111-
* @return A path in String format.
112-
*/
113-
public String rulesDefinitionFilePath(final String language) {
114-
String path = "bad_file";
115-
switch (language) {
116-
case Fortran77Language.KEY:
117-
path = PATH_TO_F77_RULES_XML;
118-
break;
119-
case Fortran90Language.KEY:
120-
path = PATH_TO_F90_RULES_XML;
121-
break;
122-
default:
123-
break;
124-
}
125-
return path;
126-
}
127-
}
128-
151+
}

0 commit comments

Comments
 (0)