<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>类加载可视化 - JVM类加载机制</title>
    <style>
        * { margin: 0; padding: 0; box-sizing: border-box; }
        body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; background: #f5f7fa; padding: 20px; }
        .container { max-width: 1400px; margin: 0 auto; }
        
        .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 30px; border-radius: 15px; margin-bottom: 30px; text-align: center; }
        .header h1 { font-size: 2em; margin-bottom: 10px; }
        
        .grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(400px, 1fr)); gap: 20px; margin-bottom: 30px; }
        
        .card { background: white; border-radius: 12px; padding: 25px; box-shadow: 0 4px 20px rgba(0,0,0,0.08); }
        .card h3 { color: #333; margin-bottom: 15px; border-bottom: 2px solid #eee; padding-bottom: 10px; }
        
        /* 类加载器层次结构 */
        .classloader-hierarchy { display: flex; flex-direction: column; gap: 15px; }
        .classloader-item { 
            background: linear-gradient(135deg, #f5f7fa 0%, #e4e7f1 100%); 
            border-radius: 10px; 
            padding: 20px; 
            border-left: 5px solid #667eea;
            position: relative;
            transition: all 0.3s;
        }
        .classloader-item:hover { transform: translateX(5px); box-shadow: 0 4px 15px rgba(102, 126, 234, 0.2); }
        .classloader-item.bootstrap { border-left-color: #e74c3c; }
        .classloader-item.extension { border-left-color: #f39c12; }
        .classloader-item.application { border-left-color: #27ae60; }
        .classloader-item.webapp { border-left-color: #3498db; }
        
        .classloader-item::after {
            content: '▼';
            position: absolute;
            bottom: -20px;
            left: 50%;
            transform: translateX(-50%);
            color: #999;
            font-size: 12px;
        }
        .classloader-item:last-child::after { display: none; }
        
        .classloader-name { font-weight: bold; font-size: 16px; color: #333; margin-bottom: 5px; }
        .classloader-type { display: inline-block; padding: 3px 10px; border-radius: 15px; font-size: 11px; margin-bottom: 8px; }
        .classloader-type.bootstrap { background: #ffeaea; color: #c0392b; }
        .classloader-type.extension { background: #fef5e7; color: #d68910; }
        .classloader-type.application { background: #eafaf1; color: #27ae60; }
        .classloader-type.webapp { background: #ebf5fb; color: #2980b9; }
        
        .classloader-desc { font-size: 13px; color: #666; margin-bottom: 8px; }
        .classloader-info { font-size: 12px; color: #999; }
        
        /* 类加载步骤 */
        .loading-steps { display: flex; flex-direction: column; gap: 10px; }
        .step-item { 
            display: flex; 
            align-items: center; 
            padding: 15px; 
            background: #f8f9fa; 
            border-radius: 8px;
            cursor: pointer;
            transition: all 0.3s;
            border: 2px solid transparent;
        }
        .step-item:hover { background: #e8f4f8; border-color: #3498db; }
        .step-item.active { background: #d4edda; border-color: #27ae60; }
        
        .step-number { 
            width: 40px; 
            height: 40px; 
            border-radius: 50%; 
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            margin-right: 15px;
            font-size: 18px;
        }
        .step-item.active .step-number { background: linear-gradient(135deg, #27ae60 0%, #2ecc71 100%); }
        
        .step-content { flex: 1; }
        .step-name { font-weight: bold; color: #333; margin-bottom: 3px; }
        .step-desc { font-size: 12px; color: #666; }
        
        .step-detail { 
            display: none; 
            margin-top: 10px; 
            padding: 15px; 
            background: white; 
            border-radius: 8px;
            border-left: 4px solid #3498db;
        }
        .step-detail.show { display: block; }
        
        /* 类列表 */
        .class-list { max-height: 400px; overflow-y: auto; }
        .class-item { 
            padding: 12px; 
            background: #f8f9fa; 
            border-radius: 8px; 
            margin-bottom: 8px;
            cursor: pointer;
            transition: all 0.3s;
        }
        .class-item:hover { background: #e8f4f8; transform: translateX(5px); }
        
        .class-name { font-weight: bold; color: #333; margin-bottom: 3px; }
        .class-package { font-size: 11px; color: #999; }
        .class-loader { font-size: 11px; color: #667eea; margin-top: 5px; }
        
        /* Struts2模块 */
        .module-item { 
            background: #f8f9fa; 
            border-radius: 10px; 
            padding: 15px; 
            margin-bottom: 15px;
            border-left: 4px solid #667eea;
        }
        .module-name { font-weight: bold; color: #333; margin-bottom: 5px; }
        .module-desc { font-size: 12px; color: #666; margin-bottom: 10px; }
        .module-classes { display: flex; flex-wrap: wrap; gap: 8px; }
        .module-class { 
            background: white; 
            padding: 5px 10px; 
            border-radius: 15px; 
            font-size: 11px;
            border: 1px solid #ddd;
            cursor: pointer;
            transition: all 0.3s;
        }
        .module-class:hover { background: #667eea; color: white; border-color: #667eea; }
        
        /* 动画 */
        @keyframes pulse {
            0%, 100% { transform: scale(1); }
            50% { transform: scale(1.05); }
        }
        .loading { animation: pulse 1.5s infinite; }
        
        @keyframes slideIn {
            from { opacity: 0; transform: translateY(-20px); }
            to { opacity: 1; transform: translateY(0); }
        }
        .animate-in { animation: slideIn 0.5s ease-out; }
        
        .btn { padding: 10px 20px; border: none; border-radius: 6px; cursor: pointer; font-size: 14px; transition: all 0.3s; }
        .btn-primary { background: #667eea; color: white; }
        .btn-primary:hover { background: #5a6fd6; }
        
        .nav { display: flex; gap: 10px; margin-bottom: 20px; flex-wrap: wrap; }
        .nav a { padding: 10px 20px; background: white; border-radius: 20px; text-decoration: none; color: #333; font-size: 0.9em; box-shadow: 0 2px 5px rgba(0,0,0,0.1); }
        .nav a:hover { background: #667eea; color: white; }
        
        .lab { background: #fff7e6; border-left: 4px solid #fa8c16; padding: 15px; border-radius: 8px; margin-bottom: 20px; }
        .lab strong { color: #874d00; }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🔍 类加载可视化</h1>
            <p>深入理解JVM类加载机制和Struts2框架的类加载过程</p>
        </div>
        
        <div class="nav">
            <a href="index.jsp">← 返回首页</a>
            <a href="learn">学习中心</a>
            <a href="ajax-demo">AJAX演示</a>
        </div>
        
        <div class="lab">
            <strong>🧪 实验任务</strong>
            <ul>
                <li>观察<strong>类加载器层次结构</strong>，理解双亲委派模型</li>
                <li>点击<strong>类加载步骤</strong>，查看每个阶段的详细说明</li>
                <li>查看<strong>已加载的类</strong>，了解Struts2核心类的加载信息</li>
                <li>探索<strong>Struts2模块</strong>，理解框架的模块化设计</li>
            </ul>
        </div>
        
        <div class="grid">
            <!-- 类加载器层次结构 -->
            <div class="card">
                <h3>🏗️ 类加载器层次结构</h3>
                <div id="classloaderHierarchy" class="classloader-hierarchy">
                    <div style="text-align: center; padding: 20px; color: #999;">
                        加载中...
                    </div>
                </div>
            </div>
            
            <!-- 类加载步骤 -->
            <div class="card">
                <h3>📋 类加载步骤（点击展开）</h3>
                <div id="loadingSteps" class="loading-steps">
                    <div style="text-align: center; padding: 20px; color: #999;">
                        加载中...
                    </div>
                </div>
            </div>
            
            <!-- 已加载的类 -->
            <div class="card">
                <h3>📦 已加载的核心类</h3>
                <div id="loadedClasses" class="class-list">
                    <div style="text-align: center; padding: 20px; color: #999;">
                        加载中...
                    </div>
                </div>
            </div>
            
            <!-- Struts2模块 -->
            <div class="card">
                <h3>🎯 Struts2核心模块</h3>
                <div id="strutsModules">
                    <div style="text-align: center; padding: 20px; color: #999;">
                        加载中...
                    </div>
                </div>
            </div>
        </div>
        
        <div class="card">
            <h3>📚 学习要点</h3>
            <ul>
                <li><strong>类加载器层次:</strong> Bootstrap → Extension → Application → WebApp，形成双亲委派模型</li>
                <li><strong>双亲委派:</strong> 类加载时先委托父加载器，父加载器无法加载时才自己加载</li>
                <li><strong>加载过程:</strong> 加载 → 验证 → 准备 → 解析 → 初始化，五个阶段确保类正确加载</li>
                <li><strong>Struts2类加载:</strong> 框架类由Application加载器加载，应用类由WebApp加载器加载</li>
                <li><strong>热部署:</strong> WebApp类加载器可以重新加载修改后的类，实现热部署</li>
            </ul>
        </div>
    </div>
    
    <script>
        // 加载类加载器层次结构
        async function loadClassLoaderHierarchy() {
            try {
                const response = await fetch('classloader_getHierarchy');
                const data = await response.json();
                
                const container = document.getElementById('classloaderHierarchy');
                container.innerHTML = '';
                
                data.hierarchy.forEach((item, index) => {
                    const div = document.createElement('div');
                    div.className = `classloader-item ${item.type} animate-in`;
                    div.style.animationDelay = `${index * 0.1}s`;
                    
                    div.innerHTML = `
                        <div class="classloader-type ${item.type}">${item.type.toUpperCase()}</div>
                        <div class="classloader-name">${item.name}</div>
                        <div class="classloader-desc">${item.description}</div>
                        <div class="classloader-info">
                            ${item.className ? `类: ${item.className}<br>` : ''}
                            ${item.loadedClasses ? `加载类: ${item.loadedClasses}<br>` : ''}
                            ${item.parent ? `父加载器: ${item.parent}` : '父加载器: 无（顶层）'}
                        </div>
                    `;
                    
                    container.appendChild(div);
                });
            } catch (error) {
                document.getElementById('classloaderHierarchy').innerHTML = 
                    `<div style="color: #e74c3c;">加载失败: ${error.message}</div>`;
            }
        }
        
        // 加载类加载步骤
        async function loadLoadingSteps() {
            try {
                const response = await fetch('classloader_simulate');
                const data = await response.json();
                
                const container = document.getElementById('loadingSteps');
                container.innerHTML = '';
                
                data.steps.forEach((step, index) => {
                    const div = document.createElement('div');
                    div.className = 'step-item animate-in';
                    div.style.animationDelay = `${index * 0.1}s`;
                    div.onclick = () => toggleStepDetail(div, step);
                    
                    div.innerHTML = `
                        <div class="step-number">${step.icon || step.step}</div>
                        <div class="step-content">
                            <div class="step-name">${step.name}</div>
                            <div class="step-desc">${step.description}</div>
                        </div>
                        <div class="step-detail" id="step-detail-${step.step}">
                            <strong>执行动作:</strong><br>
                            ${step.action}<br><br>
                            <strong>详细说明:</strong><br>
                            ${step.description}
                        </div>
                    `;
                    
                    container.appendChild(div);
                });
            } catch (error) {
                document.getElementById('loadingSteps').innerHTML = 
                    `<div style="color: #e74c3c;">加载失败: ${error.message}</div>`;
            }
        }
        
        // 切换步骤详情
        function toggleStepDetail(element, step) {
            // 移除其他active状态
            document.querySelectorAll('.step-item').forEach(item => {
                item.classList.remove('active');
            });
            document.querySelectorAll('.step-detail').forEach(detail => {
                detail.classList.remove('show');
            });
            
            // 添加当前active状态
            element.classList.add('active');
            const detail = element.querySelector('.step-detail');
            detail.classList.add('show');
        }
        
        // 加载已加载的类
        async function loadLoadedClasses() {
            try {
                const response = await fetch('classloader_getLoadedClasses');
                const data = await response.json();
                
                const container = document.getElementById('loadedClasses');
                container.innerHTML = '';
                
                data.classes.forEach((cls, index) => {
                    const div = document.createElement('div');
                    div.className = 'class-item animate-in';
                    div.style.animationDelay = `${index * 0.05}s`;
                    
                    div.innerHTML = `
                        <div class="class-name">${cls.simpleName}</div>
                        <div class="class-package">${cls.package}</div>
                        <div class="class-loader">
                            加载器: ${cls.classLoader} | 
                            父类: ${cls.superclass} | 
                            接口: ${cls.interfaces.join(', ') || '无'}
                        </div>
                    `;
                    
                    div.onclick = () => {
                        alert(`类名: ${cls.name}\n包: ${cls.package}\n加载器: ${cls.classLoader}\n父类: ${cls.superclass}\n接口: ${cls.interfaces.join(', ') || '无'}`);
                    };
                    
                    container.appendChild(div);
                });
            } catch (error) {
                document.getElementById('loadedClasses').innerHTML = 
                    `<div style="color: #e74c3c;">加载失败: ${error.message}</div>`;
            }
        }
        
        // 加载Struts2模块
        async function loadStrutsModules() {
            try {
                const response = await fetch('classloader_getStrutsClasses');
                const data = await response.json();
                
                const container = document.getElementById('strutsModules');
                container.innerHTML = '';
                
                data.modules.forEach((module, index) => {
                    const div = document.createElement('div');
                    div.className = 'module-item animate-in';
                    div.style.animationDelay = `${index * 0.1}s`;
                    
                    const classesHtml = module.classes.map(cls => 
                        `<span class="module-class" title="${cls.package}.${cls.name}">${cls.name}</span>`
                    ).join('');
                    
                    div.innerHTML = `
                        <div class="module-name">${module.name}</div>
                        <div class="module-desc">${module.description}</div>
                        <div class="module-classes">${classesHtml}</div>
                    `;
                    
                    container.appendChild(div);
                });
            } catch (error) {
                document.getElementById('strutsModules').innerHTML = 
                    `<div style="color: #e74c3c;">加载失败: ${error.message}</div>`;
            }
        }
        
        // 页面加载时初始化
        window.onload = function() {
            loadClassLoaderHierarchy();
            loadLoadingSteps();
            loadLoadedClasses();
            loadStrutsModules();
        };
    </script>
</body>
</html>
