1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.request.components.editor.views.source;
14
15 import java.awt.Dimension;
16 import java.awt.Toolkit;
17 import java.awt.event.ActionEvent;
18 import java.awt.event.MouseAdapter;
19 import java.awt.event.MouseEvent;
20 import java.beans.PropertyChangeListener;
21
22 import javax.swing.AbstractAction;
23 import javax.swing.Action;
24 import javax.swing.DefaultListModel;
25 import javax.swing.JComponent;
26 import javax.swing.JList;
27 import javax.swing.JPopupMenu;
28 import javax.swing.JScrollPane;
29 import javax.swing.JSplitPane;
30 import javax.swing.SwingUtilities;
31 import javax.swing.text.Document;
32
33 import com.eviware.soapui.impl.wsdl.panels.request.components.editor.XmlEditor;
34 import com.eviware.soapui.impl.wsdl.panels.request.components.editor.XmlLocation;
35 import com.eviware.soapui.impl.wsdl.panels.request.components.editor.support.AbstractEditorView;
36 import com.eviware.soapui.impl.wsdl.panels.request.components.editor.support.ValidationError;
37 import com.eviware.soapui.support.DocumentListenerAdapter;
38 import com.eviware.soapui.support.UISupport;
39 import com.eviware.soapui.support.swing.SoapUISplitPaneUI;
40 import com.eviware.soapui.support.xml.JXEditTextArea;
41 import com.eviware.soapui.support.xml.actions.FormatXmlAction;
42 import com.eviware.soapui.support.xml.actions.SaveXmlTextAreaAction;
43
44 public class XmlSourceEditorView extends AbstractEditorView implements PropertyChangeListener
45 {
46 private JXEditTextArea editArea;
47 private ValidateMessageXmlAction validateXmlAction;
48 private JSplitPane splitter;
49 private JScrollPane errorScrollPane;
50 private DefaultListModel errorListModel;
51 private FormatXmlAction formatXmlAction;
52 private SaveXmlTextAreaAction saveXmlTextAreaAction;
53 private boolean updating;
54 private JPopupMenu editorPopup;
55 public boolean isLocating;
56
57 public XmlSourceEditorView( XmlEditor xmlEditor )
58 {
59 super( "XML" );
60 }
61
62 protected void buildUI()
63 {
64 editArea = JXEditTextArea.createXmlEditor();
65 editArea.setMinimumSize(new Dimension(50, 50));
66 editArea.setCaretPosition(0);
67 editArea.setDiscardEditsOnSet(false);
68 editArea.setEnabled( false );
69
70 errorListModel = new DefaultListModel();
71 JList list = new JList(errorListModel);
72 list.addMouseListener(new ValidationListMouseAdapter(list, editArea));
73 errorScrollPane = new JScrollPane(list);
74 errorScrollPane.setVisible(false);
75
76 splitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT)
77 {
78 public void requestFocus()
79 {
80 SwingUtilities.invokeLater( new Runnable() {
81
82 public void run()
83 {
84 editArea.requestFocusInWindow();
85 }} );
86 }
87
88 public boolean hasFocus()
89 {
90 return editArea.hasFocus();
91 }
92 };
93
94 splitter.setUI( new SoapUISplitPaneUI() );
95 splitter.setDividerSize( 0 );
96 splitter.setOneTouchExpandable( true );
97
98 editorPopup = new JPopupMenu();
99 buildPopup( editorPopup, editArea );
100
101 editArea.setRightClickPopup(editorPopup);
102 editArea.getDocument().addDocumentListener(
103 new DocumentListenerAdapter() {
104
105 public void update(Document document)
106 {
107 if( !updating && getXmlDocument() != null )
108 {
109 updating = true;
110 getXmlDocument().setXml( editArea.getText());
111 updating = false;
112 }
113 }
114 });
115
116 editArea.getInputHandler().addKeyBinding("A+V", validateXmlAction);
117 editArea.getInputHandler().addKeyBinding("A+F", formatXmlAction);
118 editArea.getInputHandler().addKeyBinding("C+S", saveXmlTextAreaAction);
119
120 splitter.setTopComponent(new JScrollPane(editArea));
121 splitter.setBottomComponent(errorScrollPane);
122 splitter.setDividerLocation(1.0);
123 splitter.setBorder(null);
124 }
125
126 protected void buildPopup(JPopupMenu inputPopup, JXEditTextArea editArea )
127 {
128 validateXmlAction = new ValidateMessageXmlAction( );
129 formatXmlAction = new FormatXmlAction(editArea);
130 saveXmlTextAreaAction = new SaveXmlTextAreaAction( editArea, "Save" );
131
132 inputPopup.add(validateXmlAction);
133 inputPopup.add(formatXmlAction);
134 inputPopup.addSeparator();
135 inputPopup.add(editArea.getUndoAction());
136 inputPopup.add(editArea.getRedoAction());
137 inputPopup.add(editArea.getCopyAction());
138 inputPopup.add(editArea.getCutAction());
139 inputPopup.add(editArea.getPasteAction());
140 inputPopup.addSeparator();
141 inputPopup.add(editArea.getFindAndReplaceAction());
142 inputPopup.addSeparator();
143 inputPopup.add(saveXmlTextAreaAction);
144 }
145
146 private final static class ValidationListMouseAdapter extends MouseAdapter
147 {
148 private final JList list;
149
150 private final JXEditTextArea textArea;
151
152 public ValidationListMouseAdapter(JList list, JXEditTextArea textArea)
153 {
154 this.list = list;
155 this.textArea = textArea;
156 }
157
158 public void mouseClicked(MouseEvent e)
159 {
160 if (e.getClickCount() < 2)
161 return;
162
163 int ix = list.getSelectedIndex();
164 if (ix == -1)
165 return;
166
167 Object obj = list.getModel().getElementAt(ix);
168 if (obj instanceof ValidationError)
169 {
170 ValidationError error = (ValidationError) obj;
171 if (error.getLineNumber() >= 0)
172 {
173 textArea.setCaretPosition(textArea.getLineStartOffset(error
174 .getLineNumber() - 1));
175 textArea.requestFocus();
176 }
177 else
178 Toolkit.getDefaultToolkit().beep();
179 }
180 else
181 Toolkit.getDefaultToolkit().beep();
182 }
183 }
184
185 public JXEditTextArea getInputArea()
186 {
187 getComponent();
188 return editArea;
189 }
190
191 public void setEditable(boolean enabled)
192 {
193 getComponent();
194 editArea.setEditable( enabled );
195 }
196
197 protected ValidationError[] validateXml( String xml )
198 {
199 return null;
200 }
201
202 public class ValidateMessageXmlAction extends AbstractAction
203 {
204 public ValidateMessageXmlAction()
205 {
206 super( "Validate" );
207 putValue( Action.ACCELERATOR_KEY, UISupport.getKeyStroke( "alt V" ));
208 }
209
210 public void actionPerformed(ActionEvent e)
211 {
212 if( validate())
213 UISupport.showInfoMessage( "Validation OK" );
214 }
215 }
216
217 public boolean activate(XmlLocation location)
218 {
219 super.activate( location );
220
221 if( location != null )
222 setLocation( location );
223
224 editArea.requestFocus();
225
226 return true;
227 }
228
229 public JComponent getComponent()
230 {
231 if( splitter == null )
232 buildUI();
233
234 return splitter;
235 }
236
237 public XmlLocation getLocation()
238 {
239 return new XmlLocation( getCurrentLine(), getCurrentColumn() );
240 }
241
242 public void setLocation(XmlLocation location)
243 {
244 if( location != null && location.getLine() >= 0 )
245 {
246 int offset = editArea.getLineStartOffset( location.getLine() );
247 try
248 {
249 editArea.setCaretPosition( offset + location.getColumn() );
250 }
251 catch( RuntimeException e )
252 {
253 }
254 }
255 }
256
257 public int getCurrentLine()
258 {
259 if( editArea == null )
260 return -1;
261 return editArea.getCaretLine();
262 }
263
264 public int getCurrentColumn()
265 {
266 if( editArea == null )
267 return -1;
268 return editArea.getCaretColumn();
269 }
270
271 public String getText()
272 {
273 if( editArea == null )
274 return null;
275 return editArea.getText();
276 }
277
278 public boolean validate()
279 {
280 ValidationError[] errors = validateXml( editArea.getText() );
281
282 errorListModel.clear();
283 if( errors == null || errors.length == 0 )
284 {
285 splitter.setDividerLocation( 1.0 );
286 splitter.setDividerSize( 0 );
287 errorScrollPane.setVisible( false );
288 return true;
289 }
290 else
291 {
292 Toolkit.getDefaultToolkit().beep();
293 for( int c = 0; c < errors.length; c++ )
294 {
295 errorListModel.addElement( errors[c] );
296 }
297 errorScrollPane.setVisible( true );
298 splitter.setDividerLocation( 0.8 );
299 splitter.setDividerSize( 10 );
300 return false;
301 }
302 }
303
304 protected void setXml(String xml)
305 {
306 if( !updating )
307 {
308 updating = true;
309
310 if( xml == null )
311 {
312 editArea.setText( "" );
313 editArea.setEnabled( false );
314 }
315 else
316 {
317 editArea.setEnabled( true );
318 editArea.setText( xml );
319 editArea.setCaretPosition( 0 );
320 }
321
322 updating = false;
323 }
324 }
325
326 public boolean saveDocument( boolean validate )
327 {
328 return validate ? validate() : true;
329 }
330
331 public void locationChanged(XmlLocation location)
332 {
333 isLocating = true;
334 setLocation( location );
335 isLocating = false;
336 }
337
338 public JPopupMenu getEditorPopup()
339 {
340 return editorPopup;
341 }
342
343 public boolean hasFocus()
344 {
345 return editArea.hasFocus();
346 }
347
348
349 public boolean isInspectable()
350 {
351 return true;
352 }
353
354 public String getViewId()
355 {
356 return XmlSourceEditorFactory.VIEW_ID;
357 }
358 }