You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by fu...@apache.org on 2006/04/05 01:44:26 UTC

svn commit: r391455 [1/2] - in /incubator/felix/trunk/org.apache.felix.upnp.tester: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/felix/ src/main/java/org/apache/felix/upnp/ src/main/java/org/apa...

Author: furfari
Date: Tue Apr  4 16:44:23 2006
New Revision: 391455

URL: http://svn.apache.org/viewcvs?rev=391455&view=rev
Log:
Committed the initial version of the UPnP Tester bundle (FELIX-52).
It requires org.osgi.core, org.osgi.compendium and org.apache.felix.upnp.extra.
The tester acts as Generic Control Point useful to monitor the registered UPnPDevice services.


Added:
    incubator/felix/trunk/org.apache.felix.upnp.tester/
    incubator/felix/trunk/org.apache.felix.upnp.tester/pom.xml
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Activator.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/ControlPoint.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Mediator.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/UPnPSubscriber.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceChangeListener.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNode.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNodeListener.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DevicesList.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DriverProxy.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/RootDeviceListener.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/ActionPanel.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/LogPanel.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/PropertiesViewer.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/SubscriptionPanel.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/TreeViewer.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/UPnPDeviceTreeNode.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/Util.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/test.java
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/META-INF/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/META-INF/Manifest.mf
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/AnimatedStateVariable.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/DeviceNode.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/EventedStateVariable.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/RootDeviceNode.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/SubscribedStateVariable.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/UPnPAction.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/UPnPService.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/UPnPStateVariable.gif   (with props)
    incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/resources/org/apache/felix/upnp/tester/gui/IMAGES/logo.gif   (with props)

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/pom.xml
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/pom.xml?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/pom.xml (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/pom.xml Tue Apr  4 16:44:23 2006
@@ -0,0 +1,66 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <parent>
+    <groupId>org.apache.felix</groupId>
+    <artifactId>felix</artifactId>
+    <version>0.8.0-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+  <packaging>osgi-bundle</packaging>
+  <groupId>org.apache.felix</groupId>
+  <name>Apache Felix UPnP Tester</name>
+  <artifactId>org.apache.felix.upnp.tester</artifactId>
+  <version>0.1.0-SNAPSHOT</version>
+  <!-- <url>http://maven.apache.org</url> -->
+  <dependencies>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.core</artifactId>
+      <version>4.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.osgi</groupId>
+      <artifactId>org.osgi.compendium</artifactId>
+      <version>4.0</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.felix</groupId>
+      <artifactId>org.apache.felix.upnp.extra</artifactId>
+      <version>1.0-SNAPSHOT</version>
+      <scope>provided</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.felix.plugins</groupId>
+        <artifactId>maven-osgi-plugin</artifactId>
+        <!-- <version>${pom.version}</version> -->
+        <extensions>true</extensions>
+        <configuration>
+          <osgiManifest>
+            <bundleName>UPnPTester</bundleName>
+            <bundleVendor>Apache Software Foundation</bundleVendor>
+            <bundleVersion>0.1.0</bundleVersion>
+            <bundleDescription>
+               	OSGi Generic Control Point to control UPnPDevice services
+            </bundleDescription>
+            <bundleSymbolicName>org.apache.felix.upnp.tester</bundleSymbolicName>
+		<bundleActivator>org.apache.felix.upnp.tester.Activator</bundleActivator>
+            <importPackage>
+			org.osgi.framework;specification-version=1.3,org.osgi.service.upnp;specification-version=1.1,org.apache.felix.upnp.extra.util;specification-version=1.0,org.apache.felix.upnp.extra.controller;specification-version=1.0
+            </importPackage>
+          </osgiManifest>
+          <manifestFile>src/main/resources/META-INF/Manifest.mf</manifestFile>
+        </configuration>
+      </plugin>
+    </plugins>
+    <resources>
+      <resource>
+	  <directory>src/main/resources</directory>
+      </resource>
+    </resources>
+  </build>
+</project>

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Activator.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Activator.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Activator.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Activator.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,50 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester;
+
+
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * @author Stefano "Kismet" Lenzi
+ * @author Francesco Furfari 
+ * 
+ */
+public class Activator implements BundleActivator {
+
+	public static BundleContext context;
+    
+	private ControlPoint cp;
+	
+	/**
+	 * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		Activator.context = context;
+        cp = new ControlPoint();
+	}
+
+	/**
+	 * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		cp.close();
+		Activator.context=null;
+	}
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/ControlPoint.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/ControlPoint.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/ControlPoint.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/ControlPoint.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,376 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester;
+
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyEvent;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import java.net.URL;
+
+import javax.swing.AbstractAction;
+import javax.swing.ButtonGroup;
+import javax.swing.ImageIcon;
+import javax.swing.JFrame;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JPanel;
+import javax.swing.JPopupMenu;
+import javax.swing.JRadioButtonMenuItem;
+import javax.swing.JSplitPane;
+import javax.swing.event.PopupMenuEvent;
+import javax.swing.event.PopupMenuListener;
+
+import org.apache.felix.upnp.tester.discovery.DriverProxy;
+import org.apache.felix.upnp.tester.discovery.RootDeviceListener;
+import org.apache.felix.upnp.tester.gui.LogPanel;
+import org.apache.felix.upnp.tester.gui.PropertiesViewer;
+import org.apache.felix.upnp.tester.gui.TreeViewer;
+import org.apache.felix.upnp.tester.gui.Util;
+import org.osgi.framework.BundleException;
+ 
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ *  
+ */
+public class ControlPoint implements PopupMenuListener {
+	RootDeviceListener x;
+	RootDeviceListener listener;
+	TreeViewer viewer;
+	PropertiesViewer properties;
+	JFrame frame;
+	
+	
+	public ControlPoint() {
+		frame = new JFrame("OSGi UPnP Device Tester");
+       try {
+            URL eventIconUrl = Util.class.getResource("IMAGES/logo.gif");           
+            ImageIcon icon=  new ImageIcon(eventIconUrl,"logo");
+            frame.setIconImage(icon.getImage());
+       }
+        catch (Exception ex){
+                System.out.println("Resource: IMAGES/logo.gif not found : " + ex.toString());
+        }
+		//frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+        
+		frame.addWindowListener(new WindowAdapter(){
+			public void windowClosing(WindowEvent e){
+				try {
+					Activator.context.getBundle().stop();
+				} catch (BundleException ex) {
+					ex.printStackTrace();
+				}
+			}
+
+		});       
+		frame.setBounds(0,0,300,200);
+        
+        
+        doMenuBar(frame);
+		doControlPanel();
+        Mediator.setControlPoint(this);
+        Mediator.setMainFrame(frame);
+        Mediator.setRootDeviceListener(listener);
+		listener = new RootDeviceListener();
+        Mediator.setRootDeviceListener(listener);
+		listener.setDeviceNodeListener(viewer);
+		
+		frame.pack();
+		frame.setVisible(true);
+        
+		DriverProxy driverProxy = new DriverProxy();
+        Mediator.setDriverProxy(driverProxy);
+        
+		listener.activate();
+	}
+	
+	public void close(){
+		listener.deactive();
+		frame.dispose();
+        Mediator.getDriverProxy().close();           
+	}
+	
+	private void doControlPanel(){
+		JPanel panel = new JPanel(new BorderLayout());
+		viewer = new TreeViewer();
+		viewer.setPreferredSize(new Dimension(180,450));
+		properties = new PropertiesViewer();
+		Mediator.setPropertiesViewer(properties);
+	
+		JSplitPane treeSplitter = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,viewer,properties);
+		JPanel logPanel = new LogPanel();
+		logPanel.setPreferredSize(new Dimension(180,100));
+		JSplitPane logSplitter = new JSplitPane(JSplitPane.VERTICAL_SPLIT,treeSplitter,logPanel);
+		panel.add(logSplitter);
+		frame.getContentPane().add(panel);
+		
+		
+	}
+	
+      /////////////////////////// MENU /////////////////////////////
+    JMenu searchMenu,loggerMenu,cyberMenu;  
+    public void doMenuBar(JFrame frame) {
+
+        JMenuBar menuBar = new JMenuBar();
+        
+        //////////////// FILE
+        JMenu file_menu = new JMenu("File");
+        file_menu.setMnemonic(KeyEvent.VK_F);
+
+        searchMenu = new JMenu("Search");
+        final String ALL_DEVICE = "ssdp:all";
+        final String ROOT_DEVICE = "upnp:rootdevice";
+        searchMenu.setMnemonic(KeyEvent.VK_L);
+        searchMenu.setEnabled(false);
+        AbstractAction searchAction = new AbstractAction(){
+            public void actionPerformed(ActionEvent e) {
+                DriverProxy controller = Mediator.getDriverProxy();
+                if (e.getActionCommand().equals(ALL_DEVICE))
+                    controller.doSearch(ALL_DEVICE);
+                else if (e.getActionCommand().equals(ROOT_DEVICE))
+                    controller.doSearch(ROOT_DEVICE);
+            }
+        };
+        
+        JMenuItem rootDeviceItem = new JMenuItem("Root Devices");
+        rootDeviceItem.setMnemonic(KeyEvent.VK_R);
+        rootDeviceItem.addActionListener(searchAction);
+        rootDeviceItem.setActionCommand(ROOT_DEVICE);
+        searchMenu.add(rootDeviceItem);
+        
+        JMenuItem allDeviceItem = new JMenuItem("All Devices");
+        allDeviceItem .setMnemonic(KeyEvent.VK_A);
+        allDeviceItem .addActionListener(searchAction);
+        allDeviceItem .setActionCommand(ALL_DEVICE);
+        searchMenu.add(allDeviceItem);
+        
+        
+        JMenuItem checkIncompleteItem = new JMenuItem("Print Pending Devices");
+        checkIncompleteItem.setMnemonic(KeyEvent.VK_I);
+        checkIncompleteItem.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    Mediator.getRootDeviceListener().checkIncompleteDevice();
+                }
+            });
+        
+        JMenuItem checkErrataItem = new JMenuItem("Check Errata UPnPDevices");
+        checkErrataItem.setMnemonic(KeyEvent.VK_E);
+        checkErrataItem.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {                    
+                    RootDeviceListener.checkErrataDevice();}
+            });
+        
+        
+        loggerMenu = new JMenu("Domoware Logger");
+        final String NO_LOGGING ="No Logging";
+        final String ERROR ="Error";
+        final String WARNING ="Warning";
+        final String INFO ="Info";
+        final String DEBUG ="Debug";
+
+        loggerMenu.getPopupMenu().addPopupMenuListener(this);
+        loggerMenu.setMnemonic(KeyEvent.VK_L);
+        loggerMenu.setEnabled(false);
+        AbstractAction loggerAction = new AbstractAction(){
+            public void actionPerformed(ActionEvent e) {
+                DriverProxy controller = Mediator.getDriverProxy();
+                if (e.getActionCommand().equals(NO_LOGGING))
+                    controller.setLogLevel(0);
+                else if (e.getActionCommand().equals(ERROR))
+                    controller.setLogLevel(1);
+                else if (e.getActionCommand().equals(WARNING))
+                    controller.setLogLevel(2);
+                else if (e.getActionCommand().equals(INFO))
+                    controller.setLogLevel(3);
+                else if (e.getActionCommand().equals(DEBUG))
+                    controller.setLogLevel(4);
+            }
+        };
+       
+        ButtonGroup group = new ButtonGroup();
+        
+        JRadioButtonMenuItem rbMenuItem = new JRadioButtonMenuItem(NO_LOGGING);
+        rbMenuItem.setSelected(true);
+        rbMenuItem.setMnemonic(KeyEvent.VK_N);
+        rbMenuItem.setActionCommand(NO_LOGGING);
+        rbMenuItem.addActionListener(loggerAction);
+        group.add(rbMenuItem);
+        loggerMenu.add(rbMenuItem);
+        loggerMenu.addSeparator();
+        
+        rbMenuItem = new JRadioButtonMenuItem(ERROR);
+        rbMenuItem.setMnemonic(KeyEvent.VK_E);
+        rbMenuItem.setActionCommand(ERROR);
+        rbMenuItem.addActionListener(loggerAction);
+        group.add(rbMenuItem);
+        loggerMenu.add(rbMenuItem);
+
+        rbMenuItem = new JRadioButtonMenuItem(WARNING);
+        rbMenuItem.setMnemonic(KeyEvent.VK_W);
+        rbMenuItem.setActionCommand(WARNING);
+        rbMenuItem.addActionListener(loggerAction);
+        group.add(rbMenuItem);
+        loggerMenu.add(rbMenuItem);
+        
+        rbMenuItem = new JRadioButtonMenuItem(INFO);
+        rbMenuItem.setMnemonic(KeyEvent.VK_I);
+        rbMenuItem.setActionCommand(INFO);
+        rbMenuItem.addActionListener(loggerAction);
+        group.add(rbMenuItem);
+        loggerMenu.add(rbMenuItem);
+        
+        rbMenuItem = new JRadioButtonMenuItem(DEBUG);
+        rbMenuItem.setMnemonic(KeyEvent.VK_D);
+        rbMenuItem.setActionCommand(DEBUG);
+        rbMenuItem.addActionListener(loggerAction);
+        group.add(rbMenuItem);
+        loggerMenu.add(rbMenuItem);
+
+        final String ON ="On";
+        final String OFF ="Off";
+        cyberMenu = new JMenu("Cyber Debugger");
+        cyberMenu.getPopupMenu().addPopupMenuListener(this);
+        cyberMenu.setMnemonic(KeyEvent.VK_C);
+        cyberMenu.setEnabled(false);
+        AbstractAction cyberAction = new AbstractAction(){
+            public void actionPerformed(ActionEvent e) {
+                DriverProxy controller = Mediator.getDriverProxy();
+                if (e.getActionCommand().equals(ON))
+                    controller.setCyberDebug(true);
+                else if (e.getActionCommand().equals(OFF))
+                    controller.setCyberDebug(false);
+            }
+        };
+
+       
+        ButtonGroup cyberGroup = new ButtonGroup();
+        rbMenuItem = new JRadioButtonMenuItem(ON);
+        rbMenuItem.setSelected(true);
+        rbMenuItem.setMnemonic(KeyEvent.VK_O);
+        rbMenuItem.setActionCommand(ON);
+        rbMenuItem.addActionListener(cyberAction);
+        cyberGroup.add(rbMenuItem);
+        cyberMenu.add(rbMenuItem);
+
+        rbMenuItem = new JRadioButtonMenuItem(OFF);
+        rbMenuItem.setMnemonic(KeyEvent.VK_F);
+        rbMenuItem.setActionCommand(OFF);
+        rbMenuItem.addActionListener(cyberAction);
+        cyberGroup.add(rbMenuItem);
+        cyberMenu.add(rbMenuItem);
+        
+        /*
+        JMenuItem clearSubscriptionItem = new JMenuItem("Clear Subscriptions");
+        clearSubscriptionItem.setMnemonic(KeyEvent.VK_S);
+        clearSubscriptionItem.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+// to do
+                    }
+            });
+        */
+        
+        JMenuItem exitItem = new JMenuItem("Exit");
+        exitItem.setMnemonic(KeyEvent.VK_X);
+        exitItem.addActionListener(new ActionListener() {
+                public void actionPerformed(ActionEvent e) {
+                    try {
+                        Activator.context.getBundle().stop();
+                    }catch (Exception ex){
+                        ex.printStackTrace();
+                    }
+                }
+            });
+        
+
+        file_menu.add(searchMenu);
+        file_menu.addSeparator();
+        file_menu.add(loggerMenu);
+        file_menu.add(cyberMenu);
+        file_menu.addSeparator();
+        file_menu.add(checkIncompleteItem);
+        file_menu.add(checkErrataItem);
+        //file_menu.addSeparator();
+        //file_menu.add(clearSubscriptionItem);
+        file_menu.addSeparator();
+        file_menu.add(exitItem);
+
+        menuBar.add(file_menu);                   
+        frame.setJMenuBar(menuBar);
+
+    }
+
+ 
+    public void enableMenus(boolean driverAvailable,int logLevel,boolean cyberDebug) {
+        searchMenu.setEnabled(driverAvailable);
+        Component[] items = searchMenu.getPopupMenu().getComponents();
+        for (int i=0;i < items.length;i++)
+            items[i].setEnabled(driverAvailable);
+
+        loggerMenu.setEnabled(driverAvailable);
+        items = loggerMenu.getPopupMenu().getComponents();
+        for (int i=0;i < items.length;i++)
+            items[i].setEnabled(driverAvailable);
+        if (driverAvailable){
+                ((JRadioButtonMenuItem)items[logLevel>0?logLevel+1:0]).setSelected(true);
+        }
+        cyberMenu.setEnabled(driverAvailable);           
+        items = cyberMenu.getPopupMenu().getComponents();
+        for (int i=0;i < items.length;i++)
+            items[i].setEnabled(driverAvailable);
+        if (driverAvailable){
+            if (cyberDebug)
+                ((JRadioButtonMenuItem)items[0]).setSelected(true);
+            else
+                ((JRadioButtonMenuItem)items[1]).setSelected(true);
+        }
+   }
+
+    public void popupMenuCanceled(PopupMenuEvent e) { }
+    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { }
+
+    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+        JPopupMenu loggerPopup = loggerMenu.getPopupMenu();
+        JPopupMenu cyberPopup = cyberMenu.getPopupMenu();
+        if (e.getSource()==loggerPopup){
+            int logLevel = Mediator.getDriverProxy().getLogLevel();
+            Component[] items = loggerPopup.getComponents();
+            ((JRadioButtonMenuItem)items[logLevel>0?logLevel+1:0]).setSelected(true);          
+        }
+        else if (e.getSource()==cyberPopup){
+            boolean cyberDebug = Mediator.getDriverProxy().getCyberDebug();
+            Component[] items = cyberPopup.getComponents();
+            if (cyberDebug)
+                ((JRadioButtonMenuItem)items[0]).setSelected(true);
+            else
+                ((JRadioButtonMenuItem)items[1]).setSelected(true);            
+        }
+       
+        
+    }
+
+
+
+	
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Mediator.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Mediator.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Mediator.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/Mediator.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,90 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester;
+
+
+import javax.swing.*;
+
+import org.apache.felix.upnp.tester.discovery.*;
+import org.apache.felix.upnp.tester.gui.*;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ *  
+ */
+public  class Mediator {
+	static PropertiesViewer props;
+	static JTree tree;
+    static JFrame frame; 
+    static DriverProxy driverProxy;
+    static RootDeviceListener rootDeviceListener; 
+    static ControlPoint controlPoint; 
+    static TreeViewer treeViewer; 
+	
+
+	public static void setPropertiesViewer(PropertiesViewer props){
+		Mediator.props=props;
+	}
+	public static PropertiesViewer getPropertiesViewer(){
+		return props;
+	}
+	
+    public static void setUPnPDeviceTree(JTree tree){
+        Mediator.tree=tree;
+    }
+    public static JTree getUPnPDeviceTree(){
+        return tree;
+    }
+    
+    public static void setTreeViewer(TreeViewer treeViewer){
+        Mediator.treeViewer=treeViewer;
+    }
+    public static TreeViewer getTreeViewer(){
+        return treeViewer;
+    }
+	
+    public static void setMainFrame(JFrame frame){
+        Mediator.frame=frame;
+    }
+    public static JFrame getMainFrame(){
+        return frame;
+    }
+    public static void setControlPoint(ControlPoint controlPoint){
+        Mediator.controlPoint=controlPoint;
+    }
+    public static ControlPoint getControlPoint(){
+        return controlPoint;
+    }
+    
+    public static void setDriverProxy(DriverProxy driverProxy) {
+        Mediator.driverProxy = driverProxy;        
+    }
+    
+    public static DriverProxy getDriverProxy(){
+        return driverProxy;
+    }
+    
+    public static void setRootDeviceListener(RootDeviceListener listener) {
+        Mediator.rootDeviceListener = listener;        
+    }
+    
+    public static RootDeviceListener getRootDeviceListener(){
+        return rootDeviceListener;
+    }
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/UPnPSubscriber.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/UPnPSubscriber.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/UPnPSubscriber.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/UPnPSubscriber.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,84 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+ 
+package org.apache.felix.upnp.tester;
+
+import java.util.*;
+
+import org.osgi.framework.*;
+import org.osgi.service.upnp.*;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ * 
+ */
+public class UPnPSubscriber {
+	private BundleContext context;
+	private UPnPEventListener listener;
+	private HashMap hash;
+	
+	private class Subscription implements UPnPEventListener{
+	    ServiceRegistration registration;
+	    
+	    Subscription(String keys){
+	 		try {
+				Filter filter = context.createFilter(keys);
+				Properties props = new Properties();
+				props.put(UPnPEventListener.UPNP_FILTER, filter);
+				registration = context.registerService(UPnPEventListener.class.getName(), this, props);
+			}catch (Exception ex){
+				System.out.println(ex);
+			}
+	    }
+	    
+	    public void unsubscribe(){
+			registration.unregister();
+	    }
+	    
+        public void notifyUPnPEvent(String arg0, String arg1, Dictionary arg2) {
+            listener.notifyUPnPEvent( arg0,  arg1,  arg2);
+        }
+	}
+	
+	
+	public UPnPSubscriber(BundleContext context,UPnPEventListener listener){
+		this.context = context;
+		this.listener = listener;
+		hash = new HashMap();
+	}
+	
+	public void subscribe(String deviceId, String serviceId){
+		String keys = "(&(" + UPnPDevice.ID + "="+ deviceId + ")(" + UPnPService.ID + "=" + serviceId + "))";
+		if (hash.get(keys) == null){
+		    hash.put(keys, new Subscription(keys));
+		}
+	}
+	
+	public void unsubscribe(String deviceId, String serviceId){
+		String keys = "(&(" + UPnPDevice.ID + "="+ deviceId + ")(" + UPnPService.ID + "=" + serviceId + "))";
+		if (hash.containsKey(keys)) {
+		    Subscription subscription = (Subscription) hash.get(keys);
+		    subscription.unsubscribe();
+			hash.remove(keys);
+		}
+	}
+
+
+ 	
+
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceChangeListener.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceChangeListener.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceChangeListener.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceChangeListener.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,31 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.discovery;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ *  
+ */
+public interface DeviceChangeListener {
+	
+	public void addedDevice(DeviceNode dn);
+	
+	public void removedDevice(DeviceNode dn);
+	
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNode.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNode.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNode.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNode.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,211 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.discovery;
+import java.util.*;
+
+import org.osgi.framework.*;
+import org.osgi.service.upnp.*;
+
+/**
+ * @author Stefano "Kismet" Lenzi
+ * @author Francesco Furfari 
+ *  
+ */
+public class DeviceNode {
+	
+	private ServiceReference sr;
+	private boolean isRootNode;
+	private String udn ;
+	private boolean hasChild;
+	private int numberOfSons;
+	private ArrayList children;
+	private DeviceNode parent;
+	
+	public DeviceNode(ServiceReference sr){
+		//PRE: argument is always UPnPDevice service reference
+		if (sr == null) 
+			throw new IllegalArgumentException("null is not a valid arg in DeviceNode constructor");
+		this.sr = sr;
+		udn = (String) sr.getProperty(UPnPDevice.UDN);
+		parent=null;
+		isRootNode = (sr.getProperty(UPnPDevice.PARENT_UDN) == null);
+		String[] sons = ((String[]) sr.getProperty(UPnPDevice.CHILDREN_UDN));
+		hasChild = (sons != null);
+		if (hasChild) {
+			children = new ArrayList();
+			numberOfSons = sons.length;
+		}
+		/*
+		//Operation to let DeviceNode::isComplete() O(1)
+		isComplete = !hasChild;
+		*/					
+	}
+	
+	public ServiceReference getReference(){
+		return sr;
+	}
+	public UPnPDevice getDevice(BundleContext ctx){
+		return (UPnPDevice)ctx.getService(sr);
+	}
+	
+	public void attach(DeviceNode node){
+		if (node == null) 
+			throw new IllegalArgumentException("null is not a valid arg in DeviceNode.attach() method");
+		node.parent = this;
+		/*
+		//Operation to let DeviceNode::isComplete() O(1)
+		if((numberOfSons==children.size()-1)
+				&&(node.isComplete())){
+			this.isComplete = true;
+		}
+		*/
+		children.add(node);
+	}
+	
+	public DeviceNode dethatch(String name){
+		DeviceNode dn = this.search(name);
+		if(dn==null) 
+			return null;
+		
+		if(dn.parent!=null){
+			Iterator list = dn.parent.children.iterator();
+			while (list.hasNext()) {
+				DeviceNode x = (DeviceNode) list.next();
+				if(x.udn.equals(name)){
+					list.remove();
+					/*
+					//Operation to let DeviceNode::isComplete() O(1)
+					dn.parent.isComplete=false;
+					*/					
+					break;
+				}
+			}
+		}
+		dn.parent=null;
+		return dn;
+	}
+	
+	public Collection getAllChildren(){
+		if((this.children==null)||(this.children.size()==0)) 
+			return new ArrayList();
+		
+		Vector v = new Vector(this.children);
+		Iterator list = this.children.iterator();
+		while (list.hasNext()) {
+			DeviceNode x = (DeviceNode) list.next();
+			Collection c = x.getAllChildren();
+			if(c==null) continue;
+			v.addAll(c);
+		}
+		return v;
+	}
+
+	public Collection getChildren(){
+		if((this.children==null)||(this.children.size()==0)) 
+			return new ArrayList();
+		return this.children;
+	}	
+	
+	/**
+	 * @param name <code>String</code> that contain the UDN to look for
+	 * @return return a <code>DeviceNode</code> that have the UDN equals to name and <br>
+	 * 		if there is any <code>DeviceNode</code> with the proper UDN value return <code>null</code>
+	 */
+	public DeviceNode search(String name){
+		if (name == null) 
+			throw new IllegalArgumentException("null is not a valid arg in DeviceNode.search() method");
+		if (name.equals(udn))
+			return this;
+		else if (hasChild){
+			Iterator list = children.iterator();
+			while (list.hasNext()){
+				DeviceNode child = (DeviceNode)list.next();
+				DeviceNode node = child.search(name);
+				if (node != null) return node;				
+			}
+		}
+		return null;
+	}
+	
+	/**
+	 * 
+	 * @param udn
+	 * @return <code>true</code> if and only if this <code>DeviceNode</code>
+	 * 		contains a DeviceNode with UDN equals to passed argument or if
+	 * 		its USN is equal to passed argument
+	 */
+	public boolean contains(String udn){
+		return this.search(udn)!=null;
+	}
+	
+	public boolean isComplete(){	
+		/*
+		//Operation to let DeviceNode::isComplete() O(1)
+		return isComplete;
+		*/		
+		if (! hasChild) return true;
+		if (numberOfSons != children.size())return false;
+		Iterator list = children.iterator();
+		while (list.hasNext()){
+			DeviceNode child = (DeviceNode)list.next();
+			if (! child.isComplete()) return false;
+		}
+		return true;
+	}
+	
+	public DeviceNode isAttachable(DeviceNode node){
+		if (node == null) 
+			throw new IllegalArgumentException("null is not a valid arg in DeviceNode.isAttachable() method");
+		String parentUDN=(String) node.getReference().getProperty(UPnPDevice.PARENT_UDN);
+		if(parentUDN==null) return null;
+		return search(parentUDN);		
+	}
+		
+	public boolean isRoot(){
+		return isRootNode;		
+	}
+	
+	public boolean equals(String udn){
+		return this.udn.equals(udn);
+	}
+	
+	public String toString(){
+		return udn;
+	}		
+	public boolean isLeaf() {
+		return !hasChild;
+	}
+    
+    public void print(){
+        System.out.println("####Device Node");
+        String[] props = sr.getPropertyKeys();
+        for (int i=0;i< props.length;i++){
+            Object prop= sr.getProperty(props[i]);
+            if (prop instanceof String[]){
+                System.out.println(props[i]+ "=");
+                String[] multiple = (String[])prop;
+                for (int j=0;j< multiple.length;j++){
+                    System.out.println(multiple[j]+ ";"); 
+                }
+
+            }
+            else System.out.println(props[i]+ "="+ prop);
+        }
+        System.out.println("####Device Node");
+   }
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNodeListener.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNodeListener.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNodeListener.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DeviceNodeListener.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,28 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.discovery;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ *  
+ */
+public interface DeviceNodeListener {
+	public void deviceDetected(DeviceNode d);
+	public void rootDeviceUnplugged(String udn);
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DevicesList.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DevicesList.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DevicesList.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DevicesList.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,62 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.discovery;
+
+import java.util.*;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ *  
+ */
+public class DevicesList {
+	
+	ArrayList devices;	
+	DeviceChangeListener listener = null;
+	
+	public DevicesList(){
+		devices = new ArrayList();
+	}
+	
+	
+	public boolean add(DeviceNode dev) {
+		if(listener!=null) 
+			listener.addedDevice(dev);
+		return devices.add(dev);
+	}
+
+	public Iterator iterator() {
+		return devices.iterator();
+	}
+
+	public boolean remove(DeviceNode dev) {
+		if(listener!=null)
+			listener.removedDevice(dev);
+		return devices.remove(dev);
+	}
+
+	public DeviceChangeListener getChangeListener() {
+		return listener;
+	}
+
+	public void setChangeListener(DeviceChangeListener listener) {
+		this.listener = listener;
+	}
+	
+	
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DriverProxy.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DriverProxy.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DriverProxy.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/DriverProxy.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,118 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.discovery;
+
+import org.apache.felix.upnp.extra.controller.*;
+import org.apache.felix.upnp.tester.*;
+
+import org.osgi.framework.*;
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ *  
+ */
+public class DriverProxy implements ServiceListener {
+    private DevicesInfo devicesInfo;
+    private DriverController drvController;
+    public DriverProxy(){
+        ServiceReference sr = Activator.context.getServiceReference(DevicesInfo.class.getName());
+        if (sr != null){
+            devicesInfo = (DevicesInfo)Activator.context.getService(sr);
+            drvController = (DriverController) devicesInfo;
+            Mediator.getControlPoint().enableMenus(true,getLogLevel(),getCyberDebug());
+            Mediator.getTreeViewer().setPopupMenuEnabled(true);
+        }
+        String filter =  "(" + Constants.OBJECTCLASS + "=" + DevicesInfo.class.getName() + ")" ;
+        try {
+            Activator.context.addServiceListener(this,filter);  
+        } catch (Exception ignored){};
+     }
+    
+    public boolean isDriverAvailable(){
+        return (drvController != null);
+    }
+    
+    public String getDeviceDescriptionURI(String udn){
+        if (devicesInfo != null)
+            return devicesInfo.getLocationURL(udn);
+        return "";
+    }
+    
+    public String getServiceDescriptionURI(String udn,String serviceId){
+        if (devicesInfo != null)
+            return devicesInfo.getSCPDURL(udn,serviceId);
+        return null;
+    }
+    
+    public String resolveRelativeUrl(String udn,String link){
+        if (devicesInfo != null)
+            return devicesInfo.resolveRelativeUrl(udn,link);
+        return null;
+    }
+    
+    public boolean getCyberDebug(){
+        if (drvController != null)
+            return drvController.getCyberDebug();
+        return false;
+    }
+    public void setCyberDebug(boolean b){
+        if (drvController != null)
+            drvController.setCyberDebug(b);
+    }
+    public int getLogLevel(){
+        if (drvController != null)
+            return drvController.getLogLevel();
+        return 0;
+    }
+    
+    public void setLogLevel(int value){
+        if (drvController != null)
+            drvController.setLogLevel(value);
+    }
+    public void doSearch(String target){
+        if (drvController != null)
+            drvController.search(target);
+    }
+    
+    
+    public void serviceChanged(ServiceEvent e) {
+        switch(e.getType()){
+            case ServiceEvent.REGISTERED:{
+                Object service = Activator.context.getService(e.getServiceReference());
+                if (service != null){
+                devicesInfo = (DevicesInfo) service;
+                drvController = (DriverController) devicesInfo;
+                Mediator.getControlPoint().enableMenus(true,getLogLevel(),getCyberDebug());
+                Mediator.getTreeViewer().setPopupMenuEnabled(true);
+                }
+            };break;
+            case ServiceEvent.UNREGISTERING:{   
+                devicesInfo = null;
+                drvController =null;
+                Mediator.getControlPoint().enableMenus(false,0,false);
+                Mediator.getTreeViewer().setPopupMenuEnabled(false);
+            };break;
+        }       
+    }
+    
+    public void close(){
+        Activator.context.removeServiceListener(this);           
+    }
+
+
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/RootDeviceListener.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/RootDeviceListener.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/RootDeviceListener.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/discovery/RootDeviceListener.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,295 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.discovery;
+
+
+import java.util.*;
+
+import org.apache.felix.upnp.tester.Activator;
+import org.apache.felix.upnp.tester.gui.*;
+import org.osgi.framework.*;
+import org.osgi.service.upnp.*;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari
+ *  
+ */
+public class RootDeviceListener implements ServiceListener {
+		
+	//This list contains all partial tree of UPnP Device
+	//when a device is complete it will be removed from the list
+    private ArrayList devices;
+	
+	private DeviceNodeListener listener;
+
+	public RootDeviceListener(){
+		devices = new ArrayList();
+
+	}
+	
+	public void setDeviceNodeListener(DeviceNodeListener listener){
+		this.listener = listener;
+	}
+	
+	public synchronized void addNewDevice(ServiceReference sr){
+		LogPanel.log("adding device:"+sr.getProperty(UPnPDevice.FRIENDLY_NAME));
+		DeviceNode node = new DeviceNode(sr);
+		//node.print();	
+		if(node.isRoot() && node.isLeaf()){
+			//Obiovsly
+			listener.deviceDetected(node);
+			return;
+		}
+
+		if(!node.isLeaf()){
+			//I look if there is some partial tree that is child 
+			//of my new node. This operation may complete the tree 
+			Iterator list = devices.iterator();
+			DeviceNode handle = null;
+			while(list.hasNext()){
+				DeviceNode tree = (DeviceNode) list.next();
+				if((handle = node.isAttachable(tree)) != null){
+					handle.attach(tree);
+					list.remove();
+                    monitorDevices();
+					if(node.isRoot() && node.isComplete()){
+						listener.deviceDetected(node);
+//						removeChildren(node);
+						return;
+					}
+				}
+			}
+		}
+		
+		if(!node.isRoot()){
+			//I look if there is some partial tree that should own
+			//my new node. This operation may complete the tree			
+			Iterator list = devices.iterator();
+			DeviceNode handle = null;
+			while(list.hasNext()){
+				DeviceNode tree = (DeviceNode) list.next();
+				if((handle = tree.isAttachable(node)) != null){
+					handle.attach(node);
+					if(tree.isRoot() && tree.isComplete()){
+						list.remove();
+                        monitorDevices();
+						listener.deviceDetected(tree);
+//						removeChildren(tree);
+					}
+					return;
+				}
+			}		
+		}
+		
+		devices.add(node);
+        monitorDevices();
+	}
+
+	private void monitorDevices() {
+        LogPanel.status("Pending Devices: " + devices.size() );      
+    }
+
+    public void removeDevice(ServiceReference sr){
+		DeviceNode node = new DeviceNode(sr);
+		if (node.isRoot()) {
+			LogPanel.log("removing root device ..."+sr.getProperty(UPnPDevice.FRIENDLY_NAME));
+			listener.rootDeviceUnplugged(node.toString());
+			return;
+		}
+
+	}
+	/**
+	 * @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
+	 */
+	public void serviceChanged(ServiceEvent e) {
+		switch(e.getType()){
+			case ServiceEvent.REGISTERED:{
+				addNewDevice(e.getServiceReference());
+			};break;
+			
+			case ServiceEvent.MODIFIED:{				
+			};break;
+			
+			case ServiceEvent.UNREGISTERING:{	
+				removeDevice(e.getServiceReference());
+			};break;
+				
+		}
+	}
+
+
+	/**
+	 * Register this object to listen to all "well registered" UPnPDevice<br> 
+	 * that should be Exported<br>
+	 * And look for all the already registered UPnPDevice to be exported
+	 * 
+	 */
+	public void activate() {
+		/*
+		 * I listen for the UPnPDevice service that are Root 
+		 * that should be exported to UPnP Network.
+		 */
+	    try {
+			Activator.context.addServiceListener(this,
+				"(&"+
+					"("+Constants.OBJECTCLASS+"="+UPnPDevice.class.getName()+")"+
+					"("+UPnPDevice.UDN+"=*)"+
+				")"
+				);
+		} catch (InvalidSyntaxException e) {
+			e.printStackTrace();
+		}
+		ServiceReference[] roots = null; 
+		try {
+			roots = Activator.context.getServiceReferences(
+					UPnPDevice.class.getName(),
+					"(&"+
+					"("+Constants.OBJECTCLASS+"="+UPnPDevice.class.getName()+")"+
+					"("+UPnPDevice.UDN+"=*)"+
+					")"
+				);
+		} catch (InvalidSyntaxException e) {
+			e.printStackTrace();
+		}
+		if(roots!=null){
+			for (int i = 0; i < roots.length; i++) {
+				addNewDevice(roots[i]);
+			}
+		}
+	}
+
+	/**
+	 * 
+	 */
+	public void deactive() {
+	    Activator.context.removeServiceListener(this);
+	}
+    
+    
+    
+    
+    
+    
+    public void checkIncompleteDevice() {
+        if (devices.size() == 0){
+            LogPanel.log("[check incomplete device] no pending devices !"  );
+            return;
+        }
+        Iterator list = devices.iterator();
+        while(list.hasNext()){
+            LogPanel.log("[check incomplete device] "  );           
+            LogPanel.log("------- device -------- "  );           
+            DeviceNode tree = (DeviceNode) list.next();
+            printProperties(tree.getReference());
+        }
+        
+    }
+    
+    public static void checkErrataDevice() {
+        ServiceReference[] allUPnPDevice = null; 
+        ServiceReference[] UPnPbaseDriverDevice = null;
+        try {
+            allUPnPDevice = Activator.context.getServiceReferences(
+                    UPnPDevice.class.getName(),
+                    "(&" + "(" + UPnPDevice.UPNP_EXPORT + "=*)" 
+                         + "("+Constants.OBJECTCLASS+"="+UPnPDevice.class.getName()+")"
+                    + ")"
+                );
+            // filter used by UPnP base Driver
+            UPnPbaseDriverDevice = Activator.context.getServiceReferences(UPnPDevice.class.getName(),
+                        "(&" + "(" + UPnPDevice.UPNP_EXPORT + "=*)" + 
+                                "(DEVICE_CATEGORY=UPnP)" + 
+                                "(" + UPnPDevice.UDN + "=*)" + 
+                                "(" + UPnPDevice.FRIENDLY_NAME + "=*)" +  
+                                "(" + UPnPDevice.MANUFACTURER + "=*)" + 
+                                "(" + UPnPDevice.MODEL_NAME + "=*)" + 
+                                "(" + UPnPDevice.TYPE + "=*)" + 
+                                "(!("+ UPnPDevice.PARENT_UDN + "=*))" + 
+            ")");
+
+        } catch (InvalidSyntaxException e) {
+            e.printStackTrace();
+        }
+        if (allUPnPDevice!=null){
+            if (UPnPbaseDriverDevice!= null){
+                if (allUPnPDevice.length == UPnPbaseDriverDevice.length){                   
+                    LogPanel.log("---- Check Errata Device ----");
+                    LogPanel.log("All registered Devices have mandatory properties specified");
+                    LogPanel.log("--------  End Check  --------");
+                }
+                else if (allUPnPDevice.length > UPnPbaseDriverDevice.length)
+                    printErrataDevice(allUPnPDevice,UPnPbaseDriverDevice) ;               
+            }
+            else {
+                printErrataDevice(allUPnPDevice,UPnPbaseDriverDevice) ;               
+            }
+        }
+        
+    }
+    
+    public static void  printErrataDevice(ServiceReference[] allUPnPDevice,ServiceReference[] UPnPbaseDriverDevice) {
+        LogPanel.log("---- Check Errata Device ----");
+        for (int i =0;i< allUPnPDevice.length;i++){
+             if (! isPresent(allUPnPDevice[i],UPnPbaseDriverDevice)){
+                 LogPanel.log("---- Device ----");
+                 printProperties(allUPnPDevice[i]);
+             }
+         }
+        LogPanel.log("--------  End Check  --------");
+    }
+    
+    public static boolean isPresent(ServiceReference sr, ServiceReference[] list) {
+        Object s = Activator.context.getService(sr);
+        for(int i = 0; i<list.length;i++){
+            Object item =Activator.context.getService(list[i]);
+            if (s == item) {
+                Activator.context.ungetService(sr);
+                Activator.context.ungetService(list[i]);
+                return true;
+            }
+            Activator.context.ungetService(list[i]);           
+        }
+        Activator.context.ungetService(sr);
+        return false;
+    }
+    
+    public static void printProperties(ServiceReference service){
+        String[] properties = service.getPropertyKeys();
+        if (properties == null)
+            LogPanel.log("properties are null");
+        else {
+            for(int j =0;j<properties.length;j++)
+                LogPanel.log(properties[j] + "=" + Util.justString(service.getProperty(properties[j])));
+        }
+        
+        if ( service.getProperty(UPnPDevice.UDN)== null) 
+            LogPanel.log("[Warning] missing property: "+UPnPDevice.UDN);
+        if ( service.getProperty(UPnPDevice.FRIENDLY_NAME)== null) 
+            LogPanel.log("[Warning] missing property: "+UPnPDevice.FRIENDLY_NAME);
+        if ( service.getProperty(UPnPDevice.MANUFACTURER)== null) 
+            LogPanel.log("[Warning] missing property: "+UPnPDevice.MANUFACTURER);
+        if ( service.getProperty(UPnPDevice.MODEL_NAME)== null) 
+            LogPanel.log("[Warning] missing property: "+UPnPDevice.MODEL_NAME);
+        if ( service.getProperty(UPnPDevice.TYPE)== null) 
+            LogPanel.log("[Warning] missing property: "+UPnPDevice.TYPE);
+
+    }
+    
+
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/ActionPanel.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/ActionPanel.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/ActionPanel.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/ActionPanel.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,365 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.util.Dictionary;
+import java.util.Hashtable;
+
+import javax.swing.AbstractAction;
+import javax.swing.AbstractCellEditor;
+import javax.swing.DefaultCellEditor;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSlider;
+import javax.swing.JTable;
+import javax.swing.JTextField;
+import javax.swing.SwingConstants;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableModel;
+
+import org.apache.felix.upnp.extra.util.Converter;
+import org.apache.felix.upnp.extra.util.UPnPException;
+import org.apache.felix.upnp.tester.Mediator;
+import org.osgi.service.upnp.UPnPAction;
+import org.osgi.service.upnp.UPnPStateVariable;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+  * @author Francesco  Furfari 
+ *  
+ */
+public class ActionPanel extends JPanel {
+	
+	UPnPAction action;
+	ArgumentsModel argsModel;
+	MyTable table; 
+	JPanel buttonPanel;
+	
+	OutputArgumentsModel outArgsModel; 
+	JTable outTable; 
+	
+	/**
+	 * 
+	 */
+	public ActionPanel() {
+		super(new GridBagLayout());
+		buildButtonPanel();
+		buildTable();
+		add(new JScrollPane(table),Util.setConstrains(0,0,1,1,100,100));
+		add(new JScrollPane(outTable),Util.setConstrains(0,1,1,1,100,100)); 
+		add(buttonPanel,Util.setConstrains(1,0,1,1,1,1));
+	}
+
+	private void buildButtonPanel(){
+		buttonPanel = new JPanel();
+		JButton doAction = new JButton("Do Action");
+		doAction.addActionListener(new AbstractAction(){
+			public void actionPerformed(ActionEvent e) {
+				outArgsModel.clearData(); 
+
+				Dictionary params = null;
+				Dictionary result = null;
+				if (argsModel.getRowCount()!= 0){
+					if (table.isEditing()) table.getCellEditor().stopCellEditing();
+					params = new Hashtable();
+					for (int i =0;i<argsModel.getRowCount();i++){
+						String name = (String) argsModel.getValueAt(i,0);
+						String value = (String)argsModel.getValueAt(i,3);
+						try {
+                            params.put(
+                            	name,
+                                Converter.parseString(
+                                    value,
+                                    action.getStateVariable(name).getUPnPDataType()));
+                        } catch (Exception ex) {
+                        	LogPanel.log("Error invoking action (bad parameter)");
+                         	return ;
+                        }
+					}
+				}
+				try {result = action.invoke(params);}
+                catch (UPnPException ex){
+                    String error =  
+                        "===== Action Failed =====" +
+                        "\nUPnP Error Code::\n    " +ex.getErrorCode() +
+                        "\nUPnP Error Description::\n    " +ex.getErrorDescription();
+                    printReport(params,error);
+                    JOptionPane.showMessageDialog(
+                        Mediator.getPropertiesViewer(),error);                   
+                }
+                catch (Exception ex){
+                    printReport(params,ex.getMessage());
+					JOptionPane.showMessageDialog(
+						Mediator.getPropertiesViewer(),
+						ex.getMessage()
+					);
+				}
+				if (result != null) {
+                    printReport(params,result);
+					outArgsModel.setData(action,result);
+					JOptionPane.showMessageDialog(
+						Mediator.getPropertiesViewer(),
+						"Action invoked!"
+					);
+				
+				}
+			}
+            private void printReport(Dictionary params,Object result) {
+                String input = "";
+                String output = "";
+                if (params != null) input = params.toString();
+                if (output != null) output = result.toString();
+                String method = action.getName();
+                String report = "\n==== Action:: " + method + " ====\n"
+                                + input 
+                                + "\n----------- result ----------\n"
+                                + output
+                                + "\n-----------------------------";
+               LogPanel.log(report);
+            }
+		});		
+	    buttonPanel.add(doAction);
+	}
+	
+	private void buildTable(){
+		argsModel = new ArgumentsModel();
+	    table = new MyTable(argsModel); 
+		argsModel.setTable(table); 		
+
+		outArgsModel = new OutputArgumentsModel();
+	    outTable = new JTable(outArgsModel); 
+	}
+
+	public void setArguments(UPnPAction action){
+		this.action = action;
+		argsModel.setData(action);		
+		outArgsModel.clearData(); 
+	}
+	
+}
+
+//thanks to Thomas Wagner 18/10/2005
+class OutputArgumentsModel extends ArgumentsModel { 
+
+	public OutputArgumentsModel() {
+		super();
+        header = new String[]{"output arg name","related Var","Java \\ UpnP type","value"};
+	}
+
+	public void clearData() {
+		names = new String[]{""};
+        related = new String[]{""};
+    	types = new String[]{""};
+    	values = new String[]{""};
+		size=0;
+		this.fireTableChanged(new TableModelEvent(this));
+	}
+
+    public void setData(UPnPAction  action, Object result){
+
+		Hashtable res = (Hashtable) result;
+
+        String[] names = action.getOutputArgumentNames();
+   	    size = 0;
+    	this.names = names;
+    	if (names!=null){
+	    	values = new String[names.length];
+            types = new String[names.length];
+            related = new String[names.length];
+	    	for (int i=0;i<names.length;i++) {
+                UPnPStateVariable currentStateVar = action.getStateVariable(names[i]);
+
+				Object value = res.get(names[i]);
+                values[i]=value.toString();
+                related[i] = currentStateVar.getName();
+                
+                String javaType =currentStateVar.getJavaDataType().toString();
+                javaType = javaType.substring(javaType.lastIndexOf('.')+1);
+                String upnpType = currentStateVar.getUPnPDataType();
+                types[i] = javaType + " \\ " + upnpType;
+            }   	
+	    	size = names.length;
+    	}
+		this.fireTableChanged(new TableModelEvent(this));
+    }
+}
+
+//thanks to Thomas Wagner 12/10/2005
+class ArgumentsModel extends  AbstractTableModel {
+	int size = 0;
+	private MyTable table;	
+	String[] names = new String[]{""};
+    String[] related = new String[]{""};
+    String[] types = new String[]{""};
+    String[] values = new String[]{""};
+	String[] header = new String[]{"arg name","related Var","Java \\ UpnP type","value"};
+   
+	public void setTable(MyTable table) { 
+		this.table = table;
+	}
+ 
+	public int getColumnCount() { return 4; }
+    public int getRowCount() { return size;}
+    public String getColumnName(int col) { return header[col]; }
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+    	return (columnIndex ==3);
+    }
+    public Object getValueAt(int row, int col) { 
+    	if (col == 0) return names[row];
+        else if (col == 1) return related[row];
+        else if (col == 2) return types[row];
+        else if (col == 3) return values[row];
+    	return null;
+	}   
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+    	values[rowIndex]= (String) aValue; 
+    }
+
+    public void setData(UPnPAction  action){
+
+		table.deleteMyCellEditors();
+        
+
+        String[] names = action.getInputArgumentNames();
+   	    size = 0;
+    	this.names = names;
+    	if (names!=null){
+	    	values = new String[names.length];
+            related = new String[names.length];
+            types = new String[names.length];
+	    	for (int i=0;i<names.length;i++) {
+                values[i]="";
+                UPnPStateVariable currentStateVar = action.getStateVariable(names[i]);
+                related[i] = currentStateVar.getName();
+                String javaType = currentStateVar.getJavaDataType().toString();
+                javaType = javaType.substring(javaType.lastIndexOf('.')+1);
+                String upnpType = currentStateVar.getUPnPDataType();
+                types[i] = javaType + " \\ " + upnpType;
+
+				//handle allowed value list
+				if ( currentStateVar.getAllowedValues() != null) {
+					String av[] = currentStateVar.getAllowedValues();
+					JComboBox comboBox = new JComboBox();
+					for (int j = 0; j < av.length; j++) {
+						comboBox.addItem(av[j]);
+					}
+					values[i] = av[0]; //preset the first value from list
+					table.setMyCellEditor(new DefaultCellEditor(comboBox),i);
+				}
+
+				//handle default value
+				if (currentStateVar.getDefaultValue() != null) {
+					String val = currentStateVar.getDefaultValue().toString();
+					if(val.length() > 0)
+						values[i] = val;
+				}
+				
+               //handle range values
+               if ((currentStateVar.getMaximum()!= null)
+                   &&(currentStateVar.getMinimum()!= null)){
+                   int max = currentStateVar.getMaximum().intValue();
+                   int min = currentStateVar.getMinimum().intValue();
+                   int value = min;
+                   try { value = Integer.parseInt(values[i]);}
+                   catch (NumberFormatException ignored){}
+                   table.setMyCellEditor(new SliderEditor(min,max,value),i);
+               }
+
+            }   	
+	    	size = names.length;
+    	}
+		this.fireTableChanged(new TableModelEvent(this));
+        this.fireTableStructureChanged();
+    }
+}
+
+// thanks to Thomas Wagner 12/10/2005
+class MyTable extends JTable { 
+
+	private Hashtable cellEditors;
+	
+	public MyTable(TableModel dm) {
+		super(dm);
+		cellEditors = new Hashtable();
+	}
+
+	public void setMyCellEditor(TableCellEditor editor,int col){
+		cellEditors.put(new Integer(col),editor);
+	}
+
+	public void deleteMyCellEditors(){
+		cellEditors.clear();
+	}
+
+	//overwritten JTable method	
+	public TableCellEditor getCellEditor(int row,int col) {
+		TableCellEditor tce = (TableCellEditor) cellEditors.get(new Integer(row));
+		if( tce != null) {
+			return tce;
+		} else {
+			return super.getCellEditor(row,col);
+		}
+	}
+}
+
+class SliderEditor extends AbstractCellEditor implements TableCellEditor
+{
+    JPanel editor;
+    JTextField text;
+    JSlider slider;
+    public SliderEditor(int min, int max, int value){
+         editor = new JPanel(new BorderLayout());
+         //editor.setBorder(new EmptyBorder(1,0,1,0));
+         text = new JTextField(Integer.toString(max).length());
+         slider = new JSlider(SwingConstants.HORIZONTAL,min,max,value);
+         editor.add(text,BorderLayout.WEST);
+         editor.add(slider);
+         slider.addChangeListener(new ChangeListener(){
+            public void stateChanged(ChangeEvent e) {
+                //if (! replSlider.getValueIsAdjusting()){
+                text.setText(new Integer(slider.getValue()).toString());
+                //}
+            }
+         });
+
+    }
+    
+    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+        text.setText((String) value);
+        try {
+            slider.setValue(Integer.parseInt((String)value));
+        } catch (NumberFormatException ignored) {}
+        return editor;
+    }
+
+    public Object getCellEditorValue() {
+        return text.getText();
+    }
+}
+

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/LogPanel.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/LogPanel.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/LogPanel.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/LogPanel.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,74 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.gui;
+
+import java.awt.BorderLayout;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollBar;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco Furfari 
+ *  
+ */
+public class LogPanel extends JPanel {
+    private static JTextArea logArea = new JTextArea(4,50);
+    private static JPanel statusBar = new JPanel(new BorderLayout());
+    private static JLabel statusText = new JLabel();
+    
+    private static JScrollPane scroll = new JScrollPane(logArea);
+    
+    public LogPanel() {
+        super(new BorderLayout());
+        logArea.setText("");
+        //add(new JScrollPane(new JTextArea(4,80)));
+        add(scroll);
+        statusBar.add(statusText,BorderLayout.EAST);
+        add(statusBar,BorderLayout.SOUTH);
+        }
+
+    /* public static void log(String msg) {
+        logArea.append(msg + "\n\r");
+		JScrollBar scrBar = scroll.getVerticalScrollBar();
+		int maxPos = scrBar.getMaximum();
+		scrBar.setValue(maxPos);
+   }*/
+    
+    public static void log(final String msg){ 
+        synchronized (logArea) {
+            logArea.append(msg );
+            logArea.append("\n\r");
+        }
+        JScrollBar scrBar = scroll.getVerticalScrollBar();
+        int maxPos = scrBar.getMaximum();
+        scrBar.setValue(maxPos);
+    }
+    
+    public static void status(final String msg){ 
+        statusText.setText(msg);
+     }
+
+   public static void clear(String msg) {
+        logArea.setText("");
+   }
+
+}

Added: incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/PropertiesViewer.java
URL: http://svn.apache.org/viewcvs/incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/PropertiesViewer.java?rev=391455&view=auto
==============================================================================
--- incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/PropertiesViewer.java (added)
+++ incubator/felix/trunk/org.apache.felix.upnp.tester/src/main/java/org/apache/felix/upnp/tester/gui/PropertiesViewer.java Tue Apr  4 16:44:23 2006
@@ -0,0 +1,225 @@
+/*
+ *   Copyright 2006 The Apache Software Foundation
+ *
+ *   Licensed under the Apache License, Version 2.0 (the "License");
+ *   you may not use this file except in compliance with the License.
+ *   You may obtain a copy of the License at
+ *
+ *       http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *   Unless required by applicable law or agreed to in writing, software
+ *   distributed under the License is distributed on an "AS IS" BASIS,
+ *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *   See the License for the specific language governing permissions and
+ *   limitations under the License.
+ *
+ */
+
+package org.apache.felix.upnp.tester.gui;
+
+
+
+import java.awt.Component;
+import java.awt.Cursor;
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+import java.awt.Point;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.event.MouseMotionListener;
+
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTable;
+import javax.swing.JTree;
+import javax.swing.event.TableModelEvent;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+
+import org.apache.felix.upnp.tester.Mediator;
+import org.apache.felix.upnp.tester.discovery.DeviceNode;
+import org.osgi.service.upnp.UPnPAction;
+import org.osgi.service.upnp.UPnPDevice;
+
+/**
+ * @author Stefano "Kismet" Lenzi 
+ * @author Francesco  Furfari
+ *  
+ */
+public class PropertiesViewer extends JPanel {
+
+    ActionPanel actionsPanel;
+	SubscriptionPanel subscriptionPanel;
+	DataModel dataModel;
+	JTable table;
+	
+	public PropertiesViewer(){
+		super(new GridBagLayout());
+		buildTable();
+		actionsPanel = new ActionPanel();
+		subscriptionPanel = new SubscriptionPanel();
+		
+		JScrollPane scroll = new JScrollPane(table);
+		scroll.setPreferredSize(new Dimension(500,200));
+		//actionsPanel.setPreferredSize(new Dimension(500,100)); twa
+		actionsPanel.setPreferredSize(new Dimension(500,200));
+		add(scroll,Util.setConstrains(0,0,6,2,100,50));
+		add(actionsPanel,Util.setConstrains(0,2,6,1,100,20));
+		add(subscriptionPanel,Util.setConstrains(0,3,6,1,100,5));
+		showActionPanel(false);
+		showSubscriptionPanel(false);
+         
+        table.addMouseMotionListener(new MouseMotionListener(){
+           private final Cursor handCursor = new Cursor(Cursor.HAND_CURSOR);
+           
+           public void mouseDragged(MouseEvent e) {}
+           public void mouseMoved(MouseEvent e) {
+                String link = getDataLink(e.getPoint());
+                if (link != null)
+                    table.setCursor(handCursor);                       
+                else
+                    table.setCursor(Cursor.getDefaultCursor());
+           }
+
+        });
+        
+        table.addMouseListener(new MouseAdapter(){
+            public void mouseClicked(MouseEvent e){
+                String link = getDataLink(e.getPoint());
+                if (link != null)
+                    Util.openUrl(link);              
+            }
+        });
+
+    }   
+        
+    public String getDataLink(Point p) {
+        int col = table.columnAtPoint(p);
+        if (col != 1) 
+            return null;
+        else {
+            int row = table.rowAtPoint(p);
+            String data = (String) dataModel.getValueAt(row,col);
+            if (data == null) return null;
+            if (data.length()<4) return null;
+            String begin = data.substring(0,4);
+            if (begin.equalsIgnoreCase("http"))
+                return data;
+            else {
+                String propertyName= (String) dataModel.getValueAt(row,0);
+                if (propertyName.equalsIgnoreCase(UPnPDevice.PRESENTATION_URL)
+                    ||propertyName.equalsIgnoreCase(UPnPDevice.MANUFACTURER_URL)
+                    ||propertyName.equalsIgnoreCase(UPnPDevice.MODEL_URL) )
+                    {
+                    JTree tree = Mediator.getUPnPDeviceTree();
+                    UPnPDeviceTreeNode selectedNode = (UPnPDeviceTreeNode)tree.getLastSelectedPathComponent();   
+                    String url = "";
+                    if (selectedNode.category.equals(UPnPDeviceTreeNode.DEVICE)){
+                        UPnPDeviceTreeNode parent =  (UPnPDeviceTreeNode)selectedNode.getParent();
+                        while (parent.category!=UPnPDeviceTreeNode.ROOT_DEVICE)
+                             parent =  (UPnPDeviceTreeNode)parent.getParent();
+                        DeviceNode device =  (DeviceNode) parent.getUserObject();
+                        String udn = (String)device.getReference().getProperty(UPnPDevice.UDN);
+                        url = Mediator.getDriverProxy().resolveRelativeUrl(udn,data);
+                        return url;
+                    }                           
+                    else if (selectedNode.category.equals(UPnPDeviceTreeNode.ROOT_DEVICE))
+                    {
+                        DeviceNode node =  (DeviceNode) selectedNode.getUserObject();
+                        String udn = (String)node.getReference().getProperty(UPnPDevice.UDN);
+                        url = Mediator.getDriverProxy().resolveRelativeUrl(udn,data);
+                        return url;
+                    }
+                }
+                return null;     
+            }
+        }
+	}
+	
+	public void setProperties(String[]name,String[]values){
+		dataModel.setData(name,values);
+	}
+	
+	public void setAction(UPnPAction action){
+		actionsPanel.setArguments(action);
+		
+	}
+	
+	public void showActionPanel(boolean show){
+		actionsPanel.setVisible(show);
+	}
+	
+	public void showSubscriptionPanel(boolean show){
+	    subscriptionPanel.setVisible(show);
+	}
+	
+	private void buildTable(){
+		dataModel = new DataModel();
+	    table = new JTable(dataModel);
+        table.setDefaultRenderer(table.getColumnClass(1), new LinkCellRenderer());
+	}
+
+
+}
+
+class DataModel extends  AbstractTableModel {
+	int size = 0;
+	String[] names = new String[]{""};
+	String[] values = new String[]{""};
+    String[] header = new String[]{"property key","value"};
+    
+    public String getColumnName(int col) { return header[col]; }
+	public int getColumnCount() { return 2; }
+    public int getRowCount() { return size;}
+    public Object getValueAt(int row, int col) { 
+    	if (col==0) return names[row];
+    	else return values[row];
+    }
+    
+    /*
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+        return false;
+    }
+    */
+    
+    public void setData(String[]names,String[]values){
+        String[] lowerNames = new String[names.length];
+        for (int i=0;i<names.length;i++)
+            lowerNames[i]= names[i].toLowerCase();
+    	this.names=lowerNames;
+    	this.values=values;
+    	size = names.length;
+		this.fireTableChanged(new TableModelEvent(this));
+    }
+    
+}
+
+class LinkCellRenderer extends DefaultTableCellRenderer
+{
+    public LinkCellRenderer(){
+        super();
+    }
+    
+    public Component getTableCellRendererComponent(JTable table, Object value,
+            boolean isSelected, boolean hasFocus, int row, int column) {
+        super.getTableCellRendererComponent(table,value,isSelected,hasFocus,row,column);
+        if (column==1){
+            String propertyName = (String)table.getModel().getValueAt(row,0);
+            if (propertyName.equalsIgnoreCase(UPnPDevice.PRESENTATION_URL)
+                ||propertyName.equalsIgnoreCase(UPnPDevice.MODEL_URL)
+                ||propertyName.equalsIgnoreCase(UPnPDevice.MANUFACTURER_URL))
+            {
+                if (!value.equals(""))
+                    setValue("<html><a href=''>"+value+"</a></html>");
+                return this;
+            }
+            if (((String) value).length()<4) return this;
+            String begin = ((String) value).substring(0,4);
+            if (begin.equalsIgnoreCase("http"))
+                setValue("<html><a href=''>"+value+"</a></html>");
+        }
+        return this;
+    }
+ 
+}
+