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