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