package pluginbase.debugsession; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import pluginbase.messages.Message; import pluginbase.messages.Theme; import pluginbase.messages.messaging.MessageReceiver; import pluginbase.messages.messaging.MessagerDebugSubscription; import pluginbase.messages.messaging.Messaging; import java.util.HashMap; import java.util.Map; public class DebugSessionManager { public static final Message DEBUG_SESSION_REMINDER = Message.createMessage("debugsession.reminder", Theme.INFO + "Your debug session is still running. Don't forget to stop it!"); @NotNull private final Messaging messagingPlugin; @NotNull final Map<MessageReceiver, DebugSession> debugSessions = new HashMap<>(); @NotNull private final DebugStream systemOutDebugStream; @NotNull private final DebugStream systemErrDebugStream; private boolean closed = false; public DebugSessionManager(@NotNull Messaging messagingPlugin) { this.messagingPlugin = messagingPlugin; systemOutDebugStream = new DebugStream("System.out", System.out); System.setOut(systemOutDebugStream); systemErrDebugStream = new DebugStream("System.err", System.err); System.setErr(systemErrDebugStream); } @Nullable public DebugSession getDebugSession(@NotNull MessageReceiver messageReceiver) { if (closed) { throw new IllegalStateException("This debug session manager is closed. A new one must be created."); } return debugSessions.get(messageReceiver); } public boolean hasDebugSession(@NotNull MessageReceiver messageReceiver) { if (closed) { throw new IllegalStateException("This debug session manager is closed. A new one must be created."); } return debugSessions.containsKey(messageReceiver); } @NotNull public DebugSession startDebugSession(@NotNull MessageReceiver messageReceiver) throws IllegalStateException { if (closed) { throw new IllegalStateException("This debug session manager is closed. A new one must be created."); } if (debugSessions.containsKey(messageReceiver)) { throw new IllegalStateException("DebugSession already exists for this messageReceiver"); } DebugSubscription debugSubscription = new DebugSubscription(messageReceiver); DebugSession debugSession = startSession(debugSubscription); debugSessions.put(messageReceiver, debugSession); return debugSession; } @NotNull private DebugSession startSession(@NotNull DebugSubscription debugSubscription) { messagingPlugin.getMessager().subscribeToDebugBroadcast(debugSubscription); messagingPlugin.getLog().subscribeToDebugBroadcast(debugSubscription); systemOutDebugStream.subscribeToDebugBroadcast(debugSubscription); systemErrDebugStream.subscribeToDebugBroadcast(debugSubscription); Runnable reminderTask = new Runnable() { @Override public void run() { messagingPlugin.getMessager().message(debugSubscription.getSubscriber(), DEBUG_SESSION_REMINDER); } }; return new DebugSession(debugSubscription, reminderTask); } @NotNull public DebugSession stopDebugSession(@NotNull MessageReceiver messageReceiver) throws IllegalArgumentException { if (closed) { throw new IllegalStateException("This debug session manager is closed. A new one must be created."); } DebugSession debugSession = getDebugSession(messageReceiver); if (debugSession == null) { throw new IllegalArgumentException("There is no DebugSession to stop for this messageReceiver"); } stopSession(debugSession); debugSessions.remove(messageReceiver); return debugSession; } private void stopSession(@NotNull DebugSession debugSession) { messagingPlugin.getMessager().unsubscribeFromDebugBroadcast(debugSession.getDebugSubscription()); messagingPlugin.getLog().unsubscribeFromDebugBroadcast(debugSession.getDebugSubscription()); systemOutDebugStream.unsubscribeFromDebugBroadcast(debugSession.getDebugSubscription()); systemErrDebugStream.unsubscribeFromDebugBroadcast(debugSession.getDebugSubscription()); debugSession.close(); } public void shutdown() { if (closed) { throw new IllegalStateException("This debug session manager is closed. A new one must be created."); } for (DebugSession session : debugSessions.values()) { stopSession(session); } debugSessions.clear(); System.setOut(systemOutDebugStream.getOriginalStream()); System.setErr(systemErrDebugStream.getOriginalStream()); closed = true; } public boolean hasActiveDebugSessions() { if (closed) { throw new IllegalStateException("This debug session manager is closed. A new one must be created."); } return !debugSessions.isEmpty(); } }