Web-based Code Debugger Java

👤 Sharing: AI
```java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class WebBasedCodeDebugger {

    private static final int PORT = 8080; // Or any other available port
    private static ExecutorService executorService = Executors.newFixedThreadPool(10); // Thread pool for handling clients
    private static Map<Integer, DebuggerBreakpoint> breakpoints = new HashMap<>();
    private static List<String> sourceCodeLines = new ArrayList<>();
    private static boolean isRunning = false;
    private static int currentLine = 0;

    public static void main(String[] args) throws IOException {
        System.out.println("Web-based Code Debugger Server started on port " + PORT);

        // Example source code (you can load from file later)
        sourceCodeLines.add("public class Main {");
        sourceCodeLines.add("    public static void main(String[] args) {");
        sourceCodeLines.add("        int x = 5;");
        sourceCodeLines.add("        int y = 10;");
        sourceCodeLines.add("        int sum = x + y;");
        sourceCodeLines.add("        System.out.println(\"Sum: \" + sum);");
        sourceCodeLines.add("    }");
        sourceCodeLines.add("}");


        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            while (true) {
                Socket clientSocket = serverSocket.accept();
                System.out.println("Client connected: " + clientSocket.getInetAddress().getHostAddress());
                executorService.submit(new ClientHandler(clientSocket));
            }
        } catch (IOException e) {
            System.err.println("Error starting server: " + e.getMessage());
        } finally {
            executorService.shutdown();
        }
    }


    static class ClientHandler implements Runnable {
        private Socket clientSocket;
        private PrintWriter out;
        private BufferedReader in;

        public ClientHandler(Socket socket) {
            this.clientSocket = socket;
            try {
                out = new PrintWriter(clientSocket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
            } catch (IOException e) {
                System.err.println("Error creating input/output streams: " + e.getMessage());
            }
        }

        @Override
        public void run() {
            try {
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    System.out.println("Received: " + inputLine);
                    processCommand(inputLine);
                }
            } catch (IOException e) {
                System.err.println("Error reading from client: " + e.getMessage());
            } finally {
                try {
                    clientSocket.close();
                    System.out.println("Client disconnected: " + clientSocket.getInetAddress().getHostAddress());
                } catch (IOException e) {
                    System.err.println("Error closing client socket: " + e.getMessage());
                }
            }
        }



        private void processCommand(String command) {
            String[] parts = command.split(" ", 2);
            String action = parts[0].toLowerCase();

            switch (action) {
                case "getsource":
                    sendSourceCode();
                    break;
                case "setbreakpoint":
                    try {
                        int lineNumber = Integer.parseInt(parts[1]);
                        setBreakpoint(lineNumber);
                    } catch (NumberFormatException e) {
                        sendMessage("Invalid line number.");
                    }
                    break;
                case "removebreakpoint":
                    try {
                        int lineNumber = Integer.parseInt(parts[1]);
                        removeBreakpoint(lineNumber);
                    } catch (NumberFormatException e) {
                        sendMessage("Invalid line number.");
                    }
                    break;

                case "listbreakpoints":
                    listBreakpoints();
                    break;

                case "run":
                    runCode();
                    break;
                case "step":
                    stepCode();
                    break;

                case "continue":
                    continueCode();
                    break;
                case "stop":
                    stopCode();
                    break;
                case "getcurrentline":
                    sendCurrentLine();
                    break;
                default:
                    sendMessage("Unknown command: " + command);
            }
        }



        private void sendSourceCode() {
            StringBuilder code = new StringBuilder();
            for (int i = 0; i < sourceCodeLines.size(); i++) {
                code.append(i + 1).append(": ").append(sourceCodeLines.get(i)).append("\n");
            }
            sendMessage("source\n" + code.toString());
        }


        private void setBreakpoint(int lineNumber) {
            if (lineNumber > 0 && lineNumber <= sourceCodeLines.size()) {
                breakpoints.put(lineNumber, new DebuggerBreakpoint(lineNumber));
                sendMessage("Breakpoint set at line " + lineNumber);
            } else {
                sendMessage("Invalid line number for breakpoint.");
            }
        }


        private void removeBreakpoint(int lineNumber) {
            if (breakpoints.containsKey(lineNumber)) {
                breakpoints.remove(lineNumber);
                sendMessage("Breakpoint removed at line " + lineNumber);
            } else {
                sendMessage("No breakpoint found at line " + lineNumber);
            }
        }


        private void listBreakpoints() {
            StringBuilder breakpointList = new StringBuilder("Breakpoints:\n");
            if (breakpoints.isEmpty()) {
                breakpointList.append("No breakpoints set.");
            } else {
                for (Integer lineNumber : breakpoints.keySet()) {
                    breakpointList.append("Line ").append(lineNumber).append("\n");
                }
            }
            sendMessage("breakpoints\n" + breakpointList.toString());
        }


        private void runCode() {
            isRunning = true;
            currentLine = 1; // Start at the first line
            sendMessage("running"); // Inform client that the code started running
            executeCode();
        }

        private void stepCode() {
            if (!isRunning) {
                sendMessage("Code is not running. Please start the debugger with 'run'.");
                return;
            }

            if (currentLine <= sourceCodeLines.size()) {
                executeLine(currentLine);
                currentLine++;
                sendCurrentLine();


                // Check if we hit a breakpoint after stepping
                 if (breakpoints.containsKey(currentLine)) {
                     sendMessage("breakpoint\n" + currentLine);
                }
                 else if(currentLine > sourceCodeLines.size()){
                     sendMessage("finished");
                     isRunning = false;
                 }
            } else {
                sendMessage("finished"); // Indicates that the execution is finished
                isRunning = false;
            }
        }

        private void continueCode() {
            if (!isRunning) {
                sendMessage("Code is not running. Please start the debugger with 'run'.");
                return;
            }
            executeCode();
        }

        private void stopCode() {
            isRunning = false;
            sendMessage("stopped");
        }

        private void sendCurrentLine() {
             sendMessage("currentline\n" + currentLine);
        }



        private void executeCode() {
            while (isRunning && currentLine <= sourceCodeLines.size()) {
                 executeLine(currentLine);

                if (breakpoints.containsKey(currentLine)) {
                   sendMessage("breakpoint\n" + currentLine);
                    return;  // Pause execution at breakpoint
                }

                currentLine++;
            }

             if(currentLine > sourceCodeLines.size()){
                 sendMessage("finished");
             }

            isRunning = false;
        }


        private void executeLine(int lineNumber) {
            // Simulate execution (in a real debugger, this would involve actual JVM interaction)
            String line = sourceCodeLines.get(lineNumber - 1); // Adjust for 0-based index

            // Simple print to console for simulation
            System.out.println("Executing line " + lineNumber + ": " + line);

            // Example: If you want to send the output of a line (like System.out.println),
            // you would capture it here and send it to the client.
            // For simplicity, we're skipping that step here.
        }

        private void sendMessage(String message) {
            out.println(message);
        }
    }


    static class DebuggerBreakpoint {
        private int lineNumber;

        public DebuggerBreakpoint(int lineNumber) {
            this.lineNumber = lineNumber;
        }

        public int getLineNumber() {
            return lineNumber;
        }
    }
}
```
👁️ Viewed: 9

Comments