FileDocCategorySizeDatePackage
UPnPRootDeviceImpl.javaAPI DocAzureus 3.0.3.49067Tue Sep 25 13:45:14 BST 2007com.aelitis.net.upnp.impl.device

UPnPRootDeviceImpl

public class UPnPRootDeviceImpl extends Object implements UPnPRootDevice
author
parg

Fields Summary
public static final String[]
ROUTERS
public static final String[]
BAD_ROUTER_VERSIONS
public static final boolean[]
BAD_ROUTER_REPORT_FAIL
private com.aelitis.net.upnp.impl.UPnPImpl
upnp
private NetworkInterface
network_interface
private InetAddress
local_address
private String
usn
private URL
location
private URL
url_base_for_relative_urls
private URL
saved_url_base_for_relative_urls
private String
info
private UPnPDeviceImpl
root_device
private boolean
port_mapping_result_received
private boolean
destroyed
private List
listeners
Constructors Summary
public UPnPRootDeviceImpl(com.aelitis.net.upnp.impl.UPnPImpl _upnp, NetworkInterface _network_interface, InetAddress _local_address, String _usn, URL _location)

	
	
	
					
			
					
						
							 
	
		 
	
		upnp				= _upnp;
		network_interface	= _network_interface;
		local_address		= _local_address;
		usn					= _usn;
		location			= _location;
		
		SimpleXMLParserDocument	doc = upnp.downloadXML( location );
			
		SimpleXMLParserDocumentNode url_base_node = doc.getChild("URLBase");
		
		try{
			if ( url_base_node != null ){
				
				String	url_str = url_base_node.getValue().trim();
			
					// url_str is sometimes blank
				
				if ( url_str.length() > 0 ){
					
					url_base_for_relative_urls = new URL(url_str);
				}
			}
			
			upnp.log( "Relative URL base is " + (url_base_for_relative_urls==null?"unspecified":url_base_for_relative_urls.toString()));
			
		}catch( MalformedURLException e ){
			
			upnp.log( "Invalid URLBase - " + (url_base_node==null?"mill":url_base_node.getValue()));
			
			upnp.log( e );
			
			Debug.printStackTrace( e );
		}
		
		SimpleXMLParserDocumentNode device = doc.getChild( "Device" );
		
		if ( device == null ){
			
			throw( new UPnPException( "Root device '" + usn + "(" + location + ") is missing the device description" ));
		}
		
		root_device = new UPnPDeviceImpl( this, "", device );
		
		info = root_device.getFriendlyName();
		
		String	version	= root_device.getModelNumber();
		
		if ( version != null ){
			
			info += "/" + version;
		}
	
Methods Summary
public voidaddListener(UPnPRootDeviceListener l)

		listeners.add( l );
	
protected synchronized voidclearRelativeBaseURL()

		if ( url_base_for_relative_urls != null ){
			
			saved_url_base_for_relative_urls 	= url_base_for_relative_urls;
			url_base_for_relative_urls			= null;
		}
	
public voiddestroy(boolean replaced)

		destroyed	= true;
		
		for (int i=0;i<listeners.size();i++){
			
			((UPnPRootDeviceListener)listeners.get(i)).lost( this, replaced);
		}
	
protected java.lang.StringgetAbsoluteURL(java.lang.String url)

		String	lc_url = url.toLowerCase().trim();
		
		if ( lc_url.startsWith( "http://") || lc_url.startsWith( "https://" )){
			
				// already absolute
			
			return( url );
		}
		
			// relative URL
		
		if ( url_base_for_relative_urls != null ){
			
			String	abs_url = url_base_for_relative_urls.toString();
			
			if ( !abs_url.endsWith("/")){
				
				abs_url += "/";
			}
			
			if ( url.startsWith("/")){
				
				abs_url += url.substring(1);
				
			}else{
				
				abs_url += url;
			}
			
			return( abs_url );
			
		}else{
		
				// base on the root document location
			
			String	abs_url = location.toString();
		
			int	p1 = abs_url.indexOf( "://" ) + 3;
			
			p1 = abs_url.indexOf( "/", p1 );
			
			abs_url = abs_url.substring( 0, p1 );
			
			return( abs_url + (url.startsWith("/")?"":"/") + url );
		}
	
