diff --git a/README.md b/README.md index cc0effb..05653ca 100644 --- a/README.md +++ b/README.md @@ -5,17 +5,6 @@ Just send a GET, POST, PUT or DELETE HTTP request on a server and get it's respo # Build -You need JavaFX 14, you can download it [here](https://gluonhq.com/products/javafx/) +⚠ Nothing is working for now -I use the language level 14 of Java, if you want to use Java 11, you need to refactor some Switches/Cases - -Tested (and compiled) on Windows 10 and IntelliJ - -# Known issues - -* Issue with HTTPS on IIS (SSL Handshake failed) - -# Binaries - -Compiled binaries with installer downloadable [here](https://alexisdelhaie.ovh/dlcenter/endpoint-installer.exe). (There is no fancy web page now) -This installer are based on [chronos-installer-bootstrap](https://github.com/alexlegarnd/chronos-installer-bootstrap) and [chronos-installer](https://github.com/alexlegarnd/chronos-installer) \ No newline at end of file +I use the language level 15 of Java, if you want to use Java 11, you need to refactor some Switches/Cases diff --git a/javafx.bootstrap/javafx.bootstrap/icon.ico b/javafx.bootstrap/javafx.bootstrap/icon.ico new file mode 100644 index 0000000..2c0ff3c Binary files /dev/null and b/javafx.bootstrap/javafx.bootstrap/icon.ico differ diff --git a/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc b/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc index 222a172..6ad1bf4 100644 --- a/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc +++ b/javafx.bootstrap/javafx.bootstrap/javafx.bootstrap.rc @@ -52,7 +52,7 @@ END // Icon with lowest ID value placed first to ensure application icon // remains consistent on all systems. -IDI_ICON2 ICON "C:\\Users\\robof\\Downloads\\icon.ico" +IDI_ICON2 ICON ".\\icon.ico" #endif // English (United States) resources ///////////////////////////////////////////////////////////////////////////// diff --git a/javafx.bootstrap/javafx.bootstrap/main.cpp b/javafx.bootstrap/javafx.bootstrap/main.cpp index 72aa108..5365560 100644 --- a/javafx.bootstrap/javafx.bootstrap/main.cpp +++ b/javafx.bootstrap/javafx.bootstrap/main.cpp @@ -13,7 +13,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - LPTSTR command = _tcsdup(TEXT(".\\runtime\\bin\\javaw.exe --module-path \".\\lib\" --add-modules javafx.controls,javafx.fxml -jar .\\app\\EndPoint.jar")); + LPTSTR command = _tcsdup(TEXT(".\\runtime\\bin\\javaw.exe -cp .\\app\\EndPoint.jar ovh.alexisdelhaie.endpoint.Application")); if (!CreateProcess(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) { CloseHandle(&pi.hProcess); diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..d11feaa --- /dev/null +++ b/pom.xml @@ -0,0 +1,36 @@ + + + 4.0.0 + + ovh.alexisdelhaie + EndPoint + 0.1.3 + + + 15 + + + + + + com.fasterxml.jackson.core + jackson-core + 2.11.3 + + + + com.fasterxml.jackson.core + jackson-databind + 2.11.3 + + + + com.formdev + flatlaf + 0.43 + + + + \ No newline at end of file diff --git a/src/META-INF/MANIFEST.MF b/src/META-INF/MANIFEST.MF deleted file mode 100644 index 091c70a..0000000 --- a/src/META-INF/MANIFEST.MF +++ /dev/null @@ -1,3 +0,0 @@ -Manifest-Version: 1.0 -Main-Class: ovh.alexisdelhaie.endpoint.Main - diff --git a/src/main/java/META-INF/MANIFEST.MF b/src/main/java/META-INF/MANIFEST.MF new file mode 100644 index 0000000..c0393eb --- /dev/null +++ b/src/main/java/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: ovh.alexisdelhaie.endpoint.Application + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/Application.java b/src/main/java/ovh/alexisdelhaie/endpoint/Application.java new file mode 100644 index 0000000..0f65b7b --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/Application.java @@ -0,0 +1,21 @@ +package ovh.alexisdelhaie.endpoint; + +import com.formdev.flatlaf.FlatIntelliJLaf; +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.*; +import java.io.IOException; + +public class Application { + + public static void main(String[] args) throws UnsupportedLookAndFeelException, IOException { + UIManager.setLookAndFeel(new FlatIntelliJLaf()); + MainWindow dialog = new MainWindow(); + dialog.pack(); + dialog.setTitle("EndPoint"); + dialog.setVisible(true); + Tools.centerFrame(dialog); + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form new file mode 100644 index 0000000..83b9eb6 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form @@ -0,0 +1,127 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java new file mode 100644 index 0000000..354d1f1 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java @@ -0,0 +1,243 @@ +package ovh.alexisdelhaie.endpoint; + +import ovh.alexisdelhaie.endpoint.builder.TabBuilder; +import ovh.alexisdelhaie.endpoint.configuration.ConfigurationDialog; +import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties; +import ovh.alexisdelhaie.endpoint.http.HttpClient; +import ovh.alexisdelhaie.endpoint.http.Request; +import ovh.alexisdelhaie.endpoint.http.RequestBuilder; +import ovh.alexisdelhaie.endpoint.http.Response; +import ovh.alexisdelhaie.endpoint.utils.MessageDialog; + +import javax.imageio.ImageIO; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.io.IOException; +import java.security.KeyManagementException; +import java.security.NoSuchAlgorithmException; +import java.util.HashMap; +import java.util.Objects; +import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; + +public class MainWindow extends JFrame { + + private enum StatusColor { + INFORMATION("#53baf5"), + SUCCESS("#7ccf16"), + REDIRECTION("#b153f5"), + ERROR_CLIENT("#f5ca53"), + ERROR_SERVER("#f55353"); + + private final String hex; + + StatusColor(String s) { + hex = s; + } + + public String getHex() { + return hex; + } + } + + // Constants + public final static int WIDTH = 1280; + public final static int HEIGHT = 720; + + private JPanel contentPane; + private JComboBox methodBox; + private JTextField urlField; + private JButton sendButton; + private JTabbedPane tabbedPane1; + private JButton newTabButton; + private JProgressBar progressBar1; + private JLabel statusLabel; + private JButton settingsButton; + + private final ConfigurationProperties props; + private final HashMap urls; + + private final ConcurrentHashMap controlState; + private final ConcurrentHashMap responses; + + public MainWindow() throws IOException { + props = new ConfigurationProperties(); + controlState = new ConcurrentHashMap<>(); + responses = new ConcurrentHashMap<>(); + urls = new HashMap<>(); + setIconImage(ImageIO.read(MainWindow.class.getResource("/icon.png"))); + setContentPane(contentPane); + setMinimumSize(new Dimension(WIDTH, HEIGHT)); + setSize(WIDTH, HEIGHT); + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + TabBuilder.create(tabbedPane1, "New request", urls, urlField); + Component tab = tabbedPane1.getSelectedComponent(); + urls.put(tab.hashCode(), ""); + enableControl(true, tab.hashCode()); + settingsButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + ConfigurationDialog.showDialog(props); + } + }); + newTabButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + TabBuilder.create(tabbedPane1, "New request", urls, urlField); + Component tab = tabbedPane1.getSelectedComponent(); + urls.put(tab.hashCode(), ""); + enableControl(true, tab.hashCode()); + showStatus(tab.hashCode()); + } + }); + sendButton.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (!urlField.getText().isBlank()) { + sendRequest(); + } else { + MessageDialog.info("Url field empty", "Please enter an url"); + } + } + }); + tabbedPane1.addChangeListener(e -> { + if (tabbedPane1.getSelectedIndex() != -1) { + int hashCode = tabbedPane1.getSelectedComponent().hashCode(); + urlField.setText(urls.get(hashCode)); + enableControl(controlState.get(hashCode), hashCode); + showStatus(tab.hashCode()); + } + }); + urlField.getDocument().addDocumentListener(new DocumentListener() { + public void changedUpdate(DocumentEvent e) { + warn(); + } + public void removeUpdate(DocumentEvent e) { + warn(); + } + public void insertUpdate(DocumentEvent e) { + warn(); + } + + public void warn() { + if (tabbedPane1.getSelectedIndex() != -1) { + urls.put(tabbedPane1.getSelectedComponent().hashCode(), urlField.getText()); + } + } + }); + } + + private void sendRequest() { + Optional possibleTab = getSelectedTab(); + if (possibleTab.isPresent()) { + JSplitPane tab = possibleTab.get(); + int tabHashCode = tab.hashCode(); + statusLabel.setVisible(false); + enableControl(false, tabHashCode); + int i = tabbedPane1.indexOfComponent(tab); + JTextArea responseBody = TabBuilder.getResponseArea(i); + responseBody.setForeground(Color.black); + responseBody.setText(""); + JTextArea bodyField = TabBuilder.getBody(i); + new Thread(() -> { + try { + String url = urlField.getText(); + HttpClient h = new HttpClient(props); + Request r = new RequestBuilder(url) + .setCustomHeaders(TabBuilder.getHeaders(i)) + .build(); + Optional possibleRes = Optional.empty(); + switch ((String) Objects.requireNonNull(methodBox.getSelectedItem())) { + case "GET" -> possibleRes = h.get(r); + case "POST" -> possibleRes = h.post(r, bodyField.getText()); + case "PUT" -> possibleRes = h.put(r, bodyField.getText()); + case "DELETE" -> possibleRes = h.delete(r); + case "HEAD" -> possibleRes = h.head(r); + } + if (possibleRes.isPresent()) { + Response res = possibleRes.get(); + responses.put(tabHashCode, res); + responseBody.setText(res.getBody()); + } + } catch (KeyManagementException | IOException | NoSuchAlgorithmException e) { + responseBody.setForeground(Color.red); + responseBody.setText(e.getMessage()); + if (responses.containsKey(tabHashCode)) { + responses.remove(tabHashCode); + showStatus(tabHashCode); + } + } finally { + enableControl(true, tabHashCode); + showStatus(tabHashCode); + } + }).start(); + } else { + MessageDialog.error("Error", "Cannot get current tab"); + } + } + + private void enableControl(Boolean state, int hashCode) { + if (Objects.nonNull(state)) { + controlState.put(hashCode, state); + if (tabbedPane1.getSelectedComponent().hashCode() == hashCode) { + sendButton.setEnabled(state); + urlField.setEnabled(state); + methodBox.setEnabled(state); + progressBar1.setIndeterminate(!state); + } + } + } + + private void showStatus(int hashCode) { + if (controlState.get(hashCode) && responses.containsKey(hashCode) && + tabbedPane1.getSelectedComponent().hashCode() == hashCode) { + statusLabel.setForeground(Color.BLACK); + Response res = responses.get(hashCode); + final StringBuilder sb = new StringBuilder(); + if (res.getStatusCode() != -1) { + sb.append(res.getStatusCode()) + .append(" ") + .append(res.getStatus()) + .append(" (in ") + .append(res.getTime()) + .append(" ms)"); + if (res.getStatusCode() >= 100 && res.getStatusCode() < 200) { + statusLabel.setForeground(Color.decode(StatusColor.INFORMATION.getHex())); + } else if (res.getStatusCode() >= 200 && res.getStatusCode() < 300) { + statusLabel.setForeground(Color.decode(StatusColor.SUCCESS.getHex())); + } else if (res.getStatusCode() >= 300 && res.getStatusCode() < 400) { + statusLabel.setForeground(Color.decode(StatusColor.REDIRECTION.getHex())); + } else if (res.getStatusCode() >= 400 && res.getStatusCode() < 500) { + statusLabel.setForeground(Color.decode(StatusColor.ERROR_CLIENT.getHex())); + } else if (res.getStatusCode() >= 500) { + statusLabel.setForeground(Color.decode(StatusColor.ERROR_SERVER.getHex())); + } + } else { + sb.append("in ") + .append(res.getTime()) + .append(" ms"); + } + + statusLabel.setText(sb.toString()); + statusLabel.setVisible(true); + } else { + statusLabel.setVisible(false); + } + } + + private Optional getSelectedTab() { + Component c = tabbedPane1.getSelectedComponent(); + if (c instanceof JSplitPane) { + return Optional.of((JSplitPane) c); + } + return Optional.empty(); + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java b/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java new file mode 100644 index 0000000..881a393 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java @@ -0,0 +1,142 @@ +package ovh.alexisdelhaie.endpoint.builder; + +import ovh.alexisdelhaie.endpoint.utils.Tools; +import ovh.alexisdelhaie.endpoint.utils.adapter.CustomDeleteMouseAdapter; +import ovh.alexisdelhaie.endpoint.utils.adapter.CustomNewMouseAdapter; +import ovh.alexisdelhaie.endpoint.utils.adapter.DeleteParamMouseAdapter; +import ovh.alexisdelhaie.endpoint.utils.adapter.NewParamMouseAdapter; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.HashMap; + +public class TabBuilder { + + private static final HashMap indexes = new HashMap<>(); + + public static void create(JTabbedPane tab, String label, HashMap urls, JTextField urlField) { + Component c = tab.add("", buildMainPanel(urlField)); + int index = tab.indexOfComponent(c); + updateIndexes(index); + tab.setTabComponentAt(index, buildTabPanel(tab, c, label, urls)); + tab.setSelectedComponent(c); + } + + private static void updateIndexes(int index) { + indexes.put("main[" + index + "].responseTextArea", indexes.get("main[waiting].responseTextArea")); + indexes.put("main[" + index + "].body", indexes.get("main[waiting].body")); + indexes.put("main[" + index + "].params", indexes.get("main[waiting].params")); + indexes.put("main[" + index + "].headers", indexes.get("main[waiting].headers")); + indexes.remove("main[waiting].responseTextArea"); + indexes.remove("main[waiting].body"); + indexes.remove("main[waiting].params"); + indexes.remove("main[waiting].headers"); + } + + private static JPanel buildTabPanel(JTabbedPane tab, Component c, String label, HashMap urls) { + JPanel p = new JPanel(new GridBagLayout()); + p.setOpaque(false); + JLabel l = new JLabel(label); + GridBagConstraints g = new GridBagConstraints(); + g.gridx = 0; + g.gridy = 0; + g.weightx = 1; + p.add(l, g); + g.gridx++; + g.weightx = 0; + p.add(buildCloseButton(tab, c, urls), g); + return p; + } + + private static JButton buildCloseButton(JTabbedPane tab, Component c, HashMap urls) { + JButton b = new JButton("×"); + b.setBorderPainted(false); + b.setFocusPainted(false); + b.setOpaque(false); + b.setContentAreaFilled(false); + b.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + urls.remove(c.hashCode()); + tab.remove(c); + } + }); + return b; + } + + private static JSplitPane buildMainPanel(JTextField urlField) { + JTextArea t = new JTextArea(); + t.setBackground(Color.WHITE); + t.setEditable(false); + JScrollPane sp = new JScrollPane(t); + indexes.put("main[waiting].responseTextArea", t); + return new JSplitPane( + JSplitPane.VERTICAL_SPLIT, + buildParametersTabbedPane(urlField), + sp + ); + } + + private static JTabbedPane buildParametersTabbedPane(JTextField urlField) { + JTabbedPane p = new JTabbedPane(); + p.add("Params", buildParamsTab(true, urlField)); + p.add("Authorization", new JPanel()); + p.add("Headers", buildParamsTab(false, null)); + JTextArea body = new JTextArea(); + indexes.put("main[waiting].body", body); + p.add("Body", body); + return p; + } + + public static JTextArea getResponseArea(int index) { + return (JTextArea) indexes.get("main[" + index + "].responseTextArea"); + } + + public static JTextArea getBody(int index) { + return (JTextArea) indexes.get("main[" + index + "].body"); + } + + public static HashMap getParams(int index) { + JTable t = (JTable) indexes.get("main[" + index + "].params"); + return Tools.tableToHashMap(t); + } + + public static HashMap getHeaders(int index) { + JTable t = (JTable) indexes.get("main[" + index + "].headers"); + return Tools.tableToHashMap(t); + } + + private static JPanel buildParamsTab(boolean isParam, JTextField urlField) { + String[] headers = {"Keys", "Values"}; + DefaultTableModel model = new DefaultTableModel(new Object[][]{}, headers); + JPanel p = new JPanel(); + JTable t = new JTable(model); + indexes.put((isParam) ? "main[waiting].params" : "main[waiting].headers", t); + JButton addButton = new JButton("New"); + JButton delButton = new JButton("Remove"); + delButton.setEnabled(false); + t.getSelectionModel().addListSelectionListener(event -> delButton.setEnabled(t.getSelectedRows().length > 0)); + if (isParam) { + addButton.addMouseListener(new NewParamMouseAdapter(t, urlField)); + delButton.addMouseListener(new DeleteParamMouseAdapter(t, urlField)); + } else { + addButton.addMouseListener(new CustomNewMouseAdapter(t)); + delButton.addMouseListener(new CustomDeleteMouseAdapter(t)); + } + p.add(addButton); + p.add(delButton); + p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS)); + + JPanel pp = new JPanel(); + pp.add(p); + JScrollPane sp = new JScrollPane(t); + pp.add(sp); + pp.setLayout(new BoxLayout(pp, BoxLayout.Y_AXIS)); + return pp; + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form new file mode 100644 index 0000000..4703c1d --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form @@ -0,0 +1,63 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java new file mode 100644 index 0000000..d4dc42f --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java @@ -0,0 +1,37 @@ +package ovh.alexisdelhaie.endpoint.configuration; + +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.*; + +public class AboutDialog extends JDialog { + + public static final int WIDTH = 450; + public static final int HEIGHT = 500; + + public static final String VERSION = "0.1.3"; + + private JPanel contentPane; + private JLabel version; + private JLabel javaVersion; + + private AboutDialog() { + setContentPane(contentPane); + setModal(true); + setTitle("About EndPoint"); + version.setText("Version: " + VERSION + " (NOT FINISHED)"); + javaVersion.setText("Software: Java " + System.getProperty("java.version") + " (GUI: Java Swing)"); + } + + public static void showDialog() { + AboutDialog dialog = new AboutDialog(); + dialog.setModal(true); + dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setResizable(false); + Tools.centerFrame(dialog); + dialog.setVisible(true); + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.form b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.form new file mode 100644 index 0000000..f45007c --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.form @@ -0,0 +1,175 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.java b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.java new file mode 100644 index 0000000..50ad4c1 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationDialog.java @@ -0,0 +1,64 @@ +package ovh.alexisdelhaie.endpoint.configuration; + +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.*; + +public class ConfigurationDialog extends JDialog { + + public static final int WIDTH = 450; + public static final int HEIGHT = 700; + + private JPanel contentPane; + private JButton buttonOK; + private JCheckBox allowInvalidSsl; + private JCheckBox allowDowngrade; + private JComboBox httpVersion; + private JSpinner timeout; + private JButton aboutButton; + + private final ConfigurationProperties props; + + private ConfigurationDialog(ConfigurationProperties props) { + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + setTitle("Settings"); + this.props = props; + buttonOK.addActionListener(e -> onOK()); + aboutButton.addActionListener(e -> AboutDialog.showDialog()); + allowInvalidSsl.setSelected(this.props.getBooleanProperty("allowInvalidSsl", false)); + allowDowngrade.setSelected(this.props.getBooleanProperty("allowDowngrade", true)); + httpVersion.setSelectedItem(this.props.getStringProperty("httpVersion", "HTTP/1.0")); + timeout.setValue(this.props.getIntegerProperty("timeout", 10000)); + + allowInvalidSsl.addActionListener((e) -> { + this.props.setProperty("allowInvalidSsl", String.valueOf(allowInvalidSsl.isSelected())); + }); + allowDowngrade.addActionListener((e) -> { + this.props.setProperty("allowDowngrade", String.valueOf(allowDowngrade.isSelected())); + }); + httpVersion.addActionListener((e) -> { + this.props.setProperty("httpVersion", (String) httpVersion.getSelectedItem()); + }); + timeout.addChangeListener((e) -> { + this.props.setProperty("timeout", String.valueOf(timeout.getValue())); + }); + + } + + private void onOK() { + dispose(); + } + + public static void showDialog(ConfigurationProperties props) { + ConfigurationDialog dialog = new ConfigurationDialog(props); + dialog.setModal(true); + dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setResizable(false); + Tools.centerFrame(dialog); + dialog.setVisible(true); + } +} diff --git a/src/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java similarity index 77% rename from src/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java rename to src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java index a2a5b21..6616350 100644 --- a/src/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/ConfigurationProperties.java @@ -2,7 +2,7 @@ package ovh.alexisdelhaie.endpoint.configuration; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; -import javafx.scene.control.Alert; +import ovh.alexisdelhaie.endpoint.utils.MessageDialog; import java.io.File; import java.io.IOException; @@ -52,15 +52,18 @@ public class ConfigurationProperties { return defaultB; } + public int getIntegerProperty(String key, int defaultI) { + if (properties.containsKey(key)) { + return Integer.parseInt(properties.get(key)); + } + return defaultI; + } + private void save() { try { mapper.writeValue(new File(filepath), properties); } catch (Exception e) { - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle("Cannot save settings"); - alert.setHeaderText("There was an error while saving settings file"); - alert.setContentText(e.getMessage()); - alert.showAndWait(); + MessageDialog.error("Cannot save settings", "There was an error while saving settings file"); } } @@ -71,11 +74,7 @@ public class ConfigurationProperties { properties = mapper.readValue(f, new TypeReference>() { }); } } catch (IOException e) { - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle("Cannot initialize settings"); - alert.setHeaderText("There was an error while initializing settings file"); - alert.setContentText(e.getMessage()); - alert.showAndWait(); + MessageDialog.error("Cannot initialize settings", "There was an error while initializing settings file"); } } @@ -88,11 +87,7 @@ public class ConfigurationProperties { Files.createDirectories(path); } } catch (IOException e) { - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle("Cannot create app folder"); - alert.setHeaderText("There was an error while creating appdata folder"); - alert.setContentText(e.getMessage()); - alert.showAndWait(); + MessageDialog.error("Cannot create app folder", "There was an error while creating appdata folder"); } } diff --git a/src/ovh/alexisdelhaie/endpoint/http/HttpClient.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java similarity index 96% rename from src/ovh/alexisdelhaie/endpoint/http/HttpClient.java rename to src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java index 7541d83..261d5bf 100644 --- a/src/ovh/alexisdelhaie/endpoint/http/HttpClient.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/http/HttpClient.java @@ -22,17 +22,21 @@ public class HttpClient { public final static int DEFAULT_TIMEOUT = 10000; public final static boolean DEFAULT_ALLOW_INVALID_SSL = false; public final static boolean DEFAULT_ALLOW_DOWNGRADE = true; - public final static String DEFAULT_HTTP_VERSION = "HTTP/1.1"; + public final static String DEFAULT_HTTP_VERSION = "HTTP/1.0"; private final boolean allowInvalidSsl; private final boolean allowDowngrade; private final String httpVersion; + private final int timeout; + private boolean downgraded; public HttpClient(ConfigurationProperties props) { this.allowInvalidSsl = props.getBooleanProperty("allowInvalidSsl", DEFAULT_ALLOW_INVALID_SSL); this.allowDowngrade = props.getBooleanProperty("allowDowngrade", DEFAULT_ALLOW_DOWNGRADE); this.httpVersion = props.getStringProperty("httpVersion", DEFAULT_HTTP_VERSION); + this.timeout = props.getIntegerProperty("timeout", DEFAULT_TIMEOUT); + this.downgraded = false; } @@ -99,7 +103,7 @@ public class HttpClient { private Socket buildSocket(String host, int port) throws IOException { Socket s = new Socket(host, port); s.setKeepAlive(false); - s.setSoTimeout(DEFAULT_TIMEOUT); + s.setSoTimeout(timeout); return s; } @@ -124,7 +128,7 @@ public class HttpClient { SSLSocket s = (SSLSocket) factory.createSocket(host, port); s.setEnabledProtocols(new String[] { "SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" }); s.setKeepAlive(false); - s.setSoTimeout(DEFAULT_TIMEOUT); + s.setSoTimeout(timeout); if (allowDowngrade) { try { s.startHandshake(); diff --git a/src/ovh/alexisdelhaie/endpoint/http/HttpStatus.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/HttpStatus.java similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/http/HttpStatus.java rename to src/main/java/ovh/alexisdelhaie/endpoint/http/HttpStatus.java diff --git a/src/ovh/alexisdelhaie/endpoint/http/Request.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/Request.java similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/http/Request.java rename to src/main/java/ovh/alexisdelhaie/endpoint/http/Request.java diff --git a/src/ovh/alexisdelhaie/endpoint/http/RequestBuilder.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/RequestBuilder.java similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/http/RequestBuilder.java rename to src/main/java/ovh/alexisdelhaie/endpoint/http/RequestBuilder.java diff --git a/src/ovh/alexisdelhaie/endpoint/http/Response.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/http/Response.java rename to src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java diff --git a/src/ovh/alexisdelhaie/endpoint/http/parsers/Chunked.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/parsers/Chunked.java similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/http/parsers/Chunked.java rename to src/main/java/ovh/alexisdelhaie/endpoint/http/parsers/Chunked.java diff --git a/src/ovh/alexisdelhaie/endpoint/url/SpecialChar.java b/src/main/java/ovh/alexisdelhaie/endpoint/url/SpecialChar.java similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/url/SpecialChar.java rename to src/main/java/ovh/alexisdelhaie/endpoint/url/SpecialChar.java diff --git a/src/ovh/alexisdelhaie/endpoint/url/URLGenerator.java b/src/main/java/ovh/alexisdelhaie/endpoint/url/URLGenerator.java similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/url/URLGenerator.java rename to src/main/java/ovh/alexisdelhaie/endpoint/url/URLGenerator.java diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/InsertToTableDialog.form b/src/main/java/ovh/alexisdelhaie/endpoint/utils/InsertToTableDialog.form new file mode 100644 index 0000000..91d4557 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/InsertToTableDialog.form @@ -0,0 +1,105 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/InsertToTableDialog.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/InsertToTableDialog.java new file mode 100644 index 0000000..02796c5 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/InsertToTableDialog.java @@ -0,0 +1,79 @@ +package ovh.alexisdelhaie.endpoint.utils; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.*; +import java.util.Optional; + +public class InsertToTableDialog extends JDialog { + + public static final int WIDTH = 325; + public static final int HEIGHT = 195; + + private JPanel contentPane; + private JButton buttonOK; + private JButton buttonCancel; + private JTextField keyField; + private JTextField valueField; + private JLabel message; + + private boolean accepted = false; + + private InsertToTableDialog(String message) { + setTitle("Insert"); + setContentPane(contentPane); + setModal(true); + getRootPane().setDefaultButton(buttonOK); + this.message.setText(message); + + buttonOK.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + onOK(); + } + }); + + buttonCancel.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }); + + // call onCancel() when cross is clicked + setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + onCancel(); + } + }); + + // call onCancel() on ESCAPE + contentPane.registerKeyboardAction(new ActionListener() { + public void actionPerformed(ActionEvent e) { + onCancel(); + } + }, KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); + } + + private void onOK() { + accepted = true; + dispose(); + } + + private void onCancel() { + dispose(); + } + + public static Optional showDialog(String message) { + InsertToTableDialog dialog = new InsertToTableDialog(message); + dialog.setModal(true); + dialog.setMinimumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setMaximumSize(new Dimension(WIDTH, HEIGHT)); + dialog.setResizable(false); + Tools.centerFrame(dialog); + dialog.setVisible(true); + if (dialog.accepted && !dialog.keyField.getText().isBlank()) { + return Optional.of(new KeyValuePair(dialog.keyField.getText(), dialog.valueField.getText())); + } + return Optional.empty(); + } +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/KeyValuePair.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/KeyValuePair.java new file mode 100644 index 0000000..1766c68 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/KeyValuePair.java @@ -0,0 +1,20 @@ +package ovh.alexisdelhaie.endpoint.utils; + +public class KeyValuePair { + + private String key; + private String value; + + public KeyValuePair(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/MessageDialog.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/MessageDialog.java new file mode 100644 index 0000000..012c731 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/MessageDialog.java @@ -0,0 +1,22 @@ +package ovh.alexisdelhaie.endpoint.utils; + +import javax.swing.*; + +public class MessageDialog { + + public static void error(String title, String message) { + JOptionPane.showMessageDialog(new JFrame(), message, title, + JOptionPane.ERROR_MESSAGE); + } + + public static void warning(String title, String message) { + JOptionPane.showMessageDialog(new JFrame(), message, title, + JOptionPane.WARNING_MESSAGE); + } + + public static void info(String title, String message) { + JOptionPane.showMessageDialog(new JFrame(), message, title, + JOptionPane.INFORMATION_MESSAGE); + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/Tools.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/Tools.java new file mode 100644 index 0000000..65d51f1 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/Tools.java @@ -0,0 +1,35 @@ +package ovh.alexisdelhaie.endpoint.utils; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.*; +import java.util.HashMap; + +public class Tools { + + public static Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + + public static void centerFrame(Dialog dialog) { + int y = (int)( screen.getHeight() / 2 ) - dialog.getHeight() / 2; + int x = (int)( screen.getWidth() / 2 ) - dialog.getWidth() / 2; + dialog.setLocation(x, y); + } + + public static void centerFrame(Frame frame) { + int y = (int)( screen.getHeight() / 2 ) - frame.getHeight() / 2; + int x = (int)( screen.getWidth() / 2 ) - frame.getWidth() / 2; + frame.setLocation(x, y); + } + + public static HashMap tableToHashMap(JTable table) { + HashMap result = new HashMap<>(); + DefaultTableModel m = (DefaultTableModel) table.getModel(); + for (int i = 0; i < m.getRowCount(); i++) { + String key = (String) m.getValueAt(i, 0); + String value = (String) m.getValueAt(i, 1); + result.put(key, value); + } + return result; + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomDeleteMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomDeleteMouseAdapter.java new file mode 100644 index 0000000..3583dc9 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomDeleteMouseAdapter.java @@ -0,0 +1,34 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class CustomDeleteMouseAdapter extends MouseAdapter { + + protected final JTable table; + protected boolean valid = false; + + public CustomDeleteMouseAdapter(JTable table) { + this.table = table; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + updateTable(); + } + + private void updateTable() { + int n = table.getSelectedRows().length; + if (n > 0) { + DefaultTableModel m = (DefaultTableModel) table.getModel(); + for(int i = 0; i < n; i++) { + m.removeRow(table.getSelectedRow()); + } + valid = true; + } + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomNewMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomNewMouseAdapter.java new file mode 100644 index 0000000..f2288ab --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/CustomNewMouseAdapter.java @@ -0,0 +1,36 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import ovh.alexisdelhaie.endpoint.utils.InsertToTableDialog; +import ovh.alexisdelhaie.endpoint.utils.KeyValuePair; + +import javax.swing.*; +import javax.swing.table.DefaultTableModel; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.Optional; + +public class CustomNewMouseAdapter extends MouseAdapter { + + protected final JTable table; + protected boolean valid = false; + + public CustomNewMouseAdapter(JTable table) { + this.table = table; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + updateTable(); + } + + private void updateTable() { + Optional result = InsertToTableDialog.showDialog("Enter value"); + if (result.isPresent()) { + DefaultTableModel m = (DefaultTableModel) table.getModel(); + m.addRow(new Object[]{result.get().getKey(), result.get().getValue()}); + valid = true; + } + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/DeleteParamMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/DeleteParamMouseAdapter.java new file mode 100644 index 0000000..d7e5080 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/DeleteParamMouseAdapter.java @@ -0,0 +1,26 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import ovh.alexisdelhaie.endpoint.url.URLGenerator; +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.event.MouseEvent; + +public class DeleteParamMouseAdapter extends CustomDeleteMouseAdapter { + + private final JTextField urlField; + + public DeleteParamMouseAdapter(JTable table, JTextField urlField) { + super(table); + this.urlField = urlField; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (super.valid) { + urlField.setText(URLGenerator.processNewUrl(Tools.tableToHashMap(super.table), urlField.getText())); + } + } + +} diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/NewParamMouseAdapter.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/NewParamMouseAdapter.java new file mode 100644 index 0000000..e85992a --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/adapter/NewParamMouseAdapter.java @@ -0,0 +1,26 @@ +package ovh.alexisdelhaie.endpoint.utils.adapter; + +import ovh.alexisdelhaie.endpoint.url.URLGenerator; +import ovh.alexisdelhaie.endpoint.utils.Tools; + +import javax.swing.*; +import java.awt.event.MouseEvent; + +public class NewParamMouseAdapter extends CustomNewMouseAdapter { + + private final JTextField urlField; + + public NewParamMouseAdapter(JTable table, JTextField urlField) { + super(table); + this.urlField = urlField; + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (super.valid) { + urlField.setText(URLGenerator.processNewUrl(Tools.tableToHashMap(super.table), urlField.getText())); + } + } + +} diff --git a/src/ovh/alexisdelhaie/endpoint/controllers/icon.png b/src/main/resources/icon.png similarity index 100% rename from src/ovh/alexisdelhaie/endpoint/controllers/icon.png rename to src/main/resources/icon.png diff --git a/src/ovh/alexisdelhaie/endpoint/Main.java b/src/ovh/alexisdelhaie/endpoint/Main.java deleted file mode 100644 index 00cd5e6..0000000 --- a/src/ovh/alexisdelhaie/endpoint/Main.java +++ /dev/null @@ -1,33 +0,0 @@ -package ovh.alexisdelhaie.endpoint; - -import javafx.application.Application; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.image.Image; -import javafx.stage.Stage; -import ovh.alexisdelhaie.endpoint.controllers.Controller; - -public class Main extends Application { - - @Override - public void start(Stage primaryStage) throws Exception{ - FXMLLoader loader = new FXMLLoader(getClass().getResource("mainwindow.fxml")); - Parent root = loader.load(); - Controller controller = loader.getController(); - controller.setStageAndSetupListeners(primaryStage); - primaryStage.setTitle("EndPoint"); - primaryStage.setScene(new Scene(root, 1067, 644)); - primaryStage.setMinWidth(1067); - primaryStage.setMinHeight(644); - primaryStage.setMaximized(true); - primaryStage.getIcons().add( new Image( - Main.class.getResourceAsStream( "icon.png" ))); - primaryStage.show(); - } - - - public static void main(String[] args) { - launch(args); - } -} diff --git a/src/ovh/alexisdelhaie/endpoint/controllers/ConfigurationController.java b/src/ovh/alexisdelhaie/endpoint/controllers/ConfigurationController.java deleted file mode 100644 index d82605e..0000000 --- a/src/ovh/alexisdelhaie/endpoint/controllers/ConfigurationController.java +++ /dev/null @@ -1,85 +0,0 @@ -package ovh.alexisdelhaie.endpoint.controllers; - -import javafx.collections.FXCollections; -import javafx.event.ActionEvent; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.Alert; -import javafx.scene.control.CheckBox; -import javafx.scene.control.ChoiceBox; -import javafx.scene.image.Image; -import javafx.scene.input.MouseEvent; -import javafx.stage.Modality; -import javafx.stage.Stage; -import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties; - -import java.io.IOException; - -public class ConfigurationController -{ - - private ConfigurationProperties configurationProperties; - private Stage primaryStage; - - @FXML - private CheckBox allowInvalidSsl; - @FXML - private CheckBox allowDowngrade; - @FXML - private ChoiceBox httpVersion; - - public void setStageAndSetupListeners(Stage s) { - primaryStage = s; - } - - public void setConfigurationProperties(ConfigurationProperties properties) { - String[] versions = { "HTTP/1.1", "HTTP/1.0" }; - httpVersion.setItems(FXCollections.observableArrayList(versions)); - configurationProperties = properties; - allowInvalidSsl.setSelected(properties.getBooleanProperty("allowInvalidSsl", false)); - allowDowngrade.setSelected(properties.getBooleanProperty("allowDowngrade", true)); - httpVersion.setValue(properties.getStringProperty("httpVersion", versions[0])); - httpVersion.setOnAction(this::onChoiceBoxValueChanged); - } - - @FXML - private void onBooleanValueChanged(MouseEvent event) { - CheckBox c = (CheckBox) event.getSource(); - configurationProperties.setProperty(c.getId(), String.valueOf(c.isSelected())); - } - - @SuppressWarnings("unchecked") - private void onChoiceBoxValueChanged(ActionEvent event) { - ChoiceBox c = (ChoiceBox) event.getSource(); - configurationProperties.setProperty(c.getId(), c.getValue()); - } - - @FXML - private void showAboutDialog() { - try { - Stage dialog = new Stage(); - Parent xml = FXMLLoader.load(getClass().getResource("about.fxml")); - dialog.initOwner(primaryStage); - dialog.setScene(new Scene(xml, 707, 365)); - dialog.setMaxHeight(365); - dialog.setMinHeight(365); - dialog.setMaxWidth(707); - dialog.setMinWidth(707); - dialog.setResizable(false); - dialog.setTitle("About EndPoint"); - dialog.getIcons().add( new Image( - Controller.class.getResourceAsStream( "icon.png" ))); - dialog.initModality(Modality.APPLICATION_MODAL); - dialog.showAndWait(); - } catch (IOException e) { - Alert alert = new Alert(Alert.AlertType.ERROR); - alert.setTitle("Cannot initialize About"); - alert.setHeaderText("There was an error while initializing this dialog"); - alert.setContentText(e.getMessage()); - alert.showAndWait(); - } - } - -} diff --git a/src/ovh/alexisdelhaie/endpoint/controllers/Controller.java b/src/ovh/alexisdelhaie/endpoint/controllers/Controller.java deleted file mode 100644 index ee4ce00..0000000 --- a/src/ovh/alexisdelhaie/endpoint/controllers/Controller.java +++ /dev/null @@ -1,471 +0,0 @@ -package ovh.alexisdelhaie.endpoint.controllers; - -import javafx.application.Platform; -import javafx.beans.property.StringProperty; -import javafx.collections.FXCollections; -import javafx.fxml.FXML; -import javafx.fxml.FXMLLoader; -import javafx.fxml.Initializable; -import javafx.geometry.Orientation; -import javafx.scene.Node; -import javafx.scene.Parent; -import javafx.scene.Scene; -import javafx.scene.control.*; -import javafx.scene.control.cell.PropertyValueFactory; -import javafx.scene.image.Image; -import javafx.scene.layout.GridPane; -import javafx.scene.layout.Pane; -import javafx.scene.paint.Color; -import javafx.stage.Modality; -import javafx.stage.Stage; -import org.apache.commons.validator.routines.UrlValidator; -import ovh.alexisdelhaie.endpoint.configuration.ConfigurationProperties; -import ovh.alexisdelhaie.endpoint.http.HttpClient; -import ovh.alexisdelhaie.endpoint.http.Request; -import ovh.alexisdelhaie.endpoint.http.RequestBuilder; -import ovh.alexisdelhaie.endpoint.http.Response; -import ovh.alexisdelhaie.endpoint.impl.EditCell; -import ovh.alexisdelhaie.endpoint.model.Param; -import ovh.alexisdelhaie.endpoint.url.URLGenerator; - -import java.io.IOException; -import java.net.MalformedURLException; -import java.net.URL; -import java.security.KeyManagementException; -import java.security.NoSuchAlgorithmException; -import java.util.HashMap; -import java.util.Map; -import java.util.Optional; -import java.util.ResourceBundle; -import java.util.function.Function; - -public class Controller implements Initializable { - - private enum StatusColor { - INFORMATION("#53baf5"), - SUCCESS("#7ccf16"), - REDIRECTION("#b153f5"), - ERROR_CLIENT("#f5ca53"), - ERROR_SERVER("#f55353"), - DEFAULT("BLACK"); - - private final String hex; - - StatusColor(String s) { - hex = s; - } - - public String getHex() { - return hex; - } - } - - private enum RequestTab { - PARAMS(0), - AUTHORIZATION(1), - HEADERS(2), - BODY(3), - RESPONSE(4); - - private final int index; - - RequestTab (int i) { index = i; } - public int getIndex() { return index; } - } - - @FXML - private ChoiceBox httpMethod; - @FXML - private TabPane tabs; - @FXML - private TextField requestInput; - @FXML - private Pane runningIndicatorPane; - - private Stage primaryStage; - private HashMap requests; - private HashMap methods; - - private ConfigurationProperties properties; - - @Override - public void initialize(URL location, ResourceBundle resources) { - properties = new ConfigurationProperties(); - requests = new HashMap<>(); - methods = new HashMap<>(); - String[] method = { "GET", "POST", "HEAD", "PUT", "DELETE" }; - httpMethod.setItems(FXCollections.observableArrayList(method)); - httpMethod.setValue(method[0]); - httpMethod.setOnAction(actionEvent -> httpMethodChanged()); - tabs.getSelectionModel().selectedItemProperty().addListener( - (ov, t, t1) -> { - requestInput.setText((t1 != null) ? requests.get(t1.hashCode()) : ""); - httpMethod.setValue((t1 != null) ? methods.get(t1.hashCode()) : httpMethod.getValue()); - } - ); - createNewTab(); - } - - private Tab newTab() { - SplitPane sp = new SplitPane(); - - Tab params = new Tab("Params", createParamTable()); - Tab auth = new Tab("Authorization"); - Tab headers = new Tab("Headers", createParamTable()); - Tab body = new Tab("Body", new TextArea()); - Tab response = new Tab("Response", createResponseTab()); - - TabPane options = new TabPane(); - TextArea ta = new TextArea(); - ta.setEditable(false); - - options.setTabClosingPolicy(TabPane.TabClosingPolicy.UNAVAILABLE); - options.getTabs().addAll(params, auth, headers, body, response); - sp.getItems().add(options); - sp.getItems().add(ta); - sp.setOrientation(Orientation.VERTICAL); - - Tab tab = new Tab("untitled", sp); - tab.setOnCloseRequest(arg0 -> { - requests.remove(tab.hashCode()); - methods.remove(tab.hashCode()); - }); - - return tab; - } - - @SuppressWarnings("unchecked") - private ScrollPane createResponseTab() { - ScrollPane sp = new ScrollPane(); - Pane p = new Pane(); - sp.setContent(p); - try { - Parent xml = FXMLLoader.load(getClass().getResource("responsetab.fxml")); - p.getChildren().add(xml); - TableView headers = (TableView) p.lookup("#headers"); - headers.getColumns().get(0).setCellValueFactory(new PropertyValueFactory<>("name")); - headers.getColumns().get(1).setCellValueFactory(new PropertyValueFactory<>("value")); - } catch (IOException e) { - System.err.println(e.getMessage()); - } - return sp; - } - - private TableView createParamTable() { - TableView paramsTable = new TableView<>(); - - TableColumn name = createColumn("Name", Param::name); - TableColumn value = createColumn("Value", Param::value); - - name.prefWidthProperty().bind(paramsTable.widthProperty().multiply(0.5)); - value.prefWidthProperty().bind(paramsTable.widthProperty().multiply(0.5)); - - name.setOnEditCommit(t -> { - TableView tv = t.getTableView(); - t.getRowValue().name().set(t.getNewValue()); - manageEmptyCells(t, tv); - }); - value.setOnEditCommit(t -> { - TableView tv = t.getTableView(); - t.getRowValue().value().set(t.getNewValue()); - manageEmptyCells(t, tv); - }); - - paramsTable.getColumns().add(name); - paramsTable.getColumns().add(value); - - paramsTable.setEditable(true); - paramsTable.getItems().add(new Param()); - - return paramsTable; - } - - private void manageEmptyCells(TableColumn.CellEditEvent t, TableView tv) { - if (t.getRowValue().isEmpty() && tv.getItems().size() > 1) { - tv.getItems().remove(t.getRowValue()); - } - if (!tv.getItems().get(tv.getItems().size() - 1).isEmpty()) { - tv.getItems().add(new Param()); - } - requestInput.setText(URLGenerator.processNewUrl(getParamsMap(), requestInput.getText())); - } - - private TableColumn createColumn(String title, Function property) { - TableColumn col = new TableColumn<>(title); - col.setCellValueFactory(cellData -> property.apply(cellData.getValue())); - - col.setCellFactory(column -> EditCell.createStringEditCell()); - return col ; - } - - @FXML - private void start() { - if (requestInput.getText().isBlank()) { - Alert alert = new Alert(Alert.AlertType.WARNING); - alert.setTitle("URL field empty"); - alert.setContentText("Enter your URL in the field at the top of the window."); - alert.showAndWait(); - return; - } - runningIndicatorPane.setVisible(true); - new Thread(() -> { - final String method = httpMethod.getValue(); - Optional -