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