001package jmri.jmrit.logixng.actions.swing; 002 003import java.awt.*; 004import java.awt.event.ActionEvent; 005import java.util.*; 006import java.util.List; 007 008import javax.annotation.CheckForNull; 009import javax.annotation.Nonnull; 010import javax.swing.*; 011import javax.swing.table.TableColumn; 012 013import jmri.InstanceManager; 014import jmri.jmrit.logixng.*; 015import jmri.jmrit.logixng.SymbolTable.InitialValueType; 016import jmri.jmrit.logixng.actions.WebRequest; 017import jmri.jmrit.logixng.actions.WebRequest.RequestMethodType; 018import jmri.jmrit.logixng.util.parser.*; 019import jmri.jmrit.logixng.util.swing.LogixNG_SelectCharsetSwing; 020import jmri.jmrit.logixng.util.swing.LogixNG_SelectEnumSwing; 021import jmri.jmrit.logixng.util.swing.LogixNG_SelectStringSwing; 022import jmri.util.table.ButtonEditor; 023import jmri.util.table.ButtonRenderer; 024 025/** 026 * Configures an WebRequest object with a Swing JPanel. 027 * 028 * @author Daniel Bergqvist Copyright (C) 2021 029 */ 030public class WebRequestSwing extends AbstractDigitalActionSwing { 031 032 private JTabbedPane _tabbedPane; 033 private JPanel _panelUrl; 034 private JPanel _panelCharset; 035 private JPanel _panelRequestMethod; 036 private JPanel _panelUserAgent; 037 038 private LogixNG_SelectStringSwing _selectUrlSwing; 039 private LogixNG_SelectCharsetSwing _selectCharsetSwing; 040 private LogixNG_SelectEnumSwing<RequestMethodType> _selectRequestMethodSwing; 041 private LogixNG_SelectStringSwing _selectUserAgentSwing; 042 043 private JTextField _localVariableForResponseCodeTextField; 044 private JTextField _localVariableForReplyContentTextField; 045 private JTextField _localVariableForCookiesTextField; 046 047 private JTable _logDataTable; 048 private WebRequestTableModel _logDataTableModel; 049 050 051 @Override 052 protected void createPanel(@CheckForNull Base object, @Nonnull JPanel buttonPanel) { 053 if ((object != null) && !(object instanceof WebRequest)) { 054 throw new IllegalArgumentException("object must be an WebRequest but is a: "+object.getClass().getName()); 055 } 056 057 _tabbedPane = new JTabbedPane(); 058 _panelUrl = new JPanel(); 059 _panelCharset = new JPanel(); 060 _panelRequestMethod = new JPanel(); 061 _panelUserAgent = new JPanel(); 062 063 _selectUrlSwing = new LogixNG_SelectStringSwing(getJDialog(), this); 064 _selectCharsetSwing = new LogixNG_SelectCharsetSwing(getJDialog(), this); 065 _selectRequestMethodSwing = new LogixNG_SelectEnumSwing<>(getJDialog(), this); 066 _selectUserAgentSwing = new LogixNG_SelectStringSwing(getJDialog(), this); 067 068 WebRequest action = (WebRequest)object; 069 070 panel = new JPanel(); 071 panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS)); 072 073 JPanel tabbedPaneUrl; 074 JPanel tabbedPaneCharset; 075 JPanel tabbedPaneRequestMethod; 076 JPanel tabbedPaneUserAgent; 077 078 if (action != null) { 079 tabbedPaneUrl = _selectUrlSwing.createPanel(action.getSelectUrl()); 080 tabbedPaneCharset = _selectCharsetSwing.createPanel(action.getSelectCharset()); 081 tabbedPaneRequestMethod = _selectRequestMethodSwing.createPanel(action.getSelectRequestMethod(), RequestMethodType.values()); 082 tabbedPaneUserAgent = _selectUserAgentSwing.createPanel(action.getSelectUserAgent()); 083 } else { 084 tabbedPaneUrl = _selectUrlSwing.createPanel(null); 085 tabbedPaneCharset = _selectCharsetSwing.createPanel(null); 086 tabbedPaneRequestMethod = _selectRequestMethodSwing.createPanel(null, RequestMethodType.values()); 087 tabbedPaneUserAgent = _selectUserAgentSwing.createPanel(null); 088 } 089 090 091 JLabel selectUrlLabel = new JLabel(Bundle.getMessage("WebRequestSwing_Url")); 092 selectUrlLabel.setLabelFor(tabbedPaneUrl); 093 094 JLabel selectCharsetLabel = new JLabel(Bundle.getMessage("WebRequestSwing_Charset")); 095 selectCharsetLabel.setLabelFor(tabbedPaneCharset); 096 097 JLabel selectRequestMethodLabel = new JLabel(Bundle.getMessage("WebRequestSwing_RequestMethod")); 098 selectRequestMethodLabel.setLabelFor(tabbedPaneRequestMethod); 099 100 JLabel selectUserAgentLabel = new JLabel(Bundle.getMessage("WebRequestSwing_UserAgent")); 101 selectUserAgentLabel.setLabelFor(tabbedPaneUserAgent); 102 103 _panelUrl.add(selectUrlLabel); 104 _panelUrl.add(tabbedPaneUrl); 105 106 _panelCharset.add(selectCharsetLabel); 107 _panelCharset.add(tabbedPaneCharset); 108 109 _panelRequestMethod.add(selectRequestMethodLabel); 110 _panelRequestMethod.add(tabbedPaneRequestMethod); 111 112 _panelUserAgent.add(selectUserAgentLabel); 113 _panelUserAgent.add(tabbedPaneUserAgent); 114 115 _tabbedPane.addTab(Bundle.getMessage("WebRequestSwing_Url"), _panelUrl); 116 _tabbedPane.addTab(Bundle.getMessage("WebRequestSwing_Charset"), _panelCharset); 117 _tabbedPane.addTab(Bundle.getMessage("WebRequestSwing_RequestMethod"), _panelRequestMethod); 118 _tabbedPane.addTab(Bundle.getMessage("WebRequestSwing_UserAgent"), _panelUserAgent); 119 120 JLabel localVariableForResponseCodeLabel = new JLabel(Bundle.getMessage("WebRequestSwing_LocalVariableForResponseCode")); 121 _localVariableForResponseCodeTextField = new JTextField(); 122 _localVariableForResponseCodeTextField.setColumns(30); 123 124 JLabel localVariableForReplyContentLabel = new JLabel(Bundle.getMessage("WebRequestSwing_LocalVariableForReplyContent")); 125 _localVariableForReplyContentTextField = new JTextField(); 126 _localVariableForReplyContentTextField.setColumns(30); 127 128 JLabel localVariableForCookiesLabel = new JLabel(Bundle.getMessage("WebRequestSwing_LocalVariableForCookies")); 129 _localVariableForCookiesTextField = new JTextField(); 130 _localVariableForCookiesTextField.setColumns(30); 131 132 133 _logDataTable = new JTable(); 134 135 if (action != null) { 136 List<WebRequest.Parameter> dataList 137 = new ArrayList<>(action.getParameters()); 138 139 _logDataTableModel = new WebRequestTableModel(dataList); 140 } else { 141 _logDataTableModel = new WebRequestTableModel(null); 142 } 143 144 _logDataTable.setModel(_logDataTableModel); 145 _logDataTable.setDefaultRenderer(InitialValueType.class, 146 new WebRequestTableModel.CellRenderer()); 147 _logDataTable.setDefaultEditor(InitialValueType.class, 148 new WebRequestTableModel.DataTypeCellEditor()); 149 _logDataTableModel.setColumnsForComboBoxes(_logDataTable); 150 _logDataTable.setDefaultRenderer(JButton.class, new ButtonRenderer()); 151 _logDataTable.setDefaultEditor(JButton.class, new ButtonEditor(new JButton())); 152 153 JButton testButton = new JButton("XXXXXX"); // NOI18N 154 _logDataTable.setRowHeight(testButton.getPreferredSize().height); 155 TableColumn deleteColumn = _logDataTable.getColumnModel() 156 .getColumn(WebRequestTableModel.COLUMN_DUMMY); 157 deleteColumn.setMinWidth(testButton.getPreferredSize().width); 158 deleteColumn.setMaxWidth(testButton.getPreferredSize().width); 159 deleteColumn.setResizable(false); 160 161 // The dummy column is used to be able to force update of the 162 // other columns when the panel is closed. 163 TableColumn dummyColumn = _logDataTable.getColumnModel() 164 .getColumn(WebRequestTableModel.COLUMN_DUMMY); 165 dummyColumn.setMinWidth(0); 166 dummyColumn.setPreferredWidth(0); 167 dummyColumn.setMaxWidth(0); 168 169 JScrollPane scrollpane = new JScrollPane(_logDataTable); 170 scrollpane.setPreferredSize(new Dimension(400, 200)); 171 172 // Add parameter 173 JButton add = new JButton(Bundle.getMessage("WebRequest_TableAdd")); 174 buttonPanel.add(add); 175 add.addActionListener((ActionEvent e) -> { 176 _logDataTableModel.add(); 177 }); 178 179 JLabel parametersLabel = new JLabel(Bundle.getMessage("WebRequest_Parameters")); 180 parametersLabel.setAlignmentX(Component.LEFT_ALIGNMENT); 181 scrollpane.setAlignmentX(Component.LEFT_ALIGNMENT); 182 183 JPanel tablePanel = new JPanel(); 184 tablePanel.setLayout(new BoxLayout(tablePanel, BoxLayout.PAGE_AXIS)); 185 tablePanel.add(parametersLabel); 186 tablePanel.add(scrollpane); 187 188 189 190 panel.setLayout(new GridBagLayout()); 191 GridBagConstraints constraint = new GridBagConstraints(); 192 Insets defaultInsets = constraint.insets; 193 constraint.gridwidth = 1; 194 constraint.gridheight = 1; 195 constraint.gridx = 0; 196 constraint.gridy = 0; 197 constraint.gridwidth = 2; 198 constraint.anchor = GridBagConstraints.CENTER; 199 panel.add(_tabbedPane, constraint); 200 constraint.gridy = 1; 201 constraint.insets = new Insets(10,0,10,0); 202 panel.add(tablePanel, constraint); 203 204 constraint.gridwidth = 1; 205 constraint.gridy = 2; 206 constraint.anchor = GridBagConstraints.EAST; 207 constraint.insets = defaultInsets; 208 panel.add(localVariableForResponseCodeLabel, constraint); 209 localVariableForResponseCodeLabel.setLabelFor(_localVariableForResponseCodeTextField); 210 constraint.gridy = 3; 211 panel.add(localVariableForReplyContentLabel, constraint); 212 localVariableForReplyContentLabel.setLabelFor(_localVariableForReplyContentTextField); 213 constraint.gridy = 4; 214 panel.add(localVariableForCookiesLabel, constraint); 215 localVariableForCookiesLabel.setLabelFor(_localVariableForCookiesTextField); 216 217 constraint.gridx = 1; 218 constraint.gridy = 2; 219 constraint.anchor = GridBagConstraints.EAST; 220 panel.add(_localVariableForResponseCodeTextField, constraint); 221 constraint.gridy = 3; 222 panel.add(_localVariableForReplyContentTextField, constraint); 223 constraint.gridy = 4; 224 panel.add(_localVariableForCookiesTextField, constraint); 225 226 227 if (action != null) { 228 _localVariableForResponseCodeTextField.setText(action.getLocalVariableForResponseCode()); 229 _localVariableForReplyContentTextField.setText(action.getLocalVariableForReplyContent()); 230 _localVariableForCookiesTextField.setText(action.getLocalVariableForCookies()); 231 } 232 } 233 234 /** {@inheritDoc} */ 235 @Override 236 public boolean validate(@Nonnull List<String> errorMessages) { 237 // Create a temporary action to test formula 238 WebRequest action = new WebRequest("IQDA1", null); 239 240 _selectUrlSwing.validate(action.getSelectUrl(), errorMessages); 241 _selectCharsetSwing.validate(action.getSelectCharset(), errorMessages); 242 _selectRequestMethodSwing.validate(action.getSelectRequestMethod(), errorMessages); 243 _selectUserAgentSwing.validate(action.getSelectUserAgent(), errorMessages); 244 245 for (WebRequest.Parameter data : _logDataTableModel.getDataList()) { 246 if (data.getType() == InitialValueType.Formula) { 247 try { 248 Map<String, Variable> variables = new HashMap<>(); 249 RecursiveDescentParser parser = new RecursiveDescentParser(variables); 250 parser.parseExpression(data.getData()); 251 } catch (ParserException e) { 252 errorMessages.add(e.getLocalizedMessage()); 253 } 254 } 255 } 256 257 return errorMessages.isEmpty(); 258 } 259 260 /** {@inheritDoc} */ 261 @Override 262 public MaleSocket createNewObject(@Nonnull String systemName, @CheckForNull String userName) { 263 WebRequest action = new WebRequest(systemName, userName); 264 updateObject(action); 265 return InstanceManager.getDefault(DigitalActionManager.class).registerAction(action); 266 } 267 268 /** {@inheritDoc} */ 269 @Override 270 public void updateObject(@Nonnull Base object) { 271 if (!(object instanceof WebRequest)) { 272 throw new IllegalArgumentException("object must be an WebRequest but is a: "+object.getClass().getName()); 273 } 274 275 WebRequest action = (WebRequest)object; 276 277 _selectUrlSwing.updateObject(action.getSelectUrl()); 278 _selectCharsetSwing.updateObject(action.getSelectCharset()); 279 _selectRequestMethodSwing.updateObject(action.getSelectRequestMethod()); 280 _selectUserAgentSwing.updateObject(action.getSelectUserAgent()); 281 282 action.setLocalVariableForResponseCode(_localVariableForResponseCodeTextField.getText()); 283 action.setLocalVariableForReplyContent(_localVariableForReplyContentTextField.getText()); 284 action.setLocalVariableForCookies(_localVariableForCookiesTextField.getText()); 285 286 // Do this to force update of the table 287 _logDataTable.editCellAt(0, 2); 288 289 action.getParameters().clear(); 290 291 for (WebRequest.Parameter data : _logDataTableModel.getDataList()) { 292 action.getParameters().add(data); 293 } 294 } 295 296 /** {@inheritDoc} */ 297 @Override 298 public String toString() { 299 return Bundle.getMessage("WebRequest_Short"); 300 } 301 302 @Override 303 public void dispose() { 304 _selectUrlSwing.dispose(); 305 _selectCharsetSwing.dispose(); 306 _selectRequestMethodSwing.dispose(); 307 _selectUserAgentSwing.dispose(); 308 } 309 310}