Skip to content

Commit c6434a2

Browse files
Copilotvinod0m
andcommitted
Implement backend parser for UML/SYSML diagrams with database storage
Co-authored-by: vinod0m <221896197+vinod0m@users.noreply.github.com>
1 parent b2ba512 commit c6434a2

File tree

16 files changed

+3524
-0
lines changed

16 files changed

+3524
-0
lines changed

examples/parser_demo.py

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Example script demonstrating the parser functionality.
4+
5+
This script shows how to use the different parsers to extract information
6+
from diagram files and store them in the database.
7+
"""
8+
9+
import sys
10+
from pathlib import Path
11+
12+
# Add src to path for imports
13+
sys.path.insert(0, str(Path(__file__).parent.parent / "src"))
14+
15+
from parsers import PlantUMLParser, MermaidParser, DrawIOParser
16+
from parsers.database import DiagramDatabase, get_diagram_statistics
17+
from parsers.base_parser import DiagramType
18+
19+
20+
def create_sample_diagrams():
21+
"""Create sample diagram content for testing."""
22+
23+
plantuml_content = """
24+
@startuml
25+
title Sample Class Diagram
26+
27+
class User {
28+
+id: String
29+
+name: String
30+
+email: String
31+
+login(): boolean
32+
+logout(): void
33+
}
34+
35+
class Admin {
36+
+permissions: List<String>
37+
+manageUsers(): void
38+
}
39+
40+
interface Authenticatable {
41+
+authenticate(): boolean
42+
}
43+
44+
User <|-- Admin
45+
User ..|> Authenticatable
46+
@enduml
47+
"""
48+
49+
mermaid_content = """
50+
classDiagram
51+
class Animal {
52+
+String name
53+
+int age
54+
+makeSound() void
55+
}
56+
class Dog {
57+
+String breed
58+
+bark() void
59+
}
60+
class Cat {
61+
+int lives
62+
+meow() void
63+
}
64+
Animal <|-- Dog
65+
Animal <|-- Cat
66+
"""
67+
68+
drawio_content = """<?xml version="1.0" encoding="UTF-8"?>
69+
<mxGraphModel>
70+
<root>
71+
<mxCell id="0"/>
72+
<mxCell id="1" parent="0"/>
73+
<mxCell id="user" value="User" style="rounded=0;whiteSpace=wrap;html=1" vertex="1" parent="1">
74+
<mxGeometry x="160" y="80" width="120" height="60" as="geometry"/>
75+
</mxCell>
76+
<mxCell id="system" value="System" style="rounded=0;whiteSpace=wrap;html=1" vertex="1" parent="1">
77+
<mxGeometry x="320" y="80" width="120" height="60" as="geometry"/>
78+
</mxCell>
79+
<mxCell id="conn1" value="uses" style="endArrow=classic;html=1" edge="1" parent="1" source="user" target="system">
80+
<mxGeometry width="50" height="50" relative="1" as="geometry"/>
81+
</mxCell>
82+
</root>
83+
</mxGraphModel>"""
84+
85+
return {
86+
'plantuml': plantuml_content,
87+
'mermaid': mermaid_content,
88+
'drawio': drawio_content
89+
}
90+
91+
92+
def main():
93+
"""Main demonstration function."""
94+
print("🔍 Diagram Parser Demo")
95+
print("=" * 50)
96+
97+
# Initialize database
98+
db = DiagramDatabase("demo_diagrams.db")
99+
print("✅ Database initialized")
100+
101+
# Create parsers
102+
parsers = {
103+
'PlantUML': PlantUMLParser(),
104+
'Mermaid': MermaidParser(),
105+
'DrawIO': DrawIOParser()
106+
}
107+
108+
# Get sample diagrams
109+
samples = create_sample_diagrams()
110+
111+
diagram_ids = []
112+
113+
# Parse and store each diagram type
114+
for parser_name, parser in parsers.items():
115+
print(f"\n📊 Testing {parser_name} Parser")
116+
print("-" * 30)
117+
118+
if parser_name == 'PlantUML':
119+
content = samples['plantuml']
120+
filename = "sample.puml"
121+
elif parser_name == 'Mermaid':
122+
content = samples['mermaid']
123+
filename = "sample.mmd"
124+
else: # DrawIO
125+
content = samples['drawio']
126+
filename = "sample.drawio"
127+
128+
try:
129+
# Parse the content
130+
parsed = parser.parse(content, filename)
131+
132+
print(f" 📄 Source: {parsed.source_file}")
133+
print(f" 🔢 Elements: {len(parsed.elements)}")
134+
print(f" 🔗 Relationships: {len(parsed.relationships)}")
135+
print(f" 🏷️ Tags: {len(parsed.tags)}")
136+
137+
# Store in database
138+
diagram_id = db.store_diagram(parsed)
139+
diagram_ids.append(diagram_id)
140+
print(f" 💾 Stored with ID: {diagram_id}")
141+
142+
# Show element details
143+
for element in parsed.elements[:3]: # Show first 3 elements
144+
print(f" - {element.element_type.value}: {element.name}")
145+
146+
if len(parsed.elements) > 3:
147+
print(f" ... and {len(parsed.elements) - 3} more")
148+
149+
except Exception as e:
150+
print(f" ❌ Error: {e}")
151+
152+
# Show database statistics
153+
print(f"\n📈 Database Statistics")
154+
print("-" * 30)
155+
156+
all_diagrams = db.get_all_diagrams()
157+
print(f" 📊 Total diagrams: {len(all_diagrams)}")
158+
159+
for diagram_id in diagram_ids:
160+
stats = get_diagram_statistics(db, diagram_id)
161+
diagram = db.get_diagram(diagram_id)
162+
if diagram:
163+
print(f" \n🔍 {diagram.source_file} ({diagram.diagram_type}):")
164+
print(f" - Elements: {stats['total_elements']}")
165+
print(f" - Relationships: {stats['total_relationships']}")
166+
print(f" - Element types: {list(stats['element_type_counts'].keys())}")
167+
168+
# Demonstrate search functionality
169+
print(f"\n🔍 Search Examples")
170+
print("-" * 30)
171+
172+
# Search by element type
173+
classes = db.search_elements_by_type("class")
174+
print(f" 📋 Found {len(classes)} class elements")
175+
176+
# Search by tags (if any were created)
177+
tag_results = db.search_by_tags(["important", "core", "api"])
178+
total_tagged = sum(len(results) for results in tag_results.values())
179+
print(f" 🏷️ Found {total_tagged} tagged items")
180+
181+
print(f"\n✅ Demo completed successfully!")
182+
print(f"💾 Database saved as: demo_diagrams.db")
183+
184+
185+
if __name__ == "__main__":
186+
main()

src/parsers/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Ignore database files created during testing
2+
*.db
3+
4+
# Ignore Python cache
5+
__pycache__/
6+
*.pyc
7+
*.pyo

src/parsers/README.md

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# Parser Module Documentation
2+
3+
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.
4+
5+
## Supported Formats
6+
7+
### PlantUML (.puml, .plantuml, .pu)
8+
- Class diagrams with attributes and methods
9+
- Interface definitions
10+
- Actors and components
11+
- Inheritance, composition, aggregation, association, and dependency relationships
12+
- Comments and metadata extraction
13+
14+
### Mermaid (.mmd, .mermaid)
15+
- Class diagrams
16+
- Flowcharts and graphs
17+
- Sequence diagrams
18+
- Entity-relationship diagrams
19+
- Various node shapes and connection types
20+
21+
### DrawIO (.drawio, .xml)
22+
- XML-based diagram formats
23+
- Shape and connector extraction
24+
- Style property parsing
25+
- Position and geometry information
26+
27+
## Architecture
28+
29+
### Base Classes
30+
- `BaseParser`: Abstract base class defining the parser interface
31+
- `ParsedDiagram`: Container for parsed diagram data
32+
- `DiagramElement`: Represents individual diagram elements
33+
- `DiagramRelationship`: Represents relationships between elements
34+
35+
### Database Layer
36+
- `DiagramDatabase`: SQLite-based storage for parsed diagrams
37+
- Database models for diagrams, elements, and relationships
38+
- Search and query capabilities
39+
- Export functionality (JSON, CSV)
40+
41+
## Usage Example
42+
43+
```python
44+
from parsers import PlantUMLParser, MermaidParser, DrawIOParser
45+
from parsers.database import DiagramDatabase
46+
47+
# Initialize parser and database
48+
parser = PlantUMLParser()
49+
db = DiagramDatabase("diagrams.db")
50+
51+
# Parse diagram content
52+
with open("diagram.puml", "r") as f:
53+
content = f.read()
54+
55+
parsed_diagram = parser.parse(content, "diagram.puml")
56+
57+
# Store in database
58+
diagram_id = db.store_diagram(parsed_diagram)
59+
60+
# Query elements
61+
elements = db.get_elements(diagram_id)
62+
for element in elements:
63+
print(f"{element.element_type}: {element.name}")
64+
```
65+
66+
## Testing
67+
68+
The module includes comprehensive unit tests for:
69+
- Base parser functionality
70+
- Format-specific parsing
71+
- Database operations
72+
- Search and export features
73+
74+
Run tests with: `python -m pytest test/unit/parsers/`
75+
76+
## Database Schema
77+
78+
### Diagrams Table
79+
- `id`: Unique identifier
80+
- `source_file`: Original file path
81+
- `diagram_type`: Format type (plantuml, mermaid, drawio)
82+
- `metadata`: JSON metadata
83+
- `tags`: JSON tag array
84+
- `created_at`, `updated_at`: Timestamps
85+
86+
### Elements Table
87+
- `id`: Unique identifier
88+
- `diagram_id`: Foreign key to diagrams
89+
- `element_id`: Element identifier within diagram
90+
- `element_type`: Type (class, interface, component, etc.)
91+
- `name`: Element name
92+
- `properties`: JSON properties
93+
- `position`: JSON position data
94+
- `tags`: JSON tag array
95+
96+
### Relationships Table
97+
- `id`: Unique identifier
98+
- `diagram_id`: Foreign key to diagrams
99+
- `relationship_id`: Relationship identifier
100+
- `source_element_id`: Source element
101+
- `target_element_id`: Target element
102+
- `relationship_type`: Type (inheritance, composition, etc.)
103+
- `properties`: JSON properties
104+
- `tags`: JSON tag array
105+
106+
## Extensibility
107+
108+
The modular design allows for easy addition of new diagram formats:
109+
110+
1. Inherit from `BaseParser`
111+
2. Implement required abstract methods
112+
3. Add format-specific parsing logic
113+
4. Register in the main module
114+
115+
## Error Handling
116+
117+
- `ParseError`: Raised when diagram parsing fails
118+
- Graceful handling of malformed content
119+
- Validation of diagram integrity
120+
- Database transaction safety

src/parsers/__init__.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
"""
2+
Parser module for processing different diagram formats (UML/SYSML).
3+
4+
This module provides parsers for:
5+
- PlantUML (.puml, .plantuml)
6+
- Mermaid (.mmd, .mermaid)
7+
- DrawIO (.drawio, .xml)
8+
9+
The parsers extract information from diagram sources and create structured data
10+
with relevant tags for downstream tool implementations.
11+
"""
12+
13+
from .base_parser import BaseParser, ParsedDiagram
14+
from .plantuml_parser import PlantUMLParser
15+
from .mermaid_parser import MermaidParser
16+
from .drawio_parser import DrawIOParser
17+
18+
__all__ = [
19+
'BaseParser',
20+
'ParsedDiagram',
21+
'PlantUMLParser',
22+
'MermaidParser',
23+
'DrawIOParser'
24+
]

0 commit comments

Comments
 (0)