public UPnPDevicegetDevice()

		return( root_device );
	
public java.lang.StringgetInfo()

		return( info );
	
public java.net.InetAddressgetLocalAddress()

		return( local_address );
	
public java.net.URLgetLocation()

		return( location );
	
public java.net.NetworkInterfacegetNetworkInterface()

		return( network_interface );
	
public UPnPgetUPnP()

		return( upnp );
	
public java.lang.StringgetUSN()

		return( usn  );
	
protected booleanisBadVersion(java.lang.String current, java.lang.String bad)

		if ( bad.equals( "any" )){
			
			return( true );
		}
			// comparator does A10 -vs- A9 correctly (i.e. 111 is > 20 )
		
		Comparator comp = upnp.getAdapter().getAlphanumericComparator();
		
		//Comparator comp = getAlphanumericComparator( true );
		
			// look for a delimiter (non alpha/numeric)
		
		Set	delimiters = new HashSet();
		
		char	current_delim 	= '1";
		char	bad_delim		= '1";
		
		for (int i=0;i<current.length();i++){
			
			char	c = current.charAt(i);
			
			if ( !Character.isLetterOrDigit( c )){
				
				delimiters.add( new Character( c ));
				
				current_delim = c;
			}
		}
		
		for (int i=0;i<bad.length();i++){
			
			char	c = bad.charAt(i);
			
			if ( !Character.isLetterOrDigit( c )){
				
				delimiters.add( new Character( c ));
				
				bad_delim = c;
			}
		}
		
		if ( 	delimiters.size() != 1 || 
				current_delim != bad_delim ){
			
			return( comp.compare( current, bad ) <= 0 );
		}
		
		StringTokenizer	current_tk 	= new StringTokenizer( current, ""+current_delim );
		StringTokenizer	bad_tk 		= new StringTokenizer( bad, ""+bad_delim );
		
		int	num_current = current_tk.countTokens();
		int	num_bad		= bad_tk.countTokens();
		
		for (int i=0;i<Math.min( num_current, num_bad);i++){
			
			String	current_token 	= current_tk.nextToken();
			String	bad_token 		= bad_tk.nextToken();
			
			int	res = comp.compare( current_token, bad_token );
			
			if ( res != 0 ){
				
				return( res < 0 );
			}
		}
		
		return( num_current <= num_bad );
	
public booleanisDestroyed()

		return( destroyed );
	
public voidportMappingResult(boolean ok)

		if ( port_mapping_result_received ){
			
			return;
		}
		
		port_mapping_result_received	= true;
		
		if ( ok ){
			
			info += "/OK";
			
		}else{

			info += "/Failed";
		}
		
		String	model 	= root_device.getModelName();
		String	version	= root_device.getModelNumber();
		
		if ( model == null || version == null ){
			
			return;
		}
			
		for (int i=0;i<ROUTERS.length;i++){
			
			if ( ROUTERS[i].equals( model )){
				
				if ( isBadVersion( version, BAD_ROUTER_VERSIONS[i])){
					
					boolean	report_on_fail = BAD_ROUTER_REPORT_FAIL[i];
					
					if ( report_on_fail && ok ){
						
						// don't warn here, only warn on failures
						
					}else{
						
						String	url = root_device.getModeURL();
						
						upnp.logAlert( 
								"Device '" + model + "', version '" + version + 
								"' has known problems with UPnP. Please update to the latest software version (see " + 
								(url==null?"the manufacturer's web site":url) + ") and refer to http://azureus.aelitis.com/wiki/index.php/UPnP",
								false,
								UPnPLogListener.TYPE_ONCE_EVER );
					}
					
					break;
				}
			}
		}
	
public voidremoveListener(UPnPRootDeviceListener l)

		listeners.remove( l );
	
protected synchronized voidrestoreRelativeBaseURL()

		if ( saved_url_base_for_relative_urls != null ){
			
			url_base_for_relative_urls			= saved_url_base_for_relative_urls;
			saved_url_base_for_relative_urls	= null;
		}