View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
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    		// hack to improve rendering performance
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    		//getTreeModel().notifyNodeChanged( this );
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 }