You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by le...@apache.org on 2008/01/09 17:57:02 UTC

svn commit: r610454 - in /felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver: export/BuildDevice.java export/ThreadExporter.java importer/core/upnp/UPnPStateVariableImpl.java

Author: lenzi
Date: Wed Jan  9 08:56:50 2008
New Revision: 610454

URL: http://svn.apache.org/viewvc?rev=610454&view=rev
Log:
Fixed bug #FELIX-460 in BuildDevice
Removed unused code and avoiding overriding of UPnP configuration in ThreadExporter
Added caching and better control on constraint defined for imported Device in UPnPStateVariableImpl


Modified:
    felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java
    felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ThreadExporter.java
    felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java

Modified: felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java
URL: http://svn.apache.org/viewvc/felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java?rev=610454&r1=610453&r2=610454&view=diff
==============================================================================
--- felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java (original)
+++ felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/BuildDevice.java Wed Jan  9 08:56:50 2008
@@ -171,7 +171,7 @@
 		UPnPDevice devOSGi = (UPnPDevice) Activator.bc.getService(sr);
 
 		if( devOSGi == null) {	//added by twa to prevent a null pointer exception
-			Activator.logger.WARNING("UPnP Device taht cotains serviceId="
+			Activator.logger.WARNING("UPnP Device that cotains serviceId="
 					+id+" is deregistered from the framework while is exported");
 			return;
 		}
@@ -194,6 +194,7 @@
 
 			UPnPAction[] actions = services[i].getActions();
 			for (int j = 0; j < actions.length; j++) {
+                boolean valid=true;
 				Action act = new Action(ser.getServiceNode());
 				act.setName(actions[j].getName());
 				ArgumentList al = new ArgumentList();
@@ -201,29 +202,51 @@
 				String[] names=actions[j].getInputArgumentNames();				
 				if(names!=null){
 					for (int k = 0; k < names.length; k++) {
-						Argument a = new Argument();
+                        UPnPStateVariable variable = actions[j].getStateVariable(names[k]);
+                        if(variable==null){
+                            /*
+                             * //TODO Create a stict and relaxed behavior of the base driver which 
+                             * export as much it can or export only 100% complaint UPnPDevice service 
+                             */
+                            Activator.logger.WARNING(
+                                "UPnP Device that cotains serviceId="+id+" contains the action "
+                                +actions[j].getName()+" with the Input argument "+names[k]
+                                +" not related to any UPnPStateVariable. Thus this action won't be exported");
+                            valid=false;
+                            break;
+                        }
+                        Argument a = new Argument();
 						a.setDirection(Argument.IN);
 						a.setName(names[k]);
-						a.setRelatedStateVariableName(
-								actions[j].getStateVariable(names[k]).getName()
-						);						
+						a.setRelatedStateVariableName(variable.getName());						
 						al.add(a);						
 					}
 				}
 				names=actions[j].getOutputArgumentNames();
-				if(names!=null){
+				if(names!=null && valid){
 					for (int k = 0; k < names.length; k++) {
+                        UPnPStateVariable variable = actions[j].getStateVariable(names[k]);
+                        if(variable==null){
+                            /*
+                             * //TODO Create a stict and relaxed behavior of the base driver which 
+                             * export as much it can or export only 100% complaint UPnPDevice service 
+                             */
+                            Activator.logger.WARNING(
+                                "UPnP Device that cotains serviceId="+id+" contains the action "
+                                +actions[j].getName()+" with the Output argument "+names[k]
+                                +" not related to any UPnPStateVariable. Thus this action won't be exported");                            
+                        }
 						Argument a = new Argument();
 						a.setDirection(Argument.OUT);
 						a.setName(names[k]);
-						a.setRelatedStateVariableName(
-								actions[j].getStateVariable(names[k]).getName()
-						);						
+						a.setRelatedStateVariableName(variable.getName());						
 						al.add(a);						
 					}
 				}
-				act.setArgumentList(al);
-				ser.addAction(act);
+                if(valid) {
+    				act.setArgumentList(al);
+    				ser.addAction(act);
+                }
 			}			
 			
 			UPnPStateVariable[] vars = services[i].getStateVariables();

Modified: felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ThreadExporter.java
URL: http://svn.apache.org/viewvc/felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ThreadExporter.java?rev=610454&r1=610453&r2=610454&view=diff
==============================================================================
--- felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ThreadExporter.java (original)
+++ felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/export/ThreadExporter.java Wed Jan  9 08:56:50 2008
@@ -101,13 +101,10 @@
 	public ThreadExporter(RootDeviceExportingQueue queue) throws InvalidSyntaxException {
 	    end=false;
 	    queueRootDevice=queue;
-//		basePath="./tmp/device"; twa: redundant
-//		baseFile = Activator.bc.getDataFile("./tmp/device"); twa: redundant
-//		if(!baseFile.exists())	baseFile.mkdirs(); twa: redundant
 		this.exportedDevices=new Hashtable();
 		setListening(false);
-		UPnP.setEnable(UPnP.USE_ONLY_IPV4_ADDR);		
 	}
+    
 	public void run() {
 		
 		File osgiRoot = Activator.bc.getDataFile("");
@@ -138,75 +135,33 @@
 			if(!getListening()) 
 				setListen();
 			Activator.logger.INFO("[Exporter] Exporting device "+ rootDevice.getProperty(UPnPDevice.FRIENDLY_NAME));
-			/*
-			File xml = new File(baseFile, 
-					Converter.sanitizeFilename(
-						(String) rootDevice.getProperty(UPnPDevice.UDN)
-					)
-				);
-			if (xml == null)
-				continue;			
-			if (!xml.exists())
-				xml.mkdir();
-
-			FileOutputStream fos = null;
-			try {
-				fos = new FileOutputStream(xml.getAbsolutePath()
-						+ File.separator + "desc.xml");
-			} catch (FileNotFoundException e) {				
-				Activator.logger.log(LogService.LOG_ERROR,"Unable to write:" + xml.getAbsolutePath(), e);
-				continue;
-			}
-			if (fos == null)
-				continue;*/
-			/*
+			
+            /*
 			 * I don't know if the exporting should be make default language of the framework
 			 * or without any lanuguages
 			Root r = new Root(rootDevice, context, context
 					.getProperty(Constants.FRAMEWORK_LANGUAGE));
-					*/
+			*/
             
 			synchronized (this) {
-				//Root r = new Root(rootDevice, Activator.bc, null);
-				/*
-				 * Now that I have XML I'm going to exporting device
-				 * so I have to avoid rece condition with deregistration 
-				 * of the same device
-				 */
-				/*
-				try {
-					r.writeXML(fos);
-				} catch (IOException e) {
-					e.printStackTrace();
-					continue;
-				}
-				if(writeXMLService(xml.getAbsolutePath(),r.getRootDevice())){
-					Device d = null;
-					try {
-						d = new Device(xml.getAbsolutePath()
-								+ File.separator + "desc.xml");
-					} catch (InvalidDescriptionException e) {
-						e.printStackTrace();
-					}*/
-					Device d = BuildDevice.createCyberLinkDevice(dn.getReference());
-					if (d != null) {
-						if(!bindInvokes(d,rootDevice)){
-							Activator.logger.DEBUG("Unable to find all the sub device or to set action listener");
-							continue;
-						}
-						ServiceRegistration listenReg = bindSubscribe(d);
-						if(listenReg==null){
-							Activator.logger.DEBUG("Unable to set action listener event listener");
-							continue;
-						}			
-						//makeIcons(r.getRootDevice(),xml.getAbsolutePath());
-						d.start();
-						exportedDevices.put(
-								rootDevice.getProperty(UPnPDevice.UDN),
-								new ExportedDeviceInfo(d,listenReg,dn)
-						);
+				Device d = BuildDevice.createCyberLinkDevice(dn.getReference());
+				if (d != null) {
+					if(!bindInvokes(d,rootDevice)){
+						Activator.logger.DEBUG("Unable to find all the sub device or to set action listener");
+						continue;
 					}
-				//}
+					ServiceRegistration listenReg = bindSubscribe(d);
+					if(listenReg==null){
+						Activator.logger.DEBUG("Unable to set action listener event listener");
+						continue;
+					}			
+					//makeIcons(r.getRootDevice(),xml.getAbsolutePath());
+					d.start();
+					exportedDevices.put(
+							rootDevice.getProperty(UPnPDevice.UDN),
+							new ExportedDeviceInfo(d,listenReg,dn)
+					);
+				}
 			}
 		}
 	}
@@ -274,7 +229,6 @@
 	 */
 	private boolean bindInvokes(Device d, ServiceReference rootDevice) {
 		bindInvoke(d,rootDevice);
-		//Activator.bc.ungetService(rootDevice);
 		ServiceReference[] childs = null;
 		try {
 			childs = Activator.bc.getServiceReferences(
@@ -290,20 +244,12 @@
 		}else if((childs==null)||(childsUDN==null)){
 			return false;
 		}else if(childs.length==childsUDN.length){
-            /*--- your code ---            
-            for (int i = 0; i < childs.length; i++) {
-                if(!bindInvokes(d,childs[i]))
-                    return false;
-            }           
-            ----- your code end ---*/
-            /*--- twa code ---*/
             DeviceList dl = d.getDeviceList();
             for (int i = 0; i < childs.length; i++) {
                 Device dev = (Device)dl.elementAt(i);
                 if(!bindInvokes(dev,childs[i]))
                     return false;
             }
-            /*----- twa code end ---*/
 
 			return true;
 		}else{
@@ -311,48 +257,7 @@
 		}
 			
 	}
-	/*
-	/**
-	 * @param path
-	 *
-	private boolean writeXMLService(String path,org.apache.felix.upnpbase.export.xml.Device d) {
-		Vector v = new Vector();
-		v.add(d);
-		while(v.size()!=0){
-			d=(org.apache.felix.upnpbase.export.xml.Device) v.elementAt(0);
-			v.remove(0);
-			Service[] servs = d.getServices();
-			if(servs==null)
-				continue;
-			for (int i = 0; i < servs.length; i++) {
-				FileOutputStream fos;
-				String xmlPath=path+servs[i].getScpdURL().replace('/',File.separatorChar);
-				if(!Converter.makeParentPath(xmlPath)) return false;
-				try {
-					fos = new FileOutputStream(xmlPath);
-				} catch (FileNotFoundException e) {
-					e.printStackTrace();
-					return false;
-				}
-				try {
-					servs[i].writeXML(fos);
-					fos.close();
-				} catch (IOException e) {
-					e.printStackTrace();
-				}
-			}
-			
-			org.apache.felix.upnpbase.export.xml.Device[] subs = d.getDevices();
-			if(subs==null){
-				return true;
-			}else{
-				for(int i = 0; i < subs.length;i++){
-					v.add(subs[i]);
-				}
-			}
-		}
-		return true;
-	}*/
+    
 	/**
 	 * This method add an UPnPEventListener Service to the OSGi Framework so that
 	 * the Base Driver can notify all the event listener registered on the CyberLink

Modified: felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java?rev=610454&r1=610453&r2=610454&view=diff
==============================================================================
--- felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java (original)
+++ felix/trunk/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPStateVariableImpl.java Wed Jan  9 08:56:50 2008
@@ -29,6 +29,7 @@
 
 import org.osgi.service.upnp.UPnPStateVariable;
 
+import org.apache.felix.upnp.basedriver.Activator;
 import org.apache.felix.upnp.basedriver.util.Converter;
 
 /* 
@@ -37,6 +38,16 @@
 public class UPnPStateVariableImpl implements UPnPStateVariable {
 
 	private StateVariable variable;
+    
+    private Number max = null;
+    private Number min = null;
+    private Number step = null;
+
+    private String[] values = null;    
+    
+    private Boolean hasMaxMinStep = null;
+    private Boolean hasRangeValues = null;    
+
 	private static Hashtable upnp2javaTable = null;
 	
 	static{
@@ -96,37 +107,30 @@
 	public UPnPStateVariableImpl(StateVariable variable) {
 
 		this.variable = variable;
-	} /*
-	   * (non-Javadoc)
-	   * 
-	   * @see org.osgi.service.upnp.UPnPStateVariable#getName()
-	   */
+	} 
 
+    /**
+     * @see org.osgi.service.upnp.UPnPStateVariable#getName()
+	 */
 	public String getName() {
 		return variable.getName();
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#getJavaDataType()
 	 */
 	public Class getJavaDataType() {
 		return (Class) upnp2javaTable.get(variable.getDataType());
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#getUPnPDataType()
 	 */
 	public String getUPnPDataType() {
 		return variable.getDataType();
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#getDefaultValue()
 	 */
 	public Object getDefaultValue() {
@@ -134,100 +138,132 @@
 		return null;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#getAllowedValues()
 	 */
 	public String[] getAllowedValues() {
-		if (variable.getDataType().equals("string")) {
-			AllowedValueList allowedvalue = variable.getAllowedValueList();
-            if (allowedvalue == null) return null;
-			if(allowedvalue.size()==0){
-				return null;
-			} 
-			String[] values = new String[allowedvalue.size()];
-			for (int i = 0; i < allowedvalue.size(); i++) {
-				values[i] = allowedvalue.getAllowedValue(i).getValue();
-			}
-			return values;
-		}
-
-		return null;
+        if(hasRangeValues == null)
+            initValueConstraint();
+        
+        return values;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#getMinimum()
 	 */
 	public Number getMinimum() {
-		//TODO the same thing for getMaximum
-		AllowedValueRange allowedValueRange = variable.getAllowedValueRange();
-		if(allowedValueRange==null){
-			return null;
-		}
-		String min=allowedValueRange.getMinimum();
-        //francesco 22/10/2005
-        if (min.equals("")) return null;
-		try {
-			return (Number)Converter.parseString(min,getUPnPDataType());
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-			return null;
-		}
+        if(hasMaxMinStep == null)
+            initValueConstraint();
+        
+        return min;
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#getMaximum()
 	 */
 	public Number getMaximum() {
-		//TODO I think that this method will be invoked from people that know what is doing
-		AllowedValueRange allowedValueRange = variable.getAllowedValueRange();
-		if(allowedValueRange==null){
-			return null;
-		}
-		String max = allowedValueRange.getMaximum();
-        //francesco 22/10/2005
-        if (max.equals("")) return null;
-		try {
-			return (Number)Converter.parseString(max,getUPnPDataType());
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-			return null;
-		}
-	}
-
-	/*
-	 * (non-Javadoc)
-	 * 
+        if(hasMaxMinStep == null)
+            initValueConstraint();
+        
+        return max;
+	}
+
+    /**
+     * <b>NOTE:</b>  This type of control caches the value recieved by the Device so if XML changes it doesn't affect the OSGi service
+     * 
+     * @since 0.3
+     */
+    private void initValueConstraint(){
+        if(hasRangeValues != null || hasMaxMinStep != null)
+            return;
+
+        hasRangeValues = Boolean.FALSE;
+        hasMaxMinStep = Boolean.FALSE;
+        
+        final AllowedValueRange allowedValueRange = variable.getAllowedValueRange();
+        final AllowedValueList allowedValueList = variable.getAllowedValueList();
+        
+        if(allowedValueRange != null && allowedValueList != null){
+            Activator.logger.WARNING("Imported device with StateVariable "
+                                     +variable.getName()+" contains either AllowedValueRange and AllowedValueList UPnP doesn't allow it because it. Neither of the restriction will be applied");
+            
+        }else if( allowedValueRange != null ){
+            
+            initMaxMinStep(allowedValueRange);
+            
+        }else if( allowedValueList != null ){
+            
+            initAllowedValues(allowedValueList);
+            
+        }
+    }
+    
+    /**
+     * @param allowedValueList
+     * @since 0.3
+     */
+    private void initAllowedValues(AllowedValueList allowedValueList){
+        //PRE:invoked only by initValueConstraint() thus allowedValueList must not null
+        if (String.class != getJavaDataType()) {
+            Activator.logger.WARNING("Imported device with StateVariable "
+                                     +variable.getName()+" contains AllowedValueList but its UPnP type doesn't allow it because it is +"+getUPnPDataType());            
+            return;
+        }
+
+        if(allowedValueList.size() == 0){
+            return ;
+        } 
+
+        values = new String[allowedValueList.size()];
+        for (int i = 0; i < allowedValueList.size(); i++) {
+            values[i] = allowedValueList.getAllowedValue(i).getValue();
+        }
+    }
+
+    /**
+     * @param allowedValueRange
+     * @since 0.3
+     */
+    private void initMaxMinStep(AllowedValueRange allowedValueRange){
+        //PRE:invoked only by initValueConstraint() thus allowedValueRange must not  be null
+        if(allowedValueRange==null){
+            return;
+        }
+
+        if(!Number.class.isAssignableFrom(getJavaDataType())){
+            Activator.logger.WARNING("Imported device with StateVariable "
+                                     +variable.getName()+" contains AllowedValueRange but its UPnP type doesn't allow it because it is +"+getUPnPDataType());            
+            return;
+        }
+        
+        final String maxStr = allowedValueRange.getMaximum();
+        final String minStr = allowedValueRange.getMinimum();
+        final String stepStr = allowedValueRange.getStep();
+        
+        try{
+            final String type = getUPnPDataType();
+            max = (Number)Converter.parseString(maxStr,type);
+            min = (Number)Converter.parseString(minStr,type);
+            step = (Number)Converter.parseString(stepStr,type);
+        }catch(Exception ex){
+            Activator.logger.WARNING("Imported device with StateVariable "
+                +variable.getName()+" contains an invalid definition for AllowedValueRange");
+        }
+        hasMaxMinStep = Boolean.TRUE;
+    }
+    
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#getStep()
 	 */
 	public Number getStep() {
-		//TODO same things of getMaxium
-		AllowedValueRange allowedValueRange = variable.getAllowedValueRange();
-		if(allowedValueRange==null){
-			return null;
-		}
-		String step = allowedValueRange.getStep();
-        //francesco 22/10/2005
-        if (step.equals("")) return null;
-		try {
-			return (Number)Converter.parseString(step,getUPnPDataType());
-		} catch (Exception e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-			return null;
-		}
+        if(hasMaxMinStep == null)
+            initValueConstraint();
+        
+        return step;        
+
 	}
 
-	/*
-	 * (non-Javadoc)
-	 * 
+	/**
 	 * @see org.osgi.service.upnp.UPnPStateVariable#sendsEvents()
 	 */
 	public boolean sendsEvents() {