-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathstruts_migrator.py
More file actions
186 lines (150 loc) · 7.38 KB
/
Copy pathstruts_migrator.py
File metadata and controls
186 lines (150 loc) · 7.38 KB
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
import os
import shutil
import json
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
import re
from datetime import datetime
import logging
# Configure logging
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
logger = logging.getLogger(__name__)
class StrutsMigratorApp:
def __init__(self, root):
"""Initialize the main application window and GUI components."""
self.root = root
self.root.title("Struts 2 Migration Tool")
self.root.geometry("600x400")
# Variables for file paths
self.project_path = tk.StringVar()
self.rules_path = tk.StringVar()
# Create GUI components
self.create_gui()
# Initialize backup directory
self.backup_dir = None
def create_gui(self):
"""Create and layout all GUI components."""
# Project folder selection
tk.Label(self.root, text="Project Folder:").grid(row=0, column=0, padx=5, pady=5, sticky="w")
tk.Entry(self.root, textvariable=self.project_path, width=50).grid(row=0, column=1, padx=5, pady=5)
tk.Button(self.root, text="Browse", command=self.browse_project).grid(row=0, column=2, padx=5, pady=5)
# Rules file selection
tk.Label(self.root, text="Rules File:").grid(row=1, column=0, padx=5, pady=5, sticky="w")
tk.Entry(self.root, textvariable=self.rules_path, width=50).grid(row=1, column=1, padx=5, pady=5)
tk.Button(self.root, text="Browse", command=self.browse_rules).grid(row=1, column=2, padx=5, pady=5)
# Migrate button
tk.Button(self.root, text="Start Migration", command=self.start_migration).grid(row=2, column=0, columnspan=3, pady=10)
# Status display
self.status_text = tk.Text(self.root, height=10, width=70)
self.status_text.grid(row=3, column=0, columnspan=3, padx=5, pady=5)
# Progress bar
self.progress = ttk.Progressbar(self.root, length=400, mode='determinate')
self.progress.grid(row=4, column=0, columnspan=3, pady=5)
def browse_project(self):
"""Open file dialog to select project folder."""
path = filedialog.askdirectory()
if path:
self.project_path.set(path)
self.update_status(f"Selected project folder: {path}")
def browse_rules(self):
"""Open file dialog to select rules file."""
path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])
if path:
self.rules_path.set(path)
self.update_status(f"Selected rules file: {path}")
def update_status(self, message):
"""Update the status text area with a message."""
self.status_text.insert(tk.END, f"{message}\n")
self.status_text.see(tk.END)
self.root.update()
def start_migration(self):
"""Initiate the migration process."""
try:
project_path = self.project_path.get()
rules_path = self.rules_path.get()
if not project_path or not rules_path:
messagebox.showerror("Error", "Please select both project folder and rules file")
return
if not os.path.exists(project_path) or not os.path.exists(rules_path):
messagebox.showerror("Error", "Invalid path selected")
return
# Load rules
with open(rules_path, 'r') as f:
rules = json.load(f)
# Create backup
self.create_backup(project_path)
# Process files
self.process_files(project_path, rules)
messagebox.showinfo("Success", "Migration completed successfully!")
except Exception as e:
logger.error(f"Migration error: {str(e)}")
messagebox.showerror("Error", f"Migration failed: {str(e)}")
def create_backup(self, project_path):
"""Create a backup of the project folder."""
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
self.backup_dir = f"{project_path}_backup_{timestamp}"
shutil.copytree(project_path, self.backup_dir)
self.update_status(f"Created backup at: {self.backup_dir}")
def process_files(self, project_path, rules):
"""Process all JSP and Java files in the project."""
css_rules = rules.get('css_class_name_changes', {})
jsp_rules = rules.get('jsp_property_changes', {})
# Get all files
all_files = []
for root, _, files in os.walk(project_path):
for file in files:
if file.endswith(('.jsp', '.java')):
all_files.append(os.path.join(root, file))
self.progress['maximum'] = len(all_files)
self.progress['value'] = 0
# Process each file
for i, file_path in enumerate(all_files):
try:
if file_path.endswith('.jsp'):
self.process_jsp_file(file_path, css_rules, jsp_rules)
elif file_path.endswith('.java'):
self.process_java_file(file_path, jsp_rules)
self.progress['value'] = i + 1
self.update_status(f"Processed: {file_path}")
except Exception as e:
logger.error(f"Error processing {file_path}: {str(e)}")
self.update_status(f"Error processing {file_path}: {str(e)}")
self.root.update()
def process_jsp_file(self, file_path, css_rules, jsp_rules):
"""Process a JSP file and apply refactoring rules."""
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Apply CSS class name changes
for old_class, new_class in css_rules.items():
content = re.sub(rf'class\s*=\s*"{old_class}"', f'class="{new_class}"', content)
# Apply JSP property changes
for old_prop, new_prop in jsp_rules.items():
content = re.sub(rf'\b{old_prop}\b', new_prop, content)
# Write modified content back to file
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
def process_java_file(self, file_path, jsp_rules):
"""Process a Java file and apply refactoring rules."""
with open(file_path, 'r', encoding='utf-8') as f:
content = f.read()
# Apply property changes in Java files
for old_prop, new_prop in jsp_rules.items():
# Update field names
content = re.sub(rf'\b{old_prop}\b(?=\s*;|\s*=)', new_prop, content)
# Update getter/setter names
old_getter = f'get{old_prop[0].upper() + old_prop[1:]}'
new_getter = f'get{new_prop[0].upper() + new_prop[1:]}'
old_setter = f'set{old_prop[0].upper() + old_prop[1:]}'
new_setter = f'set{new_prop[0].upper() + new_prop[1:]}'
content = content.replace(old_getter, new_getter)
content = content.replace(old_setter, new_setter)
# Write modified content back to file
with open(file_path, 'w', encoding='utf-8') as f:
f.write(content)
def main():
"""Main function to launch the application."""
root = tk.Tk()
app = StrutsMigratorApp(root)
root.mainloop()
if __name__ == "__main__":
main()