Francesco Furfari | 91af5da | 2006-04-04 23:44:23 +0000 | [diff] [blame] | 1 | /*
|
| 2 | * Copyright 2006 The Apache Software Foundation
|
| 3 | *
|
| 4 | * Licensed under the Apache License, Version 2.0 (the "License");
|
| 5 | * you may not use this file except in compliance with the License.
|
| 6 | * You may obtain a copy of the License at
|
| 7 | *
|
| 8 | * http://www.apache.org/licenses/LICENSE-2.0
|
| 9 | *
|
| 10 | * Unless required by applicable law or agreed to in writing, software
|
| 11 | * distributed under the License is distributed on an "AS IS" BASIS,
|
| 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
| 13 | * See the License for the specific language governing permissions and
|
| 14 | * limitations under the License.
|
| 15 | *
|
| 16 | */
|
| 17 |
|
| 18 | package org.apache.felix.upnp.tester.gui;
|
| 19 |
|
| 20 |
|
| 21 | import java.awt.BorderLayout;
|
| 22 | import java.awt.event.ActionEvent;
|
| 23 | import java.awt.event.MouseAdapter;
|
| 24 | import java.awt.event.MouseEvent;
|
| 25 | import java.util.ArrayList;
|
| 26 | import java.util.Dictionary;
|
| 27 | import java.util.Enumeration;
|
| 28 |
|
| 29 | import javax.swing.AbstractAction;
|
| 30 | import javax.swing.JMenuItem;
|
| 31 | import javax.swing.JPanel;
|
| 32 | import javax.swing.JPopupMenu;
|
| 33 | import javax.swing.JScrollPane;
|
| 34 | import javax.swing.JTree;
|
| 35 | import javax.swing.SwingUtilities;
|
| 36 | import javax.swing.ToolTipManager;
|
| 37 | import javax.swing.event.PopupMenuEvent;
|
| 38 | import javax.swing.event.PopupMenuListener;
|
| 39 | import javax.swing.event.TreeSelectionEvent;
|
| 40 | import javax.swing.event.TreeSelectionListener;
|
| 41 | import javax.swing.tree.DefaultTreeModel;
|
| 42 | import javax.swing.tree.TreePath;
|
| 43 |
|
| 44 | import org.apache.felix.upnp.tester.Activator;
|
| 45 | import org.apache.felix.upnp.tester.Mediator;
|
| 46 | import org.apache.felix.upnp.tester.discovery.DeviceNode;
|
| 47 | import org.apache.felix.upnp.tester.discovery.DeviceNodeListener;
|
| 48 | import org.osgi.service.upnp.UPnPAction;
|
| 49 | import org.osgi.service.upnp.UPnPDevice;
|
| 50 | import org.osgi.service.upnp.UPnPService;
|
| 51 | import org.osgi.service.upnp.UPnPStateVariable;
|
| 52 |
|
Francesco Furfari | f2a6791 | 2006-07-17 17:08:02 +0000 | [diff] [blame^] | 53 | /*
|
| 54 | * @author <a href="mailto:felix-dev@incubator.apache.org">Felix Project Team</a>
|
| 55 | */
|
| 56 |
|
Francesco Furfari | 91af5da | 2006-04-04 23:44:23 +0000 | [diff] [blame] | 57 | public class TreeViewer extends JPanel implements DeviceNodeListener
|
| 58 | {
|
| 59 |
|
| 60 | private UPnPDeviceTreeNode root;
|
| 61 | private DefaultTreeModel treeModel;
|
| 62 | private JTree tree;
|
| 63 | final TreePopup popup ;
|
| 64 | public TreeViewer(){
|
| 65 | super(new BorderLayout());
|
| 66 | Mediator.setTreeViewer(this);
|
| 67 | root = new UPnPDeviceTreeNode("UPnP Devices");
|
| 68 | treeModel= new DefaultTreeModel(root);
|
| 69 | tree = new JTree(treeModel);
|
| 70 | Mediator.setUPnPDeviceTree(tree);
|
| 71 | tree.setCellRenderer(new TreeNodeCellRenderer() );
|
| 72 | tree.putClientProperty("JTree.lineStyle", "Angled");
|
| 73 | add(new JScrollPane(tree));
|
| 74 | addTreeSelectionListener();
|
| 75 |
|
| 76 |
|
| 77 | popup = new TreePopup(tree);
|
| 78 | popup.setEnabled(false);
|
| 79 | tree.addMouseListener(new MouseAdapter(){
|
| 80 | public void mouseClicked(MouseEvent e){
|
| 81 | if (SwingUtilities.isRightMouseButton(e)){
|
| 82 | TreePath path = tree.getClosestPathForLocation(e.getX(), e.getY());
|
| 83 | tree.setSelectionPath(path);
|
| 84 | tree.scrollPathToVisible(path);
|
| 85 | popup.show(tree, e.getX(), e.getY());
|
| 86 | }
|
| 87 | }
|
| 88 | });
|
| 89 | ToolTipManager.sharedInstance().registerComponent(tree);
|
| 90 |
|
| 91 |
|
| 92 | }
|
| 93 |
|
| 94 | public void setPopupMenuEnabled(boolean driverControllerAvailable){
|
| 95 | popup.getComponent(0).setEnabled(driverControllerAvailable);
|
| 96 | }
|
Francesco Furfari | 91af5da | 2006-04-04 23:44:23 +0000 | [diff] [blame] | 97 | public void deviceDetected(DeviceNode node) {
|
| 98 | root.add(new UPnPDeviceTreeNode(node,Activator.context));
|
| 99 | treeModel.nodeStructureChanged(root);
|
| 100 | }
|
| 101 |
|
| 102 | public void rootDeviceUnplugged(String udn){
|
| 103 | Enumeration list = root.children();
|
| 104 | while (list.hasMoreElements()){
|
| 105 | UPnPDeviceTreeNode node= (UPnPDeviceTreeNode)list.nextElement();
|
| 106 | DeviceNode device = (DeviceNode)node.getUserObject();
|
| 107 | if (udn.equals(device.toString())) {
|
| 108 | node.removeFromParent();
|
| 109 | treeModel.nodeStructureChanged(root);
|
| 110 | }
|
| 111 | }
|
| 112 | }
|
| 113 |
|
| 114 | private void addTreeSelectionListener(){
|
| 115 | tree.addTreeSelectionListener(new TreeSelectionListener(){
|
| 116 | public void valueChanged(TreeSelectionEvent e){
|
| 117 | UPnPDeviceTreeNode selectedNode = (UPnPDeviceTreeNode)tree.getLastSelectedPathComponent();
|
| 118 | doNodeAction(selectedNode);
|
| 119 | }
|
| 120 | });
|
| 121 | }
|
| 122 |
|
| 123 | private void doNodeAction(UPnPDeviceTreeNode node){
|
| 124 | if (node == null) {
|
| 125 | clearPropertiesViewer();
|
| 126 | return;
|
| 127 | }
|
| 128 | if (node.category.equals(UPnPDeviceTreeNode.ACTION))
|
| 129 | Mediator.getPropertiesViewer().showActionPanel(true);
|
| 130 | else
|
| 131 | Mediator.getPropertiesViewer().showActionPanel(false);
|
| 132 |
|
| 133 | if (node.category.equals(UPnPDeviceTreeNode.SERVICE))
|
| 134 | Mediator.getPropertiesViewer().showSubscriptionPanel(true);
|
| 135 | else
|
| 136 | Mediator.getPropertiesViewer().showSubscriptionPanel(false);
|
| 137 |
|
| 138 | if ( node.category.equals(UPnPDeviceTreeNode.DEVICE)
|
| 139 | ||node.category.equals(UPnPDeviceTreeNode.ROOT_DEVICE)){
|
| 140 | DeviceNode device = (DeviceNode) node.getUserObject();
|
| 141 | UPnPDevice upnpDevice = device.getDevice(Activator.context);
|
| 142 | makeProperties(upnpDevice);
|
| 143 | }
|
| 144 | else if (node.category.equals(UPnPDeviceTreeNode.SERVICE)){
|
| 145 | UPnPService service = (UPnPService) node.getUserObject();
|
| 146 | makeProperties(service);
|
| 147 | }
|
| 148 | else if (node.category.equals(UPnPDeviceTreeNode.ACTION)){
|
| 149 | UPnPAction action = (UPnPAction) node.getUserObject();
|
| 150 | makeProperties(action);
|
| 151 | Mediator.getPropertiesViewer().setAction(action);
|
| 152 | }
|
| 153 | else if (node.category.equals(UPnPDeviceTreeNode.STATE)
|
| 154 | ||node.category.equals(UPnPDeviceTreeNode.EVENTED_STATE)
|
| 155 | ||node.category.equals(UPnPDeviceTreeNode.SUBSCRIBED_STATE)){
|
| 156 | UPnPStateVariable state = (UPnPStateVariable) node.getUserObject();
|
| 157 | makeProperties(state);
|
| 158 | }
|
| 159 |
|
| 160 | }
|
| 161 |
|
| 162 | private void clearPropertiesViewer(){
|
| 163 | String[] names = new String[]{};
|
| 164 | String[] values = new String[]{};
|
| 165 | PropertiesViewer viewer = Mediator.getPropertiesViewer();
|
| 166 | viewer.setProperties(names,values);
|
| 167 | viewer.showActionPanel(false);
|
| 168 | viewer.showSubscriptionPanel(false);
|
| 169 | }
|
| 170 |
|
| 171 | private void makeProperties(UPnPDevice upnpDevice){
|
| 172 | Dictionary dict = upnpDevice.getDescriptions(null);
|
| 173 | int size = dict.size();
|
| 174 | String[] names = new String[size];
|
| 175 | String[] values = new String[size];
|
| 176 | Enumeration keys = dict.keys();
|
| 177 | for (int i=0;i<size;i++){
|
| 178 | names[i]= (String) keys.nextElement();
|
| 179 | values[i]= Util.justString(dict.get(names[i]));
|
| 180 | }
|
| 181 | Mediator.getPropertiesViewer().setProperties(names,values);
|
| 182 | }
|
| 183 |
|
| 184 | private void makeProperties(UPnPService service){
|
| 185 | String[] names = new String[]{"Id","Type","Version"};
|
| 186 | String[] values = new String[]{service.getId(),service.getType(),service.getType()};
|
| 187 | Mediator.getPropertiesViewer().setProperties(names,values);
|
| 188 | }
|
| 189 |
|
| 190 | private void makeProperties(UPnPAction action){
|
| 191 | ArrayList names = new ArrayList();
|
| 192 | ArrayList values = new ArrayList();
|
| 193 | names.add("Name");
|
| 194 | values.add(action.getName());
|
| 195 |
|
| 196 | String returnName = action.getReturnArgumentName();
|
| 197 | if (returnName != null){
|
| 198 | names.add("Return value name");
|
| 199 | values.add(returnName);
|
| 200 | }
|
| 201 | String[] inArg = action.getInputArgumentNames();
|
| 202 | if (inArg != null){
|
| 203 | for (int i = 0; i<inArg.length;i++){
|
| 204 | names.add("Input arg["+ (i+1)+"]");
|
| 205 | values.add(inArg[i]);
|
| 206 | }
|
| 207 | }
|
| 208 | String[] outArg = action.getOutputArgumentNames();
|
| 209 | if (outArg != null){
|
| 210 | for (int i = 0; i<outArg.length;i++){
|
| 211 | names.add("Output arg["+ (i+1)+"]");
|
| 212 | values.add(outArg[i]);
|
| 213 | }
|
| 214 | }
|
| 215 |
|
| 216 | Mediator.getPropertiesViewer().setProperties(
|
| 217 | (String[])names.toArray(new String[]{}),
|
| 218 | (String[])values.toArray(new String[]{})
|
| 219 | );
|
| 220 |
|
| 221 | }
|
| 222 |
|
| 223 | private void makeProperties(UPnPStateVariable state){
|
| 224 | ArrayList names = new ArrayList();
|
| 225 | ArrayList values = new ArrayList();
|
| 226 | names.add("Name");
|
| 227 | values.add(state.getName());
|
| 228 | names.add("Evented");
|
| 229 | values.add(state.sendsEvents()? "yes":"no");
|
| 230 | names.add("Default Value");
|
| 231 | values.add(Util.justString(state.getDefaultValue()));
|
| 232 | names.add("Java Data Type");
|
| 233 | values.add(state.getJavaDataType().getName());
|
| 234 | names.add("Java UPnP Type");
|
| 235 | values.add(state.getUPnPDataType());
|
| 236 | names.add("Minimum");
|
| 237 | values.add(Util.justString(state.getMinimum()));
|
| 238 | names.add("Maximum");
|
| 239 | values.add(Util.justString(state.getMaximum()));
|
| 240 | names.add("Step");
|
| 241 | values.add(Util.justString(state.getStep()));
|
| 242 | String[] allowed = state.getAllowedValues();
|
| 243 | if (allowed!=null){
|
| 244 | for (int i=0;i<allowed.length;i++){
|
| 245 | names.add("Allowed value["+i+1+"]");
|
| 246 | values.add(allowed[i]);
|
| 247 | }
|
| 248 | }
|
| 249 | Mediator.getPropertiesViewer().setProperties(
|
| 250 | (String[])names.toArray(new String[]{}),
|
| 251 | (String[])values.toArray(new String[]{})
|
| 252 | );
|
| 253 | }
|
| 254 |
|
| 255 |
|
| 256 | }
|
| 257 |
|
| 258 | class TreePopup extends JPopupMenu implements PopupMenuListener {
|
| 259 | JTree tree;
|
| 260 | JMenuItem item;
|
| 261 |
|
| 262 | public TreePopup(final JTree tree){
|
| 263 | super();
|
| 264 | this.tree = tree;
|
| 265 | (item = add(new AbstractAction(){
|
| 266 | public void actionPerformed(ActionEvent e){
|
| 267 | UPnPDeviceTreeNode selectedNode = (UPnPDeviceTreeNode)tree.getLastSelectedPathComponent();
|
| 268 | String url = "";
|
| 269 | if (selectedNode.category.equals(UPnPDeviceTreeNode.DEVICE)){
|
| 270 | UPnPDeviceTreeNode parent = (UPnPDeviceTreeNode)selectedNode.getParent();
|
| 271 | while (parent.category!=UPnPDeviceTreeNode.ROOT_DEVICE)
|
| 272 | parent = (UPnPDeviceTreeNode)parent.getParent();
|
| 273 | DeviceNode device = (DeviceNode) parent.getUserObject();
|
| 274 | String udn = (String)device.getReference().getProperty(UPnPDevice.UDN);
|
| 275 | url = Mediator.getDriverProxy().getDeviceDescriptionURI(udn);
|
| 276 | }
|
| 277 |
|
| 278 | else if (selectedNode.category.equals(UPnPDeviceTreeNode.ROOT_DEVICE))
|
| 279 | {
|
| 280 | DeviceNode node = (DeviceNode) selectedNode.getUserObject();
|
| 281 | String udn = (String)node.getReference().getProperty(UPnPDevice.UDN);
|
| 282 | url = Mediator.getDriverProxy().getDeviceDescriptionURI(udn);
|
| 283 | }
|
| 284 | else if (selectedNode.category.equals(UPnPDeviceTreeNode.SERVICE))
|
| 285 | {
|
| 286 | UPnPDeviceTreeNode parent = (UPnPDeviceTreeNode)selectedNode.getParent();
|
| 287 | while (parent.category!=UPnPDeviceTreeNode.ROOT_DEVICE)
|
| 288 | parent = (UPnPDeviceTreeNode)parent.getParent();
|
| 289 | DeviceNode device = (DeviceNode) parent.getUserObject();
|
| 290 | String udn = (String)device.getReference().getProperty(UPnPDevice.UDN);
|
| 291 | UPnPService service = (UPnPService) selectedNode.getUserObject();
|
| 292 | url = Mediator.getDriverProxy().getServiceDescriptionURI(udn,service.getId());
|
| 293 | }
|
| 294 | Util.openUrl(url);
|
| 295 | }
|
| 296 | })).setText("Show Description");
|
| 297 | addPopupMenuListener(this);
|
| 298 |
|
| 299 | }
|
| 300 |
|
| 301 | public void popupMenuCanceled(PopupMenuEvent e){}
|
| 302 | public void popupMenuWillBecomeInvisible(PopupMenuEvent e){}
|
| 303 | public void popupMenuWillBecomeVisible(PopupMenuEvent e){
|
| 304 | if (Mediator.getDriverProxy().isDriverAvailable()){
|
| 305 | UPnPDeviceTreeNode selectedNode = (UPnPDeviceTreeNode)tree.getLastSelectedPathComponent();
|
| 306 | if (selectedNode.category.equals(UPnPDeviceTreeNode.DEVICE)
|
| 307 | ||selectedNode.category.equals(UPnPDeviceTreeNode.ROOT_DEVICE)
|
| 308 | ||selectedNode.category.equals(UPnPDeviceTreeNode.SERVICE))
|
| 309 | {
|
| 310 | item.setEnabled(true);
|
| 311 | }
|
| 312 | else
|
| 313 | item.setEnabled(false);
|
| 314 | }
|
| 315 | else
|
| 316 | item.setEnabled(false);
|
| 317 |
|
| 318 | }
|
| 319 | }
|