├── .gitignore ├── _config.yml ├── .settings ├── org.eclipse.wst.jsdt.ui.superType.name ├── org.eclipse.wst.jsdt.ui.superType.container ├── org.eclipse.m2e.core.prefs ├── org.eclipse.jdt.core.prefs └── .jsdtscope ├── sonar-flow-plugin-documentation ├── .gitignore ├── assets │ ├── sslr.png │ ├── plugin.png │ ├── build-jar.png │ ├── sonar-gui-issues-view.png │ └── sonar-gui-project-view.png ├── DEVELOPMENT_SETUP.md ├── DEVELOPMENT.md └── QUICK_SETUP.md ├── sonar-flow-plugin ├── src │ ├── test │ │ ├── resources │ │ │ └── WmTestPackage │ │ │ │ ├── .gitx │ │ │ │ └── someFile │ │ │ │ ├── ns │ │ │ │ └── I8cFlowSonarPluginTest │ │ │ │ │ ├── pub │ │ │ │ │ ├── checkTryCatchInvalid │ │ │ │ │ │ ├── flow.out.txt │ │ │ │ │ │ ├── flow.xml │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkBranchPropertiesValid │ │ │ │ │ │ ├── flow.out.html │ │ │ │ │ │ ├── flow.out.txt │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── node.idf │ │ │ │ │ ├── checkEmptyFlowInvalid │ │ │ │ │ │ ├── flow.xml │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkQualityNameInvalid │ │ │ │ │ │ ├── flow.xml │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkInterfaceCommentsInvalid │ │ │ │ │ │ └── flow.xml │ │ │ │ │ ├── commentLinesVisitor2 │ │ │ │ │ │ └── flow.xml │ │ │ │ │ ├── checkAllDebugFlowsInvalid │ │ │ │ │ │ ├── flow.out.txt │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkSavePipelineInvalid │ │ │ │ │ │ ├── flow.xml │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkTryCatchValid │ │ │ │ │ │ ├── flow.xml │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkEmptyMapInvalid │ │ │ │ │ │ ├── flow.xml │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkDisabledInvalid │ │ │ │ │ │ ├── flow.xml │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkLinesOfCode │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkExitStepInvalid │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkBranchPropertiesInvalidA │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── checkBranchPropertiesInvalidB │ │ │ │ │ │ └── node.ndf │ │ │ │ │ └── checkEmptyMapValid │ │ │ │ │ │ └── node.ndf │ │ │ │ │ ├── node.idf │ │ │ │ │ └── flows │ │ │ │ │ └── node.idf │ │ │ │ └── manifest.v3 │ │ └── java │ │ │ └── be │ │ │ └── i8c │ │ │ └── codequality │ │ │ └── sonar │ │ │ └── plugins │ │ │ └── sag │ │ │ └── webmethods │ │ │ └── flow │ │ │ ├── utils │ │ │ └── FlowUtilsTest.java │ │ │ ├── FlowPluginTest.java │ │ │ ├── squid │ │ │ ├── NodeAstScannerTest.java │ │ │ └── FlowAstScannerTest.java │ │ │ ├── visitor │ │ │ ├── FlowLinesOfCodeVisitorTest.java │ │ │ ├── check │ │ │ │ ├── ExitCheckTest.java │ │ │ │ ├── DisabledCheckTest.java │ │ │ │ ├── SavePipelineCheckTest.java │ │ │ │ └── EmptyFlowCheckTest.java │ │ │ └── FlowCommentLinesVisitorTest.java │ │ │ └── ws │ │ │ └── sources │ │ │ └── FlowActionHandlerTest.java │ ├── main │ │ ├── resources │ │ │ └── org │ │ │ │ └── sonar │ │ │ │ └── l10n │ │ │ │ └── flow │ │ │ │ └── rules │ │ │ │ └── flow │ │ │ │ ├── S00005.html │ │ │ │ ├── S00003.html │ │ │ │ ├── S00002.html │ │ │ │ ├── S00008.html │ │ │ │ ├── S00004.html │ │ │ │ ├── S00001.html │ │ │ │ ├── S00007.html │ │ │ │ ├── S00006.html │ │ │ │ └── S00009.html │ │ ├── java │ │ │ └── be │ │ │ │ └── i8c │ │ │ │ └── codequality │ │ │ │ └── sonar │ │ │ │ └── plugins │ │ │ │ └── sag │ │ │ │ └── webmethods │ │ │ │ └── flow │ │ │ │ ├── visitor │ │ │ │ ├── check │ │ │ │ │ ├── type │ │ │ │ │ │ ├── FlowCheckProperties.java │ │ │ │ │ │ ├── FlowCheckRuleType.java │ │ │ │ │ │ ├── FlowCheckProperty.java │ │ │ │ │ │ ├── FlowCheck.java │ │ │ │ │ │ └── AnnotationUtils.java │ │ │ │ │ ├── Tags.java │ │ │ │ │ ├── CheckList.java │ │ │ │ │ ├── DisabledCheck.java │ │ │ │ │ ├── EmptyFlowCheck.java │ │ │ │ │ └── InterfaceCommentsCheck.java │ │ │ │ ├── type │ │ │ │ │ └── FlowVisitor.java │ │ │ │ ├── FlowLinesOfCodeVisitor.java │ │ │ │ ├── SimpleMetricVisitor.java │ │ │ │ ├── FlowCommentLinesVisitor.java │ │ │ │ └── FlowDependencyVisitor.java │ │ │ │ ├── utils │ │ │ │ └── FlowUtils.java │ │ │ │ ├── ws │ │ │ │ └── sources │ │ │ │ │ ├── xslt │ │ │ │ │ └── LocationFilter.java │ │ │ │ │ ├── FlowWebWs.java │ │ │ │ │ └── PipeResponse.java │ │ │ │ ├── squid │ │ │ │ └── CommentAnalyser.java │ │ │ │ ├── web │ │ │ │ └── FlowWebPageDefinition.java │ │ │ │ ├── FlowQualityProfile.java │ │ │ │ ├── metric │ │ │ │ └── FlowMetric.java │ │ │ │ └── FlowPlugin.java │ │ └── js │ │ │ ├── functions │ │ │ └── sonar_api.js │ │ │ ├── app-flow_issues.js │ │ │ └── components │ │ │ ├── flow │ │ │ ├── Map.js │ │ │ ├── Exit.js │ │ │ ├── Invoke.js │ │ │ ├── Loop.js │ │ │ ├── Branch.js │ │ │ ├── Repeat.js │ │ │ ├── Sequence.js │ │ │ ├── functions │ │ │ │ └── flowUtils.js │ │ │ └── Flow.js │ │ │ ├── FlowIssuesViewer.js │ │ │ ├── FlowIssuesList.js │ │ │ ├── FlowIssuesApp.js │ │ │ └── FlowIssueItem.js │ └── assembly │ │ └── dep.xml ├── .gitignore ├── conf │ ├── jest │ │ ├── CSSStub.js │ │ ├── FileStub.js │ │ └── SetupTestEnvironment.js │ ├── webpack │ │ ├── webpack.config.dev.js │ │ ├── webpack.config.js │ │ └── webpack.config.prod.js │ └── env.js ├── .checkstyle ├── scripts │ ├── test.js │ └── build.js └── package.json ├── sonar-flow-plugin-sslr ├── bin │ ├── .gitignore │ ├── src │ │ ├── main │ │ │ └── java │ │ │ │ └── be │ │ │ │ └── i8c │ │ │ │ └── codequality │ │ │ │ └── sonar │ │ │ │ └── plugins │ │ │ │ └── sag │ │ │ │ └── webmethods │ │ │ │ └── flow │ │ │ │ └── sslr │ │ │ │ ├── FlowLexer.class │ │ │ │ ├── FlowParser.class │ │ │ │ ├── NodeParser.class │ │ │ │ ├── FlowGrammar.class │ │ │ │ ├── NodeGrammar.class │ │ │ │ ├── FlowConfiguration.class │ │ │ │ ├── FlowLexer$FlowTypes.class │ │ │ │ ├── channels │ │ │ │ ├── SaxChannel.class │ │ │ │ └── sax │ │ │ │ │ └── FlowContentHandler.class │ │ │ │ └── FlowLexer$FlowAttTypes.class │ │ └── test │ │ │ ├── java │ │ │ └── be │ │ │ │ └── i8c │ │ │ │ └── codequality │ │ │ │ └── sonar │ │ │ │ └── plugins │ │ │ │ └── sag │ │ │ │ └── webmethods │ │ │ │ └── flow │ │ │ │ └── sslr │ │ │ │ └── FlowParserTest.class │ │ │ └── resources │ │ │ └── node.ndf │ └── pom.xml ├── .gitignore ├── .checkstyle ├── src │ ├── main │ │ └── java │ │ │ └── be │ │ │ └── i8c │ │ │ └── codequality │ │ │ └── sonar │ │ │ └── plugins │ │ │ └── sag │ │ │ └── webmethods │ │ │ └── flow │ │ │ └── sslr │ │ │ ├── types │ │ │ ├── FlowAttTypes.java │ │ │ ├── FlowTypes.java │ │ │ └── FlowAttIdentifierTypes.java │ │ │ ├── FlowConfiguration.java │ │ │ ├── FlowLexer.java │ │ │ ├── FlowParser.java │ │ │ ├── NodeParser.java │ │ │ └── channels │ │ │ └── SaxChannel.java │ └── test │ │ ├── java │ │ └── be │ │ │ └── i8c │ │ │ └── codequality │ │ │ └── sonar │ │ │ └── plugins │ │ │ └── sag │ │ │ └── webmethods │ │ │ └── flow │ │ │ └── sslr │ │ │ └── FlowParserTest.java │ │ └── resources │ │ └── node.ndf └── pom.xml ├── sonar-flow-plugin-sslr-toolkit ├── .gitignore ├── src │ └── main │ │ └── java │ │ └── be │ │ └── i8c │ │ └── codequality │ │ └── sonar │ │ └── plugins │ │ └── sag │ │ └── webmethods │ │ └── flow │ │ └── sslr │ │ └── toolkit │ │ └── FlowToolkit.java └── pom.xml ├── Dockerfile ├── README.md └── .classpath /.gitignore: -------------------------------------------------------------------------------- 1 | .project 2 | /target/ 3 | -------------------------------------------------------------------------------- /_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-minimal -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.name: -------------------------------------------------------------------------------- 1 | Global -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/.gitignore: -------------------------------------------------------------------------------- 1 | /.project 2 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/.gitx/someFile: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.settings/org.eclipse.wst.jsdt.ui.superType.container: -------------------------------------------------------------------------------- 1 | org.eclipse.wst.jsdt.launching.JRE_CONTAINER -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.settings/ 3 | /.classpath 4 | /.project 5 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr-toolkit/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.settings/ 3 | /.project 4 | /.classpath 5 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.settings/ 3 | /.classpath 4 | /.project 5 | /bin/ 6 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkTryCatchInvalid/flow.out.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkBranchPropertiesValid/flow.out.html: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.settings/org.eclipse.m2e.core.prefs: -------------------------------------------------------------------------------- 1 | activeProfiles= 2 | eclipse.preferences.version=1 3 | resolveWorkspaceProjects=true 4 | version=1 5 | -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/assets/sslr.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-documentation/assets/sslr.png -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/assets/plugin.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-documentation/assets/plugin.png -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/assets/build-jar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-documentation/assets/build-jar.png -------------------------------------------------------------------------------- /sonar-flow-plugin/.gitignore: -------------------------------------------------------------------------------- 1 | /target/ 2 | /.settings/ 3 | /.classpath 4 | /.project 5 | /bin/ 6 | /node/ 7 | /node_modules/ 8 | /yarn.lock 9 | /target/ 10 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/node.idf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/assets/sonar-gui-issues-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-documentation/assets/sonar-gui-issues-view.png -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/assets/sonar-gui-project-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-documentation/assets/sonar-gui-project-view.png -------------------------------------------------------------------------------- /sonar-flow-plugin/conf/jest/CSSStub.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | module.exports = {}; 7 | -------------------------------------------------------------------------------- /sonar-flow-plugin/conf/jest/FileStub.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | module.exports = 'test-file-stub'; 7 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkEmptyFlowInvalid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkQualityNameInvalid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkInterfaceCommentsInvalid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowLexer.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowLexer.class -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowParser.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowParser.class -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/NodeParser.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/NodeParser.class -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowGrammar.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowGrammar.class -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/NodeGrammar.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/NodeGrammar.class -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowParserTest.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowParserTest.class -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 3 | org.eclipse.jdt.core.compiler.compliance=1.8 4 | org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning 5 | org.eclipse.jdt.core.compiler.source=1.8 6 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowConfiguration.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowConfiguration.class -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowLexer$FlowTypes.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowLexer$FlowTypes.class -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/channels/SaxChannel.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/channels/SaxChannel.class -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00005.html: -------------------------------------------------------------------------------- 1 |

2 | Flow asset names should follow naming conventions 3 |

4 | 5 |

6 | Flow asset names should follow naming conventions. The naming convention is defined in the param "Naming convention". 7 |

8 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowLexer$FlowAttTypes.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowLexer$FlowAttTypes.class -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/commentLinesVisitor2/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/channels/sax/FlowContentHandler.class: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/I8C/sonar-flow-plugin/HEAD/sonar-flow-plugin-sslr/bin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/channels/sax/FlowContentHandler.class -------------------------------------------------------------------------------- /sonar-flow-plugin/conf/jest/SetupTestEnvironment.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | window.baseUrl = ''; 7 | 8 | window.t = (window.tp = function() { 9 | const args = Array.prototype.slice.call(arguments, 0); 10 | return args.join('.'); 11 | }); 12 | -------------------------------------------------------------------------------- /.settings/.jsdtscope: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sonar-flow-plugin/.checkstyle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/.checkstyle: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/node.idf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | interface 5 | unknown 6 | I8cFlowSonarPluginTest 7 | false 8 | 9 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/flows/node.idf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | interface 5 | unknown 6 | I8cFlowSonarPluginTest.flows 7 | false 8 | 9 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkTryCatchInvalid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00003.html: -------------------------------------------------------------------------------- 1 |

2 | Services should not contain any disabled elements. 3 |

4 | 5 |

6 | Services should be free of any disabled code snippets. 7 |

8 | 9 |

Noncompliant Code Example

10 |
11 | Any disabled code.
12 | 
13 | 14 |

Compliant Solution

