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() {