diff --git a/javafx.bootstrap/javafx.bootstrap/main.cpp b/javafx.bootstrap/javafx.bootstrap/main.cpp index 5365560..d19e09e 100644 --- a/javafx.bootstrap/javafx.bootstrap/main.cpp +++ b/javafx.bootstrap/javafx.bootstrap/main.cpp @@ -6,6 +6,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam, int iCmdShow) { + int return_code = 0; STARTUPINFO si; PROCESS_INFORMATION pi; @@ -16,17 +17,15 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdParam 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); - CloseHandle(&pi.hThread); int msgboxID = MessageBox( NULL, TEXT("Unable to start the JVM. Try reinstalling the program to fix this problem."), TEXT("EndPoint bootstrap"), MB_ICONHAND | MB_OK | MB_DEFBUTTON1 ); - return -1; + return_code = -1; } CloseHandle(&pi.hProcess); CloseHandle(&pi.hThread); - return 0; + return return_code; } \ No newline at end of file diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form index 83b9eb6..d916b32 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form +++ b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.form @@ -116,7 +116,7 @@ - + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java index 354d1f1..f36a592 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/MainWindow.java @@ -8,6 +8,7 @@ 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 ovh.alexisdelhaie.endpoint.utils.RequestTab; import javax.imageio.ImageIO; import javax.swing.*; @@ -17,9 +18,10 @@ import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; 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.Objects; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; @@ -47,6 +49,7 @@ public class MainWindow extends JFrame { // Constants public final static int WIDTH = 1280; public final static int HEIGHT = 720; + public final static String NEW_TAB_NAME = "New request"; private JPanel contentPane; private JComboBox methodBox; @@ -59,25 +62,17 @@ public class MainWindow extends JFrame { private JButton settingsButton; private final ConfigurationProperties props; - private final HashMap urls; - - private final ConcurrentHashMap controlState; - private final ConcurrentHashMap responses; + private final ConcurrentHashMap tabs; public MainWindow() throws IOException { props = new ConfigurationProperties(); - controlState = new ConcurrentHashMap<>(); - responses = new ConcurrentHashMap<>(); - urls = new HashMap<>(); + tabs = new ConcurrentHashMap<>(); 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()); + newTab(); settingsButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { @@ -89,11 +84,7 @@ public class MainWindow extends JFrame { @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()); + newTab(); } }); sendButton.addMouseListener(new MouseAdapter() { @@ -110,9 +101,22 @@ public class MainWindow extends JFrame { 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()); + RequestTab requestTab = tabs.get(hashCode); + if (Objects.nonNull(requestTab)) { + urlField.setText(requestTab.getUrl()); + methodBox.setSelectedItem(requestTab.getMethod()); + enableControl(requestTab.isRunning(), hashCode); + showStatus(hashCode); + } + } + }); + methodBox.addItemListener((e) -> { + if (tabbedPane1.getSelectedIndex() != -1) { + int hashCode = tabbedPane1.getSelectedComponent().hashCode(); + RequestTab requestTab = tabs.get(hashCode); + if (Objects.nonNull(requestTab)) { + requestTab.setMethod((String) methodBox.getSelectedItem()); + } } }); urlField.getDocument().addDocumentListener(new DocumentListener() { @@ -128,23 +132,58 @@ public class MainWindow extends JFrame { public void warn() { if (tabbedPane1.getSelectedIndex() != -1) { - urls.put(tabbedPane1.getSelectedComponent().hashCode(), urlField.getText()); + int i = tabbedPane1.indexOfComponent(tabbedPane1.getSelectedComponent()); + JLabel title = TabBuilder.getLabel(i); + tabs.get(tabbedPane1.getSelectedComponent().hashCode()).setUrl(urlField.getText()); + if (Objects.nonNull(title)) { + if (!urlField.getText().isBlank()) { + try { + URL u = new URL((!urlField.getText().toLowerCase().startsWith("http://") && + !urlField.getText().toLowerCase().startsWith("https://")) ? + "http://" + urlField.getText() : urlField.getText()); + if (u.getPath().isBlank()) { + title.setText(u.getHost()); + } else { + title.setText(String.format("%s (%s)", u.getPath(), u.getHost())); + } + } catch (MalformedURLException e) { + title.setText(urlField.getText()); + } + } else { + title.setText(NEW_TAB_NAME); + } + } } } }); } + private void newTab() { + RequestTab requestTab = new RequestTab((String) methodBox.getSelectedItem()); + TabBuilder.create(tabbedPane1, NEW_TAB_NAME, tabs, urlField); + Component tab = tabbedPane1.getSelectedComponent(); + tabs.put(tab.hashCode(), requestTab); + enableControl(true, tab.hashCode()); + showStatus(tab.hashCode()); + urlField.setText(""); + } + private void sendRequest() { Optional possibleTab = getSelectedTab(); if (possibleTab.isPresent()) { JSplitPane tab = possibleTab.get(); int tabHashCode = tab.hashCode(); + RequestTab requestTab = tabs.get(tabHashCode); statusLabel.setVisible(false); enableControl(false, tabHashCode); int i = tabbedPane1.indexOfComponent(tab); JTextArea responseBody = TabBuilder.getResponseArea(i); + JTextArea responseHeader = TabBuilder.getResponseHeaderTextArea(i); + JTextArea requestHeader = TabBuilder.getRequestHeaderTextArea(i); responseBody.setForeground(Color.black); responseBody.setText(""); + responseHeader.setText(""); + requestHeader.setText(""); JTextArea bodyField = TabBuilder.getBody(i); new Thread(() -> { try { @@ -163,14 +202,16 @@ public class MainWindow extends JFrame { } if (possibleRes.isPresent()) { Response res = possibleRes.get(); - responses.put(tabHashCode, res); + requestTab.setRes(res); responseBody.setText(res.getBody()); + requestHeader.setText(res.getRequest().getRawRequest()); + responseHeader.setText(res.getRawHeaders()); } } catch (KeyManagementException | IOException | NoSuchAlgorithmException e) { responseBody.setForeground(Color.red); responseBody.setText(e.getMessage()); - if (responses.containsKey(tabHashCode)) { - responses.remove(tabHashCode); + if (Objects.nonNull(requestTab.getRes())) { + requestTab.setRes(null); showStatus(tabHashCode); } } finally { @@ -185,7 +226,7 @@ public class MainWindow extends JFrame { private void enableControl(Boolean state, int hashCode) { if (Objects.nonNull(state)) { - controlState.put(hashCode, state); + tabs.get(hashCode).setRunning(state); if (tabbedPane1.getSelectedComponent().hashCode() == hashCode) { sendButton.setEnabled(state); urlField.setEnabled(state); @@ -196,10 +237,11 @@ public class MainWindow extends JFrame { } private void showStatus(int hashCode) { - if (controlState.get(hashCode) && responses.containsKey(hashCode) && + RequestTab requestTab = tabs.get(hashCode); + if (requestTab.isRunning() && Objects.nonNull(requestTab.getRes()) && tabbedPane1.getSelectedComponent().hashCode() == hashCode) { statusLabel.setForeground(Color.BLACK); - Response res = responses.get(hashCode); + Response res = requestTab.getRes(); final StringBuilder sb = new StringBuilder(); if (res.getStatusCode() != -1) { sb.append(res.getStatusCode()) diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java b/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java index 881a393..a8d9ed8 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/builder/TabBuilder.java @@ -1,5 +1,6 @@ package ovh.alexisdelhaie.endpoint.builder; +import ovh.alexisdelhaie.endpoint.utils.RequestTab; import ovh.alexisdelhaie.endpoint.utils.Tools; import ovh.alexisdelhaie.endpoint.utils.adapter.CustomDeleteMouseAdapter; import ovh.alexisdelhaie.endpoint.utils.adapter.CustomNewMouseAdapter; @@ -12,17 +13,18 @@ import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; public class TabBuilder { - private static final HashMap indexes = new HashMap<>(); + public static final ConcurrentHashMap indexes = new ConcurrentHashMap<>(); - public static void create(JTabbedPane tab, String label, HashMap urls, JTextField urlField) { + public static void create(JTabbedPane tab, String label, ConcurrentHashMap tabs, JTextField urlField) { Component c = tab.add("", buildMainPanel(urlField)); int index = tab.indexOfComponent(c); - updateIndexes(index); - tab.setTabComponentAt(index, buildTabPanel(tab, c, label, urls)); + tab.setTabComponentAt(index, buildTabPanel(tab, c, label, tabs)); tab.setSelectedComponent(c); + updateIndexes(index); } private static void updateIndexes(int index) { @@ -30,16 +32,23 @@ public class TabBuilder { 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.put("main[" + index + "].tabTitle", indexes.get("main[waiting].tabTitle")); + indexes.put("main[" + index + "].requestHeaderTextArea", indexes.get("main[waiting].requestHeaderTextArea")); + indexes.put("main[" + index + "].responseHeaderTextArea", indexes.get("main[waiting].responseHeaderTextArea")); indexes.remove("main[waiting].responseTextArea"); indexes.remove("main[waiting].body"); indexes.remove("main[waiting].params"); indexes.remove("main[waiting].headers"); + indexes.remove("main[waiting].tabTitle"); + indexes.remove("main[waiting].requestHeaderTextArea"); + indexes.remove("main[waiting].responseHeaderTextArea"); } - private static JPanel buildTabPanel(JTabbedPane tab, Component c, String label, HashMap urls) { + private static JPanel buildTabPanel(JTabbedPane tab, Component c, String label, ConcurrentHashMap tabs) { JPanel p = new JPanel(new GridBagLayout()); p.setOpaque(false); JLabel l = new JLabel(label); + indexes.put("main[waiting].tabTitle", l); GridBagConstraints g = new GridBagConstraints(); g.gridx = 0; g.gridy = 0; @@ -47,11 +56,11 @@ public class TabBuilder { p.add(l, g); g.gridx++; g.weightx = 0; - p.add(buildCloseButton(tab, c, urls), g); + p.add(buildCloseButton(tab, c, tabs), g); return p; } - private static JButton buildCloseButton(JTabbedPane tab, Component c, HashMap urls) { + private static JButton buildCloseButton(JTabbedPane tab, Component c, ConcurrentHashMap tabs) { JButton b = new JButton("×"); b.setBorderPainted(false); b.setFocusPainted(false); @@ -61,7 +70,7 @@ public class TabBuilder { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); - urls.remove(c.hashCode()); + tabs.remove(c.hashCode()); tab.remove(c); } }); @@ -89,6 +98,22 @@ public class TabBuilder { JTextArea body = new JTextArea(); indexes.put("main[waiting].body", body); p.add("Body", body); + // Response tab + JTextArea repHeader = new JTextArea(); + repHeader.setBackground(Color.WHITE); + repHeader.setEditable(false); + JScrollPane rep = new JScrollPane(repHeader); + JTextArea reqHeader = new JTextArea(); + reqHeader.setBackground(Color.WHITE); + reqHeader.setEditable(false); + JScrollPane req = new JScrollPane(reqHeader); + indexes.put("main[waiting].requestHeaderTextArea", reqHeader); + indexes.put("main[waiting].responseHeaderTextArea", repHeader); + p.add("Response", new JSplitPane( + JSplitPane.HORIZONTAL_SPLIT, + rep, + req + )); return p; } @@ -100,6 +125,14 @@ public class TabBuilder { return (JTextArea) indexes.get("main[" + index + "].body"); } + public static JTextArea getRequestHeaderTextArea(int index) { + return (JTextArea) indexes.get("main[" + index + "].requestHeaderTextArea"); + } + + public static JTextArea getResponseHeaderTextArea(int index) { + return (JTextArea) indexes.get("main[" + index + "].responseHeaderTextArea"); + } + public static HashMap getParams(int index) { JTable t = (JTable) indexes.get("main[" + index + "].params"); return Tools.tableToHashMap(t); @@ -110,6 +143,10 @@ public class TabBuilder { return Tools.tableToHashMap(t); } + public static JLabel getLabel(int index) { + return (JLabel) indexes.get("main[" + index + "].tabTitle"); + } + private static JPanel buildParamsTab(boolean isParam, JTextField urlField) { String[] headers = {"Keys", "Values"}; DefaultTableModel model = new DefaultTableModel(new Object[][]{}, headers); diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form index 4703c1d..b09a23d 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.form @@ -1,9 +1,9 @@
- + - + @@ -11,7 +11,7 @@ - + @@ -58,6 +58,18 @@ + + + + + + + + + + + + diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java index d4dc42f..eaf3a30 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/configuration/AboutDialog.java @@ -1,20 +1,24 @@ package ovh.alexisdelhaie.endpoint.configuration; +import ovh.alexisdelhaie.endpoint.MainWindow; import ovh.alexisdelhaie.endpoint.utils.Tools; +import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; +import java.io.IOException; public class AboutDialog extends JDialog { - public static final int WIDTH = 450; + public static final int WIDTH = 740; public static final int HEIGHT = 500; - public static final String VERSION = "0.1.3"; + public static final String VERSION = "0.1.4"; private JPanel contentPane; private JLabel version; private JLabel javaVersion; + private JLabel banner; private AboutDialog() { setContentPane(contentPane); @@ -22,6 +26,11 @@ public class AboutDialog extends JDialog { setTitle("About EndPoint"); version.setText("Version: " + VERSION + " (NOT FINISHED)"); javaVersion.setText("Software: Java " + System.getProperty("java.version") + " (GUI: Java Swing)"); + try { + banner.setIcon(new ImageIcon(ImageIO.read(MainWindow.class.getResource("/banner.png")))); + } catch (IOException e) { + e.printStackTrace(); + } } public static void showDialog() { diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java b/src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java index f335898..b3ab704 100644 --- a/src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java +++ b/src/main/java/ovh/alexisdelhaie/endpoint/http/Response.java @@ -51,13 +51,13 @@ public class Response { } private void parseStatus(String l) { - Pattern p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})\\s(.+)$"); + Pattern p = Pattern.compile("^(HTTP/[0-2].[0-1])\\s([0-9]{3})\\s(.+)$"); Matcher m = p.matcher(l); if (m.matches()) { statusCode = Integer.parseInt(m.group(2)); status = m.group(3); } else { - p = Pattern.compile("^(HTTP/1.1)\\s([0-9]{3})?(.*)$"); + p = Pattern.compile("^(HTTP/[0-2].[0-1])\\s([0-9]{3})?(.*)$"); m = p.matcher(l); if (m.matches()) { statusCode = Integer.parseInt(m.group(2)); diff --git a/src/main/java/ovh/alexisdelhaie/endpoint/utils/RequestTab.java b/src/main/java/ovh/alexisdelhaie/endpoint/utils/RequestTab.java new file mode 100644 index 0000000..95cec82 --- /dev/null +++ b/src/main/java/ovh/alexisdelhaie/endpoint/utils/RequestTab.java @@ -0,0 +1,55 @@ +package ovh.alexisdelhaie.endpoint.utils; + +import ovh.alexisdelhaie.endpoint.http.Response; + +public class RequestTab { + + private String url; + private boolean running; + private Response res; + private String method; + + public RequestTab(String method) { + url = ""; + running = false; + res = null; + this.method = method; + } + + public String getUrl() { + return url; + } + + public RequestTab setUrl(String url) { + this.url = url; + return this; + } + + public boolean isRunning() { + return running; + } + + public RequestTab setRunning(boolean running) { + this.running = running; + return this; + } + + public Response getRes() { + return res; + } + + public RequestTab setRes(Response res) { + this.res = res; + return this; + } + + public String getMethod() { + return method; + } + + public RequestTab setMethod(String method) { + this.method = method; + return this; + } + +} diff --git a/src/main/resources/banner.png b/src/main/resources/banner.png new file mode 100644 index 0000000..2727c01 Binary files /dev/null and b/src/main/resources/banner.png differ diff --git a/src/main/resources/icon.png b/src/main/resources/icon.png index 0d216b3..c262330 100644 Binary files a/src/main/resources/icon.png and b/src/main/resources/icon.png differ