| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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.ArrayList; |
| import java.util.Iterator; |
| |
| import org.osgi.framework.Constants; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceEvent; |
| import org.osgi.framework.ServiceListener; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.service.upnp.UPnPDevice; |
| |
| import org.apache.felix.upnp.tester.Activator; |
| import org.apache.felix.upnp.tester.gui.LogPanel; |
| import org.apache.felix.upnp.tester.gui.Util; |
| |
| /* |
| * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> |
| */ |
| 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); |
| |
| } |
| |
| |
| } |