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