001: /*
002: * soapUI, copyright (C) 2004-2007 eviware.com
003: *
004: * soapUI is free software; you can redistribute it and/or modify it under the
005: * terms of version 2.1 of the GNU Lesser General Public License as published by
006: * the Free Software Foundation.
007: *
008: * soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009: * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
010: * See the GNU Lesser General Public License for more details at gnu.org.
011: */
012:
013: package com.eviware.soapui.impl.wsdl.panels.teststeps;
014:
015: import java.awt.BorderLayout;
016: import java.awt.Component;
017: import java.awt.Toolkit;
018: import java.awt.event.KeyAdapter;
019: import java.awt.event.KeyEvent;
020: import java.awt.event.MouseAdapter;
021: import java.awt.event.MouseEvent;
022: import java.beans.PropertyChangeEvent;
023: import java.beans.PropertyChangeListener;
024: import java.util.ArrayList;
025: import java.util.List;
026:
027: import javax.swing.AbstractListModel;
028: import javax.swing.JLabel;
029: import javax.swing.JList;
030: import javax.swing.JPanel;
031: import javax.swing.JPopupMenu;
032: import javax.swing.JScrollPane;
033: import javax.swing.ListCellRenderer;
034: import javax.swing.SwingUtilities;
035: import javax.swing.event.PopupMenuEvent;
036: import javax.swing.event.PopupMenuListener;
037:
038: import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
039: import com.eviware.soapui.impl.wsdl.support.HelpUrls;
040: import com.eviware.soapui.impl.wsdl.support.assertions.Assertable;
041: import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsListener;
042: import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
043: import com.eviware.soapui.impl.wsdl.teststeps.actions.AddAssertionAction;
044: import com.eviware.soapui.impl.wsdl.teststeps.assertions.AssertionError;
045: import com.eviware.soapui.support.action.swing.ActionList;
046: import com.eviware.soapui.support.action.swing.ActionListBuilder;
047: import com.eviware.soapui.support.action.swing.ActionSupport;
048:
049: /**
050: * Seperate panel for holding/managing assertions
051: *
052: * @author ole.matzura
053: */
054:
055: public class AssertionsPanel extends JPanel {
056: private AssertionListModel assertionListModel;
057: private JList assertionList;
058: private JPopupMenu assertionListPopup;
059: private final Assertable assertable;
060:
061: public AssertionsPanel(Assertable assertable) {
062: super (new BorderLayout());
063: this .assertable = assertable;
064:
065: assertionListModel = new AssertionListModel();
066: assertionList = new JList(assertionListModel);
067: assertionList.setToolTipText("Assertions for this request");
068: assertionList.setCellRenderer(new AssertionCellRenderer());
069:
070: assertionListPopup = new JPopupMenu();
071: assertionListPopup.add(new AddAssertionAction(assertable));
072:
073: assertionListPopup
074: .addPopupMenuListener(new PopupMenuListener() {
075:
076: public void popupMenuWillBecomeVisible(
077: PopupMenuEvent e) {
078: while (assertionListPopup.getComponentCount() > 1)
079: assertionListPopup.remove(1);
080:
081: int ix = assertionList.getSelectedIndex();
082: if (ix == -1) {
083: assertionListPopup.addSeparator();
084: assertionListPopup
085: .add(new ShowOnlineHelpAction(
086: HelpUrls.RESPONSE_ASSERTIONS_HELP_URL));
087: return;
088: }
089:
090: WsdlMessageAssertion assertion = assertionListModel
091: .getAssertionAt(ix);
092: ActionSupport.addActions(ActionListBuilder
093: .buildActions(assertion),
094: assertionListPopup);
095: }
096:
097: public void popupMenuWillBecomeInvisible(
098: PopupMenuEvent e) {
099: }
100:
101: public void popupMenuCanceled(PopupMenuEvent e) {
102: }
103: });
104:
105: assertionList.setComponentPopupMenu(assertionListPopup);
106:
107: assertionList.addMouseListener(new MouseAdapter() {
108:
109: public void mouseClicked(MouseEvent e) {
110: if (e.getClickCount() < 2)
111: return;
112:
113: int ix = assertionList.getSelectedIndex();
114: if (ix == -1)
115: return;
116:
117: Object obj = assertionList.getModel().getElementAt(ix);
118: if (obj instanceof WsdlMessageAssertion) {
119: WsdlMessageAssertion assertion = (WsdlMessageAssertion) obj;
120: if (assertion.isConfigurable())
121: assertion.configure();
122:
123: return;
124: }
125:
126: if (obj instanceof AssertionError) {
127: AssertionError error = (AssertionError) obj;
128: if (error.getLineNumber() >= 0) {
129: selectError(error);
130: } else
131: Toolkit.getDefaultToolkit().beep();
132: } else
133: Toolkit.getDefaultToolkit().beep();
134: }
135: });
136:
137: assertionList.addKeyListener(new KeyAdapter() {
138: public void keyPressed(KeyEvent e) {
139: int ix = assertionList.getSelectedIndex();
140: if (ix == -1)
141: return;
142:
143: WsdlMessageAssertion assertion = assertionListModel
144: .getAssertionAt(ix);
145: if (e.getKeyChar() == KeyEvent.VK_ENTER) {
146: if (assertion.isConfigurable())
147: assertion.configure();
148: } else {
149: ActionList actions = ActionListBuilder
150: .buildActions(assertion);
151: if (actions != null) {
152: actions.dispatchKeyEvent(e);
153: }
154: }
155: }
156: });
157:
158: add(new JScrollPane(assertionList), BorderLayout.CENTER);
159: }
160:
161: public void setEnabled(boolean enabled) {
162: assertionList.setEnabled(enabled);
163: }
164:
165: protected void selectError(AssertionError error) {
166: }
167:
168: private static class AssertionCellRenderer extends JLabel implements
169: ListCellRenderer {
170: public Component getListCellRendererComponent(JList list,
171: Object value, int index, boolean isSelected,
172: boolean cellHasFocus) {
173: if (value instanceof WsdlMessageAssertion) {
174: WsdlMessageAssertion assertion = (WsdlMessageAssertion) value;
175: setText(assertion.getName() + " - "
176: + assertion.getStatus().toString());
177: setIcon(assertion.getIcon());
178: } else if (value instanceof AssertionError) {
179: AssertionError assertion = (AssertionError) value;
180: setText(" -> " + assertion.toString());
181: setIcon(null);
182: } else if (value instanceof String) {
183: setText(value.toString());
184: }
185:
186: if (isSelected) {
187: setBackground(list.getSelectionBackground());
188: setForeground(list.getSelectionForeground());
189: } else {
190: setBackground(list.getBackground());
191: setForeground(list.getForeground());
192: }
193:
194: setEnabled(list.isEnabled());
195: setFont(list.getFont());
196: setOpaque(true);
197:
198: return this ;
199: }
200: }
201:
202: private class AssertionListModel extends AbstractListModel
203: implements PropertyChangeListener, AssertionsListener {
204: private List<Object> items = new ArrayList<Object>();
205:
206: public AssertionListModel() {
207: init();
208: }
209:
210: public int getSize() {
211: return items.size();
212: }
213:
214: public Object getElementAt(int index) {
215: return index >= items.size() ? null : items.get(index);
216: }
217:
218: public WsdlMessageAssertion getAssertionAt(int index) {
219: Object object = items.get(index);
220: while (object instanceof AssertionError && index > 0) {
221: object = items.get(--index);
222: }
223:
224: return (WsdlMessageAssertion) object;
225: }
226:
227: public void refresh() {
228: synchronized (this ) {
229: release();
230: init();
231: fireContentsChanged(this , 0, getSize() - 1);
232: }
233: }
234:
235: private void init() {
236: assertable.addAssertionsListener(this );
237:
238: for (int c = 0; c < assertable.getAssertionCount(); c++) {
239: WsdlMessageAssertion assertion = assertable
240: .getAssertionAt(c);
241: addAssertion(assertion);
242: }
243: }
244:
245: public void release() {
246: items.clear();
247:
248: for (int c = 0; c < assertable.getAssertionCount(); c++) {
249: WsdlMessageAssertion assertion = assertable
250: .getAssertionAt(c);
251: assertion.removePropertyChangeListener(this );
252: }
253:
254: assertable.removeAssertionsListener(this );
255: }
256:
257: public synchronized void propertyChange(PropertyChangeEvent evt) {
258: if (SwingUtilities.isEventDispatchThread())
259: refresh();
260: else
261: SwingUtilities.invokeLater(new Runnable() {
262:
263: public void run() {
264: refresh();
265: }
266: });
267: }
268:
269: public void assertionAdded(WsdlMessageAssertion assertion) {
270: synchronized (this ) {
271: int sz = getSize();
272: addAssertion(assertion);
273:
274: fireIntervalAdded(this , sz, items.size() - 1);
275: }
276: }
277:
278: private void addAssertion(WsdlMessageAssertion assertion) {
279: assertion.addPropertyChangeListener(this );
280: items.add(assertion);
281:
282: AssertionError[] errors = assertion.getErrors();
283: if (errors != null) {
284: for (int i = 0; i < errors.length; i++)
285: items.add(errors[i]);
286: }
287: }
288:
289: public void assertionRemoved(WsdlMessageAssertion assertion) {
290: synchronized (this ) {
291: int ix = items.indexOf(assertion);
292: if (ix == -1)
293: return;
294:
295: assertion.removePropertyChangeListener(this );
296: items.remove(ix);
297: fireIntervalRemoved(this , ix, ix);
298:
299: // remove associated errors
300: while (ix < items.size()
301: && items.get(ix) instanceof AssertionError) {
302: items.remove(ix);
303: fireIntervalRemoved(this , ix, ix);
304: }
305: }
306: }
307: }
308:
309: public void release() {
310: assertionListModel.release();
311: }
312: }
|