package com.bytezone.dm3270.application; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.util.Arrays; import java.util.Optional; import java.util.prefs.Preferences; import com.bytezone.dm3270.display.Screen; import com.bytezone.dm3270.display.ScreenDimensions; import com.bytezone.dm3270.plugins.PluginsStage; import com.bytezone.dm3270.session.Session; import com.bytezone.dm3270.streams.TelnetState; import com.bytezone.dm3270.utilities.Dm3270Utility; import com.bytezone.dm3270.utilities.Site; import com.bytezone.dm3270.utilities.WindowSaver; import javafx.application.Application; import javafx.application.Platform; import javafx.geometry.Rectangle2D; import javafx.scene.Scene; import javafx.stage.Stage; public class Console extends Application { private static final int MAINFRAME_EMULATOR_PORT = 5555; private static final Site DEFAULT_MAINFRAME = new Site ("mainframe", "localhost", MAINFRAME_EMULATOR_PORT, true, 2, false, ""); private Stage primaryStage; private Rectangle2D primaryScreenBounds; private WindowSaver consoleWindowSaver; private WindowSaver spyWindowSaver; private Preferences prefs; private Screen screen; private final ScreenDimensions screenDimensions = new ScreenDimensions (24, 80); private ScreenDimensions alternateScreenDimensions; private final TelnetState telnetState = new TelnetState (); private OptionStage optionStage; private SpyPane spyPane; private ConsolePane consolePane; private ReplayStage replayStage; private MainframeStage mainframeStage; private PluginsStage pluginsStage; public enum Function { SPY, REPLAY, TERMINAL, TEST } @Override public void init () throws Exception { super.init (); prefs = Preferences.userNodeForPackage (this.getClass ()); for (String raw : getParameters ().getRaw ()) if (raw.equalsIgnoreCase ("-reset")) prefs.clear (); if (false) { String[] keys = prefs.keys (); Arrays.sort (keys); for (String key : keys) System.out.printf ("%-18s : %s%n", key, prefs.get (key, "")); } } @Override public void start (Stage primaryStage) throws Exception { this.primaryStage = primaryStage; primaryStage.setOnCloseRequest (e -> Platform.exit ()); primaryStage.setResizable (false); pluginsStage = new PluginsStage (prefs); optionStage = new OptionStage (prefs, pluginsStage); primaryScreenBounds = javafx.stage.Screen.getPrimary ().getVisualBounds (); if (false) System.out.println (javafx.stage.Screen.getPrimary ().getDpi ()); optionStage.okButton.setOnAction (e -> startSelectedFunction ()); optionStage.cancelButton.setOnAction (e -> optionStage.hide ()); optionStage.show (); } private void startSelectedFunction () { optionStage.hide (); String errorMessage = ""; Optional<Site> optionalServerSite = optionStage.serverSitesListStage.getSelectedSite (); Optional<Site> optionalClientSite = optionStage.clientSitesListStage.getSelectedSite (); String optionText = (String) optionStage.functionsGroup.getSelectedToggle ().getUserData (); switch (optionText) { case "Replay": Path path = Paths .get (optionStage.spyFolder + "/" + optionStage.fileComboBox.getValue ()); if (!Files.exists (path)) errorMessage = path + " does not exist"; else try { Session session = new Session (telnetState, path); // can throw Exception alternateScreenDimensions = session.getScreenDimensions (); Optional<Site> serverSite = optionStage.serverSitesListStage .getSelectedSite (session.getServerName ()); if (serverSite.isPresent ()) { Site site = serverSite.get (); setConsolePane (createScreen (Function.REPLAY, site), site); } else { System.out.println ("Couldn't find the server site for " + session.getServerName ()); setConsolePane (createScreen (Function.REPLAY, null), null); } replayStage = new ReplayStage (session, path, prefs, screen); replayStage.show (); } catch (Exception e) { e.printStackTrace (); errorMessage = "Error creating replay window"; } break; case "Terminal": if (optionalServerSite.isPresent ()) { Site serverSite = optionalServerSite.get (); setModel (serverSite); setConsolePane (createScreen (Function.TERMINAL, serverSite), serverSite); consolePane.connect (); } else errorMessage = "No server selected"; break; case "Spy": if (!optionalServerSite.isPresent ()) errorMessage = "No server selected"; else if (!optionalClientSite.isPresent ()) errorMessage = "No client selected"; else { Site serverSite = optionalServerSite.get (); Site clientSite = optionalClientSite.get (); setSpyPane (createScreen (Function.SPY, null), serverSite, clientSite); } break; case "Test": if (!optionalClientSite.isPresent ()) errorMessage = "No client selected"; else { Site clientSite = optionalClientSite.get (); setSpyPane (createScreen (Function.TEST, null), DEFAULT_MAINFRAME, clientSite); mainframeStage = new MainframeStage (telnetState, MAINFRAME_EMULATOR_PORT); mainframeStage.show (); mainframeStage.startServer (); } break; } if (!errorMessage.isEmpty () && Dm3270Utility.showAlert (errorMessage)) optionStage.show (); } private void setModel (Site serverSite) { int model = serverSite.getModel (); System.out.println ("model: " + model); switch (model) { case 2: alternateScreenDimensions = new ScreenDimensions (24, 80); telnetState.setDoDeviceType (2); break; case 3: alternateScreenDimensions = new ScreenDimensions (32, 80); telnetState.setDoDeviceType (3); break; case 4: alternateScreenDimensions = new ScreenDimensions (43, 80); telnetState.setDoDeviceType (4); break; case 5: alternateScreenDimensions = new ScreenDimensions (27, 132); telnetState.setDoDeviceType (5); default: System.out.println ("Invalid model number: " + model); } } // private Optional<Site> findSite (String serverName) // { // Optional<Site> optionalServerSite = // optionStage.serverSitesListStage.getSelectedSite (serverName); // return optionalServerSite; // } private void setConsolePane (Screen screen, Site serverSite) { consolePane = new ConsolePane (screen, serverSite, pluginsStage); Scene scene = new Scene (consolePane); primaryStage.setScene (scene); primaryStage.setTitle ("dm3270"); if (screen.getFunction () == Function.TERMINAL) { consoleWindowSaver = new WindowSaver (prefs, primaryStage, "Terminal"); if (!consoleWindowSaver.restoreWindow ()) primaryStage.centerOnScreen (); } else { consoleWindowSaver = new WindowSaver (prefs, primaryStage, "Console"); if (!consoleWindowSaver.restoreWindow ()) { primaryStage.setX (0); primaryStage.setY (primaryScreenBounds.getMinY () + 100); } } scene.setOnKeyPressed (new ConsoleKeyPress (consolePane, screen)); scene.setOnKeyTyped (new ConsoleKeyEvent (screen)); primaryStage.sizeToScene (); primaryStage.show (); } private void setSpyPane (Screen screen, Site server, Site client) { spyPane = new SpyPane (screen, server, client, telnetState); primaryStage.setScene (new Scene (spyPane)); primaryStage.setTitle ("Terminal Spy"); spyWindowSaver = new WindowSaver (prefs, primaryStage, "Spy"); if (!spyWindowSaver.restoreWindow ()) { primaryStage.setX (0); primaryStage.setY (0); double height = primaryScreenBounds.getHeight () - 20; primaryStage.setHeight (Math.min (height, 1200)); } primaryStage.show (); spyPane.startServer (); } @Override public void stop () { if (mainframeStage != null) mainframeStage.disconnect (); if (spyPane != null) spyPane.disconnect (); if (consolePane != null) consolePane.disconnect (); if (replayStage != null) replayStage.disconnect (); savePreferences (); if (consoleWindowSaver != null) consoleWindowSaver.saveWindow (); if (spyWindowSaver != null) spyWindowSaver.saveWindow (); if (screen != null) screen.close (); } private void savePreferences () { prefs.put ("Function", (String) optionStage.functionsGroup.getSelectedToggle ().getUserData ()); if (screen != null) { prefs.put ("FontName", screen.getFontManager ().getFontName ()); prefs.put ("FontSize", "" + screen.getFontManager ().getFontSize ()); } prefs.put ("Mode", optionStage.toggleModeMenuItem.isSelected () ? "Release" : "Debug"); String filename = optionStage.fileComboBox.getValue (); if (filename != null) prefs.put ("ReplayFile", filename); prefs.put ("SpyFolder", optionStage.spyFolder); prefs.put ("ServerName", optionStage.serverComboBox.getSelectionModel ().getSelectedItem ()); prefs.put ("ClientName", optionStage.clientComboBox.getSelectionModel ().getSelectedItem ()); } private Screen createScreen (Function function, Site site) { screen = new Screen (screenDimensions, alternateScreenDimensions, prefs, function, pluginsStage, site, telnetState); return screen; } public static void main (final String[] arguments) { Application.launch (arguments); } }