@startuml new-model-analyzer
' --------------------------------------------------------------------------
class PatternFinderMain {
    + {static} findPatterns(path: String): PatternSearchResult
}
note right of PatternFinderMain::findPatterns
    finder = new ConcretePatternFinder()
    ...
    project = SoftwareProject.construct_from_folder(path)
    ...
    return finder.findPatterns(project)
end note
PatternFinderMain "one" ..> "many" AbstractPatternFinder : uses

' --------------------------------------------------------------------------
class LabelingMain {
    + {static} generateLabels(path: String): LabelingProcessResult
}
LabelingMain "one" ..> "many" AbstractProjectLabeler : uses

' --------------------------------------------------------------------------
abstract class AbstractPatternFinder {
    - {abstract} callsFinder AbstractCallsFinder
    + {abstract} findPatterns(p: SoftwareProject): PatternSearchResult
}
AbstractPatternFinder ..> SoftwareProject : analyzes
AbstractPatternFinder "one" ..> "many" PatternSearchResult : obtains
' --------------------------------------------------------------------------
class GeneratorPatternFinder extends AbstractPatternFinder {
    - callsFinder GeneratorCallsFinder
    + findPatterns(p: SoftwareProject): PatternSearchResult
    
    - findYieldKeywords(): void
    - findCalls(): void
}
class ObserverPatternFinder extends AbstractPatternFinder {
    - callsFinder ObserverCallsFinder
    + findPatterns(p: SoftwareProject): PatternSearchResult
}
class DecoratorPatternFinder extends AbstractPatternFinder {
    - callsFinder DecoratorCallsFinder
    + findPatterns(p: SoftwareProject): PatternSearchResult
}
GeneratorPatternFinder "one" *--> "one" GeneratorCallsFinder : "collaborates with"
DecoratorPatternFinder "one" *--> "one" DecoratorCallsFinder : "collaborates with"
ObserverPatternFinder "one" *--> "one" ObserverCallsFinder : "collaborates with"

' --------------------------------------------------------------------------
abstract class AbstractProjectLabeler {
    + {abstract} generateLabels(p: SoftwareProject): LabelingProcessResult
}
AbstractProjectLabeler "one" ..> "one" PatternSearchResult : analyses
AbstractProjectLabeler "one" ..> "one" LabelingProcessResult : obtains

class GeneratorProjectLabeler extends AbstractProjectLabeler {
    + generateLabels(p: SoftwareProject): LabelingProcessResult
}
class ObserverProjectLabeler extends AbstractProjectLabeler {
    + generateLabels(p: SoftwareProject): LabelingProcessResult
}
class DecoratorProjectLabeler extends AbstractProjectLabeler {
    + generateLabels(p: SoftwareProject): LabelingProcessResult
}
' --------------------------------------------------------------------------
abstract class AbstractCallsFinder {
    + {abstract} findPatternCalls(p: SoftwareProject): CallsSearchResult
}
AbstractCallsFinder "one" ..> "one" CallsSearchResult : obtains

class GeneratorCallsFinder extends AbstractCallsFinder {
    + findPatternCalls(p: SoftwareProject): CallsSearchResult
}
class ObserverCallsFinder extends AbstractCallsFinder {
    + findPatternCalls(p: SoftwareProject): CallsSearchResult
}
class DecoratorCallsFinder extends AbstractCallsFinder {
    + findPatternCalls(p: SoftwareProject): CallsSearchResult
}
' --------------------------------------------------------------------------
class SoftwareProject {
    - files: List<SoftwareProjectFile>
    + {static} construct_from_folder(path: String): SoftwareProject
    - isFileAllowedInProject(fileName: String): Boolean
    - createProjectFile(fileName: String, filePath: String): ProjectFile
}
class PythonProject extends SoftwareProject {
    - isFileAllowedInProject(fileName: String): Boolean
    - createProjectFile(fileName: String, filePath: String): PythonFile
}
SoftwareProject "one" *--> "many" ProjectFile : contains
class ProjectFile {
    - fileName: String
    - filePath: String
    + getFileName(): String
    + getFilePath(): String
    + getFileType(): String
}
class PythonFile extends ProjectFile {
    - fileName: String
    - filePath: String
    + getFileName(): String
    + getFilePath(): String
    + getFileType(): String
}
' --------------------------------------------------------------------------
' class SourceMap implements CSVExportable {
'     + exportToCSV(): CSVFolderStructure
' }

