diff --git a/src/main/java/com/cflint/config/CFLintPluginInfo.java b/src/main/java/com/cflint/config/CFLintPluginInfo.java index 36f42a245..b00b3a5ff 100644 --- a/src/main/java/com/cflint/config/CFLintPluginInfo.java +++ b/src/main/java/com/cflint/config/CFLintPluginInfo.java @@ -8,15 +8,19 @@ import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.XmlTransient; +import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage; import com.cflint.plugins.CFLintScanner; +import com.fasterxml.jackson.annotation.JsonIdentityInfo; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; +import com.fasterxml.jackson.annotation.ObjectIdGenerators; @XmlRootElement(name = "CFLint-Plugin") @JsonInclude(Include.NON_NULL) public class CFLintPluginInfo { - List rules = new ArrayList(); + List rules = new ArrayList(); + List ruleGroups = new ArrayList(); public List getRules() { return rules; @@ -27,6 +31,15 @@ public void setRules(final List rules) { this.rules = rules; } + public List getRuleGroups() { + return ruleGroups; + } + + @XmlElement(name = "ruleGroup") + public void setRuleGroups(final List ruleGroups) { + this.ruleGroups = ruleGroups; + } + public PluginInfoRule getRuleByName(final String ruleName) { for (final PluginInfoRule rule : rules) { if (ruleName != null && ruleName.equals(rule.getName())) { @@ -44,6 +57,47 @@ public String toString(){ return sb.toString(); } + @JsonInclude(Include.NON_NULL) + public static class RuleGroup { + + public RuleGroup(String name) { + super(); + this.name = name; + } + public RuleGroup() { + super(); + } + + String name; + List messages = new ArrayList(); + String defaultSeverity; + + + public String getDefaultSeverity() { + return defaultSeverity; + } + @XmlAttribute(name = "defaultSeverity") + public void setDefaultSeverity(String defaultSeverity) { + this.defaultSeverity = defaultSeverity; + } + public String getName() { + return name; + } + + @XmlAttribute(name = "name") + public void setName(String name) { + this.name = name; + } + + public List getMessages() { + return messages; + } + + @XmlElement(name = "message") + public void setMessages(final List messages) { + this.messages = messages; + } + } @JsonInclude(Include.NON_NULL) public static class PluginInfoRule { @@ -181,6 +235,7 @@ public void setValue(final String value) { } } + @JsonIdentityInfo(generator=ObjectIdGenerators.PropertyGenerator.class,property="code") public static class PluginMessage { String code; diff --git a/src/main/java/com/cflint/config/ConfigUtils.java b/src/main/java/com/cflint/config/ConfigUtils.java index 261dcbca2..190893c8b 100644 --- a/src/main/java/com/cflint/config/ConfigUtils.java +++ b/src/main/java/com/cflint/config/ConfigUtils.java @@ -1,179 +1,183 @@ -package com.cflint.config; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.Reader; -import java.io.StringReader; -import java.io.StringWriter; -import java.util.HashMap; - -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Marshaller; -import javax.xml.bind.Unmarshaller; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import com.cflint.config.CFLintPluginInfo.PluginInfoRule; -import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginParameter; -import com.cflint.plugins.CFLintScanner; -import com.fasterxml.jackson.core.JsonGenerationException; -import com.fasterxml.jackson.core.JsonParseException; -import com.fasterxml.jackson.databind.JsonMappingException; -import com.fasterxml.jackson.databind.ObjectMapper; -import com.fasterxml.jackson.databind.SerializationFeature; -import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; - -public class ConfigUtils { - - final static Logger log = LoggerFactory.getLogger(ConfigUtils.class); - static JAXBContext CFLintConfigContext = null; - - public static Marshaller createMarshaller() throws JAXBException { - if (CFLintConfigContext == null) { - init(); - } - return CFLintConfigContext.createMarshaller(); - } - - private static Unmarshaller createUnmarshaller() throws JAXBException { - if (CFLintConfigContext == null) { - init(); - } - return CFLintConfigContext.createUnmarshaller(); - } - - protected static synchronized void init() throws JAXBException { - CFLintConfigContext = JAXBContext.newInstance(CFLintPluginInfo.class, CFLintConfig.class); - } - - public static String marshal(final Object obj) throws JAXBException { - final StringWriter sw = new StringWriter(); - createMarshaller().marshal(obj, sw); - return sw.toString(); - } - - public static String marshalQuietly(final Object obj) { - try { - return marshal(obj); - } catch (final JAXBException e) { - return null; - } - } - - @SuppressWarnings("unchecked") - public static E unmarshal(final String xml, final Class expectedClass) throws JAXBException { - return (E) createUnmarshaller().unmarshal(new StringReader(xml)); - } - - @SuppressWarnings("unchecked") - public static E unmarshal(final InputStream inputStream, final Class expectedClass) throws JAXBException { - return (E) createUnmarshaller().unmarshal(new InputStreamReader(inputStream)); - } - - public static String marshalJson(final Object obj) - throws JsonGenerationException, JsonMappingException, IOException { - final StringWriter sw = new StringWriter(); - final ObjectMapper objectMapper = new ObjectMapper(); - final JaxbAnnotationModule module = new JaxbAnnotationModule(); - objectMapper.registerModule(module); - objectMapper.enable(SerializationFeature.INDENT_OUTPUT); - objectMapper.writeValue(sw, obj); - return sw.toString(); - } - - public static E unmarshalJson(final InputStream inputStream, final Class expectedClass) - throws JsonParseException, JsonMappingException, IOException { - final ObjectMapper objectMapper = new ObjectMapper(); - final JaxbAnnotationModule module = new JaxbAnnotationModule(); - objectMapper.registerModule(module); - // AnnotationIntrospector introspector = new - // JaxbAnnotationIntrospector(); - // mapper.setAnnotationIntrospector(introspector); - return objectMapper.readValue(inputStream, expectedClass); - } - - public static E unmarshalJson(final Reader reader, final Class expectedClass) - throws JsonParseException, JsonMappingException, IOException { - final ObjectMapper objectMapper = new ObjectMapper(); - final JaxbAnnotationModule module = new JaxbAnnotationModule(); - objectMapper.registerModule(module); - return objectMapper.readValue(reader, expectedClass); - } - - /** - * Load the plugin definitions. If it is available use the json definition - * file first. - * - * @return CFLintPluginInfo instance of plugin definitions - */ - public static CFLintPluginInfo loadDefaultPluginInfo() { - final InputStream jsonInputStream = ConfigUtils.class.getResourceAsStream("/cflint.definition.json"); - if (jsonInputStream != null) { - try { - return unmarshalJson(jsonInputStream, CFLintPluginInfo.class); - } catch (final IOException e) { - log.error("Error loading default plugin json info",e); - } - } - - final InputStream inputStream = ConfigUtils.class.getResourceAsStream("/cflint.definition.xml"); - if (inputStream != null) { - try { - return unmarshal(inputStream, CFLintPluginInfo.class); - } catch (final JAXBException e) { - log.error("Error loading default plugin xml info",e); - } - } - return new CFLintPluginInfo(); - } - - /** - * Load the plugin description. - * - * @return MapList<String,String> map of message codes to descriptions - */ - public static HashMap loadDescriptions() { - final HashMap descriptions = new HashMap(); - final InputStream inputStream = ConfigUtils.class.getResourceAsStream("/cflint.description.txt"); - - try { - final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); - String line; - while ((line = reader.readLine()) != null) { - final String[] parts = line.split(":"); - if (parts.length == 2) { - descriptions.put(parts[0], parts[1]); - } - } - } catch (final Exception e) { - log.error("Error loading descriptions",e); - } - - return descriptions; - } - - static final String PLUGIN_PACKAGE = "com.cflint.plugins.core"; - - public static CFLintScanner loadPlugin(final PluginInfoRule ruleInfo) { - final String shortClassName = ruleInfo.getClassName() != null && ruleInfo.getClassName().trim().length() > 0 - ? ruleInfo.getClassName() : ruleInfo.getName(); - final String className = PLUGIN_PACKAGE + "." + shortClassName.trim(); - try { - final Class pluginClass = Class.forName(className); - final CFLintScanner plugin = (CFLintScanner) pluginClass.newInstance(); - for (final PluginParameter param : ruleInfo.getParameters()) { - plugin.setParameter(param.getName(), param.getValue()); - } - ruleInfo.setPluginInstance(plugin); - return plugin; - } catch (final Exception e) { - log.error("Could not load plugin " + className, e); - } - return null; - } - -} +package com.cflint.config; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.HashMap; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; +import javax.xml.bind.Unmarshaller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import com.cflint.config.CFLintPluginInfo.PluginInfoRule; +import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginParameter; +import com.cflint.plugins.CFLintScanner; +import com.fasterxml.jackson.core.JsonGenerationException; +import com.fasterxml.jackson.core.JsonParseException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.SerializationFeature; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationModule; + +public class ConfigUtils { + + final static Logger log = LoggerFactory.getLogger(ConfigUtils.class); + static JAXBContext CFLintConfigContext = null; + + public static Marshaller createMarshaller() throws JAXBException { + if (CFLintConfigContext == null) { + init(); + } + return CFLintConfigContext.createMarshaller(); + } + + private static Unmarshaller createUnmarshaller() throws JAXBException { + if (CFLintConfigContext == null) { + init(); + } + return CFLintConfigContext.createUnmarshaller(); + } + + protected static synchronized void init() throws JAXBException { + CFLintConfigContext = JAXBContext.newInstance(CFLintPluginInfo.class, CFLintConfig.class); + } + + public static String marshal(final Object obj) throws JAXBException { + final StringWriter sw = new StringWriter(); + createMarshaller().marshal(obj, sw); + return sw.toString(); + } + + public static String marshalQuietly(final Object obj) { + try { + return marshal(obj); + } catch (final JAXBException e) { + return null; + } + } + + @SuppressWarnings("unchecked") + public static E unmarshal(final String xml, final Class expectedClass) throws JAXBException { + return (E) createUnmarshaller().unmarshal(new StringReader(xml)); + } + + @SuppressWarnings("unchecked") + public static E unmarshal(final InputStream inputStream, final Class expectedClass) throws JAXBException { + return (E) createUnmarshaller().unmarshal(new InputStreamReader(inputStream)); + } + + public static String marshalJson(final Object obj) + throws JsonGenerationException, JsonMappingException, IOException { + final StringWriter sw = new StringWriter(); + final ObjectMapper objectMapper = new ObjectMapper(); + final JaxbAnnotationModule module = new JaxbAnnotationModule(); + objectMapper.registerModule(module); + objectMapper.enable(SerializationFeature.INDENT_OUTPUT); + objectMapper.writeValue(sw, obj); + return sw.toString(); + } + + public static E unmarshalJson(final InputStream inputStream, final Class expectedClass) + throws JsonParseException, JsonMappingException, IOException { + final ObjectMapper objectMapper = new ObjectMapper(); + final JaxbAnnotationModule module = new JaxbAnnotationModule(); + objectMapper.registerModule(module); + // AnnotationIntrospector introspector = new + // JaxbAnnotationIntrospector(); + // mapper.setAnnotationIntrospector(introspector); + return objectMapper.readValue(inputStream, expectedClass); + } + + public static E unmarshalJson(final String input, final Class expectedClass) + throws JsonParseException, JsonMappingException, IOException{ + return unmarshalJson(new StringReader(input),expectedClass); + } + public static E unmarshalJson(final Reader reader, final Class expectedClass) + throws JsonParseException, JsonMappingException, IOException { + final ObjectMapper objectMapper = new ObjectMapper(); + final JaxbAnnotationModule module = new JaxbAnnotationModule(); + objectMapper.registerModule(module); + return objectMapper.readValue(reader, expectedClass); + } + + /** + * Load the plugin definitions. If it is available use the json definition + * file first. + * + * @return CFLintPluginInfo instance of plugin definitions + */ + public static CFLintPluginInfo loadDefaultPluginInfo() { + final InputStream jsonInputStream = ConfigUtils.class.getResourceAsStream("/cflint.definition.json"); + if (jsonInputStream != null) { + try { + return unmarshalJson(jsonInputStream, CFLintPluginInfo.class); + } catch (final IOException e) { + log.error("Error loading default plugin json info",e); + } + } + + final InputStream inputStream = ConfigUtils.class.getResourceAsStream("/cflint.definition.xml"); + if (inputStream != null) { + try { + return unmarshal(inputStream, CFLintPluginInfo.class); + } catch (final JAXBException e) { + log.error("Error loading default plugin xml info",e); + } + } + return new CFLintPluginInfo(); + } + + /** + * Load the plugin description. + * + * @return MapList<String,String> map of message codes to descriptions + */ + public static HashMap loadDescriptions() { + final HashMap descriptions = new HashMap(); + final InputStream inputStream = ConfigUtils.class.getResourceAsStream("/cflint.description.txt"); + + try { + final BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + while ((line = reader.readLine()) != null) { + final String[] parts = line.split(":"); + if (parts.length == 2) { + descriptions.put(parts[0], parts[1]); + } + } + } catch (final Exception e) { + log.error("Error loading descriptions",e); + } + + return descriptions; + } + + static final String PLUGIN_PACKAGE = "com.cflint.plugins.core"; + + public static CFLintScanner loadPlugin(final PluginInfoRule ruleInfo) { + final String shortClassName = ruleInfo.getClassName() != null && ruleInfo.getClassName().trim().length() > 0 + ? ruleInfo.getClassName() : ruleInfo.getName(); + final String className = PLUGIN_PACKAGE + "." + shortClassName.trim(); + try { + final Class pluginClass = Class.forName(className); + final CFLintScanner plugin = (CFLintScanner) pluginClass.newInstance(); + for (final PluginParameter param : ruleInfo.getParameters()) { + plugin.setParameter(param.getName(), param.getValue()); + } + ruleInfo.setPluginInstance(plugin); + return plugin; + } catch (final Exception e) { + log.error("Could not load plugin " + className, e); + } + return null; + } + +} diff --git a/src/main/java/com/cflint/main/CFLintMain.java b/src/main/java/com/cflint/main/CFLintMain.java index af6f999ef..699c9b240 100644 --- a/src/main/java/com/cflint/main/CFLintMain.java +++ b/src/main/java/com/cflint/main/CFLintMain.java @@ -14,7 +14,9 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Scanner; import javax.swing.JFileChooser; @@ -41,6 +43,7 @@ import com.cflint.config.CFLintPluginInfo; import com.cflint.config.CFLintPluginInfo.PluginInfoRule; import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage; +import com.cflint.config.CFLintPluginInfo.RuleGroup; import com.cflint.config.ConfigUtils; import com.cflint.tools.CFLintFilter; import com.cflint.xml.MarshallerException; @@ -131,7 +134,8 @@ public static void main(final String[] args) throws Exception { options.addOption(EXTENSIONS, true, "specify the extensions of the CF source files (default: .cfm,.cfc)"); options.addOption(CONFIGFILE, true, "specify the location of the config file"); options.addOption(STDIN, true, "use stdin for file input (default: source.cfc)"); - options.addOption("stdout", false, "output to stdout only"); + options.addOption("stdout", false, "output to stdout only"); + options.addOption("listrulegroups", false, "list rule groups"); final CommandLineParser parser = new GnuParser(); final CommandLine cmd = parser.parse(options, args); @@ -174,6 +178,12 @@ public static void main(final String[] args) throws Exception { main.defaultConfig= new CFLintConfig(); main.defaultConfig.setRules(pluginInfo.getRules()); + if (cmd.hasOption("listrulegroups")){ + listRuleGroups(pluginInfo); + return; + } + + main.verbose = (cmd.hasOption('v') || cmd.hasOption(VERBOSE)); main.quiet = (cmd.hasOption('q') || cmd.hasOption(QUIET)); main.logerror = (cmd.hasOption('e') || cmd.hasOption("logerror")); @@ -272,7 +282,33 @@ public static void main(final String[] args) throws Exception { } } - private void open() throws IOException { + /** + * List the rule groups + * @param pluginInfo + */ + private static void listRuleGroups(CFLintPluginInfo pluginInfo) { + Map allCodes = new LinkedHashMap(); + for(PluginInfoRule rule: pluginInfo.getRules()){ + for(PluginMessage msg:rule.getMessages()){ + allCodes.put(msg.getCode(),msg); + } + } + for(RuleGroup ruleGroup: pluginInfo.getRuleGroups()){ + System.out.println("Rule Group : " + ruleGroup.getName()); + for(PluginMessage msg:ruleGroup.getMessages()){ + System.out.println("\t" + msg.getCode() + " : " + msg.getSeverity()); + allCodes.remove(msg.getCode()); + } + } + if(!allCodes.isEmpty()){ + System.out.println("Rule Group : UNASSIGNED" ); + for(PluginMessage msg:allCodes.values()){ + System.out.println("\t" + msg.getCode() + " : " + msg.getSeverity()); + } + } + } + + private void open() throws IOException { if (xmlOutput) { Desktop.getDesktop().open(new File(xmlOutFile)); return; diff --git a/src/main/resources/cflint.definition.json b/src/main/resources/cflint.definition.json index 60869eca0..adc4600dc 100644 --- a/src/main/resources/cflint.definition.json +++ b/src/main/resources/cflint.definition.json @@ -907,5 +907,122 @@ } ] } + ], + "ruleGroup" : [ { + "name" : "BugProne", + "message" : [ "ARG_VAR_CONFLICT", + "NO_DEFAULT_INSIDE_SWITCH", + "NESTED_CFOUTPUT", + "OUTPUT_ATTR", + "MISSING_VAR", + "COMPARE_INSTEAD_OF_ASSIGN" + ] + }, { + "name" : "Correctness", + "message" : [ "ARG_DEFAULT_MISSING", + "ARG_TYPE_ANY", + "ARG_TYPE_MISSING", + "ARG_VAR_MIXED", + "QUERYNEW_DATATYPE", + "UNUSED_LOCAL_VARIABLE", + "UNUSED_METHOD_ARGUMENT", + "UNQUOTED_STRUCT_KEY", + "USE_DISPLAY_NAME" + ] + }, { + "name" : "BadPractice", + "message" : [ "AVOID_USING_ABORT", + "AVOID_USING_CFABORT_TAG", + "AVOID_USING_CFDUMP_TAG", + "AVOID_USING_CFEXECUTE_TAG", + "AVOID_USING_CFINSERT_TAG", + "AVOID_USING_CFMODULE_TAG", + "AVOID_USING_CFUPDATE_TAG", + "AVOID_USING_WRITEDUMP", + "GLOBAL_LITERAL_VALUE_USED_TOO_OFTEN", + "GLOBAL_VAR", + "LOCAL_LITERAL_VALUE_USED_TOO_OFTEN", + "SQL_SELECT_STAR", + "AVOID_USING_DEBUG_ATTR", + "AVOID_USING_CFSETTING_DEBUG", + "AVOID_USING_CFINCLUDE_TAG", + "AVOID_USING_ISDEBUGMODE" + ] + }, + { + "name" : "Security", + "message" : [ "CFQUERYPARAM_REQ", + "QUERYPARAM_REQ" + ] + }, + { + "name" : "CodeStyle", + "message" : [ "ARG_HINT_MISSING", + "COMPONENT_HINT_MISSING", + "FUNCTION_HINT_MISSING", + "FUNCTION_TYPE_ANY", + "FUNCTION_TYPE_MISSING", + "ARG_HINT_MISSING_SCRIPT" + ] + }, + { + "name" : "ModernSyntax", + "message" : [ "AVOID_USING_ARRAYNEW", + "AVOID_USING_STRUCTNEW", + "AVOID_USING_CREATEOBJECT" + ] + } , + { + "name" : "Complexity", + "message" : [ "COMPLEX_BOOLEAN_CHECK", + "EXCESSIVE_FUNCTIONS", + "EXCESSIVE_ARGUMENTS", + "EXPLICIT_BOOLEAN_CHECK", + "EXCESSIVE_COMPONENT_LENGTH", + "EXCESSIVE_FUNCTION_LENGTH", + "FUNCTION_TOO_COMPLEX" + ] + }, + { + "name" : "Naming", + "message" : [ "METHOD_HAS_PREFIX_OR_POSTFIX", + "METHOD_INVALID_NAME", + "METHOD_IS_TEMPORARY", + "METHOD_TOO_SHORT", + "METHOD_TOO_LONG", + "METHOD_TOO_WORDY", + "VAR_ALLCAPS_NAME", + "VAR_HAS_PREFIX_OR_POSTFIX", + "VAR_INVALID_NAME", + "VAR_IS_TEMPORARY", + "VAR_TOO_SHORT", + "VAR_TOO_LONG", + "VAR_TOO_WORDY", + "SCOPE_ALLCAPS_NAME", + "ARGUMENT_MISSING_NAME", + "ARGUMENT_INVALID_NAME", + "ARGUMENT_ALLCAPS_NAME", + "ARGUMENT_TOO_SHORT", + "ARGUMENT_TOO_LONG", + "ARGUMENT_TOO_WORDY", + "ARGUMENT_IS_TEMPORARY", + "ARGUMENT_HAS_PREFIX_OR_POSTFIX", + "METHOD_ALLCAPS_NAME", + "COMPONENT_INVALID_NAME", + "COMPONENT_ALLCAPS_NAME", + "COMPONENT_TOO_SHORT", + "COMPONENT_TOO_LONG", + "COMPONENT_TOO_WORDY", + "COMPONENT_IS_TEMPORARY", + "COMPONENT_HAS_PREFIX_OR_POSTFIX" + ] + }, + { + "name" : "Experimental", + "message" : [ + "NEVER_USE_QUERY_IN_CFM", + "FILE_SHOULD_START_WITH_LOWERCASE" + ] + } ] } \ No newline at end of file diff --git a/src/test/java/com/cflint/config/TestCFLintConfig.java b/src/test/java/com/cflint/config/TestCFLintConfig.java index b96b073fd..b5fd15f44 100644 --- a/src/test/java/com/cflint/config/TestCFLintConfig.java +++ b/src/test/java/com/cflint/config/TestCFLintConfig.java @@ -4,7 +4,6 @@ import java.io.IOException; import java.io.StringWriter; -import java.util.ArrayList; import javax.xml.bind.Marshaller; @@ -12,29 +11,12 @@ import com.cflint.config.CFLintPluginInfo.PluginInfoRule; import com.cflint.config.CFLintPluginInfo.PluginInfoRule.PluginMessage; +import com.cflint.config.CFLintPluginInfo.RuleGroup; import com.fasterxml.jackson.core.JsonFactory; +import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.JsonMappingException; -/* -issues: { - issue: { - severity: "", - id: "", - message: "", - category: "", - abbrev: "" - }, - location: { - file: "", - fileName: "", - column: "", - line: "", - message: "", - variable: "" - }, - expression: "" -} -*/ public class TestCFLintConfig { @@ -50,7 +32,6 @@ public class TestCFLintConfig { @Test public void test() throws Exception { CFLintPluginInfo config = new CFLintPluginInfo(); - config.setRules(new ArrayList()); PluginInfoRule rule = new CFLintPluginInfo.PluginInfoRule(); config.getRules().add(rule); rule.setName("OPM"); @@ -72,14 +53,47 @@ public void test() throws Exception { @Test public void test2() throws IOException{ - StringWriter writer = new StringWriter(); - JsonFactory jsonF = new JsonFactory(); - JsonGenerator jg = jsonF.createGenerator(writer); - jg.writeStartArray(); - - jg.writeEndArray(); - jg.close(); - writer.close(); - System.out.println(writer); -} + StringWriter writer = new StringWriter(); + JsonFactory jsonF = new JsonFactory(); + JsonGenerator jg = jsonF.createGenerator(writer); + jg.writeStartArray(); + + jg.writeEndArray(); + jg.close(); + writer.close(); + System.out.println(writer); + } + + @Test + /** + * Test the round trip of the config json file including rule groups. + * @throws JsonGenerationException + * @throws JsonMappingException + * @throws IOException + */ + public void testRuleGroups() throws JsonGenerationException, JsonMappingException, IOException{ + CFLintPluginInfo config = new CFLintPluginInfo(); + PluginInfoRule rule = new CFLintPluginInfo.PluginInfoRule(); + config.getRules().add(rule); + rule.setName("OPM"); + PluginMessage message = new PluginMessage(); + rule.getMessages().add(message); + message.setCode("MyCode"); + message.setMessageText("messageText"); + message.setSeverity("WARNING"); + RuleGroup ruleGroup = new RuleGroup("r1"); + ruleGroup.setDefaultSeverity("INFO"); + ruleGroup.getMessages().add(message); + config.getRuleGroups().add(ruleGroup); + RuleGroup ruleGroup2 = new RuleGroup("r2"); + config.getRuleGroups().add(ruleGroup2); + String jsonText = ConfigUtils.marshalJson(config); + System.out.println(jsonText); + CFLintPluginInfo backConfig = ConfigUtils.unmarshalJson(jsonText,CFLintPluginInfo.class); + assertEquals("MyCode",backConfig.getRules().get(0).getMessages().get(0).getCode()); + assertEquals("messageText",backConfig.getRules().get(0).getMessages().get(0).getMessageText()); + assertEquals("MyCode",backConfig.getRuleGroups().get(0).getMessages().get(0).getCode()); + assertEquals("messageText",backConfig.getRuleGroups().get(0).getMessages().get(0).getMessageText()); + assertEquals("INFO",backConfig.getRuleGroups().get(0).getDefaultSeverity()); + } }