Resolved some race condition cases
Backporting for JDK 1.3 completed (Thanks to Nico Goeminne)
Added some comment and debug lines
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@606021 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/upnp/basedriver/pom.xml b/upnp/basedriver/pom.xml
index 4174998..a85f6e2 100644
--- a/upnp/basedriver/pom.xml
+++ b/upnp/basedriver/pom.xml
@@ -145,7 +145,7 @@
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.upnp.extra</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java
index fa6b4a9..59bc43d 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/MyCtrlPoint.java
@@ -211,96 +211,108 @@
} else if (ssdpPacket.isByeBye()) {
Activator.logger.DEBUG("[Importer] ssdpPacket.isByeBye");
- if (devices.containsKey(udn)) {
- if (parseUSN.isDevice()) {
- Activator.logger.DEBUG("[Importer] parseUSN.isDevice ...unregistering all the children devices ");
-
- //unregistering all the children devices
- UPnPDeviceImpl dev = ((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
- removeOSGiandUPnPDeviceHierarchy(dev);
+ synchronized (devices) {
- } else if (parseUSN.isService()) {
- Activator.logger.DEBUG("[Importer] parseUSN.isService ...registering modified device again ");
- /*
- * I have to unregister the UPnPDevice and register it again
- * with the updated properties
- */
- UPnPDeviceImpl device =
- ((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
- ServiceRegistration registar =
- ((OSGiDeviceInfo) devices.get(udn)).getRegistration();
- String[] oldServicesID =
- (String[]) (device.getDescriptions(null).get(UPnPService.ID));
- String[] oldServiceType =
- (String[]) (device.getDescriptions(null).get(UPnPService.TYPE));
-
- Device cyberDevice = findDeviceCtrl(this, udn);
- Vector vec = new Vector();
- for (int i = 0; i < oldServiceType.length; i++) {
- Service ser = cyberDevice.getService(oldServicesID[i]);
- if (!(ser.getServiceType().equals(parseUSN.getServiceType())))
- {
- vec.add(oldServicesID[i]);
+ if (devices.containsKey(udn)) {
+ if (parseUSN.isDevice()) {
+ Activator.logger.DEBUG("[Importer] parseUSN.isDevice ...unregistering all the children devices ");
+
+ //unregistering all the children devices
+ UPnPDeviceImpl dev = ((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
+ removeOSGiandUPnPDeviceHierarchy(dev);
+
+ } else if (parseUSN.isService()) {
+ Activator.logger.DEBUG("[Importer] parseUSN.isService ...registering modified device again ");
+ /*
+ * I have to unregister the UPnPDevice and register it again
+ * with the updated properties
+ */
+ UPnPDeviceImpl device =
+ ((OSGiDeviceInfo) devices.get(udn)).getOSGiDevice();
+ ServiceRegistration registar =
+ ((OSGiDeviceInfo) devices.get(udn)).getRegistration();
+ String[] oldServicesID =
+ (String[]) (device.getDescriptions(null).get(UPnPService.ID));
+ String[] oldServiceType =
+ (String[]) (device.getDescriptions(null).get(UPnPService.TYPE));
+
+ Device cyberDevice = findDeviceCtrl(this, udn);
+ Vector vec = new Vector();
+ for (int i = 0; i < oldServiceType.length; i++) {
+ Service ser = cyberDevice.getService(oldServicesID[i]);
+ if (!(ser.getServiceType().equals(parseUSN.getServiceType())))
+ {
+ vec.add(oldServicesID[i]);
+ }
}
- }
-
- //new serviceID
- String[] actualServicesID = new String[vec.size()];
- actualServicesID = (String[]) vec.toArray(new String[]{});
-
- //new serviceType
- String[] actualServiceType = new String[oldServiceType.length - 1];
- vec.clear();
- for (int i = 0; i < oldServiceType.length; i++) {
- if (!(oldServiceType[i].equals(parseUSN.getServiceType())))
- {
- vec.add(oldServiceType[i]);
+
+ //new serviceID
+ String[] actualServicesID = new String[vec.size()];
+ actualServicesID = (String[]) vec.toArray(new String[]{});
+
+ //new serviceType
+ String[] actualServiceType = new String[oldServiceType.length - 1];
+ vec.clear();
+ for (int i = 0; i < oldServiceType.length; i++) {
+ if (!(oldServiceType[i].equals(parseUSN.getServiceType())))
+ {
+ vec.add(oldServiceType[i]);
+ }
}
+ actualServiceType = (String[]) vec.toArray(new String[]{});
+
+ //unrigistering and registering again with the new properties
+ unregisterUPnPDevice(registar);
+ device.setProperty(UPnPService.ID, actualServicesID);
+ device.setProperty(UPnPService.TYPE, actualServiceType);
+ registerUPnPDevice(null, device, device.getDescriptions(null));
+ searchForListener(cyberDevice);
}
- actualServiceType = (String[]) vec.toArray(new String[]{});
-
- //unrigistering and registering again with the new properties
- unregisterUPnPDevice(registar);
- device.setProperty(UPnPService.ID, actualServicesID);
- device.setProperty(UPnPService.TYPE, actualServiceType);
- registerUPnPDevice(null, device, device.getDescriptions(null));
- searchForListener(cyberDevice);
}
- }
+
+ }//synchronized(devices)
} else {
/*
- * if it is a service means that it is beend delete when the
+ * if it is a service means that it has deleted when the
* owner was unregister so I can skip this bye-bye
+ *
+ * //TODO Understand the comment
+ *
*/
}
}
- public synchronized void removeOSGiandUPnPDeviceHierarchy(UPnPDeviceImpl dev)
+ public synchronized void removeOSGiandUPnPDeviceHierarchy(final UPnPDeviceImpl dev)
{
/*
* remove all the UPnPDevice from the struct of local device recursively
*/
+ final String udn = (String) dev.getDescriptions(null).get(UPnPDevice.UDN);
+
+ if(devices.containsKey(udn) == false){
+ Activator.logger.INFO("Device "+dev.getDescriptions(null).get(UPnPDevice.FRIENDLY_NAME)+"("+udn+") already removed");
+ return;
+ }
+
String[] childrenUDN = (String[]) dev.getDescriptions(null).get(
UPnPDevice.CHILDREN_UDN);
+
if (childrenUDN == null) {
- //no children
- unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(dev
- .getDescriptions(null).get(UPnPDevice.UDN)))
- .getRegistration());
- devices.remove(dev.getDescriptions(null).get(UPnPDevice.UDN));
+ //no children
+ unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(udn)).getRegistration());
+ Activator.logger.INFO("Device "+dev.getDescriptions(null).get(UPnPDevice.FRIENDLY_NAME)+"("+udn+") deleted");
+ devices.remove(udn);
return;
- }
- for (int i = 0; i < childrenUDN.length; i++) {
- if (devices.get(childrenUDN[i]) == null) {
- continue;
- } else {
- removeOSGiandUPnPDeviceHierarchy(((OSGiDeviceInfo) devices
- .get(childrenUDN[i])).getOSGiDevice());
+ } else {
+ for (int i = 0; i < childrenUDN.length; i++) {
+ if (devices.get(childrenUDN[i]) != null) {
+ removeOSGiandUPnPDeviceHierarchy(((OSGiDeviceInfo) devices.get(childrenUDN[i])).getOSGiDevice());
+ }
}
+ unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(udn)).getRegistration());
+ Activator.logger.INFO("Device "+dev.getDescriptions(null).get(UPnPDevice.FRIENDLY_NAME)+"("+udn+") deleted");
+ devices.remove(udn);
}
- unregisterUPnPDevice(((OSGiDeviceInfo) devices.get(dev.getDescriptions(
- null).get(UPnPDevice.UDN))).getRegistration());
- devices.remove(dev.getDescriptions(null).get(UPnPDevice.UDN));
}
public synchronized void removeOSGiExpireDevice(Device dev) {
@@ -788,6 +800,7 @@
device.setProperty(UPnPServiceImpl.TYPE,currentServicesType);
//registering the service with the updated properties
+ //TODO Check if null to the first paramaters is correct or it requires the reference to the cyberdomo upnp device
registerUPnPDevice(null, device, device.getDescriptions(null));
searchForListener(cyberDevice);
}
@@ -809,17 +822,21 @@
doDeviceRegistration(udn);
}
- public void doDeviceRegistration(String udn){
+ public synchronized void doDeviceRegistration(String udn){
/*
- * registering the new device even if it is new root device or
+ * registering the new device either if it is new root device or
* a new embedded device
*/
Device dev = findDeviceCtrl(this, udn);
if (dev == null) {
- Activator.logger.WARNING("Cyberlink notified packet from UDN:" +udn+ ", but Device instance doesn't exist in Cyberlink structs !");
- }
- if (dev != null) {
- Activator.logger.INFO("[Importer] registering UPnPDevice UDN:"+dev.getFriendlyName());
+ /*
+ * In this case the UPnP SDK notifies us that a ssdp:alive has arrived,
+ * but, because the no root device ssdp:alive packet has recieved by the UPnP SDK
+ * no Device is present in the UPnP SDK device list.
+ */
+ Activator.logger.INFO("Cyberlink notified packet from UDN:" +udn+ ", but Device instance doesn't exist in Cyberlink structs! It will be Ignored");
+ }else if(devices.containsKey(udn) == false) {
+ Activator.logger.INFO("[Importer] registering UPnPDevice:"+dev.getFriendlyName()+"("+dev.getUDN()+")" );
registerUPnPDevice(dev, null, null);
searchForListener(dev);
/*
@@ -831,7 +848,9 @@
Device d = (Device) i.next();
doDeviceRegistration(d.getUDN(),true);
}
- }
+ }else if(devices.containsKey(udn) == true) {
+ Activator.logger.INFO("[Importer] UPnPDevice UDN::"+dev.getFriendlyName()+"("+dev.getUDN()+") already registered Skipping");
+ }
}
public void searchForListener(Device device) {
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPIconImpl.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPIconImpl.java
index 57602c9..dba0d8a 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPIconImpl.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPIconImpl.java
@@ -54,7 +54,6 @@
* @see org.osgi.service.upnp.UPnPIcon#getWidth()
*/
public int getWidth() {
- //TODO what happen if the String is empty? do I get an Exception? I think so
String width=icon.getWidth();
if(width.length()==0){
return -1;
@@ -66,7 +65,6 @@
* @see org.osgi.service.upnp.UPnPIcon#getHeight()
*/
public int getHeight() {
- // TODO Auto-generated method stub
String higth=icon.getHeight();
if(higth.length()==0){
return -1;
@@ -86,7 +84,6 @@
* @see org.osgi.service.upnp.UPnPIcon#getDepth()
*/
public int getDepth() {
- // TODO Auto-generated method stub
String depth=icon.getDepth();
if(depth.length()==0){
return -1;
@@ -98,8 +95,6 @@
* @see org.osgi.service.upnp.UPnPIcon#getInputStream()
*/
public InputStream getInputStream() throws IOException {
- // TODO Auto-generated method stub
-
String urlString=ParseLocation.getUrlBase(cyberdev.getLocation())+icon.getURL();
URL url=new URL(urlString);
HTTPRequestForIcon requestor=new HTTPRequestForIcon(url);
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPServiceImpl.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPServiceImpl.java
index 7182640..40c7c26 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPServiceImpl.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/core/upnp/UPnPServiceImpl.java
@@ -33,7 +33,7 @@
import org.osgi.service.upnp.UPnPService;
import org.osgi.service.upnp.UPnPStateVariable;
-/*
+/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class UPnPServiceImpl implements UPnPService {
@@ -87,9 +87,10 @@
* @see org.osgi.service.upnp.UPnPService#getVersion()
*/
public String getVersion() {
- //TODO to check can I speed up this? May be using lastIndexOf
- String [] splited=service.getServiceType().split(":");
- return splited[splited.length-1];
+ String serviceType = service.getServiceType();
+ int start = serviceType.lastIndexOf(':');
+ String version = serviceType.substring(start+1);
+ return version;
}
/*
* (non-Javadoc)
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/HTTPRequestForIcon.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/HTTPRequestForIcon.java
index e662561..3c38cfc 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/HTTPRequestForIcon.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/HTTPRequestForIcon.java
@@ -22,7 +22,7 @@
import java.io.*;
import java.net.*;
-/*
+/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class HTTPRequestForIcon {
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseLocation.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseLocation.java
index 6262667..21c0c4f 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseLocation.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseLocation.java
@@ -19,12 +19,13 @@
package org.apache.felix.upnp.basedriver.importer.util;
-/*
+/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class ParseLocation {
public static String getUrlBase(String location){
- String [] splited=location.split("/");
- return splited[0]+"/"+"/"+splited[2];
+ String [] splited=StringSplitter.split(location, '/');
+ String value=splited[0]+"/"+"/"+splited[2];
+ return value;
}
}
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseUSN.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseUSN.java
index 5fc5858..c0194ac 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseUSN.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/ParseUSN.java
@@ -29,7 +29,7 @@
String serviceType;
public ParseUSN(String usn) {
- String [] splited=usn.split(":");
+ String [] splited=StringSplitter.split(usn, ':');
if(splited.length==5||splited.length==2){
udn="uuid:"+splited[1];
device=true;
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/StringSplitter.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/StringSplitter.java
new file mode 100644
index 0000000..9de4e95
--- /dev/null
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/importer/util/StringSplitter.java
@@ -0,0 +1,42 @@
+/*
+ * 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.basedriver.importer.util;
+
+import java.util.ArrayList;
+
+/**
+* The class is used only for JDK1.3 backporting purpose
+*
+* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+* @since 0.3
+*/
+public class StringSplitter {
+
+ public static String [] split (String tosplit, char ch){
+ ArrayList result = new ArrayList();
+ int pos = -1;
+ while ( (pos = tosplit.indexOf(ch)) != -1) {
+ result.add(new String (tosplit.substring(0, pos)));
+ tosplit = tosplit.substring(pos + 1);
+ }
+ if (!tosplit.equals("")) result.add(new String(tosplit));
+ return (String [])result.toArray(new String [0]);
+ }
+
+}
diff --git a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/tool/Util.java b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/tool/Util.java
index 3e4088d..29a42f3 100644
--- a/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/tool/Util.java
+++ b/upnp/basedriver/src/main/java/org/apache/felix/upnp/basedriver/tool/Util.java
@@ -60,10 +60,6 @@
return value;
}
- public static String sanitizeFilename(String name){
- return name.replaceAll("[:;\\,/*?<>\"|]","_");
- }
-
public static boolean makeParentPath(String filePath){
int l=filePath.lastIndexOf(File.separator);
filePath=filePath.substring(0,l);
diff --git a/upnp/extra/pom.xml b/upnp/extra/pom.xml
index da6de3a..fb209fb 100644
--- a/upnp/extra/pom.xml
+++ b/upnp/extra/pom.xml
@@ -11,7 +11,7 @@
<groupId>org.apache.felix</groupId>
<name>Apache Felix UPnP Extra </name>
<artifactId>org.apache.felix.upnp.extra</artifactId>
- <version>0.2.0-SNAPSHOT</version>
+ <version>0.3.0-SNAPSHOT</version>
<!-- <url>http://maven.apache.org</url> -->
<dependencies>
<dependency>
diff --git a/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Constants.java b/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Constants.java
index 4826434..8b8b993 100644
--- a/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Constants.java
+++ b/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Constants.java
@@ -25,7 +25,7 @@
/**
* If this property is set on a UPnP Device means that the
* device service is been created by UPnP base Driver. <br>
- * The value of the do not mean nothing. <br>
+ * The value of the does not carry any mean. <br>
* The name of the property is "UPnP.device.import".
*/
public static final String UPNP_IMPORT = "UPnP.device.imported";
diff --git a/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Converter.java b/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Converter.java
index 7fb0fca..4b68514 100644
--- a/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Converter.java
+++ b/upnp/extra/src/main/java/org/apache/felix/upnp/extra/util/Converter.java
@@ -27,7 +27,7 @@
import org.apache.xerces.impl.dv.util.HexBin;
import org.osgi.service.upnp.*;
-/*
+/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class Converter {
@@ -153,12 +153,11 @@
String[] timeFormats=new String[]{"HH:mm:ssZ","HH:mm:ss"};
Date d=getDateValue(value,timeFormats,timeFormats);
TimeZone tz = TimeZone.getDefault();
- int dst = tz.getDSTSavings();
Calendar c = Calendar.getInstance(tz);
c.setTime(d);
- if(timeFormats[0].equals("HH:mm:ssZ")&&(dst!=0))
- c.add(Calendar.MILLISECOND,dst);
+ if(timeFormats[0].equals("HH:mm:ssZ")&&(tz.inDaylightTime(d)))
+ c.add(Calendar.MILLISECOND,3600000);
return new Long(
c.get(Calendar.HOUR_OF_DAY)*3600000
+c.get(Calendar.MINUTE)*60000