' class SourceMapRow {
'     - nodeId: Integer
'     - nodeName: String
'     - nodeType: Integer
'     - nodeTypeName: String
'     - sourcePath: String
'     - nodeTypeAncestorLevel1: Integer
'     - nodeTypeAncestorLevel2: Integer
'     - nodeTypeAncestorLevel3: Integer

'     + getNodeId(): Integer
'     + getNodeName(): String
'     + getNodeType(): Integer
'     + getNodeTypeName(): String
'     + getSourcePath(): String
' }
' --------------------------------------------------------------------------
abstract class ProcessResult {
}
class PatternSearchResult extends ProcessResult implements CSVExportable {
   - rows: List<PatternSearchResultRow>
   + getRows(): List<PatternSearchResultRow>
}
PatternSearchResult "one" *--> "many" PatternSearchResultRow : contains

class PatternSearchResultRow {
    - filePath: String
    - patternsFound: List<String>
    - lineNumber: Integer
}
class CallsSearchResult extends ProcessResult {
}
class LabelingProcessResult extends ProcessResult implements CSVExportable {
    - rows: List<LabelingProcessResultRow>
    + getRows(): List<LabelingProcessResultRow>
}
LabelingProcessResult "one" *--> "many" LabelingProcessResultRow : contains

class LabelingProcessResultRow {
    - filePath: String
    - labelList: List<String>
    - lineNumber: Integer
}
' --------------------------------------------------------------------------
' class AbstractSyntaxTree implements CSVExportable {
'     - root: ASTNode
'     + exportToCSV(): CSVFolderStructure
'     + getRoot(): ASTNode
'     + walk(): Iterator<ASTNode>
'     + getSourceMap(): SourceMap
' }

' class ASTNode {
'     - nodeName: String
'     - nodeType: Integer
'     - nodeTypeName: String
'     - childNodes: List<ASTNode>

'     + getNodeName(): String
'     + getNodeType(): Integer
'     + getNodeTypeName(): String
'     + getChildNodes(): List<ASTNode>

' }
' class ClassifiedSyntaxTree implements CSVExportable {
'     - root: ClassifiedASTNode
'     + exportToCSV(): CSVFolderStructure
'     + getRoot(): ClassifiedASTNode
'     + walk(): Iterator<ClassifiedASTNode>
'     + getSourceMap(): SourceMap
' }
' class ClassifiedASTNode {
'     - node: ASTNode
'     - patternsFound: List<String>
'     + getPatternsFound(): List<String>
'     + getNodeName(): String
'     + getNodeType(): Integer
'     + getNodeTypeName(): String
'     + getChildNodes(): List<ASTNode>
' }
' --------------------------------------------------------------------------
class CSVFolderStructure {
    - cvsFiles: List<CSVFile>
    + getFolderLocation(): String
}
CSVFolderStructure "one" *--> "many" CSVFile : contains
class CSVFile {
    + getFileLocation(): String
}
interface CSVExportable {
    + exportToCSV(): CSVFolderStructure
}
CSVExportable ..> CSVFolderStructure : returns
' --------------------------------------------------------------------------

'SourceMap
'SourceMap "one" *--> "many" SourceMapRow : contains

'AbstractSyntaxTree
'AbstractSyntaxTree ..> SourceMap : generates
'AbstractSyntaxTree "one" *--> "one" ASTNode : root

'ASTNode recursive relationship
'ASTNode "zero" *--> "many" ASTNode : children



@enduml
