Skip to content

Commit

Permalink
Merge pull request #696 from fheyng/parser-description
Browse files Browse the repository at this point in the history
Add diagrams and test for parsers
  • Loading branch information
uhafner authored Oct 19, 2021
2 parents 572cf74 + 179c82b commit f8dea0f
Show file tree
Hide file tree
Showing 3 changed files with 328 additions and 0 deletions.
124 changes: 124 additions & 0 deletions doc/parser-descriptions.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
@startuml

skinparam class {
BackgroundColor #4AD386
BorderColor #a0a0a0
BackgroundColor<<Main>> gold
BorderColor black
ArrowColor black
FontName Arial Unicode MS
FontSize 20
}

skinparam classFontSize 24
skinparam classAttributeIconSize 0
skinparam defaultFontSize 20

skinparam ArrowColor black
skinparam ArrowThickness 2

hide circle

'Aufgabe 4
abstract IssueParser {
[...]
{method} [...]
}

class ParserRegistry {
-ALL_DESCRIPTORS: ParserDescriptor[]
[...]
+getIds(): Set<String>
+getNames(): Set<String>
+contains(id: String): Boolean
+get(id: String): ParserDescriptor
+getAllDescriptors(): List<ParserDescriptor>
+main(unused: String[])
{method} [...]
}
abstract ParserDescriptor {
-id: String
-name: String
{abstract} +createParser(options: Option...): IssueParser
+getPattern(): String
+getHelp(): String
+hasHelp(): Boolean
+getUrl(): String
+hasUrl(): Boolean
+getIconUrl(): String
+getDescription(issue: Issue): String
{method} [...]
}
ParserDescriptor ..> IssueParser

ParserRegistry ..> CheckStyleDescriptor : <<create>>
class CheckStyleDescriptor extends ParserDescriptor {
[...]
+createParser(options: Option...): IssueParser
{method} [...]
}
ParserRegistry ..> DockerLintDescriptor : <<create>>
class DockerLintDescriptor extends ParserDescriptor {
[...]
+createParser(options: Option...): IssueParser
{method} [...]
}
ParserRegistry ..> MavenConsoleDescriptor : <<create>>
class MavenConsoleDescriptor extends ParserDescriptor {
[...]
+createParser(options: Option...): IssueParser
{method} [...]
}

abstract CompositeParserDescriptor extends ParserDescriptor {
+createParser(options: Option...): IssueParser
{abstract} #createParsers(): Collection<? extends IssueParser>
#asList(parser: IssueParser...): Collection<? extends IssueParser>
{method} [...]
}
ParserRegistry ..> SonarQubeDescriptor : <<create>>
class SonarQubeDescriptor extends CompositeParserDescriptor {
[...]
#createParsers(): Collection<? extends IssueParser>
{method} [...]
}
ParserRegistry ..> JavaDescriptor : <<create>>
class JavaDescriptor extends CompositeParserDescriptor {
[...]
#createParsers(): Collection<? extends IssueParser>
{method} [...]
}
ParserRegistry ..> EclipseDescriptor : <<create>>
class EclipseDescriptor extends CompositeParserDescriptor {
[...]
#createParsers(): Collection<? extends IssueParser>
{method} [...]
}

abstract DryDescriptor extends ParserDescriptor {
[...]
~getHighThreshold(options: Option...): Integer
~getNormalThreshold(options: Option...): Integer
+getDescription(issue: Issue): String
{method} [...]
}
ParserRegistry ..> SimianDescriptor : <<create>>
class SimianDescriptor extends DryDescriptor {
[...]
+createParser(options: Option...): IssueParser
{method} [...]
}
ParserRegistry ..> DupfinderDescriptor : <<create>>
class DupfinderDescriptor extends DryDescriptor {
[...]
+createParser(options: Option...): IssueParser
{method} [...]
}
ParserRegistry ..> CpdDescriptor : <<create>>
class CpdDescriptor extends DryDescriptor {
[...]
+createParser(options: Option...): IssueParser
{method} [...]
}

@enduml
187 changes: 187 additions & 0 deletions doc/parser-structure.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
@startuml

skinparam class {
BackgroundColor #4AD386
BorderColor #a0a0a0
BackgroundColor<<Main>> gold
BorderColor black
ArrowColor black
FontName Arial Unicode MS
FontSize 20
}

skinparam classFontSize 24
skinparam classAttributeIconSize 0
skinparam defaultFontSize 20

skinparam ArrowColor black
skinparam ArrowThickness 2

hide circle

'Aufgabe 3
class Report {
[...]
{method} [...]
}

interface Serializable <<interface>>
abstract IssueParser implements Serializable {
[...]
{abstract} +parse(readerFactory: ReaderFactory): Report
+parseFile(readerFactory: ReaderFactory): Report
+accepts(readerFactory: ReaderFactory): Boolean
#isXmlFile(readerFactory: ReaderFactory): Boolean
{method} [...]
}
IssueParser ..> Report
class CheckStyleParser extends IssueParser {
[...]
+parse(readerFactory: ReaderFactory): Report
{method} [...]
}
class DockerLintParser extends IssueParser {
[...]
+accepts(readerFactory: ReaderFactory): Boolean
+parse(readerFactory: ReaderFactory): Report
{method} [...]
}
class LintParser extends IssueParser {
[...]
+parse(readerFactory: ReaderFactory): Report
}

