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