1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.model.tree;
14
15 import java.awt.Rectangle;
16 import java.beans.PropertyChangeEvent;
17 import java.beans.PropertyChangeListener;
18 import java.util.Collections;
19 import java.util.Comparator;
20 import java.util.Enumeration;
21 import java.util.List;
22 import java.util.Vector;
23
24 import javax.swing.JPopupMenu;
25 import javax.swing.JTree;
26 import javax.swing.event.TreeModelEvent;
27 import javax.swing.tree.TreeNode;
28 import javax.swing.tree.TreePath;
29
30 import com.eviware.soapui.SoapUI;
31 import com.eviware.soapui.model.ModelItem;
32 import com.eviware.soapui.model.settings.SettingsListener;
33 import com.eviware.soapui.model.testsuite.TestCase;
34 import com.eviware.soapui.model.testsuite.TestStep;
35 import com.eviware.soapui.support.action.swing.ActionList;
36 import com.eviware.soapui.support.action.swing.ActionListBuilder;
37 import com.eviware.soapui.support.action.swing.ActionSupport;
38
39 /***
40 * Abstract base class for SoapUITreeNode implementations
41 *
42 * @author Ole.Matzura
43 */
44
45 public abstract class AbstractModelItemTreeNode<T extends ModelItem> implements SoapUITreeNode, PropertyChangeListener
46 {
47 private final T modelItem;
48 private final ModelItem parentItem;
49 private final SoapUITreeModel treeModel;
50 private List<? extends SoapUITreeNode> orderItems;
51 private String orderSetting;
52 private InternalSettingsListener internalSettingsListener;
53
54 protected AbstractModelItemTreeNode( T modelItem, ModelItem parentItem, SoapUITreeModel treeModel )
55 {
56 this.modelItem = modelItem;
57 this.parentItem = parentItem;
58 this.treeModel = treeModel;
59
60 modelItem.addPropertyChangeListener( this );
61 }
62
63 public SoapUITreeModel getTreeModel()
64 {
65 return treeModel;
66 }
67
68 public T getModelItem()
69 {
70 return modelItem;
71 }
72
73 public boolean valueChanged( Object newValue )
74 {
75 return false;
76 }
77
78 public boolean isLeaf()
79 {
80 return getChildCount() == 0;
81 }
82
83 public int getChildCount()
84 {
85 return orderItems == null ? 0 : orderItems.size();
86 }
87
88 public SoapUITreeNode getChildNode( int index )
89 {
90 return orderItems == null ? null : orderItems.get( index );
91 }
92
93 public int getIndexOfChild( Object child )
94 {
95 return orderItems == null ? -1 : orderItems.indexOf( child );
96 }
97
98 public String toString()
99 {
100 if( modelItem instanceof TestStep )
101 return ( ( TestStep )modelItem ).getLabel();
102 else if( modelItem instanceof TestCase )
103 return ( ( TestCase )modelItem ).getLabel();
104
105 return modelItem.getName();
106 }
107
108 public JPopupMenu getPopup()
109 {
110 return ActionSupport.buildPopup( getActions() );
111 }
112
113 public ActionList getActions()
114 {
115 return ActionListBuilder.buildActions( modelItem );
116 }
117
118 public SoapUITreeNode getParentTreeNode()
119 {
120 return treeModel.getTreeNode( parentItem );
121 }
122
123 public void propertyChange( PropertyChangeEvent evt )
124 {
125 String propertyName = evt.getPropertyName();
126 if( propertyName.equals( ModelItem.NAME_PROPERTY ) || propertyName.equals( ModelItem.LABEL_PROPERTY ) )
127 {
128
129 getTreeModel().notifyNodeChanged( this );
130 }
131 else if( propertyName.equals( ModelItem.ICON_PROPERTY ) )
132 {
133
134 JTree mainTree = SoapUI.getNavigator().getMainTree();
135 TreePath nodePath = getTreeModel().getPath( this );
136 Rectangle rowBounds = mainTree.getPathBounds( nodePath );
137 if( rowBounds != null )
138 {
139 mainTree.repaint( rowBounds );
140 }
141 }
142 }
143
144 public void release()
145 {
146 modelItem.removePropertyChangeListener( this );
147
148 if( internalSettingsListener != null )
149 SoapUI.getSettings().removeSettingsListener( internalSettingsListener );
150
151 getTreeModel().unmapModelItem( modelItem );
152 }
153
154 public <T2 extends SoapUITreeNode> void initOrdering( List<T2> items, String setting )
155 {
156 this.orderItems = items;
157 this.orderSetting = setting;
158
159 internalSettingsListener = new InternalSettingsListener( this, setting );
160 SoapUI.getSettings().addSettingsListener( internalSettingsListener );
161 sortModelItems( items, setting );
162 }
163
164 private final class InternalSettingsListener implements SettingsListener
165 {
166 private final AbstractModelItemTreeNode<?> node;
167 private final String setting;
168
169 public InternalSettingsListener( AbstractModelItemTreeNode<?> node, String setting )
170 {
171 this.node = node;
172 this.setting = setting;
173 }
174
175 public void settingChanged( String name, String newValue, String oldValue )
176 {
177 if( name.equals( setting ) )
178 {
179 if( oldValue == null )
180 oldValue = "false";
181
182 if( newValue == null )
183 newValue = "false";
184
185 if( !oldValue.equals( newValue ) )
186 {
187 TreePath path = getTreeModel().getPath( AbstractModelItemTreeNode.this );
188 node.reorder( SoapUI.getNavigator().isVisible( path ) && SoapUI.getNavigator().isExpanded( path ) );
189 }
190 }
191 }
192 }
193
194 public void reorder( boolean notify )
195 {
196 if( orderItems != null )
197 {
198 sortModelItems( orderItems, orderSetting );
199
200 if( notify )
201 {
202 getTreeModel().notifyStructureChanged( new TreeModelEvent( this, getTreeModel().getPath( this ) ) );
203 }
204 }
205 }
206
207 public <T2 extends SoapUITreeNode> void sortModelItems( List<T2> modelItems, final String setting )
208 {
209 Collections.sort( modelItems, new Comparator<T2>()
210 {
211 public int compare( T2 o1, T2 o2 )
212 {
213 String name1 = o1.getModelItem().getName();
214 String name2 = o2.getModelItem().getName();
215
216 if( name1 == null && name2 == null )
217 {
218 return 0;
219 }
220 else if( name1 == null )
221 {
222 return -1;
223 }
224 else if( name2 == null )
225 {
226 return 1;
227 }
228 else if( setting != null && SoapUI.getSettings().getBoolean( setting ) )
229 {
230 return name1.compareToIgnoreCase( name2 );
231 }
232 else
233 {
234 return name1.compareTo( name2 );
235 }
236 }
237 } );
238 }
239
240 public Enumeration<?> children()
241 {
242 Vector<TreeNode> children = new Vector<TreeNode>();
243 for( int c = 0; c < getChildCount(); c++ )
244 children.add( getChildAt( c ) );
245
246 return children.elements();
247 }
248
249 public boolean getAllowsChildren()
250 {
251 return !isLeaf();
252 }
253
254 public TreeNode getChildAt( int childIndex )
255 {
256 return getChildNode( childIndex );
257 }
258
259 public int getIndex( TreeNode node )
260 {
261 return getIndexOfChild( node );
262 }
263
264 public TreeNode getParent()
265 {
266 return getParentTreeNode();
267 }
268
269 public class ReorderPropertyChangeListener implements PropertyChangeListener
270 {
271 public void propertyChange( PropertyChangeEvent arg0 )
272 {
273 reorder( true );
274 SoapUI.getNavigator().selectModelItem( ( ModelItem )arg0.getSource() );
275 }
276 }
277 }