15 |
16 | No disabled code.
17 | 
18 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/type/FlowCheckProperties.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Documented 6 | @Target(ElementType.TYPE) 7 | @Inherited 8 | @Retention(RetentionPolicy.RUNTIME) 9 | public @interface FlowCheckProperties { 10 | FlowCheckProperty[] value(); 11 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00002.html: -------------------------------------------------------------------------------- 1 |

2 | Services should not contain any save- or restorePipeline services. 3 |

4 | 5 |

6 | Services should be free of any debugging code snippets. 7 |

8 | 9 |

Noncompliant Code Example

10 |
11 | Invoke:pub.flow:savePipelineToFile
12 | 
13 | 14 |

Compliant Solution

15 |
16 | No invoke
17 | 
18 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/utils/FlowUtils.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.utils; 2 | 3 | import java.io.File; 4 | 5 | public class FlowUtils { 6 | 7 | public static String getQualifiedName(File f) { 8 | return f.getAbsolutePath().replaceAll("(.*[/\\\\]ns[/\\\\])(.*)", "$2") 9 | .replaceAll("[/\\\\]", ".").replaceAll("(.*)\\.(.*)\\.(.*)\\.(.*)", "$1:$2"); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/type/FlowCheckRuleType.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type; 2 | 3 | import java.lang.annotation.*; 4 | 5 | import org.sonar.api.rules.RuleType; 6 | 7 | @Documented 8 | @Target(ElementType.TYPE) 9 | @Inherited 10 | @Retention(RetentionPolicy.RUNTIME) 11 | public @interface FlowCheckRuleType { 12 | RuleType ruletype(); 13 | } 14 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00008.html: -------------------------------------------------------------------------------- 1 |

2 | Empty services should be removed. 3 |

4 | 5 |

6 | Packages should be free of any empty services. 7 |

8 | 9 |

Noncompliant Code Example

10 |
11 |   Any package with a service that doesn't have any flow steps.
12 | 
13 | 14 |

Compliant Solution

15 |
16 |   Remove all services that don't have any flow steps or adjust the service.
17 | 
-------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/manifest.v3: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | yes 5 | no 6 | 1.0 7 | 8 | 9 | 10 | 11 | 12 | yes 13 | 14 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00004.html: -------------------------------------------------------------------------------- 1 |

2 | Interface elements should contain comments. 3 |

4 | 5 |

6 | Interface elements should contain comments. This allows for correct creation of documentation. 7 |

8 | 9 |

Noncompliant Code Example

10 |
11 | Any interface element without comment.
12 | 
13 | 14 |

Compliant Solution

15 |
16 | The interface element with comment added.
17 | 
18 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM sonarqube:6.7.2 2 | 3 | ENV SONARQUBE_HOME /opt/sonarqube 4 | 5 | #Only install flow plugin. make sure it is build. 6 | RUN rm -f $SONARQUBE_HOME/extensions/plugins/* 7 | COPY sonar-flow-plugin/target/sonar-flow-plugin-1.0.jar $SONARQUBE_HOME/extensions/plugins 8 | 9 | VOLUME "$SONARQUBE_HOME/extensions" 10 | 11 | WORKDIR $SONARQUBE_HOME 12 | ENTRYPOINT ["./bin/run.sh"] 13 | 14 | #Now run docker build . -t sonarqube-flow 15 | #Next run docker run --name sonarqube-flow -p 9000:9000 sonarqube-flow -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00001.html: -------------------------------------------------------------------------------- 1 |

2 | A top-level service schould contain a try-catch. 3 |

4 | 5 |

6 | Top-level services should be able to catch exceptions and log,transform and obscure data from them. 7 |

8 | 9 |

Noncompliant Code Example

10 |
11 | Any non-compliant variant
12 | 
13 | 14 |

Compliant Solution

15 |
16 | SEQUENCE (Exit on success)
17 | 	SEQUENCE (Exit on failure)
18 | 	SEQUENCE (Exit on done)
19 | 
20 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00007.html: -------------------------------------------------------------------------------- 1 |

2 | Empty 'MAP' interface elements should be removed from the service. 3 |

4 | 5 |

6 | Services should be free of any empty 'MAP' interface elements. 7 |

8 | 9 |

Noncompliant Code Example

10 |
11 | Any service with a 'MAP' interface element that doesn't have any influence.
12 | 
13 | 14 |

Compliant Solution

15 |
16 |   Remove all 'MAP' interface element that doesn't have any influence.
17 | 
-------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/functions/sonar_api.js: -------------------------------------------------------------------------------- 1 | import {getJSON} from 'sonar-request'; 2 | 3 | export function findIssues(projectKey) { 4 | return getJSON('/api/issues/search', { 5 | resolved : false, 6 | componentKeys : projectKey 7 | }).then(function (response) { 8 | return response; 9 | }); 10 | } 11 | 12 | export function getFlow(projectKey) { 13 | return getJSON('/api/flowsources/flow', { 14 | key : projectKey, 15 | type: 'json' 16 | }).then(function (response) { 17 | return response; 18 | }); 19 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/app-flow_issues.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import { render, unmountComponentAtNode } from 'react-dom'; 3 | import FlowIssuesApp from './components/FlowIssuesApp'; 4 | import './styles/style.css'; 5 | import './styles/flow.css'; 6 | 7 | window.registerExtension('flow/flow_issues', options => { 8 | 9 | const { el } = options; 10 | 11 | render( 12 | , el 16 | ); 17 | 18 | return () => unmountComponentAtNode(el); 19 | }); -------------------------------------------------------------------------------- /sonar-flow-plugin/conf/webpack/webpack.config.dev.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | const webpack = require('webpack'); 7 | const config = require('./webpack.config'); 8 | 9 | config.devtool = 'eval'; 10 | 11 | config.output.publicPath = '/static/example/'; 12 | 13 | config.output.pathinfo = true; 14 | 15 | Object.keys(config.entry).forEach(key => { 16 | config.entry[key].unshift(require.resolve('react-dev-utils/webpackHotDevClient')); 17 | }); 18 | 19 | config.plugins = [new webpack.HotModuleReplacementPlugin()]; 20 | 21 | module.exports = config; 22 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/type/FlowCheckProperty.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type; 2 | 3 | import java.lang.annotation.*; 4 | 5 | import org.sonar.api.PropertyType; 6 | 7 | @Documented 8 | @Target(ElementType.TYPE) 9 | @Inherited 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Repeatable(FlowCheckProperties.class) 12 | public @interface FlowCheckProperty { 13 | String key(); 14 | String defaultValue(); 15 | String name(); 16 | PropertyType type(); 17 | String category(); 18 | String subCategory(); 19 | String description(); 20 | String onQualifiers(); 21 | } 22 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00006.html: -------------------------------------------------------------------------------- 1 |

2 | Services with interface element 'EXIT' need to be configured correctly. 3 |

4 | 5 |
 6 |   Services with interface element 'EXIT' step need to be configured correctly:
 7 |   	- The "Exit from " property needs to be configured.
 8 |   	- The failure message needs to be added if the "Signal" property is set to "Failure".
 9 | 
10 | 11 |

Noncompliant Code Example

12 |
13 | Any non-compliant variant
14 | 
15 | 16 |

Compliant Solution

17 |
18 | 	- Configure the "Exit from " property.
19 |   	- Add the failure message if the "Signal" property is set to "Failure".
20 | 
-------------------------------------------------------------------------------- /sonar-flow-plugin/scripts/test.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | process.env.NODE_ENV = 'test'; 7 | process.env.PUBLIC_URL = ''; 8 | 9 | // Load environment variables from .env file. Surpress warnings using silent 10 | // if this file is missing. dotenv will never modify any environment variables 11 | // that have already been set. 12 | // https://github.com/motdotla/dotenv 13 | require('dotenv').config({ silent: true }); 14 | 15 | const jest = require('jest'); 16 | 17 | const argv = process.argv.slice(2); 18 | 19 | // Watch unless on CI 20 | if (!process.env.CI) { 21 | argv.push('--watch'); 22 | } 23 | 24 | argv.push('--coverage'); 25 | 26 | jest.run(argv); 27 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkAllDebugFlowsInvalid/flow.out.txt: -------------------------------------------------------------------------------- 1 | {{"flow":{"children":{"sequence":{"label":"","comment":"Main","line":"","children":{{"sequence":{"label":"","comment":"Try","line":"","children":{{"invoke":{"service":"pub.flow:debugLog","label":"","comment":"","line":""}{"invoke":{"service":"pub.flow:savePipeline","label":"","comment":"","line":""}{"invoke":{"service":"pub.flow:restorePipeline","label":"","comment":"","line":""}{"invoke":{"service":"pub.flow:tracePipeline","label":"","comment":"","line":""}}}{"sequence":{"label":"","comment":"Catch","line":"","children":{{"invoke":{"service":"pub.flow:getLastError","label":"","comment":"","line":""}{"map":{"label":"","comment":"","line":"","children":{}}}}}}}}} -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkBranchPropertiesValid/flow.out.txt: -------------------------------------------------------------------------------- 1 | {"flow":{"children":[{"sequence":{"label":"","comment":"Main","line":"","children":[{"sequence":{"label":"","comment":"Try","line":"","children":[{"invoke":{"service":"I8cFlowSonarPluginTest.flows:sendMail","label":"","comment":"","line":""}},{"branch":{"switch":"","label":"","comment":"","line":"","children":[{"map":{"label":"%lv_check9/status% != 'OK'","comment":"","line":""}}]}},{"branch":{"switch":"/lv_check9/status","label":"","comment":"","line":"","children":[{"map":{"label":"OK","comment":"","line":""}}]}}]}},{"sequence":{"label":"","comment":"Catch","line":"","children":[{"invoke":{"service":"pub.flow:getLastError","label":"","comment":"","line":""}},{"map":{"label":"","comment":"","line":""}}]}}]}}]}} -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Map.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Map extends React.PureComponent { 5 | //this.props.map 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | let isSelected=this.props.issueLine==this.props.map.line; 13 | return ( 14 |
  • 15 | 16 | {this.props.map.label} 17 | MAP 18 | {this.props.map.comment!="" && ("("+this.props.map.comment+")")} 19 | {this.props.map.line} 20 |
  • 21 | ); 22 | } 23 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Exit.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Map extends React.PureComponent { 5 | //this.props.exit 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | let isSelected=this.props.issueLine==this.props.exit.line; 13 | return ( 14 |
  • 15 | 16 | {this.props.exit.label} 17 | EXIT 18 | {this.props.exit.comment!="" && ("("+this.props.exit.comment+")")} 19 | {this.props.exit.line} 20 |
  • 21 | ); 22 | } 23 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/utils/FlowUtilsTest.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.utils; 2 | 3 | import java.io.File; 4 | 5 | import org.junit.Assert; 6 | import org.junit.Test; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | 11 | 12 | public class FlowUtilsTest { 13 | 14 | static final Logger logger = LoggerFactory.getLogger(FlowUtilsTest.class); 15 | 16 | @Test 17 | public void getQualifiedName() { 18 | Assert.assertEquals(FlowUtils.getQualifiedName(new File( 19 | "D:\\temp\\SoftwareAG\\IntegrationServer\\instances\\default\\packages" 20 | + "\\myTestPackage\\ns\\myTestPackage\\new_flowservice\\flow.xml")), 21 | "myTestPackage:new_flowservice"); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Invoke.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Invoke extends React.PureComponent { 5 | //this.props.invoke 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | let isSelected=this.props.issueLine==this.props.invoke.line; 13 | return ( 14 |
  • 15 | 16 | {this.props.invoke.label} 17 | INVOKE: {this.props.invoke.service} 18 | {this.props.invoke.comment!="" && ("("+this.props.invoke.comment+")")} 19 | {this.props.invoke.line} 20 |
  • 21 | ); 22 | } 23 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/conf/env.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | // Grab NODE_ENV and REACT_APP_* environment variables and prepare them to be 7 | // injected into the application via DefinePlugin in Webpack configuration. 8 | 9 | const REACT_APP = /^REACT_APP_/i; 10 | 11 | function getClientEnvironment() { 12 | return Object.keys(process.env).filter(key => REACT_APP.test(key)).reduce((env, key) => { 13 | env['process.env.' + key] = JSON.stringify(process.env[key]); 14 | return env; 15 | }, { 16 | // Useful for determining whether we’re running in production mode. 17 | // Most importantly, it switches React into the correct mode. 18 | 'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'development') 19 | }); 20 | } 21 | 22 | module.exports = getClientEnvironment; 23 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/resources/org/sonar/l10n/flow/rules/flow/S00009.html: -------------------------------------------------------------------------------- 1 |

    2 | There should always be a branching condition defined in the properties of a BRANCH step. Either in the switch property or in the labels of the child steps. 3 |

    4 |

    5 | If the switch property of a BRANCH step is not defined, then the 'evaluate labels' property should be set to true. This indicates that the branching conditions are defined in the labels of the child step. If the switch is defined then the 'evaluate labels' property should be false or null. 6 |

    7 | 8 |

    Noncompliant Code Example

    9 |
    10 |   Any service with a branch step that doesn't have the label expression set to 'true' while no switch value has been given.
    11 | 
    12 | 13 |

    Compliant Solution

    14 |
    15 |   Give a switch value or set the label expression value to 'true'.
    16 | 
    -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/DEVELOPMENT_SETUP.md: -------------------------------------------------------------------------------- 1 | # DEVELOPMENT SETUP 2 | 3 | ## Get the source code 4 | Clone the repository to your local machine. 5 | ```sh 6 | git clone https://github.com/I8C/sonar-flow-plugin 7 | ``` 8 | Open eclipse and import the sonar-flows-plugin and sonar-flow-plugin-sslr as maven projects. 9 | 10 | ## Develop your flow code checks 11 | Now you are ready to develop your own checks. Use the flow code checks in be.i8c.codequality.sonar.plugins.sag.webmethods.flow.check as example: 12 | * SavePipelineCheck.java 13 | * TryCatchCheck.java 14 | * InterfaceCommentsCheck.java 15 | 16 | See the [DEVELOPMENT GUIDE](DEVELOPMENT.md) for more info about this plugin. 17 | 18 | ## Build the plugin jar 19 | Build the webMethods flow-code plugin jar and add it to your SonarQube server (see the [QUICK SETUP GUIDE](QUICK_SETUP.md)). The generated jar is located under the target directory. 20 | ![eclise build](assets/build-jar.png) 21 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Loop.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Loop extends React.PureComponent { 5 | //this.props.loop 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | const children = getChildren(this.props.loop,this.props.issueLine); 13 | let isSelected=this.props.issueLine==this.props.loop.line; 14 | return ( 15 |
  • 16 | 17 | {this.props.loop.label} 18 | LOOP 19 | {this.props.loop.comment!="" && ("("+this.props.loop.comment+")")} 20 | {this.props.loop.line} 21 | 24 |
  • 25 | ); 26 | } 27 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Branch.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Branch extends React.PureComponent { 5 | //this.props.branch 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | const children = getChildren(this.props.branch,this.props.issueLine); 13 | let isSelected=this.props.issueLine==this.props.branch.line; 14 | return ( 15 |
  • 16 | 17 | {this.props.branch.label} 18 | BRANCH 19 | {this.props.branch.comment!="" && ("("+this.props.branch.comment+")")} 20 | {this.props.branch.line} 21 | 24 |
  • 25 | ); 26 | } 27 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Repeat.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Repeat extends React.PureComponent { 5 | //this.props.repeat 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | const children = getChildren(this.props.repeat,this.props.issueLine); 13 | let isSelected=this.props.issueLine==this.props.repeat.line; 14 | return ( 15 |
  • 16 | 17 | {this.props.repeat.label} 18 | REPEAT 19 | {this.props.repeat.comment!="" && ("("+this.props.repeat.comment+")")} 20 | {this.props.repeat.line} 21 | 24 |
  • 25 | ); 26 | } 27 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkSavePipelineInvalid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Main 5 | 6 | 7 | 8 | 9 | Main 10 | 11 | 12 | 13 | 14 | Try 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Catch 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Sequence.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Sequence extends React.PureComponent { 5 | //this.props.sequence 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | render(){ 12 | const children = getChildren(this.props.sequence,this.props.issueLine); 13 | let isSelected=this.props.issueLine==this.props.sequence.line; 14 | return ( 15 |
  • 16 | 17 | {this.props.sequence.label} 18 | SEQUENCE 19 | {this.props.sequence.comment!="" && ("("+this.props.sequence.comment+")")} 20 | {this.props.sequence.line} 21 | 24 |
  • 25 | ); 26 | } 27 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkTryCatchValid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | Main 10 | 11 | 12 | 13 | 14 | Try 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Catch 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkEmptyMapInvalid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Main 5 | 6 | 7 | 8 | 9 | Main 10 | 11 | 12 | 13 | 14 | Try 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | Catch 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkDisabledInvalid/flow.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Main 5 | 6 | 7 | 8 | 9 | Main 10 | 11 | 12 | 13 | 14 | Try 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Catch 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/FlowIssuesViewer.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getFlow} from '../functions/sonar_api.js' 3 | import Flow from './flow/Flow.js'; 4 | 5 | export default class FlowIssuesViewer extends React.PureComponent { 6 | constructor(props) { 7 | super(props); 8 | //this.props.issue 9 | this.state = { 10 | flow:null, 11 | component:this.props.issue.component 12 | }; 13 | } 14 | 15 | componentDidMount() { 16 | this.checkChange(); 17 | } 18 | 19 | checkChange(){ 20 | if(this.state.component != this.props.issue.component){ 21 | if(this.props.issue.component.endsWith("flow.xml")){ 22 | getFlow(this.props.issue.component).then( 23 | (response) => { 24 | this.setState({ 25 | flow: response.flow, 26 | component:this.props.issue.component 27 | }); 28 | } 29 | ); 30 | } 31 | } 32 | } 33 | 34 | render() { 35 | this.checkChange(); 36 | return ( 37 | 38 | ); 39 | } 40 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/type/FlowVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.type; 22 | 23 | import com.sonar.sslr.api.Grammar; 24 | 25 | import org.sonar.squidbridge.SquidAstVisitor; 26 | 27 | public abstract class FlowVisitor extends SquidAstVisitor { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/ws/sources/xslt/LocationFilter.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.ws.sources.xslt; 2 | 3 | import org.xml.sax.Attributes; 4 | import org.xml.sax.Locator; 5 | import org.xml.sax.SAXException; 6 | import org.xml.sax.XMLReader; 7 | import org.xml.sax.ext.Attributes2Impl; 8 | import org.xml.sax.helpers.XMLFilterImpl; 9 | 10 | public class LocationFilter extends XMLFilterImpl { 11 | 12 | public LocationFilter(XMLReader xmlReader) { 13 | super(xmlReader); 14 | } 15 | 16 | private Locator locator = null; 17 | 18 | @Override 19 | public void setDocumentLocator(Locator locator) { 20 | super.setDocumentLocator(locator); 21 | this.locator = locator; 22 | } 23 | 24 | @Override 25 | public void startElement(String uri, String localName, 26 | String qualifiedName, Attributes attributes) 27 | throws SAXException { 28 | 29 | // Add extra attribute to elements to hold location 30 | String location = String.valueOf(locator.getLineNumber()); 31 | Attributes2Impl attrs = new Attributes2Impl(attributes); 32 | attrs.addAttribute("", "location", "location", "String", location); 33 | super.startElement(uri, localName, qualifiedName, attrs); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/functions/flowUtils.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import Sequence from '../Sequence.js'; 3 | import Branch from '../Branch.js'; 4 | import Invoke from '../Invoke.js'; 5 | import Map from '../Map.js'; 6 | import Loop from '../Loop.js'; 7 | import Repeat from '../Repeat.js'; 8 | import Exit from '../Exit.js'; 9 | 10 | export function getChildren(element, issueLine){ 11 | let output = []; 12 | if(element!=null && element.children!=null){ 13 | element.children.forEach(child => { 14 | switch (Object.keys(child)[0]) { 15 | case 'sequence': output.push( );break; 16 | case 'branch': output.push( );break; 17 | case 'invoke': output.push( );break; 18 | case 'map': output.push( );break; 19 | case 'loop': output.push( );break; 20 | case 'repeat': output.push( );break; 21 | case 'exit': output.push( );break; 22 | } 23 | }); 24 | }else 25 | output.push(
    ); 26 | return output; 27 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/assembly/dep.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | jar-with-dependencies 6 | 7 | jar 8 | 9 | false 10 | 11 | 12 | ${project.basedir}/src/main/java 13 | / 14 | 15 | 16 | ${project.basedir} 17 | META-INF/ 18 | 19 | README* 20 | LICENSE* 21 | NOTICE* 22 | pom.xml 23 | 24 | 25 | 26 | 27 | 28 | META-INF/lib 29 | true 30 | false 31 | runtime 32 | 33 | 34 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr-toolkit/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/toolkit/FlowToolkit.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.toolkit; 21 | 22 | import org.sonar.sslr.toolkit.Toolkit; 23 | 24 | public class FlowToolkit { 25 | 26 | private FlowToolkit() { 27 | } 28 | 29 | public static void main(String[] args) { 30 | Toolkit toolkit = new Toolkit("i8c : flow : Toolkit", new FlowConfigurationModel()); 31 | toolkit.run(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/Tags.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | public class Tags { 24 | 25 | public static final String ERROR_HANDLING = "error-handling"; 26 | public static final String DEBUG_CODE = "debug-code"; 27 | public static final String BAD_PRACTICE = "bad-practice"; 28 | 29 | private Tags() { 30 | // This class only defines constants 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/type/FlowCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type; 22 | 23 | import com.sonar.sslr.api.Grammar; 24 | 25 | import org.sonar.squidbridge.checks.SquidCheck; 26 | 27 | public abstract class FlowCheck extends SquidCheck { 28 | 29 | public abstract boolean isFlowCheck(); 30 | 31 | public abstract boolean isNodeCheck(); 32 | 33 | public abstract boolean isTopLevelCheck(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkEmptyFlowInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | yes 8 | no 9 | no 10 | 15 11 | 1 12 | off 13 | no 14 | $null 15 | no 16 | 0 17 | 0 18 | none 19 | none 20 | 0 21 | 22 | 23 | 24 | 0 25 | false 26 | false 27 | true 28 | 29 | 0 30 | 31 | true 32 | false 33 | 34 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkQualityNameInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | yes 8 | no 9 | no 10 | 15 11 | 1 12 | off 13 | no 14 | $null 15 | no 16 | 0 17 | 0 18 | none 19 | none 20 | 0 21 | 22 | 23 | 24 | 0 25 | false 26 | false 27 | true 28 | 29 | 0 30 | 31 | true 32 | false 33 | 34 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/squid/CommentAnalyser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2018 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid; 22 | 23 | /** 24 | * A necessary comment analyser for this plugin. 25 | * @author DEWANST 26 | */ 27 | public class CommentAnalyser extends org.sonar.squidbridge.CommentAnalyser { 28 | 29 | @Override 30 | public boolean isBlank(String line) { 31 | return line.isEmpty(); 32 | } 33 | 34 | @Override 35 | public String getContents(String comment) { 36 | return comment; 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/types/FlowAttTypes.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.sonar.sslr.api.AstNode; 6 | import com.sonar.sslr.api.TokenType; 7 | 8 | public enum FlowAttTypes implements TokenType { 9 | SERVICE, EXITON("EXIT-ON"), MODE, NAME, DISABLED, FROM, SIGNAL, FAILUREMESSAGE( 10 | "FAILURE-MESSAGE"), SWITCH, LABELEXPRESSIONS; 11 | 12 | private String attName; 13 | 14 | public static boolean isInEnum(String value) { 15 | return Arrays.stream(FlowAttTypes.values()) 16 | .anyMatch(e -> e.getAttName().equalsIgnoreCase(value)); 17 | } 18 | 19 | public static FlowAttTypes getEnum(String value) { 20 | return Arrays.stream(FlowAttTypes.values()) 21 | .filter(e -> e.getAttName().equalsIgnoreCase(value)).findFirst().get(); 22 | } 23 | 24 | private FlowAttTypes() { 25 | this.attName = name(); 26 | } 27 | 28 | private FlowAttTypes(String name) { 29 | this.attName = name; 30 | } 31 | 32 | public String getAttName() { 33 | return this.attName; 34 | } 35 | 36 | @Override 37 | public String getName() { 38 | return name(); 39 | } 40 | 41 | @Override 42 | public String getValue() { 43 | return null; 44 | } 45 | 46 | @Override 47 | public boolean hasToBeSkippedFromAst(AstNode node) { 48 | return false; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /sonar-flow-plugin/conf/webpack/webpack.config.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | const path = require('path'); 7 | const autoprefixer = require('autoprefixer'); 8 | 9 | const autoprefixerOptions = { 10 | browsers: [ 11 | 'last 3 Chrome versions', 12 | 'last 3 Firefox versions', 13 | 'Safari >= 8', 14 | 'Edge >= 12', 15 | 'IE 11' 16 | ] 17 | }; 18 | 19 | const output = path.join(__dirname, '../../target/classes/static'); 20 | 21 | module.exports = { 22 | entry: { 23 | 'flow_issues': ['./src/main/js/app-flow_issues.js'] 24 | }, 25 | output: { 26 | path: output, 27 | filename: '[name].js' 28 | }, 29 | resolve: { 30 | root: path.join(__dirname, 'src/main/js') 31 | }, 32 | externals: { 33 | lodash: '_', 34 | react: 'React', 35 | 'react-dom': 'ReactDOM', 36 | 'react-redux': 'ReactRedux', 37 | 'react-router': 'ReactRouter', 38 | 'sonar-request': 'SonarRequest', 39 | 'sonar-measures': 'SonarMeasures', 40 | 'sonar-components': 'SonarComponents' 41 | }, 42 | module: { 43 | loaders: [ 44 | { 45 | test: /\.js$/, 46 | loader: 'babel', 47 | exclude: /(node_modules)/ 48 | }, 49 | { 50 | test: /\.css/, 51 | loader: 'style-loader!css-loader!postcss-loader' 52 | }, 53 | { test: /\.json$/, loader: 'json' } 54 | ] 55 | }, 56 | postcss() { 57 | return [autoprefixer(autoprefixerOptions)]; 58 | } 59 | }; 60 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/web/FlowWebPageDefinition.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.web; 22 | 23 | import org.sonar.api.web.page.Context; 24 | import org.sonar.api.web.page.Page; 25 | import org.sonar.api.web.page.Page.Scope; 26 | import org.sonar.api.web.page.PageDefinition; 27 | 28 | public class FlowWebPageDefinition implements PageDefinition { 29 | 30 | @Override 31 | public void define(Context context) { 32 | context.addPage(Page.builder("flow/flow_issues").setName("Flow issues").setAdmin(false) 33 | .setScope(Scope.COMPONENT).build()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/flow/Flow.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import {getChildren} from './functions/flowUtils.js' 3 | 4 | export default class Flow extends React.PureComponent { 5 | //this.props.flow 6 | //this.props.issueLine 7 | constructor(props) { 8 | super(props); 9 | } 10 | 11 | isFirst(flow, issueLine){ 12 | if(flow!=null && flow.children!=null && flow.children.length>0 && flow.children[0]!=null){ 13 | let firstLine = flow.children[0][Object.keys(flow.children[0])[0]].line; 14 | if(issueLine0 && flow.children[flow.children.length-1]!=null){ 22 | let lastChild = flow.children[flow.children.length-1][Object.keys(flow.children[flow.children.length-1])[0]]; 23 | if(lastChild.children!=null && lastChild.children.length>0){ 24 | return this.isLast(lastChild, issueLine); 25 | }else{ 26 | let lastLine = lastChild.line; 27 | if(issueLine>lastLine) 28 | return true; 29 | } 30 | } 31 | return false; 32 | } 33 | 34 | render(){ 35 | const children = getChildren(this.props.flow,this.props.issueLine); 36 | const isFirst = this.isFirst(this.props.flow,this.props.issueLine); 37 | const isLast = this.isLast(this.props.flow,this.props.issueLine); 38 | return ( 39 |
      40 |
    • 41 | {children} 42 |
    • 43 |
    44 | ); 45 | } 46 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/FlowIssuesList.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import FlowIssueItem from './FlowIssueItem.js' 3 | import {findIssues} from '../functions/sonar_api.js' 4 | 5 | export default class FlowIssuesList extends React.PureComponent { 6 | 7 | constructor(props) { 8 | super(props); 9 | // this.props.projectKey 10 | // this.props.selectedIssue 11 | // this.props.onSelection 12 | this.state = { 13 | issues: [], 14 | components: [] 15 | }; 16 | this.handleSelection = this.handleSelection.bind(this); 17 | } 18 | 19 | componentDidMount() { 20 | findIssues(this.props.projectKey).then( 21 | (response) => { 22 | this.setState({ 23 | issues: response.issues, 24 | components: response.components 25 | }); 26 | } 27 | ); 28 | } 29 | 30 | handleSelection(issue) { 31 | this.props.onSelection(issue); 32 | } 33 | 34 | render() { 35 | let issueItems = []; 36 | let lastComponent=undefined; 37 | this.state.issues.forEach(issue => { 38 | issue.id=issue.key; 39 | issueItems.push( 40 |
    41 | {issue.component!=lastComponent?
    {issue.component.replace(/.*:(.+?\/)(.+)(\/.+?\/.+)/,"$1...$3")}
    :""} 42 | 43 |
    44 | ); 45 | lastComponent=issue.component; 46 | }); 47 | return ( 48 |
    49 |
    {issueItems}
    50 |
    51 | ); 52 | } 53 | } -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/types/FlowTypes.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.sonar.sslr.api.AstNode; 6 | import com.sonar.sslr.api.TokenType; 7 | 8 | public enum FlowTypes implements TokenType { 9 | START_FLOW, STOP_FLOW, START_SEQUENCE, STOP_SEQUENCE, START_INVOKE, STOP_INVOKE, 10 | 11 | START_LOOP, STOP_LOOP, START_BRANCH, STOP_BRANCH, START_EXIT, STOP_EXIT, 12 | 13 | START_RETRY, STOP_RETRY, START_MAP, STOP_MAP, START_MAPTARGET, STOP_MAPTARGET, 14 | 15 | START_MAPSOURCE, STOP_MAPSOURCE, START_MAPDELETE, STOP_MAPDELETE, START_MAPSET, STOP_MAPSET, 16 | 17 | START_MAPCOPY, STOP_MAPCOPY, START_MAPINVOKE, STOP_MAPINVOKE, START_DATA, STOP_DATA, 18 | 19 | START_VALUES, STOP_VALUES, START_RECORD, STOP_RECORD, START_VALUE, STOP_VALUE, 20 | 21 | START_NUMBER, STOP_NUMBER, START_ARRAY, STOP_ARRAY, START_BOOLEAN, STOP_BOOLEAN, 22 | 23 | ELEMENT_VALUE(false), START_COMMENT, STOP_COMMENT; 24 | 25 | public static boolean isInEnum(String value) { 26 | return Arrays.stream(FlowTypes.values()).anyMatch(e -> e.name().equals(value)); 27 | } 28 | 29 | private boolean skip = true; 30 | 31 | private FlowTypes() { 32 | } 33 | 34 | private FlowTypes(boolean skip) { 35 | this.skip = skip; 36 | } 37 | 38 | @Override 39 | public String getName() { 40 | return name(); 41 | } 42 | 43 | @Override 44 | public String getValue() { 45 | return null; 46 | } 47 | 48 | @Override 49 | public boolean hasToBeSkippedFromAst(AstNode node) { 50 | return skip; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr; 22 | 23 | import java.nio.charset.Charset; 24 | 25 | import org.sonar.squidbridge.api.SquidConfiguration; 26 | 27 | /** 28 | * Configuration for Squid. 29 | * @author DEWANST 30 | * 31 | */ 32 | public class FlowConfiguration extends SquidConfiguration { 33 | 34 | private boolean ignoreNodeNdf; 35 | 36 | public FlowConfiguration(Charset encoding) { 37 | super(encoding); 38 | } 39 | 40 | public boolean getIgnoreNodeNdf() { 41 | return ignoreNodeNdf; 42 | } 43 | 44 | public void setIgnoreNodeNdf(boolean ignoreNodeNdf) { 45 | this.ignoreNodeNdf = ignoreNodeNdf; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/types/FlowAttIdentifierTypes.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types; 2 | 3 | import java.util.Arrays; 4 | 5 | import com.sonar.sslr.api.AstNode; 6 | import com.sonar.sslr.api.TokenType; 7 | 8 | public enum FlowAttIdentifierTypes implements TokenType { 9 | SIGNATURE("name","svc_sig"), SIGN_IN("name","sig_in"), SIGN_OUT("name","sig_out"), REC_FIELDS("name","rec_fields"); 10 | 11 | private String attName; 12 | private String attValue; 13 | 14 | public static boolean isInEnum(String name, String value) { 15 | return Arrays.stream(FlowAttIdentifierTypes.values()) 16 | .anyMatch(e -> (e.getAttName().equalsIgnoreCase(name) && e.getAttValue().equalsIgnoreCase(value))); 17 | } 18 | 19 | public static FlowAttIdentifierTypes getEnum(String name, String value) { 20 | return Arrays.stream(FlowAttIdentifierTypes.values()) 21 | .filter(e -> (e.getAttName().equalsIgnoreCase(name) && e.getAttValue().equalsIgnoreCase(value))).findFirst().get(); 22 | } 23 | 24 | private FlowAttIdentifierTypes(String name, String value) { 25 | this.attName = name; 26 | this.attValue = value; 27 | } 28 | 29 | public String getAttName() { 30 | return this.attName; 31 | } 32 | 33 | public String getAttValue() { 34 | return this.attValue; 35 | } 36 | 37 | @Override 38 | public String getName() { 39 | return name(); 40 | } 41 | 42 | @Override 43 | public String getValue() { 44 | return null; 45 | } 46 | 47 | @Override 48 | public boolean hasToBeSkippedFromAst(AstNode node) { 49 | return false; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowParserTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.FlowParser; 24 | 25 | import org.junit.Test; 26 | 27 | import org.slf4j.Logger; 28 | import org.slf4j.LoggerFactory; 29 | 30 | public class FlowParserTest { 31 | static final Logger logger = LoggerFactory.getLogger(FlowParserTest.class); 32 | 33 | @Test 34 | public void parseFileFlow() { 35 | FlowParser.parseFile("src/test/resources/flow.xml"); 36 | logger.debug("Flow.xml successfully parsed."); 37 | } 38 | 39 | @Test 40 | public void parseFileNode() { 41 | NodeParser.parseFile("src/test/resources/node.ndf"); 42 | logger.debug("node.ndf succesfully parsed."); 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # The sonar-flow-plugin project 2 | 3 | This project provides a SonarQube plugin for the webMethods flow language. 4 | 5 | Currently the plugin comes with following predefined rules: 6 | 7 | 1. TryCatchCheck 8 | * A top-level service schould contain a try-catch. The top-level services should be able to catch exceptions and log, transform and obscure data from them. 9 | 2. SavePipelineCheck 10 | * Services should not contain any save- or restorePipeline services. 11 | 3. DisableCheck 12 | * Services should not contain any disabled elements. 13 | 4. InterfaceCommentsCheck 14 | * Interface elements should contain comments. This allows for correct creation of documentation. 15 | 5. QualityNameCheck 16 | 6. ExitCheck 17 | * Services with interface element 'EXIT' step need to be configured correctly. The "Exit from " property needs to be configured and the failure message needs to be added if the "Signal" property is set to "Failure". 18 | 7. EmptyMapCheck 19 | * Empty 'MAP' interface elements should be removed from the service. 20 | 8. EmptyFlowCheck 21 | * Empty services should be removed. 22 | 9. BranchPropertiesCheck 23 | * If the switch property of a BRANCH step is not defined, then the 'evaluate labels' property should be set to true. This indicates that the branching conditions are defined in the labels of the child step. If the switch is defined then the 'evaluate labels' property should be false or null. 24 | 25 | ## Quick setup guide 26 | Here you'll find a [quick setup](sonar-flow-plugin-documentation/QUICK_SETUP.md). 27 | 28 | ## Develop your own flow code checks 29 | You can find the documentation to develop you own rules [here](sonar-flow-plugin-documentation/DEVELOPMENT_SETUP.md). 30 | 31 | ## License 32 | The sonar-flow-plugin is available under the [GNU Lesser General Public License v3.0](LICENSE.txt). 33 | -------------------------------------------------------------------------------- /sonar-flow-plugin/conf/webpack/webpack.config.prod.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | const webpack = require('webpack'); 7 | const config = require('./webpack.config'); 8 | const getClientEnvironment = require('../env'); 9 | 10 | // Get environment variables to inject into our app. 11 | const env = getClientEnvironment(); 12 | 13 | // Assert this just to be safe. 14 | // Development builds of React are slow and not intended for production. 15 | if (env['process.env.NODE_ENV'] !== '"production"') { 16 | throw new Error('Production builds must have NODE_ENV=production.'); 17 | } 18 | 19 | const noUglify = process.argv.some(arg => arg.indexOf('--no-uglify') > -1); 20 | 21 | // Don't attempt to continue if there are any errors. 22 | config.bail = true; 23 | 24 | config.plugins = [ 25 | // Makes some environment variables available to the JS code, for example: 26 | // if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`. 27 | // It is absolutely essential that NODE_ENV was set to production here. 28 | // Otherwise React will be compiled in the very slow development mode. 29 | new webpack.DefinePlugin(env), 30 | 31 | // This helps ensure the builds are consistent if source hasn't changed: 32 | new webpack.optimize.OccurrenceOrderPlugin(), 33 | 34 | // Try to dedupe duplicated modules, if any: 35 | new webpack.optimize.DedupePlugin() 36 | ]; 37 | 38 | if (!noUglify) { 39 | config.plugins.push( 40 | new webpack.optimize.UglifyJsPlugin({ 41 | compress: { 42 | screw_ie8: true, // React doesn't support IE8 43 | warnings: false 44 | }, 45 | mangle: { 46 | screw_ie8: true 47 | }, 48 | output: { 49 | comments: false, 50 | screw_ie8: true 51 | } 52 | }) 53 | ); 54 | } 55 | 56 | module.exports = config; 57 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowLexer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.channels.SaxChannel; 24 | 25 | import com.sonar.sslr.impl.Lexer; 26 | import com.sonar.sslr.impl.channel.BlackHoleChannel; 27 | 28 | /** 29 | * This lexer defines the tags of the flow xml file. 30 | * @author DEWANST 31 | * 32 | */ 33 | public class FlowLexer { 34 | 35 | private FlowLexer() { 36 | } 37 | 38 | /** 39 | * Creates this lexer. 40 | * @param conf 41 | * Configuration for this lexer. 42 | * @return 43 | */ 44 | public static Lexer create(FlowConfiguration conf) { 45 | return Lexer.builder().withCharset(conf.getCharset()) 46 | .withFailIfNoChannelToConsumeOneCharacter(true).withChannel(new SaxChannel()) 47 | .withChannel(new BlackHoleChannel(".*")).build(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/FlowQualityProfile.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow; 22 | 23 | import static be.i8c.codequality.sonar.plugins.sag.webmethods.flow.rule.FlowRulesDefinition.REPO_KEY; 24 | 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.rule.FlowRulesDefinition; 26 | 27 | import org.sonar.api.server.profile.BuiltInQualityProfilesDefinition; 28 | 29 | /** 30 | * This class is the default quality profile that comes with this plugin. 31 | * @author DEWANST 32 | */ 33 | public class FlowQualityProfile implements BuiltInQualityProfilesDefinition { 34 | 35 | @Override 36 | public void define(Context context) { 37 | NewBuiltInQualityProfile profile = context.createBuiltInQualityProfile("i8c Flow Rules", 38 | FlowLanguage.KEY); 39 | profile.setDefault(true); 40 | // ACTIVATE RULES 41 | for (String key : FlowRulesDefinition.getRuleKeys()) { 42 | profile.activateRule(REPO_KEY, key); 43 | } 44 | profile.done(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/FlowIssuesApp.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import FlowIssuesList from './FlowIssuesList.js'; 3 | import FlowIssuesViewer from './FlowIssuesViewer.js'; 4 | 5 | export default class FlowIssuesApp extends React.PureComponent { 6 | constructor(props) { 7 | super(props); 8 | // this.props.component 9 | this.state = { 10 | selectedIssue: {key:"n/a"} 11 | }; 12 | this.handleSelection = this.handleSelection.bind(this); 13 | } 14 | 15 | handleSelection(issue) { 16 | this.setState({selectedIssue: issue}); 17 | } 18 | 19 | render() { 20 | const projectKey = this.props.component.key; 21 | return ( 22 |
    23 | 24 |
    25 |
    26 | 27 |
    28 |
    29 | 30 |
    31 |
    32 |
    33 |
    34 |
    35 | {this.state.selectedIssue.message!=null?this.state.selectedIssue.message:"Nothing selected"} 36 |
    37 |
    38 |
    39 |
    40 | 41 |
    42 |
    43 | {this.state.selectedIssue ? ( 44 | 45 | ) : ( 46 |
    47 | )} 48 |
    49 |
    50 |
    51 |
    52 | ); 53 | } 54 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/FlowPluginTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow; 22 | 23 | import static org.junit.Assert.assertTrue; 24 | 25 | import org.junit.Test; 26 | import org.slf4j.Logger; 27 | import org.slf4j.LoggerFactory; 28 | import org.sonar.api.Plugin; 29 | import org.sonar.api.SonarQubeSide; 30 | import org.sonar.api.SonarRuntime; 31 | import org.sonar.api.internal.SonarRuntimeImpl; 32 | import org.sonar.api.utils.Version; 33 | 34 | public class FlowPluginTest { 35 | 36 | static final Logger logger = LoggerFactory.getLogger(FlowPluginTest.class); 37 | 38 | @Test 39 | public void debug() { 40 | SonarRuntime runtime = 41 | SonarRuntimeImpl.forSonarQube(Version.create(5, 6), SonarQubeSide.SCANNER); 42 | Plugin.Context context = new Plugin.Context(runtime); 43 | new FlowPlugin().define(context); 44 | logger.debug("Nr of extentions: " + context.getExtensions().size()); 45 | assertTrue(context.getExtensions().size() == 13); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/metric/FlowMetric.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.metric; 22 | 23 | import org.sonar.squidbridge.measures.CalculatedMetricFormula; 24 | import org.sonar.squidbridge.measures.MetricDef; 25 | 26 | /** 27 | * An enum of flow metrics. 28 | * @author DEWANST 29 | */ 30 | public enum FlowMetric implements MetricDef { 31 | 32 | FLOWS, 33 | INVOKES, 34 | SEQUENCES, 35 | LOOPS, 36 | BRANCHES, 37 | MAPS, 38 | LINES, 39 | FILES, 40 | LINES_OF_CODE, 41 | COMPLEXITY, 42 | COMMENT_LINES, 43 | STATEMENTS, 44 | DEPENDENCIES, 45 | IS_TOP_LEVEL; 46 | 47 | public boolean aggregateIfThereIsAlreadyAValue() { 48 | return true; 49 | } 50 | 51 | public CalculatedMetricFormula getCalculatedMetricFormula() { 52 | return null; 53 | } 54 | 55 | public String getName() { 56 | return name(); 57 | } 58 | 59 | public boolean isCalculatedMetric() { 60 | return false; 61 | } 62 | 63 | public boolean isThereAggregationFormula() { 64 | return true; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /sonar-flow-plugin/scripts/build.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2017-2017 SonarSource SA 3 | * All rights reserved 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | /* eslint-disable no-console */ 7 | process.env.NODE_ENV = 'production'; 8 | 9 | const chalk = require('chalk'); 10 | const webpack = require('webpack'); 11 | const config = require('../conf/webpack/webpack.config.prod.js'); 12 | 13 | function formatSize(bytes) { 14 | if (bytes === 0) { 15 | return '0'; 16 | } 17 | const k = 1000; // or 1024 for binary 18 | const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; 19 | const i = Math.floor(Math.log(bytes) / Math.log(k)); 20 | return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]; 21 | } 22 | 23 | function build() { 24 | console.log(chalk.cyan.bold('Creating optimized production build...')); 25 | console.log(); 26 | 27 | webpack(config, (err, stats) => { 28 | if (err) { 29 | console.log(chalk.red.bold('Failed to create a production build!')); 30 | console.log(chalk.red(err.message || err)); 31 | process.exit(1); 32 | } 33 | 34 | if (stats.compilation.errors && stats.compilation.errors.length) { 35 | console.log(chalk.red.bold('Failed to create a production build!')); 36 | stats.compilation.errors.forEach(err => console.log(chalk.red(err.message || err))); 37 | process.exit(1); 38 | } 39 | 40 | const jsonStats = stats.toJson(); 41 | 42 | console.log('Assets:'); 43 | const assets = jsonStats.assets.slice(); 44 | assets.sort((a, b) => b.size - a.size); 45 | assets.forEach(asset => { 46 | let sizeLabel = formatSize(asset.size); 47 | const leftPadding = ' '.repeat(Math.max(0, 8 - sizeLabel.length)); 48 | sizeLabel = leftPadding + sizeLabel; 49 | console.log('', chalk.yellow(sizeLabel), asset.name); 50 | }); 51 | console.log(); 52 | 53 | const seconds = jsonStats.time / 1000; 54 | console.log('Duration: ' + seconds.toFixed(2) + 's'); 55 | console.log(); 56 | 57 | console.log(chalk.green.bold('Compiled successfully!')); 58 | }); 59 | } 60 | 61 | build(); 62 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | be.i8c.codequality.sonar.plugins.sag.webmethods.flow 5 | sonar-flow-plugin-sslr 6 | 0.1 7 | Flow :: Plugin :: SSLR 8 | 9 | 5.4 10 | 1.21 11 | 2.6.1 12 | 4.12 13 | 3.5.1 14 | 15 | 16 | 17 | org.sonarsource.sslr 18 | sslr-core 19 | ${sslr.version} 20 | 21 | 22 | org.sonarsource.sslr-squid-bridge 23 | sslr-squid-bridge 24 | ${sslr.squid.version} 25 | 26 | 27 | ch.qos.logback 28 | logback-classic 29 | runtime 30 | 0.9.1 31 | 32 | 33 | junit 34 | junit 35 | test 36 | ${junit.version} 37 | 38 | 39 | 40 | 41 | 42 | 43 | maven-compiler-plugin 44 | ${maven.plugin.version} 45 | 46 | 47 | default-compile 48 | compile 49 | 50 | compile 51 | 52 | 53 | 54 | 55 | 1.8 56 | 1.8 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/DEVELOPMENT.md: -------------------------------------------------------------------------------- 1 | ## DEVELOPMENT GUIDE 2 | 3 | The project consits of 3 parts: 4 | 5 | ### sonar-flow-plugin 6 | 7 | The main code which is the actual plugin. It is dependant on the sslr flow parser. 8 | 9 | ### sonar-flow-plugin-sslr 10 | 11 | The code which contains the sslr flow parser. It contains the grammar definition of the flow language. 12 | 13 | ### sonar-flow-plugin-sslr-toolkit 14 | 15 | The toolkit is a graphical tool which helps in visualizing the sslr parsing. 16 | 17 | ## SSLR Flow parsing 18 | 19 | SonarSource Language Recognizer ([SSLR](http://docs.sonarqube.org/display/DEV/SSLR)) is a framework which provides a means to parse your code into an Abstract Syntax Tree (AST). The AST is a tree structure of nodes. 20 | 21 | ![sslr architecture](assets/sslr.png) 22 | 23 | The FlowParser will use the FlowLexer. Normally a lexer has many channels to read many types of lines. Since we're reading a xml file, we're using only one channel: SaxChannel. The SaxChannel will consume the whole file and the Sax FlowContentHandler will create the AST nodes. 24 | 25 | The output from the FlowLexer will be pseudo flow, pseudo xml: 26 | 27 | START_FLOW 28 | START_SEQUENCE 29 | ... 30 | STOP_SEQUENCE 31 | STOP_FLOW 32 | 33 | Next the Grammar steps in combining these AST nodes into higher level GrammarRuleKeys (which is a superset of AST node). So once the parser has finished building the grammar you end up with a tree of GrammarRuleKeys: 34 | 35 | FLOW 36 | SEQUENCE 37 | ATTRIBUTES 38 | ... 39 | 40 | ## Sonar flow plugin 41 | 42 | The sonar flow plugin makes use of the [sonar plugin capabilities](http://docs.sonarqube.org/display/DEV/Coding+a+Plugin). It contains identifiers for the sonar runtime components (e.g. scanner) to use its code to parse source code. It also contains the rules that can be added to quality profiles and that can trigger issues. 43 | 44 | ![flow plugin](assets/plugin.png) 45 | 46 | ### Visitors and rules 47 | 48 | Visitors are listeners that are invoked when the parser create an AST node for which the visitor is listening. Visitors allow you to buil up metrics, such as counting the number of invokes or map steps. 49 | A special kind of visitors are rules. These visitors can create violations. 50 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | be.i8c.codequality.sonar.plugins.sag.webmethods.flow 5 | sonar-flow-plugin-sslr 6 | 1.0 7 | Flow :: Plugin :: SSLR 8 | 9 | 6.6 10 | 1.22 11 | 2.6.1 12 | 4.12 13 | 1.5.6 14 | 0.9.1 15 | 2.6 16 | 17 | 18 | 19 | org.sonarsource.sslr 20 | sslr-core 21 | ${sonar.sslrVersion} 22 | 23 | 24 | org.sonarsource.sslr-squid-bridge 25 | sslr-squid-bridge 26 | ${sonar.sslrSquidVersion} 27 | 28 | 29 | ch.qos.logback 30 | logback-classic 31 | runtime 32 | ${logback.version} 33 | 34 | 35 | junit 36 | junit 37 | test 38 | ${junit.version} 39 | 40 | 41 | 42 | 43 | 44 | 45 | maven-compiler-plugin 46 | 3.5.1 47 | 48 | 49 | default-compile 50 | compile 51 | 52 | compile 53 | 54 | 55 | 56 | 57 | 1.8 58 | 1.8 59 | 60 | 61 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/squid/NodeAstScannerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.NodeAstScanner; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.SimpleMetricVisitor; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 26 | 27 | import com.sonar.sslr.api.Grammar; 28 | 29 | import java.io.File; 30 | import java.util.ArrayList; 31 | import java.util.List; 32 | 33 | import org.junit.Test; 34 | import org.slf4j.Logger; 35 | import org.slf4j.LoggerFactory; 36 | import org.sonar.squidbridge.SquidAstVisitor; 37 | 38 | public class NodeAstScannerTest { 39 | 40 | static final Logger logger = LoggerFactory.getLogger(NodeAstScannerTest.class); 41 | 42 | File nodeFile = new File( 43 | "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/flows/subProcess/node.ndf"); 44 | 45 | @Test 46 | public void scanFile() { 47 | logger.debug("Scanning file"); 48 | List> metrics = new ArrayList>(); 49 | metrics.add(new SimpleMetricVisitor()); 50 | List checks = new ArrayList(); 51 | NodeAstScanner.scanSingleFile(nodeFile, checks, metrics); 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/ws/sources/FlowWebWs.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.ws.sources; 22 | 23 | import org.sonar.api.server.ws.WebService; 24 | 25 | /** 26 | * Webservice that returns flow as graphical HTML. 27 | * 28 | * @author DEWANST 29 | * 30 | */ 31 | public class FlowWebWs implements WebService { 32 | 33 | private FlowActionHandler flowActionHandler; 34 | 35 | @Override 36 | public void define(Context context) { 37 | NewController controller = context.createController("api/flowsources").setSince("1.0") 38 | .setDescription("Get details on flow files."); 39 | 40 | flowActionHandler = new FlowActionHandler(context); 41 | 42 | WebService.NewAction action = controller.createAction("flow") 43 | .setDescription( 44 | "Get source code as flow html. Require 'See Source Code' permission on file") 45 | .setSince("1.0").setHandler(flowActionHandler); 46 | 47 | action.createParam("key").setRequired(true).setDescription("File key") 48 | .setExampleValue("my_project:src/foo/node.xml"); 49 | action.createParam("type").setRequired(true) 50 | .setDescription("output type, could be json or html") 51 | .setPossibleValues("json","html"); 52 | action.createParam("full").setPossibleValues("true","false") 53 | .setRequired(false).setDescription("Output complete html page or only body contents"); 54 | action.createParam("branch").setInternal(true); 55 | 56 | controller.done(); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/FlowLinesOfCodeVisitorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.metric.FlowMetric; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.FlowAstScanner; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 28 | 29 | import com.sonar.sslr.api.Grammar; 30 | 31 | import java.io.File; 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | import org.junit.Test; 36 | import org.slf4j.Logger; 37 | import org.slf4j.LoggerFactory; 38 | import org.sonar.squidbridge.SquidAstVisitor; 39 | import org.sonar.squidbridge.api.SourceFile; 40 | 41 | public class FlowLinesOfCodeVisitorTest { 42 | 43 | static final Logger logger = LoggerFactory.getLogger(FlowLinesOfCodeVisitorTest.class); 44 | 45 | @Test 46 | public void linesOfCodeTest() { 47 | logger.debug("Scanning file"); 48 | List> metrics = new ArrayList>(); 49 | List checks = new ArrayList(); 50 | 51 | SourceFile sfCorrect = FlowAstScanner.scanSingleFile(new File( 52 | "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest" 53 | + "/pub/checkLinesOfCode/flow.xml"), 54 | checks, metrics); 55 | int lines = (int) sfCorrect.getDouble(FlowMetric.LINES_OF_CODE); 56 | assertEquals(13, lines); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr-toolkit/pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | be.i8c.sonar.plugins.sag.webmethods 5 | sonar-flow-plugin-sslr-toolkit 6 | 0.0.1-SNAPSHOT 7 | Flow :: Plugin :: SSLR :: toolkit 8 | 9 | 0.5 10 | 6.6 11 | 1.22 12 | 2.6.1 13 | 4.12 14 | 1.5.6 15 | 0.9.1 16 | 2.6 17 | 18 | 19 | 20 | org.sonarsource.sslr 21 | sslr-toolkit 22 | ${sonar.sslrVersion} 23 | 24 | 25 | be.i8c.codequality.sonar.plugins.sag.webmethods.flow 26 | sonar-flow-plugin 27 | ${i8c.flowPLuginVersion} 28 | compile 29 | 30 | 31 | org.slf4j 32 | slf4j-api 33 | ${slf4j.version} 34 | 35 | 36 | org.slf4j 37 | slf4j-simple 38 | ${slf4j.version} 39 | 40 | 41 | junit 42 | junit 43 | test 44 | ${junit.version} 45 | 46 | 47 | 48 | 49 | 50 | 51 | maven-compiler-plugin 52 | 3.5.1 53 | 54 | 55 | default-compile 56 | compile 57 | 58 | compile 59 | 60 | 61 | 62 | 63 | 1.8 64 | 1.8 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/FlowLinesOfCodeVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.FlowGrammar; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.type.FlowVisitor; 25 | 26 | import com.sonar.sslr.api.AstNode; 27 | import com.sonar.sslr.api.Grammar; 28 | 29 | import org.sonar.squidbridge.measures.MetricDef; 30 | 31 | /** 32 | * This visitor counts the lines of flow code 33 | * (SEQUENCE, INVOKE, BRANCH, MAP, LOOP and EXIT) 34 | * and stores it in the metric that is given on initialization. 35 | * 36 | * @author DEWANST 37 | * 38 | * @param 39 | * Grammar on which it applies 40 | */ 41 | public class FlowLinesOfCodeVisitor extends FlowVisitor { 42 | 43 | private final MetricDef metric; 44 | 45 | public FlowLinesOfCodeVisitor(MetricDef metric) { 46 | this.metric = metric; 47 | } 48 | 49 | @Override 50 | public void init() { 51 | subscribeTo(FlowGrammar.SEQUENCE, FlowGrammar.INVOKE, FlowGrammar.BRANCH, FlowGrammar.MAP, 52 | FlowGrammar.LOOP, FlowGrammar.EXIT); 53 | } 54 | 55 | @Override 56 | public void visitNode(AstNode astNode) { 57 | if (astNode.getType().equals(FlowGrammar.MAP) 58 | && (astNode.getParent().getType().equals(FlowGrammar.INVOKE) 59 | || astNode.getParent().getType().equals(FlowGrammar.MAPINVOKE))) { 60 | return; 61 | } else { 62 | getContext().peekSourceCode().add(metric, 1); 63 | } 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/squid/FlowAstScannerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.FlowAstScanner; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.SimpleMetricVisitor; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.CheckList; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 27 | 28 | import com.sonar.sslr.api.Grammar; 29 | 30 | import java.io.File; 31 | import java.util.ArrayList; 32 | import java.util.List; 33 | 34 | import org.junit.Test; 35 | import org.slf4j.Logger; 36 | import org.slf4j.LoggerFactory; 37 | import org.sonar.squidbridge.SquidAstVisitor; 38 | 39 | public class FlowAstScannerTest { 40 | 41 | static final Logger logger = LoggerFactory.getLogger(FlowAstScannerTest.class); 42 | 43 | @Test 44 | public void debug() { 45 | List> checks = CheckList.getChecks(); 46 | for (Class check : checks) { 47 | logger.debug(check.toString()); 48 | } 49 | } 50 | 51 | @Test 52 | public void gitFolderTest() { 53 | logger.debug("Scanning file"); 54 | List> metrics = new ArrayList>(); 55 | metrics.add(new SimpleMetricVisitor()); 56 | List checks = new ArrayList(); 57 | FlowAstScanner.scanSingleFile(new File("src/test/resources/WmTestPackage/.gitx/someFile"), checks, 58 | metrics); 59 | 60 | } 61 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "custom-example", 3 | "version": "0.0.1", 4 | "devDependencies": { 5 | "autoprefixer": "6.2.2", 6 | "babel-core": "6.14.0", 7 | "babel-jest": "18.0.0", 8 | "babel-jest": "18.0.0", 9 | "babel-loader": "6.2.5", 10 | "babel-preset-react-app": "0.2.1", 11 | "cross-env": "2.0.0", 12 | "cross-spawn": "4.0.0", 13 | "css-loader": "0.23.1", 14 | "detect-port": "1.0.0", 15 | "dotenv": "2.0.0", 16 | "enzyme": "2.6.0", 17 | "enzyme-to-json": "1.4.5", 18 | "expose-loader": "0.7.1", 19 | "express": "4.13.4", 20 | "express-http-proxy": "0.6.0", 21 | "filesize": "3.3.0", 22 | "find-cache-dir": "0.1.1", 23 | "gzip-size": "3.0.0", 24 | "imports-loader": "0.6.5", 25 | "jest": "18.0.0", 26 | "json-loader": "0.5.4", 27 | "path-exists": "2.1.0", 28 | "postcss-loader": "0.8.0", 29 | "prettier": "0.22.0", 30 | "react": "15.6.2", 31 | "react-addons-shallow-compare": "15.6.2", 32 | "react-addons-test-utils": "15.6.2", 33 | "react-dev-utils": "0.2.1", 34 | "react-dom": "15.6.2", 35 | "react-router": "3.0.2", 36 | "react-transform-hmr": "1.0.4", 37 | "recursive-readdir": "2.1.0", 38 | "rimraf": "2.5.4", 39 | "script-loader": "0.6.1", 40 | "strip-ansi": "3.0.1", 41 | "style-loader": "0.13.0", 42 | "webpack": "1.13.2", 43 | "webpack-dev-server": "1.16.1" 44 | }, 45 | "scripts": { 46 | "build": "node scripts/build.js", 47 | "start": "node scripts/start.js", 48 | "test": "node scripts/test.js" 49 | }, 50 | "babel": { 51 | "presets": [ 52 | "react-app" 53 | ] 54 | }, 55 | "jest": { 56 | "coverageDirectory": "/target/coverage", 57 | "coveragePathIgnorePatterns": [ 58 | "/node_modules", 59 | "/tests" 60 | ], 61 | "moduleFileExtensions": [ 62 | "jsx", 63 | "js", 64 | "json" 65 | ], 66 | "moduleNameMapper": { 67 | "^.+\\.(hbs|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/conf/jest/FileStub.js", 68 | "^.+\\.css$": "/conf/jest/CSSStub.js" 69 | }, 70 | "setupFiles": [ 71 | "/conf/jest/SetupTestEnvironment.js" 72 | ], 73 | "snapshotSerializers": [ 74 | "enzyme-to-json/serializer" 75 | ], 76 | "testPathIgnorePatterns": [ 77 | "/node_modules", 78 | "/scripts", 79 | "/conf" 80 | ] 81 | } 82 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/type/AnnotationUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type; 5 | 6 | import java.lang.annotation.Annotation; 7 | import java.util.List; 8 | 9 | import org.apache.commons.lang.ClassUtils; 10 | 11 | /** 12 | * @author DEWANST 13 | * 14 | */ 15 | public class AnnotationUtils { 16 | 17 | /** 18 | * 19 | */ 20 | public AnnotationUtils() { 21 | } 22 | 23 | /** 24 | * Get the annotation of a Class 25 | * 26 | * @param objectOrClass 27 | * @param annotationClass 28 | * @return 29 | */ 30 | @SuppressWarnings("unchecked") 31 | public static A getAnnotation(Object objectOrClass, 32 | Class annotationClass) { 33 | Class initialClass = objectOrClass instanceof Class ? (Class) objectOrClass 34 | : objectOrClass.getClass(); 35 | 36 | for (Class aClass = initialClass; aClass != null; aClass = aClass.getSuperclass()) { 37 | A result = aClass.getAnnotation(annotationClass); 38 | if (result != null) { 39 | return result; 40 | } 41 | } 42 | 43 | for (Class anInterface : (List>) ClassUtils.getAllInterfaces(initialClass)) { 44 | A result = anInterface.getAnnotation(annotationClass); 45 | if (result != null) { 46 | return result; 47 | } 48 | } 49 | return null; 50 | } 51 | 52 | /** 53 | * Get the list of annotations of a Class 54 | * @param 55 | * 56 | * @param objectOrClass 57 | * @param annotationClass 58 | * @return 59 | */ 60 | @SuppressWarnings("unchecked") 61 | public static A[] getAnnotations(Object objectOrClass, 62 | Class annotationClass) { 63 | Class initialClass = objectOrClass instanceof Class ? (Class) objectOrClass 64 | : objectOrClass.getClass(); 65 | 66 | for (Class aClass = initialClass; aClass != null; aClass = aClass.getSuperclass()) { 67 | A[] result = aClass.getAnnotationsByType(annotationClass); 68 | if (result != null) { 69 | return result; 70 | } 71 | } 72 | 73 | for (Class anInterface : (List>) ClassUtils.getAllInterfaces(initialClass)) { 74 | A[] result = anInterface.getAnnotationsByType(annotationClass); 75 | if (result != null) { 76 | return result; 77 | } 78 | } 79 | return null; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/bin/src/test/resources/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | false 11 | record 12 | 0 13 | true 14 | false 15 | false 16 | 17 | 18 | true 19 | 20 | 21 | record 22 | false 23 | record 24 | 0 25 | true 26 | false 27 | false 28 | 29 | 30 | true 31 | 32 | 33 | 34 | yes 35 | no 36 | no 37 | 15 38 | 1 39 | off 40 | no 41 | $null 42 | 43 | no 44 | 0 45 | 0 46 | none 47 | none 48 | 0 49 | 50 | 51 | 52 | 0 53 | false 54 | false 55 | true 56 | 57 | 1 58 | 59 | true 60 | false 61 | 62 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/test/resources/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | false 11 | record 12 | 0 13 | true 14 | false 15 | false 16 | 17 | 18 | true 19 | 20 | 21 | record 22 | false 23 | record 24 | 0 25 | true 26 | false 27 | false 28 | 29 | 30 | true 31 | 32 | 33 | 34 | yes 35 | no 36 | no 37 | 15 38 | 1 39 | off 40 | no 41 | $null 42 | 43 | no 44 | 0 45 | 0 46 | none 47 | none 48 | 0 49 | 50 | 51 | 52 | 0 53 | false 54 | false 55 | true 56 | 57 | 1 58 | 59 | true 60 | false 61 | 62 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/FlowPlugin.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.rule.FlowRulesDefinition; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.rule.FlowSquidSensor; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.settings.FlowLanguageProperties; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.web.FlowWebPageDefinition; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.ws.sources.FlowWebWs; 28 | 29 | import org.sonar.api.Plugin; 30 | import org.sonar.api.internal.google.common.collect.ImmutableList; 31 | 32 | /** 33 | * This class represents the Flow plugin. 34 | * It holds references (extensions) to the FlowLanguage, its properties, 35 | * the sensor and rule definitions. 36 | * @author DEWANST 37 | */ 38 | public class FlowPlugin implements Plugin { 39 | 40 | @Override 41 | public void define(Context context) { 42 | ImmutableList.Builder builder = ImmutableList.builder(); 43 | 44 | // add language with default profile 45 | builder.add(FlowLanguage.class, FlowQualityProfile.class); 46 | // add language settings 47 | builder.addAll(FlowLanguageProperties.getProperties()); 48 | 49 | // add measures 50 | 51 | // add rules 52 | builder.add(FlowRulesDefinition.class, FlowSquidSensor.class); 53 | // add rules properties 54 | builder.addAll(FlowRulesDefinition.getProperties()); 55 | // add web extensions 56 | builder.add(FlowWebPageDefinition.class); 57 | builder.add(FlowWebWs.class); 58 | 59 | context.addExtensions(builder.build()); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/SimpleMetricVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.metric.FlowMetric; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.FlowGrammar; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.type.FlowVisitor; 26 | 27 | import com.sonar.sslr.api.AstNode; 28 | import com.sonar.sslr.api.Grammar; 29 | 30 | /** 31 | * This visitor counts the individual flow components 32 | * (SEQUENCE, INVOKE, BRANCH, MAP, LOOP and EXIT) 33 | * and stores it in their corresponding FlowMetric. 34 | * 35 | * @author DEWANST 36 | * 37 | * @param 38 | * Grammar on which it applies 39 | */ 40 | public class SimpleMetricVisitor extends FlowVisitor { 41 | @Override 42 | public void init() { 43 | subscribeTo(FlowGrammar.INVOKE, FlowGrammar.MAP, FlowGrammar.SEQUENCE, FlowGrammar.LOOP, 44 | FlowGrammar.COMMENT); 45 | } 46 | 47 | @Override 48 | public void visitNode(AstNode astNode) { 49 | if (astNode.is(FlowGrammar.INVOKE)) { 50 | getContext().peekSourceCode().add(FlowMetric.INVOKES, 1); 51 | } else if (astNode.is(FlowGrammar.MAP)) { 52 | getContext().peekSourceCode().add(FlowMetric.MAPS, 1); 53 | } else if (astNode.is(FlowGrammar.SEQUENCE)) { 54 | getContext().peekSourceCode().add(FlowMetric.SEQUENCES, 1); 55 | } else if (astNode.is(FlowGrammar.LOOP)) { 56 | getContext().peekSourceCode().add(FlowMetric.LOOPS, 1); 57 | } else if (astNode.is(FlowGrammar.COMMENT)) { 58 | getContext().peekSourceCode().add(FlowMetric.COMMENT_LINES, 1); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkLinesOfCode/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | false 11 | record 12 | 0 13 | true 14 | false 15 | false 16 | 17 | 18 | true 19 | 20 | 21 | record 22 | false 23 | record 24 | 0 25 | true 26 | false 27 | false 28 | 29 | 30 | true 31 | 32 | 33 | 34 | yes 35 | no 36 | no 37 | 15 38 | 1 39 | off 40 | no 41 | $null 42 | 43 | no 44 | 0 45 | 0 46 | none 47 | none 48 | 0 49 | 50 | 51 | 52 | 0 53 | false 54 | false 55 | true 56 | 57 | 1 58 | 59 | true 60 | false 61 | 62 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/FlowParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr; 22 | 23 | import com.sonar.sslr.api.AstNode; 24 | import com.sonar.sslr.api.Grammar; 25 | import com.sonar.sslr.impl.Parser; 26 | 27 | import java.io.File; 28 | import java.nio.charset.Charset; 29 | import org.apache.commons.io.FileUtils; 30 | 31 | /** 32 | * Parser for flow files. 33 | * @author DEWANST 34 | * 35 | */ 36 | public class FlowParser { 37 | private static final Parser P = FlowParser.create(); 38 | private static FlowConfiguration conf; 39 | 40 | private FlowParser() { 41 | } 42 | 43 | public static Parser create(FlowConfiguration conf) { 44 | FlowParser.conf = conf; 45 | return Parser.builder(FlowGrammar.create()).withLexer(FlowLexer.create(conf)).build(); 46 | } 47 | 48 | /** 49 | * Creates this parser. 50 | * @return 51 | */ 52 | public static Parser create() { 53 | FlowParser.conf = new FlowConfiguration(Charset.defaultCharset()); 54 | return Parser.builder(FlowGrammar.create()).withLexer(FlowLexer.create(FlowParser.conf)) 55 | .build(); 56 | } 57 | 58 | /** 59 | * Parses a file and returns the AstNode tree. 60 | * @param filePath 61 | * path to the file. 62 | * @return 63 | */ 64 | public static AstNode parseFile(String filePath) { 65 | AstNode astNode; 66 | File file = FileUtils.getFile(filePath); 67 | if (file == null || !file.exists()) { 68 | throw new AssertionError("The file \"" + filePath + "\" does not exist."); 69 | } 70 | astNode = P.parse(file); 71 | return astNode; 72 | } 73 | 74 | public static AstNode parseString(String source) { 75 | return P.parse(source); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/NodeParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr; 22 | 23 | import com.sonar.sslr.api.AstNode; 24 | import com.sonar.sslr.api.Grammar; 25 | import com.sonar.sslr.impl.Parser; 26 | 27 | import java.io.File; 28 | import java.nio.charset.Charset; 29 | import org.apache.commons.io.FileUtils; 30 | 31 | /** 32 | * Parser for node files. 33 | * @author DEWANST 34 | * 35 | */ 36 | public class NodeParser { 37 | private static final Parser P = NodeParser.create(); 38 | private static FlowConfiguration conf; 39 | 40 | private NodeParser() { 41 | } 42 | 43 | public static Parser create(FlowConfiguration conf) { 44 | NodeParser.conf = conf; 45 | return Parser.builder(NodeGrammar.create()).withLexer(FlowLexer.create(conf)).build(); 46 | } 47 | 48 | /** 49 | * Creates this parser. 50 | * @return 51 | */ 52 | public static Parser create() { 53 | NodeParser.conf = new FlowConfiguration(Charset.defaultCharset()); 54 | return Parser.builder(NodeGrammar.create()).withLexer(FlowLexer.create(NodeParser.conf)) 55 | .build(); 56 | } 57 | 58 | /** 59 | * Parses a file and returns the AstNode tree. 60 | * @param filePath 61 | * path to the file. 62 | * @return 63 | */ 64 | public static AstNode parseFile(String filePath) { 65 | AstNode astNode; 66 | File file = FileUtils.getFile(filePath); 67 | if (file == null || !file.exists()) { 68 | throw new AssertionError("The file \"" + filePath + "\" does not exist."); 69 | } 70 | astNode = P.parse(file); 71 | return astNode; 72 | } 73 | 74 | public static AstNode parseString(String source) { 75 | return P.parse(source); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/CheckList.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 24 | 25 | import com.google.common.collect.ImmutableList; 26 | 27 | import java.util.List; 28 | 29 | /** 30 | * Helper class that holds all checks. 31 | * @author DEWANST 32 | * 33 | */ 34 | public class CheckList { 35 | 36 | /** 37 | * Returns all checks. 38 | * @return 39 | */ 40 | public static List> getChecks() { 41 | return ImmutableList.>builder().addAll(getFlowChecks()) 42 | .addAll(getTopLevelChecks()).addAll(getNodeChecks()).build(); 43 | } 44 | 45 | /** 46 | * Returns checks that apply to nodes. 47 | * @return 48 | */ 49 | public static List> getNodeChecks() { 50 | return ImmutableList.>builder().add(InterfaceCommentsCheck.class) 51 | .build(); 52 | } 53 | 54 | /** 55 | * Returns checks that apply to top-level flows. 56 | * @return 57 | */ 58 | public static List> getTopLevelChecks() { 59 | return ImmutableList.>builder().add(TryCatchCheck.class).build(); 60 | } 61 | 62 | /** 63 | * Returns checks that apply to flows. 64 | * @return 65 | */ 66 | public static List> getFlowChecks() { 67 | return ImmutableList.>builder().add(QualifiedNameCheck.class) 68 | .add(SavePipelineCheck.class).add(DisabledCheck.class).add(ExitCheck.class) 69 | .add(EmptyMapCheck.class).add(BranchPropertiesCheck.class).add(EmptyFlowCheck.class) 70 | .build(); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/FlowCommentLinesVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.FlowGrammar; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types.FlowTypes; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.type.FlowVisitor; 26 | 27 | import com.sonar.sslr.api.AstNode; 28 | import com.sonar.sslr.api.Grammar; 29 | 30 | import org.sonar.squidbridge.measures.MetricDef; 31 | 32 | /** 33 | * This visitor counts the lines of flow code that contains comments (SEQUENCE, INVOKE, BRANCH, MAP, 34 | * LOOP and EXIT) and stores it in the metric that is given on initialization. 35 | * 36 | * @author DEWANST 37 | * 38 | * @param 39 | * Grammar on which it applies 40 | */ 41 | public class FlowCommentLinesVisitor extends FlowVisitor { 42 | 43 | private final MetricDef metric; 44 | 45 | public FlowCommentLinesVisitor(MetricDef metric) { 46 | this.metric = metric; 47 | } 48 | 49 | @Override 50 | public void init() { 51 | subscribeTo(FlowGrammar.COMMENT); 52 | } 53 | 54 | @Override 55 | public void visitNode(AstNode astNode) { 56 | 57 | if (astNode.getParent().getType().equals(FlowGrammar.MAP)) { 58 | AstNode map = astNode.getParent(); 59 | if (map.hasParent(FlowGrammar.INVOKE) || map.hasParent(FlowGrammar.MAPINVOKE)) { 60 | return; 61 | } 62 | } else { 63 | if (astNode.hasDirectChildren(FlowTypes.ELEMENT_VALUE)) { 64 | AstNode value = astNode.getFirstChild(FlowTypes.ELEMENT_VALUE); 65 | if (!value.getTokenOriginalValue().isEmpty()) { 66 | getContext().peekSourceCode().add(metric, 1); 67 | } 68 | } 69 | } 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/ExitCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.FlowAstScanner; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.SimpleMetricVisitor; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.ExitCheck; 28 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 29 | 30 | import com.sonar.sslr.api.Grammar; 31 | 32 | import java.io.File; 33 | import java.util.ArrayList; 34 | import java.util.List; 35 | 36 | import org.junit.Test; 37 | import org.slf4j.Logger; 38 | import org.slf4j.LoggerFactory; 39 | import org.sonar.squidbridge.SquidAstVisitor; 40 | import org.sonar.squidbridge.api.CheckMessage; 41 | import org.sonar.squidbridge.api.SourceFile; 42 | 43 | public class ExitCheckTest { 44 | 45 | static final Logger logger = LoggerFactory.getLogger(ExitCheckTest.class); 46 | 47 | @Test 48 | public void exitCheck() { 49 | List> metrics = new ArrayList>(); 50 | metrics.add(new SimpleMetricVisitor()); 51 | List checks = new ArrayList(); 52 | checks.add(new ExitCheck()); 53 | 54 | String invalidPath = "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest" 55 | + "/pub/checkExitStepInvalid/flow.xml"; 56 | 57 | SourceFile sfViolation = FlowAstScanner.scanSingleFile(new File(invalidPath), checks, metrics); 58 | List violationMessages = new ArrayList( 59 | sfViolation.getCheckMessages()); 60 | assertEquals(2, violationMessages.size()); 61 | // TODO check both violation messages 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/js/components/FlowIssueItem.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | 3 | export default class FlowIssueItem extends React.PureComponent { 4 | 5 | constructor(props) { 6 | super(props); 7 | // props.issue 8 | // props.onSelection 9 | // props.isSelected 10 | this.handleClick = this.handleClick.bind(this, this.props); 11 | } 12 | 13 | handleClick(issue, e) { 14 | this.props.onSelection(issue); 15 | } 16 | 17 | render() { 18 | const bug = ; 19 | const codesmell = ; 20 | const vulnerability = ; 21 | return ( 22 |
    23 |
    {this.props.message}
    24 |
    {this.props.type.toLowerCase()=="bug" ? bug : (this.props.type.toLowerCase()=="codesmell" ? codesmell : (this.props.type.toLowerCase()=="vulnerability" ? vulnerability : ""))}{this.props.type}{this.props.severity}
    25 |
    26 | ); 27 | } 28 | } -------------------------------------------------------------------------------- /sonar-flow-plugin-sslr/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/sslr/channels/SaxChannel.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.channels; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.channels.sax.FlowContentHandler; 24 | 25 | import com.sonar.sslr.api.Token; 26 | import com.sonar.sslr.impl.Lexer; 27 | 28 | import java.io.ByteArrayInputStream; 29 | 30 | import javax.xml.parsers.SAXParser; 31 | import javax.xml.parsers.SAXParserFactory; 32 | 33 | import org.sonar.sslr.channel.Channel; 34 | import org.sonar.sslr.channel.CodeReader; 35 | import org.xml.sax.InputSource; 36 | import org.xml.sax.XMLReader; 37 | 38 | /** 39 | * Channel that implemnts the SAX Parser. 40 | * It parses the file in one go. 41 | * @author DEWANST 42 | * 43 | */ 44 | public class SaxChannel extends Channel { 45 | 46 | private final Token.Builder tokenBuilder = Token.builder(); 47 | public static final char BOM_CHAR = '\ufeff'; 48 | 49 | @Override 50 | public boolean consume(CodeReader code, Lexer lex) { 51 | SAXParserFactory spf = SAXParserFactory.newInstance(); 52 | spf.setNamespaceAware(true); 53 | SAXParser saxParser; 54 | try { 55 | if (code.peek(1).equals(BOM_CHAR)) { 56 | // consume the BOM 57 | code.pop(); 58 | } 59 | saxParser = spf.newSAXParser(); 60 | XMLReader xmlReader = saxParser.getXMLReader(); 61 | xmlReader.setContentHandler(new FlowContentHandler(lex, tokenBuilder)); 62 | xmlReader.parse(new InputSource( 63 | new ByteArrayInputStream(new StringBuilder(code).toString().getBytes("UTF-8")))); 64 | int length = code.length(); 65 | for (int j = 0; j < length; j++) { 66 | code.pop(); 67 | } 68 | return true; 69 | } catch (Exception e) { 70 | e.printStackTrace(); 71 | throw new Error(e); 72 | // return false; 73 | } 74 | } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkDisabledInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkEmptyMapInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkExitStepInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkTryCatchInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkTryCatchValid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkAllDebugFlowsInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkBranchPropertiesValid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkSavePipelineInvalid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/FlowDependencyVisitor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.metric.FlowMetric; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.FlowGrammar; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types.FlowAttTypes; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.type.FlowVisitor; 27 | 28 | import com.sonar.sslr.api.AstNode; 29 | import com.sonar.sslr.api.Grammar; 30 | 31 | import java.util.ArrayList; 32 | 33 | import org.slf4j.Logger; 34 | import org.slf4j.LoggerFactory; 35 | 36 | 37 | /** 38 | * This visitor keeps a list of flow services it depends on. 39 | * These services are stored in the FlowMetric.DEPENDENCIES 40 | * 41 | * @author DEWANST 42 | * 43 | * @param 44 | * Grammar on which it applies 45 | */ 46 | public class FlowDependencyVisitor extends FlowVisitor { 47 | 48 | static final Logger logger = LoggerFactory.getLogger(FlowDependencyVisitor.class); 49 | 50 | public FlowDependencyVisitor() { 51 | } 52 | 53 | @Override 54 | public void init() { 55 | subscribeTo(FlowGrammar.INVOKE); 56 | } 57 | 58 | @Override 59 | public void visitNode(AstNode astNode) { 60 | String service = astNode.getFirstChild(FlowGrammar.ATTRIBUTES) 61 | .getFirstChild(FlowAttTypes.SERVICE).getTokenOriginalValue(); 62 | @SuppressWarnings("unchecked") 63 | ArrayList dependencies = (ArrayList) getContext().peekSourceCode() 64 | .getData(FlowMetric.DEPENDENCIES); 65 | if (dependencies == null) { 66 | dependencies = new ArrayList(); 67 | } 68 | dependencies.add(service); 69 | getContext().peekSourceCode().addData(FlowMetric.DEPENDENCIES, dependencies); 70 | logger.debug("**** Dependency found: " + service); 71 | } 72 | 73 | } 74 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkBranchPropertiesInvalidA/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkBranchPropertiesInvalidB/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | unknown 11 | false 12 | record 13 | 0 14 | IData 15 | true 16 | false 17 | false 18 | 19 | 20 | true 21 | 22 | 23 | record 24 | unknown 25 | false 26 | record 27 | 0 28 | IData 29 | true 30 | false 31 | false 32 | 33 | 34 | true 35 | 36 | 37 | 38 | yes 39 | no 40 | no 41 | 15 42 | 1 43 | off 44 | no 45 | $null 46 | 47 | no 48 | 0 49 | 0 50 | none 51 | none 52 | 0 53 | 54 | 55 | 56 | 0 57 | false 58 | false 59 | true 60 | 61 | 1 62 | 63 | true 64 | false 65 | 66 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/ws/sources/FlowActionHandlerTest.java: -------------------------------------------------------------------------------- 1 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.ws.sources; 2 | 3 | import static org.mockito.Mockito.mock; 4 | 5 | import java.io.ByteArrayOutputStream; 6 | import java.io.InputStream; 7 | import java.io.OutputStream; 8 | 9 | import org.junit.Test; 10 | import org.mockito.Mockito; 11 | import org.mockito.stubbing.Answer; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.sonar.api.internal.apachecommons.io.IOUtils; 15 | import org.sonar.api.server.ws.Request; 16 | import org.sonar.api.server.ws.Request.StringParam; 17 | import org.sonar.api.server.ws.RequestHandler; 18 | import org.sonar.api.server.ws.Response; 19 | import org.sonar.api.server.ws.Response.Stream; 20 | import org.sonar.api.server.ws.WebService.Action; 21 | import org.sonar.api.server.ws.WebService.Context; 22 | import org.sonar.api.server.ws.WebService.Controller; 23 | 24 | public class FlowActionHandlerTest { 25 | 26 | static final Logger logger = LoggerFactory.getLogger(FlowActionHandlerTest.class); 27 | 28 | @Test 29 | public void handleTest() throws Exception { 30 | Context wsContext = mock(Context.class); 31 | Controller wsController = mock(Controller.class); 32 | Action rawAction = mock(Action.class); 33 | RequestHandler rawActionHandler = mock(RequestHandler.class); 34 | Mockito.when(wsContext.controller("api/sources")).thenReturn(wsController); 35 | Mockito.when(wsController.action("raw")).thenReturn(rawAction); 36 | Mockito.when(rawAction.handler()).thenReturn(rawActionHandler); 37 | 38 | Mockito.doAnswer((Answer) invocation -> { 39 | Response response = invocation.getArgument(1); 40 | OutputStream os = response.stream().output(); 41 | InputStream is = this.getClass().getResourceAsStream( 42 | "/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkAllDebugFlowsInvalid/flow.xml"); 43 | IOUtils.copy(is, os); 44 | return null; 45 | }).when(rawActionHandler).handle(Mockito.any(Request.class), Mockito.any(Response.class)); 46 | Request request = mock(Request.class); 47 | StringParam full = mock(StringParam.class); 48 | Mockito.when(full.getValue()).thenReturn("true"); 49 | Mockito.when(request.getParam("full")).thenReturn(full); 50 | Mockito.when(request.mandatoryParam("key")) 51 | .thenReturn("WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkAllDebugFlowsInvalid/flow.xml"); 52 | Mockito.when(request.mandatoryParam("type")) 53 | .thenReturn("html"); 54 | Response response = mock(Response.class); 55 | Stream stream = mock(Stream.class); 56 | OutputStream os = new ByteArrayOutputStream(); 57 | Mockito.when(response.stream()).thenReturn(stream); 58 | Mockito.when(stream.output()).thenReturn(os); 59 | FlowActionHandler fah = new FlowActionHandler(wsContext); 60 | fah.handle(request, response); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/DisabledCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertTrue; 25 | 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.FlowAstScanner; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.SimpleMetricVisitor; 28 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.DisabledCheck; 29 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 30 | 31 | import com.sonar.sslr.api.Grammar; 32 | 33 | import java.io.File; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | import org.junit.Test; 38 | import org.slf4j.Logger; 39 | import org.slf4j.LoggerFactory; 40 | import org.sonar.squidbridge.SquidAstVisitor; 41 | import org.sonar.squidbridge.api.CheckMessage; 42 | import org.sonar.squidbridge.api.SourceFile; 43 | 44 | public class DisabledCheckTest { 45 | 46 | static final Logger logger = LoggerFactory.getLogger(DisabledCheckTest.class); 47 | 48 | 49 | @Test 50 | public void disabledCheck() { 51 | List> metrics = new ArrayList>(); 52 | metrics.add(new SimpleMetricVisitor()); 53 | List checks = new ArrayList(); 54 | checks.add(new DisabledCheck()); 55 | 56 | String invalidPath = "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest" 57 | + "/pub/checkDisabledInvalid/flow.xml"; 58 | String expectedMessage = "Remove disabled code"; 59 | 60 | SourceFile sfViolation = FlowAstScanner.scanSingleFile(new File(invalidPath), checks, metrics); 61 | List violationMessages = new ArrayList( 62 | sfViolation.getCheckMessages()); 63 | assertEquals(1, violationMessages.size()); 64 | assertTrue("Returned check message not as expected", 65 | expectedMessage.equals(violationMessages.get(0).getDefaultMessage())); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/SavePipelineCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertTrue; 25 | 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.FlowAstScanner; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.SimpleMetricVisitor; 28 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.SavePipelineCheck; 29 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 30 | 31 | import com.sonar.sslr.api.Grammar; 32 | 33 | import java.io.File; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | import org.junit.Test; 38 | import org.slf4j.Logger; 39 | import org.slf4j.LoggerFactory; 40 | import org.sonar.squidbridge.SquidAstVisitor; 41 | import org.sonar.squidbridge.api.CheckMessage; 42 | import org.sonar.squidbridge.api.SourceFile; 43 | 44 | public class SavePipelineCheckTest { 45 | 46 | static final Logger logger = LoggerFactory.getLogger(SavePipelineCheckTest.class); 47 | 48 | 49 | @Test 50 | public void savePipelineCheck() { 51 | List> metrics = new ArrayList>(); 52 | metrics.add(new SimpleMetricVisitor()); 53 | List checks = new ArrayList(); 54 | checks.add(new SavePipelineCheck()); 55 | 56 | String invalidPath = "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest" 57 | + "/pub/checkSavePipelineInvalid/flow.xml"; 58 | String expectedMessage = "Remove service pub.flow:savePipeline"; 59 | 60 | SourceFile sfViolation = FlowAstScanner.scanSingleFile(new File(invalidPath), checks, metrics); 61 | List violationMessages = new ArrayList( 62 | sfViolation.getCheckMessages()); 63 | assertEquals(1, violationMessages.size()); 64 | assertTrue("Returned check message not as expected", 65 | expectedMessage.equals(violationMessages.get(0).getDefaultMessage())); 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/EmptyFlowCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | import static org.junit.Assert.assertTrue; 25 | 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.FlowAstScanner; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.SimpleMetricVisitor; 28 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.EmptyFlowCheck; 29 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 30 | 31 | import com.sonar.sslr.api.Grammar; 32 | 33 | import java.io.File; 34 | import java.util.ArrayList; 35 | import java.util.List; 36 | 37 | import org.junit.Test; 38 | import org.slf4j.Logger; 39 | import org.slf4j.LoggerFactory; 40 | import org.sonar.squidbridge.SquidAstVisitor; 41 | import org.sonar.squidbridge.api.CheckMessage; 42 | import org.sonar.squidbridge.api.SourceFile; 43 | 44 | public class EmptyFlowCheckTest { 45 | 46 | static final Logger logger = LoggerFactory.getLogger(EmptyFlowCheckTest.class); 47 | 48 | @Test 49 | public void emptyFlowCheck() { 50 | List> metrics = new ArrayList>(); 51 | metrics.add(new SimpleMetricVisitor()); 52 | List checks = new ArrayList(); 53 | checks.add(new EmptyFlowCheck()); 54 | 55 | String invalidPath = "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest" 56 | + "/pub/checkEmptyFlowInvalid/flow.xml"; 57 | String expectedMessage 58 | = "Service doesn't contain any flow steps. Remove service or add flow steps."; 59 | 60 | SourceFile sfViolation = FlowAstScanner.scanSingleFile(new File(invalidPath), checks, metrics); 61 | List violationMessages = new ArrayList( 62 | sfViolation.getCheckMessages()); 63 | assertEquals(1, violationMessages.size()); 64 | assertTrue("Returned check message not as expected", 65 | expectedMessage.equals(violationMessages.get(0).getDefaultMessage())); 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/FlowCommentLinesVisitorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor; 22 | 23 | import static org.junit.Assert.assertEquals; 24 | 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.metric.FlowMetric; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.squid.FlowAstScanner; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 28 | 29 | import com.sonar.sslr.api.Grammar; 30 | 31 | import java.io.File; 32 | import java.util.ArrayList; 33 | import java.util.List; 34 | 35 | import org.junit.Test; 36 | import org.slf4j.Logger; 37 | import org.slf4j.LoggerFactory; 38 | import org.sonar.squidbridge.SquidAstVisitor; 39 | import org.sonar.squidbridge.api.SourceFile; 40 | 41 | public class FlowCommentLinesVisitorTest { 42 | 43 | static final Logger logger = LoggerFactory.getLogger(FlowCommentLinesVisitorTest.class); 44 | 45 | @Test 46 | public void commentLinesTest() { 47 | logger.debug("Scanning file"); 48 | List> metrics = new ArrayList>(); 49 | List checks = new ArrayList(); 50 | 51 | SourceFile sfCorrect = FlowAstScanner.scanSingleFile(new File( 52 | "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest" 53 | + "/pub/commentLinesVisitor/flow.xml"), 54 | checks, metrics); 55 | int lines = (int) sfCorrect.getDouble(FlowMetric.COMMENT_LINES); 56 | assertEquals(2, lines); 57 | } 58 | 59 | @Test 60 | public void commentLinesTest2() { 61 | logger.debug("Scanning file"); 62 | List> metrics = new ArrayList>(); 63 | metrics.add(new FlowCommentLinesVisitor(FlowMetric.COMMENT_LINES)); 64 | List checks = new ArrayList(); 65 | 66 | SourceFile sfCorrect = FlowAstScanner.scanSingleFile(new File( 67 | "src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest" 68 | + "/pub/commentLinesVisitor2/flow.xml"), 69 | checks, metrics); 70 | int lines = (int) sfCorrect.getDouble(FlowMetric.COMMENT_LINES); 71 | assertEquals(0, lines); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/DisabledCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.FlowGrammar; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types.FlowAttTypes; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheckRuleType; 27 | 28 | import com.sonar.sslr.api.AstNode; 29 | 30 | import org.slf4j.Logger; 31 | import org.slf4j.LoggerFactory; 32 | import org.sonar.api.rules.RuleType; 33 | import org.sonar.check.Priority; 34 | import org.sonar.check.Rule; 35 | import org.sonar.squidbridge.annotations.SqaleConstantRemediation; 36 | 37 | /** 38 | * Checks for disabled code. 39 | * @author DEWANST 40 | * 41 | */ 42 | @Rule(key = "S00003", 43 | name = "No disabled elements should be in code", 44 | priority = Priority.MINOR, 45 | tags = {Tags.DEBUG_CODE, Tags.BAD_PRACTICE }) 46 | @SqaleConstantRemediation("2min") 47 | @FlowCheckRuleType (ruletype = RuleType.CODE_SMELL) 48 | public class DisabledCheck extends FlowCheck { 49 | 50 | static final Logger logger = LoggerFactory.getLogger(DisabledCheck.class); 51 | 52 | @Override 53 | public void init() { 54 | logger.debug("++ Initializing {} ++", this.getClass().getName()); 55 | subscribeTo(FlowGrammar.INVOKE, FlowGrammar.EXIT, FlowGrammar.BRANCH, FlowGrammar.LOOP, 56 | FlowGrammar.MAP, FlowGrammar.RETRY, FlowGrammar.SEQUENCE); 57 | } 58 | 59 | @Override 60 | public void visitNode(AstNode astNode) { 61 | AstNode disabled = astNode.getFirstChild(FlowGrammar.ATTRIBUTES) 62 | .getFirstChild(FlowAttTypes.DISABLED); 63 | if (disabled != null) { 64 | String isDisabled = disabled.getToken().getOriginalValue(); 65 | if (Boolean.valueOf(isDisabled)) { 66 | getContext().createLineViolation(this, "Remove disabled code", astNode); 67 | } 68 | } 69 | } 70 | 71 | @Override 72 | public boolean isFlowCheck() { 73 | return true; 74 | } 75 | 76 | @Override 77 | public boolean isNodeCheck() { 78 | return false; 79 | } 80 | 81 | @Override 82 | public boolean isTopLevelCheck() { 83 | return false; 84 | } 85 | 86 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/EmptyFlowCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.FlowGrammar; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheckRuleType; 26 | 27 | import com.sonar.sslr.api.AstNode; 28 | 29 | import java.util.List; 30 | 31 | import org.slf4j.Logger; 32 | import org.slf4j.LoggerFactory; 33 | import org.sonar.api.rules.RuleType; 34 | import org.sonar.check.Priority; 35 | import org.sonar.check.Rule; 36 | import org.sonar.squidbridge.annotations.SqaleConstantRemediation; 37 | 38 | /** 39 | * Checks for flow services that are empty. 40 | * 41 | * @author DEWANST 42 | * 43 | */ 44 | @Rule(key = "S00008", 45 | name = "Services must contain flow steps.", 46 | priority = Priority.MINOR, 47 | tags = {Tags.DEBUG_CODE, Tags.BAD_PRACTICE }) 48 | @SqaleConstantRemediation("2min") 49 | @FlowCheckRuleType (ruletype = RuleType.CODE_SMELL) 50 | public class EmptyFlowCheck extends FlowCheck { 51 | 52 | static final Logger logger = LoggerFactory.getLogger(EmptyFlowCheck.class); 53 | 54 | @Override 55 | public void init() { 56 | logger.debug("++ Initializing {} ++", this.getClass().getName()); 57 | subscribeTo(FlowGrammar.FLOW); 58 | } 59 | 60 | @Override 61 | public void visitNode(AstNode astNode) { 62 | List flowChildren = astNode.getChildren(); 63 | for (AstNode child : flowChildren) { 64 | if (child.getName().equalsIgnoreCase("CONTENT")) { 65 | List contentChildren = child.getChildren(); 66 | int numberOfSteps = contentChildren.size(); 67 | if (numberOfSteps == 1) { 68 | logger.debug("The service contains {} flow step.", numberOfSteps); 69 | } else if (numberOfSteps == 0) { 70 | getContext().createLineViolation(this, 71 | "Service doesn't contain any flow steps. Remove service or add flow steps.", astNode); 72 | logger.debug("The service contains {} flow steps. Remove this service or add flow steps.", 73 | numberOfSteps); 74 | } else if (numberOfSteps > 1) { 75 | logger.debug("The service contains {} flow steps.", numberOfSteps); 76 | } 77 | } 78 | } 79 | } 80 | 81 | @Override 82 | public boolean isFlowCheck() { 83 | return true; 84 | } 85 | 86 | @Override 87 | public boolean isNodeCheck() { 88 | return false; 89 | } 90 | 91 | @Override 92 | public boolean isTopLevelCheck() { 93 | return false; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/visitor/check/InterfaceCommentsCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check; 22 | 23 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.NodeGrammar; 24 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types.FlowAttTypes; 25 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.sslr.types.FlowTypes; 26 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheck; 27 | import be.i8c.codequality.sonar.plugins.sag.webmethods.flow.visitor.check.type.FlowCheckRuleType; 28 | 29 | import com.sonar.sslr.api.AstNode; 30 | 31 | import org.slf4j.Logger; 32 | import org.slf4j.LoggerFactory; 33 | import org.sonar.api.rules.RuleType; 34 | import org.sonar.check.Priority; 35 | import org.sonar.check.Rule; 36 | import org.sonar.squidbridge.annotations.SqaleConstantRemediation; 37 | 38 | /** 39 | * Checks interface comments being set. This is useful in combination with document-generator. 40 | * 41 | * @author DEWANST 42 | * 43 | */ 44 | @Rule(key = "S00004", name = "Interfaces of services should contain comments", 45 | priority = Priority.MINOR, tags = { 46 | Tags.BAD_PRACTICE }) 47 | @SqaleConstantRemediation("2min") 48 | @FlowCheckRuleType (ruletype = RuleType.CODE_SMELL) 49 | public class InterfaceCommentsCheck extends FlowCheck { 50 | 51 | static final Logger logger = LoggerFactory.getLogger(InterfaceCommentsCheck.class); 52 | 53 | @Override 54 | public void init() { 55 | logger.debug("++ Initializing {} ++", this.getClass().getName()); 56 | subscribeTo(NodeGrammar.REC_FIELDS); 57 | } 58 | 59 | @Override 60 | public void visitNode(AstNode astNode) { 61 | for (AstNode record : astNode.getChildren(NodeGrammar.RECORD)) { 62 | for (AstNode value : record.getChildren(NodeGrammar.VALUE)) { 63 | for (AstNode attr : value.getChildren(NodeGrammar.ATTRIBUTES)) { 64 | for (AstNode name : attr.getChildren(FlowAttTypes.NAME)) { 65 | if (name.getTokenValue().equals("NODE_COMMENT")) { 66 | if (attr.getParent().getChildren(FlowTypes.ELEMENT_VALUE).size() <= 0) { 67 | logger.debug("++ Comment VIOLATION found: " + value.getTokenLine() + " ++"); 68 | getContext().createLineViolation(this, "Add comment", value); 69 | } 70 | } 71 | } 72 | } 73 | } 74 | } 75 | } 76 | 77 | @Override 78 | public boolean isFlowCheck() { 79 | return false; 80 | } 81 | 82 | @Override 83 | public boolean isNodeCheck() { 84 | return true; 85 | } 86 | 87 | @Override 88 | public boolean isTopLevelCheck() { 89 | return false; 90 | } 91 | } -------------------------------------------------------------------------------- /sonar-flow-plugin/src/test/resources/WmTestPackage/ns/I8cFlowSonarPluginTest/pub/checkEmptyMapValid/node.ndf: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | flow 5 | default 6 | java 3.5 7 | 8 | 9 | record 10 | false 11 | record 12 | 0 13 | IData 14 | true 15 | false 16 | false 17 | 18 | 19 | record 20 | 21 | 22 | true 23 | false 24 | false 25 | 26 | false 27 | input 28 | string 29 | 0 30 | 31 | 32 | true 33 | false 34 | false 35 | 36 | 37 | true 38 | 39 | 40 | record 41 | false 42 | record 43 | 0 44 | IData 45 | true 46 | false 47 | false 48 | 49 | 50 | true 51 | 52 | 53 | 54 | yes 55 | no 56 | no 57 | 15 58 | 1 59 | off 60 | no 61 | $null 62 | 63 | no 64 | 0 65 | 0 66 | none 67 | none 68 | 0 69 | 70 | 71 | 72 | 0 73 | false 74 | false 75 | true 76 | 77 | 1 78 | 79 | true 80 | false 81 | 82 | -------------------------------------------------------------------------------- /sonar-flow-plugin/src/main/java/be/i8c/codequality/sonar/plugins/sag/webmethods/flow/ws/sources/PipeResponse.java: -------------------------------------------------------------------------------- 1 | /* 2 | * i8c 3 | * Copyright (C) 2016 i8c NV 4 | * mailto:contact AT i8c DOT be 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the GNU Lesser General Public 8 | * License as published by the Free Software Foundation; either 9 | * version 3 of the License, or (at your option) any later version. 10 | * 11 | * This program is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 | * Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with this program; if not, write to the Free Software Foundation, 18 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 19 | */ 20 | 21 | package be.i8c.codequality.sonar.plugins.sag.webmethods.flow.ws.sources; 22 | 23 | import java.io.ByteArrayOutputStream; 24 | import java.io.IOException; 25 | import java.io.OutputStream; 26 | import java.net.HttpURLConnection; 27 | import java.util.Collection; 28 | import java.util.HashMap; 29 | import java.util.Map; 30 | 31 | import javax.annotation.CheckForNull; 32 | 33 | import org.sonar.api.server.ws.Response; 34 | import org.sonar.api.utils.text.JsonWriter; 35 | import org.sonar.api.utils.text.XmlWriter; 36 | 37 | public class PipeResponse implements Response { 38 | 39 | private ByteStream bs; 40 | private Map headers = new HashMap(); 41 | 42 | public PipeResponse() { 43 | bs = new ByteStream(); 44 | } 45 | 46 | @Override 47 | public JsonWriter newJsonWriter() { 48 | return null; 49 | } 50 | 51 | @Override 52 | public XmlWriter newXmlWriter() { 53 | return null; 54 | } 55 | 56 | @Override 57 | public Response noContent() { 58 | stream().setStatus(HttpURLConnection.HTTP_NO_CONTENT); 59 | try { 60 | bs.output().close(); 61 | } catch (IOException e) { 62 | // close quietly 63 | } 64 | ; 65 | return this; 66 | } 67 | 68 | @Override 69 | public Response setHeader(String name, String value) { 70 | headers.put(name, value); 71 | return this; 72 | } 73 | 74 | @Override 75 | public Collection getHeaderNames() { 76 | return headers.keySet(); 77 | } 78 | 79 | @Override 80 | public String getHeader(String name) { 81 | return headers.get(name); 82 | } 83 | 84 | @Override 85 | public ByteStream stream() { 86 | return bs; 87 | } 88 | 89 | public class ByteStream implements Stream { 90 | 91 | private ByteArrayOutputStream bas; 92 | private String mediaType; 93 | private int status; 94 | 95 | public ByteStream() { 96 | bas = new ByteArrayOutputStream(); 97 | } 98 | 99 | @CheckForNull 100 | public String mediaType() { 101 | return mediaType; 102 | } 103 | 104 | @Override 105 | public Stream setMediaType(String s) { 106 | this.mediaType = s; 107 | return this; 108 | } 109 | 110 | public int status() { 111 | return status; 112 | } 113 | 114 | @Override 115 | public Stream setStatus(int i) { 116 | this.status = i; 117 | return this; 118 | } 119 | 120 | @Override 121 | public OutputStream output() { 122 | return bas; 123 | } 124 | 125 | } 126 | 127 | } 128 | -------------------------------------------------------------------------------- /sonar-flow-plugin-documentation/QUICK_SETUP.md: -------------------------------------------------------------------------------- 1 | # Quick setup 2 | 3 | Download the sonar-flow-plugin jar to your working directory. The jar can be found on the GitHub [release page](https://github.com/I8C/sonar-flow-plugin/releases). 4 | 5 | ```sh 6 | wget https://github.com/I8C/sonar-flow-plugin/releases/download/v1.0/sonar-flow-plugin-1.0.jar 7 | ``` 8 | ## Install the plugin on the SonarQube server 9 | 10 | To install this plugin just add the downloaded jar to your SonarQube server in the plugins folder `/opt/sonarqube/extensions/plugins/`. You will need to restart your server. 11 | 12 | ### (Optional) Create a SonarQube server with flow plugin using docker 13 | 14 | If you do not have a SonarQube server, you can quickly create one using docker. For this part we will use the sonarqube docker image from the docker hub and add the sonar-flow-plugin jar to it. More info about this image can be found on: https://hub.docker.com/_/sonarqube/ 15 | 16 | Create a folder and download the [dockerfile](https://github.com/I8C/sonar-flow-plugin/blob/master/Dockerfile) 17 | 18 | Create a the structure sonar-flow-plugin/target inside your folder and put the downloaded in the target folder. 19 | Next is to build this container and run it using following commands from the Dockerfile location: 20 | 21 | ```sh 22 | docker build . -t i8c/sonarqube-flow 23 | docker run --name sonarqube-flow -p 9000:9000 i8c/sonarqube-flow 24 | ``` 25 | 26 | Now you should have a running SonarQube server with the sonar-flow-plugin installed on port 9000 of your dockerhost. 27 | 28 | ## Configure the SonarQube Scanner 29 | 30 | The documentation for the scanner can be found [here](http://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner). 31 | Download the scanner to your filesystem and unzip it. 32 | 33 | ```sh 34 | wget https://sonarsource.bintray.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-3.1.0.1141.zip 35 | unzip sonar-scanner-cli-3.1.0.1141.zip 36 | ``` 37 | 38 | Now configure the SonarQube scanner to point to your SonarQube server. This is done using the config file at `sonar-scanner-cli-3.1.0.1141/conf/sonar-scanner.properties`. The content of this file should look like this: 39 | 40 | ``` 41 | #No information about specific project should appear here 42 | 43 | #----- Default SonarQube server 44 | sonar.host.url=http://192.168.99.100:9000/ 45 | 46 | #----- Default source code encoding 47 | sonar.sourceEncoding=UTF-8 48 | ``` 49 | 50 | ## Run the SonarQube Scanner 51 | 52 | Go in your filesystem to the webMethods Integration server package you want to check. And make a new file `sonar-project.properties` with following content: 53 | 54 | ``` 55 | # Must be unique in a given SonarQube instance 56 | sonar.projectKey=sonar-flow-tutorial 57 | 58 | # this is the name displayed in the SonarQube UI 59 | sonar.projectName=Sonar flow plugin tutorial 60 | sonar.projectVersion=1.0 61 | 62 | # Path is relative to the sonar-project.properties file. 63 | sonar.sources=./ns 64 | 65 | # Encoding of the source code. Default is default system encoding 66 | sonar.sourceEncoding=UTF-8 67 | sonar.flow.ignore.toplevel=false 68 | ``` 69 | 70 | And finally run SonarQube Scanner script inside this directory. 71 | 72 | ``` 73 | ../sonar-scanner-cli-3.1.0.1141/bin/sonar-scanner 74 | ``` 75 | 76 | ## View results 77 | 78 | Now go to your browser and go to `http://:9000`. Here you'll see that the project "Sonar flow plugin tutorial" has been added and 2 code smells were detected in this Integration server package. 79 | ![sonar gui projects view](assets/sonar-gui-project-view.png) 80 | 81 | When you look at those 2 issues you'll see that I should have added a comment and removed the savePipeline flow. 82 | ![sonar gui issues view](assets/sonar-gui-issues-view.png) 83 | 84 | 85 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | --------------------------------------------------------------------------------