abstract AbstractDryParser<T> extends IssueParser {
-highThreshold: Integer
-normalThreshold: Integer
[...]
#getPriority(lines: Integer): Severity
+parse(readerFactory: ReaderFactory): Report
{abstract} #configureParser(digester: Digester)
{abstract} #convertDuplicationsToIssues(duplications: List<T>, issueBuilder: IssueBuilder): Report
{method} [...]
}
class CpdParser extends AbstractDryParser {
[...]
#configureParser(digester: Digester)
#convertDuplicationsToIssues(duplications: List<T>, issueBuilder: IssueBuilder): Report
{method} [...]
}
class DupFinderParser extends AbstractDryParser {
[...]
#configureParser(digester: Digester)
#convertDuplicationsToIssues(duplications: List<T>, issueBuilder: IssueBuilder): Report
{method} [...]
}
class SimianParser extends AbstractDryParser {
[...]
#configureParser(digester: Digester)
#convertDuplicationsToIssues(duplications: List<T>, issueBuilder: IssueBuilder): Report
{method} [...]
}

abstract IssuePropertiesParser extends IssueParser {
~ADDITIONAL_PROPERTIES: String
~CATEGORY: String
~DESCRIPTION: String
[...]
}
class XmlParser extends IssuePropertiesParser {
[...]
+accepts(readerFactory: ReaderFactory): Boolean
+parse(readerFactory: ReaderFactory): Report
{method} [...]
}
abstract JsonBaseParser extends IssuePropertiesParser {
[...]
~convertToIssue(jsonIssue: JSONObject): Optional<Issue>
{method} [...]
}
class JsonLogParser extends JsonBaseParser {
[...]
+accepts(readerFactory: ReaderFactory): Boolean
+parse(readerFactory: ReaderFactory): Report
{method} [...]
}
class JsonParser extends JsonBaseParser {
[...]
+accepts(readerFactory: ReaderFactory): Boolean
+parse(readerFactory: ReaderFactory): Report
}

abstract LookaheadParser extends IssueParser {
#ANT_TASK: String
[...]
+parse(readerFactory: ReaderFactory): Report
{abstract} #createIssue(matcher: Matcher, lookahead: LookaheadStream, builder: IssueBuilder): Optional<Issue>
#isLineInteresting(line: String): Boolean
#postProcess(report: Report): Report
{method} [...]
}
class JavacParser extends LookaheadParser {
[...]
#isLineInteresting(line: String): Boolean
#createIssue(matcher: Matcher, lookahead: LookaheadStream, builder: IssueBuilder): Optional<Issue>
{method} [...]
}
class MavenConsoleParser extends LookaheadParser {
[...]
#isLineInteresting(line: String): Boolean
#createIssue(matcher: Matcher, lookahead: LookaheadStream, builder: IssueBuilder): Optional<Issue>
{method} [...]
}
class GradleErrorProneParser extends LookaheadParser {
[...]
#createIssue(matcher: Matcher, lookahead: LookaheadStream, builder: IssueBuilder): Optional<Issue>
{method} [...]
}

abstract SonarQubeParser extends IssueParser {
[...]
+accepts(readerFactory: ReaderFactory): Boolean
{abstract} ~accepts(object: JSONObject): Boolean
+parse(readerFactory: ReaderFactory): Report
~filterIssue(object: JSONObject): Boolean
{abstract} ~getModulePath(component: JSONObject, issue: JSONObject): String
{abstract} ~parseStart(issue: JSONObject): Integer
{abstract} ~parseEnd(issue: JSONObject): Integer
{method} [...]
}
class SonarQubeIssuesParser extends SonarQubeParser {
[...]
~accepts(object: JSONObject): Boolean
~getModulePath(component: JSONObject, issue: JSONObject): String
~parseStart(issue: JSONObject): Integer
~parseEnd(issue: JSONObject): Integer
}
class SonarQubeDiffParser extends SonarQubeParser {
[...]
~accepts(object: JSONObject): Boolean
~filterIssue(object: JSONObject): Boolean
~getModulePath(component: JSONObject, issue: JSONObject): String
~parseStart(issue: JSONObject): Integer
~parseEnd(issue: JSONObject): Integer
}

abstract AbstractViolationAdapter extends IssueParser {
[...]
+parse(readerFactory: ReaderFactory): Report
{abstract} ~createParser(): ViolationsParser
{method} [...]
}
class JUnitAdapter extends AbstractViolationAdapter {
[...]
~createParser(): JUnitParser
+parse(readerFactory: ReaderFactory): Report
{method} [...]
}
class YamlLintAdapter extends AbstractViolationAdapter {
[...]
~createParser(): YAMLlintParser
}
class XmlLintAdapter extends AbstractViolationAdapter {
[...]
~createParser(): XMLLintParser
}

@enduml
17 changes: 17 additions & 0 deletions src/test/java/edu/hm/hafner/analysis/AbstractParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,23 @@ void shouldBeSerializable() throws IOException {
assertThat(out.toByteArray()).isNotEmpty();
}

/**
* Ensures that the parser under test can handle empty files. This test will fail if the parser does not throw a
* {@link ParsingException} or does not return an empty report.
*/
@Test
void shouldHandleEmptyFile() {
boolean passed;
try {
Report report = parseStringContent("");
passed = report.isEmpty();
}
catch (ParsingException e) {
passed = true;
}
assertThat(passed).isTrue();
}

/**
* Parses the specified file and returns the found issues.
*
Expand Down

0 comments on commit f8dea0f

Please sign in to comment.