1 package com.jsql.view.swing.panel.consoles;
2
3 import com.jsql.model.bean.util.HttpHeader;
4 import com.jsql.model.injection.vendor.model.VendorYaml;
5 import com.jsql.util.I18nUtil;
6 import com.jsql.util.LogLevelUtil;
7 import com.jsql.util.StringUtil;
8 import com.jsql.view.swing.panel.util.HTMLEditorKitTextPaneWrap;
9 import com.jsql.view.swing.tab.TabbedPaneWheeled;
10 import com.jsql.view.swing.text.JPopupTextComponent;
11 import com.jsql.view.swing.text.JTextPanePlaceholder;
12 import com.jsql.view.swing.text.SyntaxTextArea;
13 import com.jsql.view.swing.util.I18nViewUtil;
14 import com.jsql.view.swing.util.MediatorHelper;
15 import com.jsql.view.swing.util.UiUtil;
16 import org.apache.commons.lang3.StringUtils;
17 import org.apache.logging.log4j.LogManager;
18 import org.apache.logging.log4j.Logger;
19 import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
20 import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
21 import org.fife.ui.rtextarea.RTextScrollPane;
22 import org.jsoup.Jsoup;
23 import org.jsoup.safety.Safelist;
24
25 import javax.swing.*;
26 import javax.swing.text.DefaultCaret;
27 import java.awt.*;
28 import java.awt.event.FocusAdapter;
29 import java.awt.event.FocusEvent;
30 import java.util.AbstractMap.SimpleEntry;
31 import java.util.Arrays;
32 import java.util.Map;
33 import java.util.stream.Stream;
34
35 public class TabbedPaneNetworkTab extends TabbedPaneWheeled {
36
37 private static final Logger LOGGER = LogManager.getRootLogger();
38
39 private final RSyntaxTextArea textAreaUrl = new SyntaxTextArea(I18nUtil.valueByKey("NETWORK_LINE_PLACEHOLDER_URL"));
40 private final RSyntaxTextArea textAreaResponse = new SyntaxTextArea(I18nUtil.valueByKey("NETWORK_LINE_PLACEHOLDER_RESPONSE"));
41 private final RSyntaxTextArea textAreaSource = new SyntaxTextArea(I18nUtil.valueByKey("NETWORK_LINE_PLACEHOLDER_SOURCE"));
42 private final JTextPane textPanePreview = new JPopupTextComponent<>(new JTextPanePlaceholder(I18nUtil.valueByKey("NETWORK_LINE_PLACEHOLDER_PREVIEW")){
43 @Override
44 public boolean isEditable() {
45 return false;
46 }
47 }).getProxy();
48 private final RSyntaxTextArea textAreaHeader = new SyntaxTextArea(I18nUtil.valueByKey("NETWORK_LINE_PLACEHOLDER_HEADERS"));
49 private final RSyntaxTextArea textAreaRequest = new SyntaxTextArea(I18nUtil.valueByKey("NETWORK_LINE_PLACEHOLDER_REQUEST"));
50 private final JCheckBox checkBoxDecode = new JCheckBox("Decode", MediatorHelper.model().getMediatorUtils().getPreferencesUtil().isUrlDecodeNetworkTab());
51
52 public TabbedPaneNetworkTab() {
53 this.setName("tabNetwork");
54 var panelDecode = new JPanel(new BorderLayout());
55 panelDecode.add(this.checkBoxDecode, BorderLayout.EAST);
56 this.putClientProperty("JTabbedPane.trailingComponent", panelDecode);
57 this.checkBoxDecode.setHorizontalTextPosition(SwingConstants.TRAILING);
58
59 I18nViewUtil.addComponentForKey("NETWORK_LINE_PLACEHOLDER_URL", this.textAreaUrl);
60 I18nViewUtil.addComponentForKey("NETWORK_LINE_PLACEHOLDER_RESPONSE", this.textAreaResponse);
61 I18nViewUtil.addComponentForKey("NETWORK_LINE_PLACEHOLDER_SOURCE", this.textAreaSource);
62 I18nViewUtil.addComponentForKey("NETWORK_LINE_PLACEHOLDER_PREVIEW", this.textPanePreview);
63 I18nViewUtil.addComponentForKey("NETWORK_LINE_PLACEHOLDER_HEADERS", this.textAreaHeader);
64 I18nViewUtil.addComponentForKey("NETWORK_LINE_PLACEHOLDER_REQUEST", this.textAreaRequest);
65 Stream.of(
66 new SimpleEntry<>("NETWORK_TAB_URL_LABEL", this.textAreaUrl),
67 new SimpleEntry<>("NETWORK_TAB_HEADERS_LABEL", this.textAreaHeader),
68 new SimpleEntry<>("NETWORK_TAB_PARAMS_LABEL", this.textAreaRequest),
69 new SimpleEntry<>("NETWORK_TAB_RESPONSE_LABEL", this.textAreaResponse),
70 new SimpleEntry<>("NETWORK_TAB_SOURCE_LABEL", this.textAreaSource),
71 new SimpleEntry<>("NETWORK_TAB_PREVIEW_LABEL", this.textPanePreview)
72 )
73 .forEach(entry -> {
74 this.addTab(
75 I18nUtil.valueByKey(entry.getKey()),
76 entry.getValue() == this.textAreaSource
77 ? new RTextScrollPane(entry.getValue(), false)
78 : new JScrollPane(entry.getValue())
79 );
80 var label = new JLabel(I18nUtil.valueByKey(entry.getKey()));
81 label.setName("label"+ entry.getKey());
82 this.setTabComponentAt(
83 this.indexOfTab(I18nUtil.valueByKey(entry.getKey())),
84 label
85 );
86 I18nViewUtil.addComponentForKey(entry.getKey(), label);
87
88 entry.getValue().setName("text"+ entry.getKey());
89
90 DefaultCaret caret = (DefaultCaret) entry.getValue().getCaret();
91 caret.setUpdatePolicy(DefaultCaret.NEVER_UPDATE);
92 });
93
94 Arrays.asList(this.textAreaUrl, this.textAreaHeader, this.textAreaRequest, this.textAreaResponse, this.textAreaSource).forEach(entry -> {
95 entry.setEditable(false);
96 entry.setLineWrap(true);
97 });
98 this.textAreaResponse.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_HTML);
99 this.textAreaSource.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_HTML);
100 this.textAreaSource.setHighlightSecondaryLanguages(true);
101 this.applyTheme();
102
103 this.textPanePreview.setEditorKit(new HTMLEditorKitTextPaneWrap());
104 this.textPanePreview.setContentType("text/html");
105 this.textPanePreview.setEditable(false);
106 this.textPanePreview.getCaret().setBlinkRate(0);
107 this.textPanePreview.addFocusListener(new FocusAdapter() {
108 @Override
109 public void focusGained(FocusEvent focusEvent) {
110 TabbedPaneNetworkTab.this.textPanePreview.getCaret().setVisible(true);
111 TabbedPaneNetworkTab.this.textPanePreview.getCaret().setSelectionVisible(true);
112 }
113 });
114 }
115
116 public void changeTextNetwork(HttpHeader networkData) {
117 this.textAreaRequest.setText(this.getDecodedValue(this.checkBoxDecode.isSelected(), networkData.getPost()));
118 this.textAreaUrl.setText(this.getDecodedValue(this.checkBoxDecode.isSelected(), networkData.getUrl()));
119 this.updateTextArea(this.textAreaHeader, networkData.getHeader());
120 this.updateTextArea(this.textAreaResponse, networkData.getResponse());
121
122
123
124 try {
125 this.textAreaSource.setText(
126 StringUtil.detectUtf8(networkData.getSource())
127 .replaceAll(VendorYaml.CALIBRATOR_SQL +"{5,}", VendorYaml.CALIBRATOR_SQL +"*")
128 .trim()
129 );
130 } catch (ArrayIndexOutOfBoundsException | NullPointerException e) {
131 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
132 }
133
134 this.textPanePreview.getEditorKit().createDefaultDocument();
135
136
137
138
139
140 try {
141 this.textPanePreview.setText(
142 Jsoup.clean(
143 String.format(
144 "<html>%s</html>",
145 StringUtil.detectUtf8(networkData.getSource())
146 )
147 .replaceAll("<img[^>]*>",StringUtils.EMPTY)
148 .replaceAll("<input[^>]*type=\"?hidden\"?.*>", StringUtils.EMPTY)
149 .replaceAll(
150 "<input[^>]*type=\"?(submit|button)\"?.*>",
151 "<div style=\"background-color:#eeeeee;text-align:center;border:1px solid black;width:100px;\">button</div>"
152 )
153 .replaceAll(
154 "<input[^>]*>",
155 "<div style=\"text-align:center;border:1px solid black;width:100px;\">input</div>"
156 ),
157 Safelist.relaxed().addTags("center", "div", "span").addAttributes(":all", "style")
158 )
159 );
160 } catch (Exception | ExceptionInInitializerError e) {
161 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
162 }
163 }
164
165 private void updateTextArea(JTextArea textArea, Map<String, String> httpData) {
166 textArea.setText(StringUtils.EMPTY);
167 if (httpData != null) {
168 httpData.forEach((key, value) -> {
169 String decodedValue = this.getDecodedValue(this.checkBoxDecode.isSelected(), value);
170 textArea.append(key + ": " + decodedValue + "\n");
171 });
172 }
173 }
174
175 private String getDecodedValue(boolean isSelected, String value) {
176
177 try {
178 return isSelected ? StringUtil.fromUrl(value) : value;
179 } catch (IllegalArgumentException e) {
180 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, "Decoding failure: {}", e.getMessage());
181 return value;
182 }
183 }
184
185 public void reset() {
186 this.textAreaUrl.setText(StringUtils.EMPTY);
187 this.textAreaHeader.setText(StringUtils.EMPTY);
188 this.textAreaRequest.setText(StringUtils.EMPTY);
189 this.textAreaResponse.setText(StringUtils.EMPTY);
190
191
192 try {
193 this.textAreaSource.setText(StringUtils.EMPTY);
194 } catch (NullPointerException e) {
195 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
196 }
197
198
199 try {
200 this.textPanePreview.setText(StringUtils.EMPTY);
201 } catch (ArrayIndexOutOfBoundsException e) {
202 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
203 }
204 }
205
206 public void applyTheme() {
207 Arrays.asList(
208 this.textAreaUrl, this.textAreaHeader, this.textAreaRequest, this.textAreaResponse, this.textAreaSource
209 ).forEach(UiUtil::applySyntaxTheme);
210 }
211
212 public JCheckBox getCheckBoxDecode() {
213 return this.checkBoxDecode;
214 }
215 }