View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 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.util.ArrayList;
16  import java.util.HashMap;
17  import java.util.HashSet;
18  import java.util.Iterator;
19  import java.util.List;
20  import java.util.Map;
21  import java.util.Set;
22  
23  import javax.swing.event.TreeModelEvent;
24  import javax.swing.event.TreeModelListener;
25  import javax.swing.tree.TreeModel;
26  import javax.swing.tree.TreePath;
27  
28  import org.apache.log4j.Logger;
29  
30  import com.eviware.soapui.model.ModelItem;
31  import com.eviware.soapui.model.tree.nodes.PropertiesTreeNode;
32  import com.eviware.soapui.model.tree.nodes.PropertyTreeNode;
33  import com.eviware.soapui.model.tree.nodes.WorkspaceTreeNode;
34  import com.eviware.soapui.model.workspace.Workspace;
35  
36  /***
37   * The Navigator TreeModel
38   * 
39   * @author Ole.Matzura
40   */
41  
42  public class SoapUITreeModel implements TreeModel
43  {
44     private Set<TreeModelListener> listeners = new HashSet<TreeModelListener>();
45     private SoapUITreeNode workspaceNode;
46     private final static Logger logger = Logger.getLogger( SoapUITreeModel.class );
47     private Map<ModelItem,SoapUITreeNode> modelItemMap = new HashMap<ModelItem,SoapUITreeNode>();
48  	private boolean showProperties = false;
49  
50     public SoapUITreeModel(Workspace workspace)
51     {
52        workspaceNode = new WorkspaceTreeNode( workspace, this );
53        mapModelItem( workspaceNode );
54     }
55  
56     public Object getRoot()
57     {
58        return workspaceNode;
59     }
60  
61     public Object getChild(Object parent, int index)
62     {
63        SoapUITreeNode treeNode = (SoapUITreeNode) parent;
64        return treeNode.getChildNode( index );
65     }
66  
67     public int getChildCount(Object parent)
68     {
69        SoapUITreeNode treeNode = (SoapUITreeNode) parent;
70        return treeNode.getChildCount();
71     }
72  
73     public boolean isLeaf(Object node)
74     {
75        SoapUITreeNode treeNode = (SoapUITreeNode) node;
76        return treeNode.isLeaf();
77     }
78  
79     public void valueForPathChanged(TreePath path, Object newValue)
80     {
81        SoapUITreeNode treeNode = (SoapUITreeNode) path.getLastPathComponent();
82        if( treeNode.valueChanged( newValue ))
83        {
84        	// not implemented.. need to expose setName in ModelItem
85        }
86     }
87  
88     public int getIndexOfChild(Object parent, Object child)
89     {
90        SoapUITreeNode treeNode = (SoapUITreeNode) parent;
91        return treeNode.getIndexOfChild( child );
92     }
93  
94     public void addTreeModelListener(TreeModelListener l)
95     {
96        listeners.add( l );
97     }
98  
99     public void removeTreeModelListener(TreeModelListener l)
100    {
101       listeners.remove( l );
102    }
103    
104    public void mapModelItem( SoapUITreeNode soapUITreeNode )
105    {
106    	modelItemMap.put( soapUITreeNode.getModelItem(), soapUITreeNode );
107    }
108    
109    public void unmapModelItem( ModelItem modelItem )
110    {
111    	if( modelItemMap.containsKey( modelItem ))
112    	{
113    		modelItemMap.remove( modelItem );
114    	}
115    	else
116    	{
117    		logger.error( "Failed to unmap model item [" + modelItem.getName() + "]" );
118    		Thread.dumpStack();
119    	}
120    }
121    
122    public void notifyNodesInserted( TreeModelEvent e )
123    {
124       Iterator<TreeModelListener> i = listeners.iterator();
125       while( i.hasNext() )
126       {
127          i.next().treeNodesInserted( e );
128       }
129    }
130    
131    public void notifyNodesRemoved( TreeModelEvent e )
132    {
133       Iterator<TreeModelListener> i = listeners.iterator();
134       while( i.hasNext() )
135       {
136          i.next().treeNodesRemoved( e );
137       }
138    }
139    public void notifyStructureChanged( TreeModelEvent e )
140    {
141       Iterator<TreeModelListener> i = listeners.iterator();
142       while( i.hasNext() )
143       {
144          i.next().treeStructureChanged( e );
145       }
146    }
147    
148    public void notifyNodesChanged(  TreeModelEvent e )
149    {
150       Iterator<TreeModelListener> i = listeners.iterator();
151       while( i.hasNext() )
152       {
153          i.next().treeNodesChanged( e );
154       }
155    }
156 
157    public TreePath getPath(SoapUITreeNode treeNode)
158    {
159       //SoapUITreeNode treeNode = modelItemMap.get( modelItem );
160       //if( treeNode == null )
161       //	throw new RuntimeException( "Missing mapping for modelItem " + modelItem.getName() );
162 
163       List<Object> nodes = new ArrayList<Object>();
164       if( treeNode != null )
165       {
166 	      nodes.add( treeNode );
167 	      
168 	      treeNode = treeNode.getParentTreeNode();
169 	      while( treeNode != null )
170 	      {
171 	         nodes.add( 0, treeNode );
172 	         treeNode = treeNode.getParentTreeNode();
173 	      }
174       }
175       
176       return nodes.isEmpty() ? null : new TreePath( nodes.toArray() );
177    }
178    
179    public void notifyNodeChanged( SoapUITreeNode treeNode )
180    {
181       SoapUITreeNode parent = treeNode.getParentTreeNode();
182       if( parent == null )
183       {
184          notifyNodesChanged( new TreeModelEvent( this, new Object[] {treeNode} ));
185          return;
186       }
187       
188       int ix = parent.getIndexOfChild( treeNode );
189       
190       if( ix == -1 )
191       {
192       	if( ( !(treeNode instanceof PropertyTreeNode) && !(treeNode instanceof PropertiesTreeNode)) || isShowProperties() ) 
193       	    logger.error( "Changed node [" + treeNode + "] not found in parent [" + parent + "]" );
194       	
195          return;
196       }
197       
198       if( !(treeNode instanceof PropertyTreeNode) || showProperties )
199       {
200       	notifyNodesChanged( new TreeModelEvent( 
201             this, getPath( parent ), 
202             new int[] {ix}, new Object[]{parent.getChildNode( ix )}));
203       }
204    }
205 
206    public void notifyNodeInserted( SoapUITreeNode treeNode )
207    {
208       SoapUITreeNode parent = treeNode.getParentTreeNode();
209       int ix = parent.getIndexOfChild( treeNode );
210       
211       if( ix == -1 )
212       {
213          logger.error( "Inserted node [" + treeNode + "] not found in parent [" + parent + "]" );
214          return;
215       }
216       
217       mapModelItem( treeNode );
218       
219       if( !(treeNode instanceof PropertyTreeNode) || showProperties )
220       {
221 	      notifyNodesInserted( new TreeModelEvent( 
222 	            this, getPath( parent ), 
223 	            new int[] {ix}, new Object[]{parent.getChildNode( ix )}));
224       }
225    }
226 
227    public void notifyNodeRemoved( SoapUITreeNode treeNode )
228    {
229    	notifyNodeRemoved(treeNode, true );
230    }
231    
232    public void notifyNodeRemoved( SoapUITreeNode treeNode, boolean release )
233    {
234       SoapUITreeNode parent = treeNode.getParentTreeNode();
235       int ix = parent.getIndexOfChild( treeNode);
236       
237       if( ix == -1 )
238       {
239          logger.error( "Removed node [" + treeNode + "] not found in parent [" + parent + "]" );
240          return;
241       }
242       
243       if( !(treeNode instanceof PropertyTreeNode) || showProperties )
244       {
245       	notifyNodesRemoved( new TreeModelEvent( 
246             this, getPath( parent ), 
247             new int[] {ix}, new Object[]{parent.getChildNode( ix )}));
248       }
249       
250       if( release )
251       	treeNode.release();
252    }
253 
254 	public SoapUITreeNode getTreeNode(ModelItem parentItem)
255 	{
256 		return modelItemMap.get( parentItem );
257 	}
258 
259 	public TreePath getPath(ModelItem modelItem)
260 	{
261 		return getPath( modelItemMap.get( modelItem ));
262 	}
263 
264 	public void mapModelItems(List<? extends SoapUITreeNode> treeNodes)
265 	{
266 		Iterator<? extends SoapUITreeNode> iterator = treeNodes.iterator();
267 		while( iterator.hasNext() )
268 		{
269 			SoapUITreeNode item = iterator.next();
270 			mapModelItem( item );
271 		}
272 	}
273 
274 	public boolean isShowProperties()
275 	{
276 		return showProperties;
277 	}
278 
279 	public void setShowProperties( boolean showProperties )
280 	{
281 		if( this.showProperties != showProperties )
282 		{
283 			this.showProperties = showProperties;
284 			notifyStructureChanged( new TreeModelEvent( this, getPath( workspaceNode ) ) );
285 		}
286 	}
287 }