View Javadoc

1   /*
2    * @(#)$Id: NodeInfoImpl.java 790 2010-03-28 11:03:45Z bpuype $
3    *
4    * Author   : Ueli Kurmann, igesture@uelikurmann.ch
5    *                                   
6    *                                   
7    * Purpose  : 
8    *
9    * -----------------------------------------------------------------------
10   *
11   * Revision Information:
12   *
13   * Date       Who     Reason
14   *
15   * 23.03.2008 ukurmann  Initial Release
16   *
17   * -----------------------------------------------------------------------
18   *
19   * Copyright 1999-2009 ETH Zurich. All Rights Reserved.
20   *
21   * This software is the proprietary information of ETH Zurich.
22   * Use is subject to license terms.
23   * 
24   */
25  
26  package org.ximtec.igesture.tool.explorer;
27  
28  import java.lang.reflect.Constructor;
29  import java.lang.reflect.Field;
30  import java.util.ArrayList;
31  import java.util.Collection;
32  import java.util.List;
33  import java.util.Map;
34  import java.util.logging.Level;
35  import java.util.logging.Logger;
36  
37  import javax.swing.Icon;
38  import javax.swing.JPopupMenu;
39  import javax.swing.tree.TreePath;
40  
41  import org.apache.commons.beanutils.BeanUtils;
42  import org.sigtec.graphix.widget.BasicAction;
43  import org.ximtec.igesture.tool.core.Controller;
44  import org.ximtec.igesture.tool.explorer.core.ExplorerTreeView;
45  import org.ximtec.igesture.tool.explorer.core.NodeInfo;
46  import org.ximtec.igesture.tool.service.GuiBundleService;
47  
48  /**
49   * Implementation of the NodeInfo interface. Reflection and dynamic class
50   * loading is used to get children, views, etc.
51   * 
52   * @author UeliKurmann
53   * @version 1.0
54   * @since igesture
55   */
56  public class NodeInfoImpl implements NodeInfo {
57  
58    public static final String CHILD_DELIMITER = ";";
59  
60    private static final Logger LOG = Logger.getLogger(NodeInfoImpl.class.getName());
61  
62    private String propertyName;
63    private String childList;
64    private Class<? extends ExplorerTreeView> viewClass;
65    private Class<? extends Object> nodeClass;
66    private Controller controller;
67  
68    private List<Class<? extends BasicAction>> popupActions;
69  
70    private String key;
71  
72    private GuiBundleService guiBundle;
73  
74  
75    /**
76     * Constructor
77     * 
78     * @param type
79     *          the type (class) of the node
80     * @param propertyName
81     *          the name of the property containing the name of the node.
82     * @param childList
83     *          a list of properties (as ";" separated strings) which should be
84     *          used as children.
85     * @param view
86     *          the view belonging the node. The view MUST HAVE a constructor with
87     *          the node instance as the only parameter.
88     * @param popupActions
89     *          a list of actions.
90     * @param icon
91     *          the icon of the node
92     */
93    public NodeInfoImpl(Controller controller, Class<? extends Object> type, String propertyName, String childList,
94        Class<? extends ExplorerTreeView> view, List<Class<? extends BasicAction>> popupActions, String key) {
95  
96      this.controller = controller;
97      this.nodeClass = type;
98      this.propertyName = propertyName;
99      this.childList = childList;
100     this.viewClass = view;
101     this.popupActions = popupActions;
102     this.key = key;
103     this.guiBundle = controller.getLocator().getService(GuiBundleService.IDENTIFIER, GuiBundleService.class);
104   }  
105 
106   /*
107    * (non-Javadoc)
108    * 
109    * @see
110    * org.ximtec.igesture.tool.explorer.core.NodeInfo#getChildren(java.lang.Object
111    * )
112    */
113   @Override
114   public List<Object> getChildren(Object node) {
115     List<Object> result = new ArrayList<Object>();
116     if (childList != null) {
117       for (String name : childList.split(CHILD_DELIMITER)) {
118 
119         try {
120           Field field = nodeClass.getDeclaredField(name);
121           field.setAccessible(true);
122           Object o = field.get(node);
123           if (o instanceof Collection) {
124             result.addAll((Collection<?>) o);
125           } else if (o instanceof Map) {
126             result.addAll(((Map<?, ?>) o).values());
127           } else {
128             result.add(o);
129           }
130         } catch (Exception e) {
131           LOG.log(Level.SEVERE, "Can't access children.", e);
132         }
133       }
134     }
135 
136     return result;
137   }
138 
139   /*
140    * (non-Javadoc)
141    * 
142    * @see org.ximtec.igesture.tool.explorer.core.NodeInfo#getIcon()
143    */
144   @Override
145   public Icon getIcon() {
146     return guiBundle.getSmallIcon(key);
147   }
148   
149   @Override
150   public Icon getExpandedIcon() {
151     return guiBundle.getSmallIconExpanded(key);
152   }
153   
154 
155   /*
156    * (non-Javadoc)
157    * 
158    * @see
159    * org.ximtec.igesture.tool.explorer.core.NodeInfo#getName(java.lang.Object)
160    */
161   @Override
162   public String getName(Object node) {
163     if (propertyName != null) {
164       try {
165         return BeanUtils.getProperty(node, propertyName);
166       } catch (Exception e) {
167         LOG.log(Level.SEVERE, "Can't get the node name. (" + node.getClass() + ")");
168       }
169     }
170     return null;
171   }
172 
173   /*
174    * (non-Javadoc)
175    * 
176    * @see org.ximtec.igesture.tool.explorer.core.NodeInfo#getTooltip()
177    */
178   @Override
179   public String getTooltip() {
180     return guiBundle.getShortDescription(key);
181   }
182 
183   /*
184    * (non-Javadoc)
185    * 
186    * @see org.ximtec.igesture.tool.explorer.core.NodeInfo#getType()
187    */
188   @Override
189   public Class<?> getType() {
190     return nodeClass;
191   }
192 
193   /*
194    * (non-Javadoc)
195    * 
196    * @see
197    * org.ximtec.igesture.tool.explorer.core.NodeInfo#isLeaf(java.lang.Object)
198    */
199   @Override
200   public boolean isLeaf(Object object) {
201     return getChildren(object).size() == 0;
202   }
203 
204   /*
205    * (non-Javadoc)
206    * 
207    * @see
208    * org.ximtec.igesture.tool.explorer.core.NodeInfo#getView(java.lang.Object)
209    */
210   @Override
211   public ExplorerTreeView getView(Controller controller, Object node) {
212 
213     try {
214       Constructor<? extends ExplorerTreeView> ctor = null;
215       Class<? extends Object> type = nodeClass;
216       
217       while (ctor == null && type != null) {
218         try {
219           ctor = viewClass.getConstructor(Controller.class, type);
220         } finally {
221           type = type.getSuperclass();
222         }
223       }
224 
225       if (ctor != null) {
226         return ctor.newInstance(controller, node);
227       }
228     } catch (Exception e) {
229       LOG.log(Level.SEVERE, "Can't create the view.", e);
230     }
231 
232     return null;
233   }
234 
235   /*
236    * (non-Javadoc)
237    * 
238    * @see
239    * org.ximtec.igesture.tool.explorer.core.NodeInfo#getPopupMenu(javax.swing
240    * .tree.TreePath)
241    */
242   @Override
243   public JPopupMenu getPopupMenu(TreePath treePath) {
244 
245     JPopupMenu popupMenu = new JPopupMenu();
246     if (popupActions != null) {
247       for (Class<? extends BasicAction> actionClass : popupActions) {
248         try {
249           if (actionClass == SeparatorAction.class) {
250             popupMenu.addSeparator();
251           } else {
252             BasicAction action = actionClass.getConstructor(Controller.class, TreePath.class).newInstance(controller,
253                 treePath);
254             popupMenu.add(action);
255           }
256 
257         } catch (Exception e) {
258           LOG.log(Level.SEVERE, "Can't create Popup Menu.", e);
259         } 
260       }
261     }
262     return popupMenu;
263   }
264 }