All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.jball.sonar.hybris.java.HybrisJavaRulesDefinition Maven / Gradle / Ivy

There is a newer version: 0.7.0
Show newest version
package de.jball.sonar.hybris.java;

import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.sonar.api.rule.RuleStatus;
import org.sonar.api.rules.RuleType;
import org.sonar.api.server.debt.DebtRemediationFunction;
import org.sonar.api.server.rule.RulesDefinition;
import org.sonar.api.server.rule.RulesDefinitionAnnotationLoader;
import org.sonar.api.utils.AnnotationUtils;
import org.sonar.plugins.java.api.JavaCheck;
import org.sonar.squidbridge.annotations.RuleTemplate;

import javax.annotation.Nullable;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.Locale;
import java.util.stream.Collectors;

/**
 * Declare rule metadata in server repository of rules.
 * That allows to list the rules in the page "Rules".
 */
public class HybrisJavaRulesDefinition implements RulesDefinition {
	public static final String REPOSITORY_KEY = "sonar-hybris-java";
	private static final String RESOURCE_BASE_PATH = "/de/jball/sonar/l10n/java/rules/squid";
	private final Gson gson = new Gson();

	private static void addHtmlDescription(NewRule rule, String metadataKey) {
		URL resource = HybrisJavaRulesDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.html");
		if (resource != null) {
			rule.setHtmlDescription(readResource(resource));
		}
	}

	private static String readResource(URL resource) {
		try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.openStream()))) {
			return reader.lines().collect(Collectors.joining("\n"));
		} catch (Exception e) {
			throw new IllegalStateException("Failed to read: " + resource, e);
		}
	}

	@Override
	public void define(Context context) {
		NewRepository repository = context
				.createRepository(REPOSITORY_KEY, "java")
				.setName("Hybris Java Rules Repository");

		for (Class check : RulesList.getChecks()) {
			new RulesDefinitionAnnotationLoader().load(repository, check);
			newRule(check, repository);
		}
		repository.done();
	}

	protected void newRule(Class ruleClass, NewRepository repository) {

		org.sonar.check.Rule ruleAnnotation = AnnotationUtils.getAnnotation(ruleClass, org.sonar.check.Rule.class);
		if (ruleAnnotation == null) {
			throw new IllegalArgumentException("No Rule annotation was found on " + ruleClass);
		}
		String ruleKey = ruleAnnotation.key();
		if (StringUtils.isEmpty(ruleKey)) {
			throw new IllegalArgumentException("No key is defined in Rule annotation of " + ruleClass);
		}
		NewRule rule = repository.rule(ruleKey);
		if (rule == null) {
			throw new IllegalStateException("No rule was created for " + ruleClass + " in " + repository.key());
		}
		ruleMetadata(rule);

		rule.setTemplate(AnnotationUtils.getAnnotation(ruleClass, RuleTemplate.class) != null);
	}

	private void ruleMetadata(NewRule rule) {
		String metadataKey = rule.key();
		addHtmlDescription(rule, metadataKey);
		addMetadata(rule, metadataKey);
	}

	protected void addMetadata(NewRule rule, String metadataKey) {
		URL resource = HybrisJavaRulesDefinition.class.getResource(RESOURCE_BASE_PATH + "/" + metadataKey + "_java.json");
		if (resource != null) {
			RuleMetatada metatada = gson.fromJson(readResource(resource), RuleMetatada.class);
			rule.setSeverity(metatada.defaultSeverity.toUpperCase(Locale.US));
			rule.setName(metatada.title);
			rule.addTags(metatada.tags);
			rule.setType(RuleType.valueOf(metatada.type));
			rule.setStatus(RuleStatus.valueOf(metatada.status.toUpperCase(Locale.US)));
			if (metatada.remediation != null) {
				rule.setDebtRemediationFunction(metatada.remediation.remediationFunction(rule.debtRemediationFunctions()));
				rule.setGapDescription(metatada.remediation.linearDesc);
			}
		}
	}

	private static class RuleMetatada {
		String title;
		String status;
		@Nullable
		Remediation remediation;

		String type;
		String[] tags;
		String defaultSeverity;
	}

	private static class Remediation {
		String func;
		String constantCost;
		String linearDesc;
		String linearOffset;
		String linearFactor;

		protected DebtRemediationFunction remediationFunction(DebtRemediationFunctions drf) {
			if (func.startsWith("Constant")) {
				return drf.constantPerIssue(constantCost.replace("mn", "min"));
			}
			if ("Linear".equals(func)) {
				return drf.linear(linearFactor.replace("mn", "min"));
			}
			return drf.linearWithOffset(linearFactor.replace("mn", "min"), linearOffset.replace("mn", "min"));
		}
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy