Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 186 additions & 0 deletions examples/parser_demo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
#!/usr/bin/env python3
"""
Example script demonstrating the parser functionality.

This script shows how to use the different parsers to extract information
from diagram files and store them in the database.
"""

import sys
from pathlib import Path

# Add src to path for imports
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))

from parsers import PlantUMLParser, MermaidParser, DrawIOParser
from parsers.database import DiagramDatabase, get_diagram_statistics
from parsers.base_parser import DiagramType


def create_sample_diagrams():
"""Create sample diagram content for testing."""

plantuml_content = """
@startuml
title Sample Class Diagram

class User {
+id: String
+name: String
+email: String
+login(): boolean
+logout(): void
}

class Admin {
+permissions: List<String>
+manageUsers(): void
}

interface Authenticatable {
+authenticate(): boolean
}

User <|-- Admin
User ..|> Authenticatable
@enduml
"""

mermaid_content = """
classDiagram
class Animal {
+String name
+int age
+makeSound() void
}
class Dog {
+String breed
+bark() void
}
class Cat {
+int lives
+meow() void
}
Animal <|-- Dog
Animal <|-- Cat
"""

drawio_content = """<?xml version="1.0" encoding="UTF-8"?>
<mxGraphModel>
<root>
<mxCell id="0"/>
<mxCell id="1" parent="0"/>
<mxCell id="user" value="User" style="rounded=0;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="160" y="80" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="system" value="System" style="rounded=0;whiteSpace=wrap;html=1" vertex="1" parent="1">
<mxGeometry x="320" y="80" width="120" height="60" as="geometry"/>
</mxCell>
<mxCell id="conn1" value="uses" style="endArrow=classic;html=1" edge="1" parent="1" source="user" target="system">
<mxGeometry width="50" height="50" relative="1" as="geometry"/>
</mxCell>
</root>
</mxGraphModel>"""

return {
'plantuml': plantuml_content,
'mermaid': mermaid_content,
'drawio': drawio_content
}


def main():
"""Main demonstration function."""
print("🔍 Diagram Parser Demo")
print("=" * 50)

# Initialize database
db = DiagramDatabase("demo_diagrams.db")
print("✅ Database initialized")

# Create parsers
parsers = {
'PlantUML': PlantUMLParser(),
'Mermaid': MermaidParser(),
'DrawIO': DrawIOParser()
}

# Get sample diagrams
samples = create_sample_diagrams()

diagram_ids = []

# Parse and store each diagram type
for parser_name, parser in parsers.items():
print(f"\n📊 Testing {parser_name} Parser")
print("-" * 30)

if parser_name == 'PlantUML':
content = samples['plantuml']
filename = "sample.puml"
elif parser_name == 'Mermaid':
content = samples['mermaid']
filename = "sample.mmd"
else: # DrawIO
content = samples['drawio']
filename = "sample.drawio"

try:
# Parse the content
parsed = parser.parse(content, filename)

print(f" 📄 Source: {parsed.source_file}")
print(f" 🔢 Elements: {len(parsed.elements)}")
print(f" 🔗 Relationships: {len(parsed.relationships)}")
print(f" 🏷️ Tags: {len(parsed.tags)}")

# Store in database
diagram_id = db.store_diagram(parsed)
diagram_ids.append(diagram_id)
print(f" 💾 Stored with ID: {diagram_id}")

# Show element details
for element in parsed.elements[:3]: # Show first 3 elements
print(f" - {element.element_type.value}: {element.name}")

if len(parsed.elements) > 3:
print(f" ... and {len(parsed.elements) - 3} more")

except Exception as e:
print(f" ❌ Error: {e}")

# Show database statistics
print(f"\n📈 Database Statistics")
print("-" * 30)

all_diagrams = db.get_all_diagrams()
print(f" 📊 Total diagrams: {len(all_diagrams)}")

for diagram_id in diagram_ids:
stats = get_diagram_statistics(db, diagram_id)
diagram = db.get_diagram(diagram_id)
if diagram:
print(f" \n🔍 {diagram.source_file} ({diagram.diagram_type}):")
print(f" - Elements: {stats['total_elements']}")
print(f" - Relationships: {stats['total_relationships']}")
print(f" - Element types: {list(stats['element_type_counts'].keys())}")

# Demonstrate search functionality
print(f"\n🔍 Search Examples")
print("-" * 30)

# Search by element type
classes = db.search_elements_by_type("class")
print(f" 📋 Found {len(classes)} class elements")

# Search by tags (if any were created)
tag_results = db.search_by_tags(["important", "core", "api"])
total_tagged = sum(len(results) for results in tag_results.values())
print(f" 🏷️ Found {total_tagged} tagged items")

print(f"\n✅ Demo completed successfully!")
print(f"💾 Database saved as: demo_diagrams.db")


if __name__ == "__main__":
main()
7 changes: 7 additions & 0 deletions src/parsers/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Ignore database files created during testing
*.db

# Ignore Python cache
__pycache__/
*.pyc
*.pyo
120 changes: 120 additions & 0 deletions src/parsers/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
# Parser Module Documentation

The parser module provides backend parsing capabilities for different diagram input formats (UML/SYSML). It extracts information from diagram sources and creates a relational database with relevant tags for downstream tool implementations.

## Supported Formats

### PlantUML (.puml, .plantuml, .pu)
- Class diagrams with attributes and methods
- Interface definitions
- Actors and components
- Inheritance, composition, aggregation, association, and dependency relationships
- Comments and metadata extraction

### Mermaid (.mmd, .mermaid)
- Class diagrams
- Flowcharts and graphs
- Sequence diagrams
- Entity-relationship diagrams
- Various node shapes and connection types

### DrawIO (.drawio, .xml)
- XML-based diagram formats
- Shape and connector extraction
- Style property parsing
- Position and geometry information

## Architecture

### Base Classes
- `BaseParser`: Abstract base class defining the parser interface
- `ParsedDiagram`: Container for parsed diagram data
- `DiagramElement`: Represents individual diagram elements
- `DiagramRelationship`: Represents relationships between elements

### Database Layer
- `DiagramDatabase`: SQLite-based storage for parsed diagrams
- Database models for diagrams, elements, and relationships
- Search and query capabilities
- Export functionality (JSON, CSV)

## Usage Example

```python
from parsers import PlantUMLParser, MermaidParser, DrawIOParser
from parsers.database import DiagramDatabase

# Initialize parser and database
parser = PlantUMLParser()
db = DiagramDatabase("diagrams.db")

# Parse diagram content
with open("diagram.puml", "r") as f:
content = f.read()

parsed_diagram = parser.parse(content, "diagram.puml")

# Store in database
diagram_id = db.store_diagram(parsed_diagram)

# Query elements
elements = db.get_elements(diagram_id)
for element in elements:
print(f"{element.element_type}: {element.name}")
```

## Testing

The module includes comprehensive unit tests for:
- Base parser functionality
- Format-specific parsing
- Database operations
- Search and export features

Run tests with: `python -m pytest test/unit/parsers/`

## Database Schema

### Diagrams Table
- `id`: Unique identifier
- `source_file`: Original file path
- `diagram_type`: Format type (plantuml, mermaid, drawio)
- `metadata`: JSON metadata
- `tags`: JSON tag array
- `created_at`, `updated_at`: Timestamps

### Elements Table
- `id`: Unique identifier
- `diagram_id`: Foreign key to diagrams
- `element_id`: Element identifier within diagram
- `element_type`: Type (class, interface, component, etc.)
- `name`: Element name
- `properties`: JSON properties
- `position`: JSON position data
- `tags`: JSON tag array

### Relationships Table
- `id`: Unique identifier
- `diagram_id`: Foreign key to diagrams
- `relationship_id`: Relationship identifier
- `source_element_id`: Source element
- `target_element_id`: Target element
- `relationship_type`: Type (inheritance, composition, etc.)
- `properties`: JSON properties
- `tags`: JSON tag array

## Extensibility

The modular design allows for easy addition of new diagram formats:

1. Inherit from `BaseParser`
2. Implement required abstract methods
3. Add format-specific parsing logic
4. Register in the main module

## Error Handling

- `ParseError`: Raised when diagram parsing fails
- Graceful handling of malformed content
- Validation of diagram integrity
- Database transaction safety
24 changes: 24 additions & 0 deletions src/parsers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""
Parser module for processing different diagram formats (UML/SYSML).

This module provides parsers for:
- PlantUML (.puml, .plantuml)
- Mermaid (.mmd, .mermaid)
- DrawIO (.drawio, .xml)

The parsers extract information from diagram sources and create structured data
with relevant tags for downstream tool implementations.
"""

from .base_parser import BaseParser, ParsedDiagram
from .plantuml_parser import PlantUMLParser
from .mermaid_parser import MermaidParser
from .drawio_parser import DrawIOParser

__all__ = [
'BaseParser',
'ParsedDiagram',
'PlantUMLParser',
'MermaidParser',
'DrawIOParser'
]
Loading
Loading