View Javadoc

1   // UML Model Transformation Tool (UMT)
2   // Copyright (C) 2003, 2004, 2005 SINTEF 
3   // Authors:  jon.oldevik at sintef.no | roy.gronmo at sintef.no | tor.neple at sintef.no | fredrik.vraalsen at sintef.no
4   // Webpage: http://umt.sourceforge.net 
5   // Deloped in the projects:  ACEGIS (EU project - IST-2002-37724), 
6   //    CAFE (EUREKA/ITEA - ip00004), FAMILIES (ITEA project ip02009)
7   //
8   // This program is free software; you can redistribute it and/or
9   // modify it under the terms of the GNU Lesser General Public License
10  // as published by the Free Software Foundation; either version 2.1
11  // of the License, or (at your option) any later version.
12  //
13  // This program is distributed in the hope that it will be useful,
14  // but WITHOUT ANY WARRANTY; without even the implied warranty of
15  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16  // Lesser General Public License for more details.
17  //
18  // You should have received a copy of the GNU Lesser General Public
19  // License along with this program; if not, write to the Free
20  // Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
21  // 02111-1307 USA
22  
23  package org.sintef.umt.hutntree;
24  
25  
26  /*** 
27   * @author		Jon Oldevik, (jon.oldevik@sintef.no)
28   * @copyright (c) SINTEF 2002 (www.sintef.no)
29   * 
30   */
31  
32  
33  import java.awt.Graphics;
34  import java.awt.event.ActionEvent;
35  import java.awt.event.ActionListener;
36  import java.awt.event.MouseAdapter;
37  import java.awt.event.MouseEvent;
38  import java.io.StringWriter;
39  import java.util.Collection;
40  import java.util.Hashtable;
41  import java.util.Iterator;
42  
43  import javax.swing.JMenu;
44  import javax.swing.JMenuItem;
45  import javax.swing.JPopupMenu;
46  import javax.swing.JTree;
47  import javax.swing.ToolTipManager;
48  import javax.swing.event.TreeSelectionEvent;
49  import javax.swing.event.TreeSelectionListener;
50  import javax.swing.tree.DefaultMutableTreeNode;
51  import javax.swing.tree.DefaultTreeModel;
52  import javax.swing.tree.TreeNode;
53  import javax.swing.tree.TreePath;
54  
55  import org.jboss.util.property.PropertyManager;
56  import org.w3c.dom.Element;
57  import org.w3c.dom.Node;
58  import org.w3c.dom.NodeList;
59  
60  
61  public class HutnTreeView extends JTree implements TreeSelectionListener, Runnable
62  {
63  //	protected static final String img_dir = "org/sintef/umt/hutntree/img";
64  	protected PropertyManager _actionPropertyMgr;
65  	protected volatile boolean _isLoading, _indicator, _isTransforming;
66  	protected int _loadingCount = 0;
67  	private int tmp_x, tmp_y;
68  	protected Hashtable _elements;
69  	protected boolean _hasmodelelements = false;
70  	
71  	public HutnTreeView ()
72  	{
73  		super ();
74           setShowsRootHandles (true);         
75           setRootVisible(false);
76           setScrollsOnExpand(true);         		
77  		addTreeSelectionListener (this);
78  		ToolTipManager ttmanager = ToolTipManager.sharedInstance ();
79  		ttmanager.registerComponent(this);		
80  		_elements = new Hashtable ();
81  		HutnTreeMouseAdapter htma = new HutnTreeMouseAdapter ();		
82  		addMouseListener (htma);
83  		init ();
84  	}
85  		
86  	
87  	/***
88  	 * Clears all children from the tree
89  	 *
90  	 */
91  	public void clear () {
92  	    ((DefaultMutableTreeNode)getModel().getRoot()).removeAllChildren();
93  	    ((DefaultTreeModel)getModel()).reload();
94  	}
95  	
96  	protected void init () {
97  		setModel (new HutnTreeModel ("root"));
98  		setCellRenderer (new HutnTreeCellRenderer (this));
99  	}
100 	
101 	public String getNameForID (String id) {
102 		return (String) _elements.get(id);
103 	}
104 	
105 	protected void addNameWithID (String name, String id) {
106 		if (name != null && id != null)
107 			_elements.put(id, name);	
108 	}
109 	
110 	protected void removeNameWithID (String id) {
111 	    _elements.remove(id);
112 	}
113 	
114 	public synchronized String getTreeBuffer () {
115 		StringWriter writer = new StringWriter ();		
116 
117 		return writer.toString();
118 	}
119 	
120 	public boolean hasModelElements () {
121 		return _hasmodelelements;
122 	}
123 	
124 	/***
125 	 * Appends modelelements to already existing structure...
126 	 * @param modelelements
127 	 */
128 	public void addModelElements (Collection modelelements) {
129 	    _hasmodelelements = true;
130 	    _elements.clear();
131 	    clear();	    
132 		Iterator elements = modelelements.iterator ();		
133 		DefaultMutableTreeNode root = (DefaultMutableTreeNode)((HutnTreeModel)getModel()).getRoot();
134 		DefaultMutableTreeNode datatypechild = new DefaultMutableTreeNode ("Datatypes");		
135 		boolean has_datatypes = false;
136 		while (elements.hasNext()) {
137 			Object obj = elements.next();
138 			Node element = (Node)obj;
139 			if (element.getNodeType() == Node.ELEMENT_NODE) {				
140 				addModelElement (element, (DefaultMutableTreeNode)root);
141 			}
142 		}
143 		TreeNode[] path = root.getPath();
144 		// TreePath treepath = new TreePath (path);
145 		// makeVisible(treepath);
146 		root.setAllowsChildren(true);			
147 		for (int i = 0; i < root.getChildCount (); i++) {
148 			TreeNode child = root.getChildAt(i);
149 			path = ((DefaultMutableTreeNode)child).getPath();
150 			makeVisible (new TreePath (path));
151 		}
152 	}
153 	
154 	public Element getModelRoot () {
155 	    DefaultMutableTreeNode root = (DefaultMutableTreeNode)((HutnTreeModel)getModel()).getRoot();
156 	    if (root.getChildCount() > 0) {
157 	        DefaultMutableTreeNode child = (DefaultMutableTreeNode)((DefaultMutableTreeNode) root.getFirstChild());
158 		    Object userobject = child.getUserObject();
159 		    if (userobject instanceof Element) {
160 		        return (Element)userobject;
161 		    }
162 	        
163 	    }
164 	    return null;
165 	}
166 	
167 	/*
168 	public void setModelElements (Collection modelelements)	
169 	{
170 		_hasmodelelements = true;		
171 		_elements.clear();
172 		addModelElements (modelelements);
173 	}
174 	*/
175 	
176 
177 	
178 	public DefaultMutableTreeNode addModelElement (Object modelelement, DefaultMutableTreeNode treeparent){
179 		Element e = (Element) modelelement;
180 		String name = e.getAttribute("name"); String id = e.getAttribute("id");
181 		addNameWithID(name, id);
182 		NodeList children = e.getChildNodes ();
183 		DefaultMutableTreeNode treechild = null;
184 		if (e.getParentNode().getNodeType() == Node.DOCUMENT_NODE && (name.equals(""))) {
185 			treechild = treeparent;		 
186 		} else {
187 			treechild = new DefaultMutableTreeNode (e);
188 			treeparent.add (treechild);			
189 		}
190 		 							
191 		for (int i = 0; i < children.getLength(); i++){
192 			Node n = children.item(i);
193 			if (n.getNodeType () == org.w3c.dom.Node.ELEMENT_NODE && !n.getNodeName().equalsIgnoreCase("datatype") && !n.getNodeName().equalsIgnoreCase("uses")) {
194 				if (!(n.getNodeName().equalsIgnoreCase("taggedValue"))) /* SKIP TAGS FOR NOW */
195 					addModelElement (n, treechild);
196 			}
197 		}
198 		
199 		/*
200 		 *    Adds datatypes to a package in a separate 'folder' 
201 		 * */
202 		if (e.getNodeName().equalsIgnoreCase("package")) {		
203 			NodeList childnodes = e.getChildNodes();
204 			int count = 0;
205 			DefaultMutableTreeNode datatypechild = new DefaultMutableTreeNode ("Datatypes");
206 			for (int i = 0; i < childnodes.getLength(); i++) {
207 				Node childnode = childnodes.item(i);
208 				if (childnode.getNodeType () == org.w3c.dom.Node.ELEMENT_NODE && childnode.getNodeName().equalsIgnoreCase("datatype")) {
209 					addNameWithID(((Element)childnode).getAttribute("name"), ((Element)childnode).getAttribute("id"));
210 					datatypechild.add(new DefaultMutableTreeNode(childnode));
211 					count++;
212 				}
213 			}
214 			if (count > 0) {
215 				treechild.add(datatypechild);
216 			}
217 			
218 			DefaultMutableTreeNode useschild = new DefaultMutableTreeNode ("uses");
219 			for (int i = 0; i < childnodes.getLength(); i++) {
220 				Node childnode = childnodes.item(i);
221 				if (childnode.getNodeType () == org.w3c.dom.Node.ELEMENT_NODE && childnode.getNodeName().equalsIgnoreCase("uses")) {
222 					useschild.add(new DefaultMutableTreeNode(childnode));
223 					count++;
224 				}
225 			}
226 			if (count > 0) {
227 				treechild.add(useschild);
228 			}			
229 		}	
230 		return treechild;
231 		
232 	}
233 	
234  
235 
236 	public void valueChanged (TreeSelectionEvent tse){
237 //		TreePath path = tse.getPath ();
238 		try{
239 			// userobj = ((DefaultMutableTreeNode)node).getUserObject ();
240 			// System.out.println (userobj.getClass().getName ());			
241 		} catch (Exception ex){
242 			System.out.println (ex);
243 		}
244 		// System.out.println ("Selected");
245 	}	
246 	
247 	public void setLoading (boolean loading) {
248 		_isLoading = loading;		
249 		if (_isLoading) {
250 			Thread loadingThread = new Thread(this);
251 			loadingThread.start();
252 			_isLoading = loading;
253 		}			
254 	}
255 	
256 	public void setTransforming (boolean transforming) {
257 		_isTransforming = transforming;
258 		if(_isTransforming) {
259 			Thread transformThread = new Thread (this, "transformation");
260 			transformThread.start();			
261 		}
262 	}
263 
264 	public void paintComponent (Graphics g) {
265 		super.paintComponent (g);
266 		/*
267 		if (_isLoading || _isTransforming) {
268 		    if (_loadingCount == 4) _loadingCount = 0;
269 		    ImageIcon image = new ImageIcon (img_dir + "loading" + ++_loadingCount + ".gif");
270 		    g.drawImage(image.getImage(), 50,150, null);
271 		}
272 		*/
273 	}
274 	
275 	/*
276 	 * OLD Painter 
277 	public void paintComponent (Graphics g) {
278 		super.paintComponent (g);
279 //		System.out.println ("repaint " + _isLoading + " " + _indicator);
280 		if (_isLoading && _indicator) {
281 			g.setColor(Color.blue);
282 			g.setFont(new Font("Sans Serif", Font.ITALIC, 16));
283 			g.drawString("loading model", 50,150);
284 		} else if (_isTransforming && _indicator) {
285 			g.setColor(Color.blue);
286 			g.setFont(new Font("Sans Serif", Font.BOLD, 18));
287 			g.drawString("Transforming ....", 50, 150);
288 		}
289 		paintSelection (g);
290 		_indicator = !_indicator;
291 	}
292 	*/
293 
294 	private void paintSelection (Graphics g) {
295 		TreePath selPath = getSelectionPath();
296 		if (tmp_x > 0 && tmp_y > 0) {
297 			if (selPath != null) {
298 				Object path = selPath.getLastPathComponent ();
299 				Object userobj = ((DefaultMutableTreeNode)path).getUserObject ();		
300 				if (userobj instanceof Element) {
301 					Element e = (Element) userobj;
302 					String nodename = e.getNodeName ();
303 					String name = e.getAttribute ("name");
304 					String stereotype = e.getAttribute ("stereoType");
305 					String superclass = e.getAttribute ("superClass");
306 					DefaultMutableTreeNode p;					
307 /*					if (superclass != null && !superclass.equals("")) {
308 						g.drawLine(tmp_x, tmp_y, tmp_x + 50, tmp_y);						
309 					}
310 */					
311 				}
312 					
313 			}
314 		}
315 	}	
316 		
317 	public void run () {
318 		while (_isLoading || _isTransforming) {
319 			try {				
320 				Thread.sleep(120);
321 				repaint ();
322 			} catch (Exception ex) {				
323 			}
324 		}
325 	}
326 	
327 	
328 protected class HutnTreeModel extends DefaultTreeModel
329 {
330 	public HutnTreeModel (String rootTitle)
331 	{
332 		super (new DefaultMutableTreeNode (rootTitle));
333 	}
334 }
335 
336 
337 private class HutnTreeMouseAdapter extends MouseAdapter implements ActionListener {
338 	public HutnTreeMouseAdapter (){
339 	}
340 	
341 	public void mouseClicked (MouseEvent me){
342 		TreePath selPath = HutnTreeView.this.getPathForLocation(me.getX(), me.getY());
343 		tmp_x = me.getX(); tmp_y = me.getY();		
344 		if (selPath != null){
345 			HutnTreeView.this.setSelectionPath(selPath);		
346 			Object path = selPath.getLastPathComponent ();
347 			Object userobj = ((DefaultMutableTreeNode)path).getUserObject ();
348 			repaint ();
349 			if (me.isMetaDown ()){
350 				if (userobj instanceof Element){ 					
351 					Element e = (Element)userobj;
352 					// raise appropriate menu
353 					String nodename = e.getNodeName ();
354 					String stereotype = e.getAttribute ("stereoType");
355 					raiseMenuForNode (nodename, stereotype, me.getX(), me.getY());
356 				} else {
357 					// default action
358 				}
359 			} else if (me.getClickCount() == 2) {
360 				
361 			}
362 		}
363 	}
364 	
365 	private void raiseMenuForNode (String nodename, String stereotype, int posx, int posy){
366 		JPopupMenu pop = new JPopupMenu ();
367 		if (stereotype == null) stereotype = "";
368 		TreePath path = getSelectionPath ();
369 		Object node = path.getLastPathComponent ();			
370         Element context = (Element)((DefaultMutableTreeNode)node).getUserObject ();		
371 		JMenu transformations = new JMenu ("Transformations");
372 		transformations.setMnemonic('T');
373 		pop.add(transformations);				
374 		pop.show (HutnTreeView.this, posx, posy);
375 	}
376 	
377 	public void actionPerformed (ActionEvent ae){
378 		((JMenuItem)ae.getSource()).getParent().setVisible (false);
379 		String action = ae.getActionCommand ();
380 		try {
381 		  TreePath path = getSelectionPath ();
382 		  Object node = path.getLastPathComponent ();			
383 		  Element userobj = (Element)((DefaultMutableTreeNode)node).getUserObject ();
384 //		  String name = userobj.getAttribute ("name");
385 //		  String stereotype = userobj.getAttribute("stereoType");
386 		  // System.out.println ("Action on node: " + action + " - " + stereotype + " " + name);
387 		  int pindex = action.indexOf ("=");
388 		  String property, value;
389 		  if (pindex > 0) {
390 			  property = action.substring(0, pindex);
391 			  value = action.substring(pindex + 1, action.length()); 
392 		  } else {
393 			  property = action;
394 			  value = "true";
395 		  }
396 		  userobj.setAttribute (property, value);
397 		  revalidate ();
398 		  repaint ();
399 		} catch (Exception ex) {
400 			ex.printStackTrace ();
401 		}		
402 	}
403 }
404 	
405 }
406 
407