diff --git a/.classpath b/.classpath index 5914b4c04..9ba33e500 100644 --- a/.classpath +++ b/.classpath @@ -37,6 +37,7 @@ + diff --git a/build.xml b/build.xml index 35280ef78..9d208e134 100644 --- a/build.xml +++ b/build.xml @@ -196,12 +196,13 @@ - + + - + profile = null; if (hash.equals("localhash")) { // read the profile from local peer final Properties p = new Properties(); @@ -84,8 +82,8 @@ public class ViewProfile { } catch(final IOException e) {} finally { if (fileIn != null) try { fileIn.close(); fileIn = null; } catch (final Exception e) {} } - profile = new HashMap(); - profile.putAll(p); + profile = new HashMap(); + for (Map.Entry e: p.entrySet()) profile.put((String) e.getKey(), (String) e.getValue()); prop.put("success", "3"); // everything ok prop.put("localremotepeer", "0"); prop.putHTML("success_peername", sb.peers.mySeed().getName()); @@ -121,13 +119,13 @@ public class ViewProfile { } prop.put("localremotepeer", "1"); } - Iterator i; + Iterator> i; if (profile != null) { i = profile.entrySet().iterator(); } else { - i = (new ArrayList()).iterator(); + i = (new HashMap()).entrySet().iterator(); } - Map.Entry entry; + Map.Entry entry; // all known keys which should be set as they are final HashSet knownKeys = new HashSet(); knownKeys.add("name"); @@ -150,12 +148,12 @@ public class ViewProfile { //number of not explicitly recognized but displayed items int numUnknown = 0; while (i.hasNext()) { - entry = (Map.Entry) i.next(); - final String key = ((String) entry.getKey()); + entry = i.next(); + final String key = entry.getKey(); String value; // this prevents broken links ending in
- value=((String) entry.getValue()).replaceAll("\r", "").replaceAll("\\\\n", "\n"); + value = entry.getValue().replaceAll("\r", "").replaceAll("\\\\n", "\n"); //all known Keys which should be set as they are if (knownKeys.contains(key)) { @@ -165,8 +163,8 @@ public class ViewProfile { if(key.equals("comment")){ prop.putWiki( "success_" + key + "_value", - ((String) entry.getValue()).replaceAll("\r", "").replaceAll("\\\\n", "\n")); - prop.put("success_" + key + "_b64value",Base64Order.standardCoder.encodeString((String) entry.getValue())); + entry.getValue().replaceAll("\r", "").replaceAll("\\\\n", "\n")); + prop.put("success_" + key + "_b64value", Base64Order.standardCoder.encodeString(entry.getValue())); }else{ prop.putHTML("success_" + key + "_value", value); //put replaces HTML Chars by entities. } diff --git a/lib/sbbi-upnplib-1.0.4.jar b/lib/sbbi-upnplib-1.0.4.jar new file mode 100644 index 000000000..271e919c7 Binary files /dev/null and b/lib/sbbi-upnplib-1.0.4.jar differ diff --git a/source/de/anomic/http/client/Client.java b/source/de/anomic/http/client/Client.java index cc1a4e1ba..b58e956db 100644 --- a/source/de/anomic/http/client/Client.java +++ b/source/de/anomic/http/client/Client.java @@ -25,14 +25,11 @@ // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA package de.anomic.http.client; - -import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import java.util.Map.Entry; -import java.util.zip.GZIPOutputStream; import net.yacy.cora.document.MultiProtocolURI; import net.yacy.cora.protocol.ProxySettings; @@ -47,7 +44,6 @@ import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.MultiThreadedHttpConnectionManager; import org.apache.commons.httpclient.URIException; import org.apache.commons.httpclient.cookie.CookiePolicy; -import org.apache.commons.httpclient.methods.ByteArrayRequestEntity; import org.apache.commons.httpclient.methods.HeadMethod; import org.apache.commons.httpclient.methods.InputStreamRequestEntity; import org.apache.commons.httpclient.methods.PostMethod; @@ -343,6 +339,7 @@ public class Client { * @return a ByteArrayRequestEntitiy with gzipped data * @throws IOException */ + /* private RequestEntity zipRequest(final RequestEntity data) throws IOException { // cache data and gzip it final ByteArrayOutputStream zippedBytes = new ByteArrayOutputStream(512); @@ -353,7 +350,7 @@ public class Client { // use compressed data as body (not setting content length according to RFC 2616 HTTP/1.1, section 4.4) return new ByteArrayRequestEntity(zippedBytes.toByteArray(), data.getContentType()); } - + */ /* * (non-Javadoc) * @see de.anomic.http.HttpClient#CONNECT(java.lang.String, int, de.anomic.http.httpHeader) diff --git a/source/de/anomic/yacy/Tray.java b/source/de/anomic/yacy/Tray.java index f34c058f4..2760cc4b1 100644 --- a/source/de/anomic/yacy/Tray.java +++ b/source/de/anomic/yacy/Tray.java @@ -189,8 +189,7 @@ class nativeTrayIcon { } - @SuppressWarnings("unchecked") - public nativeTrayIcon(String IconPath, ActionListener al, PopupMenu menu) { + public nativeTrayIcon(String IconPath, ActionListener al, PopupMenu menu) { if(!isSupported()) return; final Image i = Toolkit.getDefaultToolkit().getImage(IconPath); @@ -200,11 +199,11 @@ class nativeTrayIcon { this.SystemTrayClass = Class.forName("java.awt.SystemTray"); // with reflections: this.TrayIcon = new TrayIcon(i, "YaCy"); - Class partypes1[] = new Class[3]; + Class partypes1[] = new Class[3]; partypes1[0] = Image.class; partypes1[1] = String.class; partypes1[2] = PopupMenu.class; - Constructor TrayIconConstructor = TrayIconClass.getConstructor(partypes1); + Constructor TrayIconConstructor = TrayIconClass.getConstructor(partypes1); Object arglist1[] = new Object[3]; arglist1[0] = i; @@ -213,7 +212,7 @@ class nativeTrayIcon { this.TrayIcon = TrayIconConstructor.newInstance(arglist1); // with reflections: this.TrayIcon.setImageAutoSize(true) - Class partypes2[] = new Class[1]; + Class partypes2[] = new Class[1]; partypes2[0] = Boolean.TYPE; Method setImageAutoSizeMethod = TrayIconClass.getMethod("setImageAutoSize", partypes2); @@ -222,7 +221,7 @@ class nativeTrayIcon { setImageAutoSizeMethod.invoke(this.TrayIcon, arglist2); // with reflections: this.TrayIcon.addActionListener(al) - Class partypes3[] = new Class[1]; + Class partypes3[] = new Class[1]; partypes3[0] = ActionListener.class; Method addActionListenerMethod = TrayIconClass.getMethod("addActionListener", partypes3); @@ -241,11 +240,10 @@ class nativeTrayIcon { } } - @SuppressWarnings("unchecked") public void addToSystemTray() { try { // with reflections: this.SystemTray.add(this.TrayIcon) - Class partypes1[] = new Class[1]; + Class partypes1[] = new Class[1]; partypes1[0] = TrayIconClass; Method addMethod = SystemTrayClass.getMethod("add", partypes1); @@ -257,11 +255,10 @@ class nativeTrayIcon { } } - @SuppressWarnings("unchecked") public void removeFromSystemTray() { try { // with reflections: this.SystemTray.remove(this.TrayIcon) - Class partypes1[] = new Class[1]; + Class partypes1[] = new Class[1]; partypes1[0] = TrayIconClass; Method removeMethod = SystemTrayClass.getMethod("remove", partypes1); @@ -273,11 +270,10 @@ class nativeTrayIcon { } } - @SuppressWarnings("unchecked") public void displayBalloonMessage(final String title, final String message) { try { // with reflections: this.TrayIcon.displayBalloonMessage(title, message, TrayIcon.MessageType.NONE) - Class partypes1[] = new Class[3]; + Class partypes1[] = new Class[3]; partypes1[0] = String.class; partypes1[1] = String.class; partypes1[2] = Class.forName("java.awt.TrayIcon.MessageType"); diff --git a/source/de/anomic/yacy/yacySearch.java b/source/de/anomic/yacy/yacySearch.java index 8922a53aa..d85aa66d0 100644 --- a/source/de/anomic/yacy/yacySearch.java +++ b/source/de/anomic/yacy/yacySearch.java @@ -328,7 +328,6 @@ public class yacySearch extends Thread { if (searchThreads == null) return 0; int alive = 0; for (int i = 0; i < searchThreads.length; i++) { - if (searchThreads == null) break; // may occur if (searchThreads[i].isAlive()) alive++; } return alive; diff --git a/source/net/sbbi/upnp/Discovery.java b/source/net/sbbi/upnp/Discovery.java deleted file mode 100644 index 0bdcd8622..000000000 --- a/source/net/sbbi/upnp/Discovery.java +++ /dev/null @@ -1,264 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.Inet4Address; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.NetworkInterface; -import java.net.URL; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; - -import net.sbbi.upnp.devices.UPNPRootDevice; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Class to discover an UPNP device on the network.
- * A multicast socket will be created to discover devices, the binding port for this socket is set to 1901, - * if this is causing a problem you can use the net.sbbi.upnp.Discovery.bindPort system property - * to specify another port. - * The discovery methods only accept matching device description and broadcast message response IP - * to avoid a security flaw with the protocol. If you are not happy with such behaviour - * you can set the net.sbbi.upnp.ddos.matchip system property to false to avoid this check. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class Discovery { - - final static Log log = LogFactory.getLog( Discovery.class ); - - public final static String ROOT_DEVICES = "upnp:rootdevice"; - public final static String ALL_DEVICES = "ssdp:all"; - - public static final int DEFAULT_MX = 3; - public static final int DEFAULT_TTL = 4; - public static final int DEFAULT_TIMEOUT = 1500; - public static final String DEFAULT_SEARCH = ALL_DEVICES; - public static final int DEFAULT_SSDP_SEARCH_PORT = 1901; - - public final static String SSDP_IP = "239.255.255.250"; - public final static int SSDP_PORT = 1900; - - /** - * Devices discovering on all network interfaces with default values, all root devices will be searched - * @return an array of UPNP Root device or null if nothing found with the default timeout. - * Null does NOT means that no UPNP device is available on the network. It only means - * that for this default timeout no devices responded or that effectively no devices - * are available at all. - * @throws IOException if some IOException occurs during discovering - */ - public static UPNPRootDevice[] discover() throws IOException { - return discover( DEFAULT_TIMEOUT, DEFAULT_TTL, DEFAULT_MX, DEFAULT_SEARCH ); - } - - /** - * Devices discovering on all network interfaces with a given root device to search - * @param searchTarget the device URI to search - * @return an array of UPNP Root device that matches the search or null if nothing found with the default timeout. - * Null does NOT means that no UPNP device is available on the network. It only means - * that for this given timeout no devices responded or that effectively no devices - * are available at all. - * @throws IOException if some IOException occurs during discovering - */ - public static UPNPRootDevice[] discover( String searchTarget ) throws IOException { - return discover( DEFAULT_TIMEOUT, DEFAULT_TTL, DEFAULT_MX, searchTarget ); - } - - /** - * Devices discovering on all network interfaces with a given timeout and a given root device to search - * @param timeOut the time allowed for a device to give a response - * @param searchTarget the device URI to search - * @return an array of UPNP Root device that matches the search or null if nothing found with the given timeout. - * Null does NOT means that no UPNP device is available on the network. It only means - * that for this given timeout no devices responded or that effectively no devices - * are available at all. - * @throws IOException if some IOException occurs during discovering - */ - public static UPNPRootDevice[] discover( int timeOut, String searchTarget ) throws IOException { - return discover( timeOut, DEFAULT_TTL, DEFAULT_MX, searchTarget ); - } - - /** - * Devices discovering on all network interfaces with a given timeout and a given root device to search, as well as a ttl and mx param - * @param timeOut the timeout for the a device to give a reponse - * @param ttl the UDP socket packets time to live - * @param mx discovery message mx http header field value - * @param searchTarget the device URI to search - * @return an array of UPNP Root device that matches the search or null if nothing found within the given timeout. - * Null return does NOT means that no UPNP device is available on the network. It only means - * that for this given timeout no devices responded or that effectively no devices - * are available at all. - * @throws IOException if some IOException occurs during discovering - */ - public static UPNPRootDevice[] discover( int timeOut, int ttl, int mx, String searchTarget ) throws IOException { - return discoverDevices( timeOut, ttl, mx, searchTarget, null ); - } - - /** - * Devices discovering with a given timeout and a given root device to search on an given network interface, as well as a ttl and mx param - * @param timeOut the timeout for the a device to give a reponse - * @param ttl the UDP socket packets time to live - * @param mx discovery message mx http header field value - * @param searchTarget the device URI to search - * @param ni the networkInterface where to search devices, null to lookup all interfaces - * @return an array of UPNP Root device that matches the search or null if nothing found within the given timeout. - * Null return does NOT means that no UPNP device is available on the network. It only means - * that for this given timeout no devices responded or that effectively no devices - * are available at all. - * @throws IOException if some IOException occurs during discovering - */ - public static UPNPRootDevice[] discover( int timeOut, int ttl, int mx, String searchTarget, NetworkInterface ni ) throws IOException { - return discoverDevices( timeOut, ttl, mx, searchTarget, ni ); - } - - private static UPNPRootDevice[] discoverDevices( int timeOut, int ttl, int mx, String searchTarget, NetworkInterface ni ) throws IOException { - if ( searchTarget == null || searchTarget.trim().length() == 0 ) { - throw new IllegalArgumentException( "Illegal searchTarget" ); - } - - final Map devices = new HashMap(); - - DiscoveryResultsHandler handler = new DiscoveryResultsHandler() { - - public void discoveredDevice( String usn, String udn, String nt, String maxAge, URL location, String firmware ) { - synchronized( devices ) { - if ( ! devices.containsKey( usn ) ) { - try { - UPNPRootDevice device = new UPNPRootDevice( location, maxAge, firmware, usn, udn ); - devices.put( usn, device ); - } catch ( Exception ex ) { - log.error( "Error occured during upnp root device object creation from location " + location, ex ); - } - } - } - } - }; - - DiscoveryListener.getInstance().registerResultsHandler( handler, searchTarget ); - if ( ni == null ) { - for ( Enumeration e = NetworkInterface.getNetworkInterfaces(); e.hasMoreElements(); ) { - NetworkInterface intf = (NetworkInterface)e.nextElement(); - for ( Enumeration adrs = intf.getInetAddresses(); adrs.hasMoreElements(); ) { - InetAddress adr = (InetAddress)adrs.nextElement(); - if ( adr instanceof Inet4Address && !adr.isLoopbackAddress() ) { - sendSearchMessage( adr, ttl, mx, searchTarget ); - } - } - } - } else { - for ( Enumeration adrs = ni.getInetAddresses(); adrs.hasMoreElements(); ) { - InetAddress adr = (InetAddress)adrs.nextElement(); - if ( adr instanceof Inet4Address && !adr.isLoopbackAddress() ) { - sendSearchMessage( adr, ttl, mx, searchTarget ); - } - } - } - - try { - Thread.sleep( timeOut ); - } catch ( InterruptedException ex ) { - // don't care - } - - DiscoveryListener.getInstance().unRegisterResultsHandler( handler, searchTarget ); - - if ( devices.size() == 0 ) { - return null; - } - int j = 0; - UPNPRootDevice[] rootDevices = new UPNPRootDevice[devices.size()]; - for ( Iterator i = devices.values().iterator(); i.hasNext(); ) { - rootDevices[j++] = (UPNPRootDevice)i.next(); - } - return rootDevices; - - } - - /** - * Sends an SSDP search message on the network - * @param src the sender ip - * @param ttl the time to live - * @param mx the mx field - * @param searchTarget the search target - * @throws IOException if some IO errors occurs during search - */ - public static void sendSearchMessage( InetAddress src, int ttl, int mx, String searchTarget ) throws IOException { - - int bindPort = DEFAULT_SSDP_SEARCH_PORT; - String port = System.getProperty( "net.sbbi.upnp.Discovery.bindPort" ); - if ( port != null ) { - bindPort = Integer.parseInt( port ); - } - InetSocketAddress adr = new InetSocketAddress( InetAddress.getByName( Discovery.SSDP_IP ), Discovery.SSDP_PORT ); - - java.net.MulticastSocket skt = new java.net.MulticastSocket( null ); - skt.bind( new InetSocketAddress( src, bindPort ) ); - skt.setTimeToLive( ttl ); - StringBuffer packet = new StringBuffer(); - packet.append( "M-SEARCH * HTTP/1.1\r\n" ); - packet.append( "HOST: 239.255.255.250:1900\r\n" ); - packet.append( "MAN: \"ssdp:discover\"\r\n" ); - packet.append( "MX: ").append( mx ).append( "\r\n" ); - packet.append( "ST: " ).append( searchTarget ).append( "\r\n" ).append( "\r\n" ); - if ( log.isDebugEnabled() ) log.debug( "Sending discovery message on 239.255.255.250:1900 multicast address form ip " + src.getHostAddress() + ":\n" + packet.toString() ); - String toSend = packet.toString(); - byte[] pk = toSend.getBytes(); - skt.send( new DatagramPacket( pk, pk.length, adr ) ); - skt.disconnect(); - skt.close(); - } - -} diff --git a/source/net/sbbi/upnp/DiscoveryAdvertisement.java b/source/net/sbbi/upnp/DiscoveryAdvertisement.java deleted file mode 100644 index 227e9d314..000000000 --- a/source/net/sbbi/upnp/DiscoveryAdvertisement.java +++ /dev/null @@ -1,389 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ - -// [MC] (C) (also) by Michael Christen: added timeout for discovery - -package net.sbbi.upnp; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * SSDP messages listener Thread, notify registered objects implementing the interface DiscoveryEventHandler
- * when a device joins the networks or leaves it.
- * The listener thread is set to only accept matching device description and broadcast message sender IP - * to avoid a security flaw with the protocol. If you are not happy with such behaviour - * you can set the net.sbbi.upnp.ddos.matchip system property to false to avoid this check. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public final class DiscoveryAdvertisement implements Runnable { - - private final static Log log = LogFactory.getLog( DiscoveryAdvertisement.class ); - - private static boolean MATCH_IP = true; - - static { - String prop = System.getProperty( "net.sbbi.upnp.ddos.matchip" ); - if ( prop != null && prop.equals( "false" ) ) MATCH_IP = false; - } - - private static final int DEFAULT_TIMEOUT = 250; - - public final static int EVENT_SSDP_ALIVE = 0; - public final static int EVENT_SSDP_BYE_BYE = 1; - - private final static String NTS_SSDP_ALIVE = "ssdp:alive"; - private final static String NTS_SSDP_BYE_BYE = "ssdp:byebye"; - private final static String NT_ALL_EVENTS = "DiscoveryAdvertisement:nt:allevents"; - - private final Map byeByeRegistered = new HashMap(); - private final Map aliveRegistered = new HashMap(); - private final Map USNPerIP = new HashMap(); - - private final Object REGISTRATION_PROCESS = new Object(); - - private final static DiscoveryAdvertisement singleton = new DiscoveryAdvertisement(); - private boolean inService = false; - private boolean daemon = true; - - private java.net.MulticastSocket skt; - private DatagramPacket input; - private int timeout; - - private DiscoveryAdvertisement() { - this.timeout = 3000; - } - - private DiscoveryAdvertisement(int timeout) { - this.timeout = timeout; - } - - public final static DiscoveryAdvertisement getInstance() { - return singleton; - } - - public void setDaemon( boolean daemon ) { - this.daemon = daemon; - } - - /** - * Registers an event category sent by UPNP devices - * @param notificationEvent the event type, either DiscoveryAdvertisement.EVENT_SSDP_ALIVE - * or DiscoveryAdvertisement.EVENT_SSDP_BYE_BYE - * @param nt the type of device advertisement, upnp:rootdevice will return you all advertisement in relation with nt upnp:rootdevice - * a null value specify that all nt type are wanted - * @param eventHandler the events handler, this objet will receive notifications.. - * @throws IOException if an error ocurs when the SSDP events listeners threads starts - */ - public void registerEvent( int notificationEvent, String nt, DiscoveryEventHandler eventHandler ) throws IOException { - synchronized( REGISTRATION_PROCESS ) { - if ( !inService ) startDevicesListenerThread(); - if ( nt == null ) nt = NT_ALL_EVENTS; - if ( notificationEvent == EVENT_SSDP_ALIVE ) { - Set handlers = (Set)aliveRegistered.get( nt ); - if ( handlers == null ) { - handlers = new HashSet(); - aliveRegistered.put( nt, handlers ); - } - handlers.add( eventHandler ); - } else if ( notificationEvent == EVENT_SSDP_BYE_BYE ) { - Set handlers = (Set)byeByeRegistered.get( nt ); - if ( handlers == null ) { - handlers = new HashSet(); - byeByeRegistered.put( nt, handlers ); - } - handlers.add( eventHandler ); - } else { - throw new IllegalArgumentException( "Unknown notificationEvent type" ); - } - } - } - - /** - * Unregisters an event category sent by UPNP devices - * @param notificationEvent the event type, either DiscoveryAdvertisement.EVENT_SSDP_ALIVE - * or DiscoveryAdvertisement.EVENT_SSDP_BYE_BYE - * @param nt the type of device advertisement, upnp:rootdevice will unregister all advertisement in relation with nt upnp:rootdevice - * a null value specify that all nt type are unregistered - * @param eventHandler the events handler that needs to be unregistred. - */ - public void unRegisterEvent( int notificationEvent, String nt, DiscoveryEventHandler eventHandler ) { - synchronized( REGISTRATION_PROCESS ) { - if ( nt == null ) nt = NT_ALL_EVENTS; - if ( notificationEvent == EVENT_SSDP_ALIVE ) { - Set handlers = (Set)aliveRegistered.get( nt ); - if ( handlers != null ) { - handlers.remove( eventHandler ); - if ( handlers.size() == 0 ) { - aliveRegistered.remove( nt ); - } - } - } else if ( notificationEvent == EVENT_SSDP_BYE_BYE ) { - Set handlers = (Set)byeByeRegistered.get( nt ); - if ( handlers != null ) { - handlers.remove( eventHandler ); - if ( handlers.size() == 0 ) { - byeByeRegistered.remove( nt ); - } - } - } else { - throw new IllegalArgumentException( "Unknown notificationEvent type" ); - } - if ( aliveRegistered.size() == 0 && byeByeRegistered.size() == 0 ) { - stopDevicesListenerThread(); - } - } - } - - private void startDevicesListenerThread() throws IOException { - synchronized( singleton ) { - if ( !inService ) { - this.startMultiCastSocket(); - Thread deamon = new Thread( this, "DiscoveryAdvertisement daemon" ); - deamon.setDaemon( daemon ); - deamon.start(); - // wait for the thread to be started - while( !inService ) { - // let's wait a few ms - try { - Thread.sleep( 2 ); - } catch( InterruptedException ex ) { - // don t care - } - } - } - } - } - - private void stopDevicesListenerThread() { - synchronized( singleton ) { - inService = false; - } - } - - private void startMultiCastSocket() throws IOException { - - skt = new java.net.MulticastSocket( null ); - skt.bind( new InetSocketAddress( InetAddress.getByName( "0.0.0.0" ), Discovery.SSDP_PORT ) ); - skt.setTimeToLive( Discovery.DEFAULT_TTL ); - skt.setSoTimeout( DEFAULT_TIMEOUT ); - skt.joinGroup( InetAddress.getByName( Discovery.SSDP_IP ) ); - - byte[] buf = new byte[2048]; - input = new DatagramPacket( buf, buf.length ); - - } - - public void run() { - if ( !Thread.currentThread().getName().equals( "DiscoveryAdvertisement daemon" ) ) { - throw new RuntimeException( "No right to call this method" ); - } - inService = true; - while ( inService ) { - try { - listenBroadCast(this.timeout); - } catch ( SocketTimeoutException ex ) { - // ignoring - } catch ( IOException ioEx ) { - log.error( "IO Exception during UPNP DiscoveryAdvertisement messages listening thread", ioEx ); - } catch( Exception ex ) { - log.error( "Fatal Error during UPNP DiscoveryAdvertisement messages listening thread, thread will exit", ex ); - inService = false; - aliveRegistered.clear(); - byeByeRegistered.clear(); - USNPerIP.clear(); - } - } - - try { - skt.leaveGroup( InetAddress.getByName( Discovery.SSDP_IP ) ); - skt.close(); - } catch ( Exception ex ) { - // ignoring - } - } - - private void listenBroadCast(int timeout) throws IOException { - - skt.setSoTimeout(timeout); // added by [MC] - skt.receive( input ); - InetAddress from = input.getAddress(); - String received = new String( input.getData(), input.getOffset(), input.getLength() ); - HttpResponse msg = null; - try { - msg = new HttpResponse( received ); - } catch (IllegalArgumentException ex ) { - // crappy http sent - if ( log.isDebugEnabled() ) log.debug( "Skipping uncompliant HTTP message " + received ); - return; - } - String header = msg.getHeader(); - if ( header != null && header.startsWith( "NOTIFY" ) ) { - if ( log.isDebugEnabled() ) log.debug( received ); - String ntsField = msg.getHTTPHeaderField( "nts" ); - if( ntsField == null || ntsField.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'ntsField' field" ); - return; - } - if ( ntsField.equals( NTS_SSDP_ALIVE ) ) { - String deviceDescrLoc = msg.getHTTPHeaderField( "location" ); - if( deviceDescrLoc == null || deviceDescrLoc.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'location' field" ); - return; - } - URL loc = new URL( deviceDescrLoc ); - if ( MATCH_IP ) { - InetAddress locHost = InetAddress.getByName( loc.getHost() ); - if ( !from.equals( locHost ) ) { - log.warn( "Discovery message sender IP " + from + - " does not match device description IP " + locHost + - " skipping message, set the net.sbbi.upnp.ddos.matchip system property" + - " to false to avoid this check" ); - return; - } - } - - String nt = msg.getHTTPHeaderField( "nt" ); - if( nt == null || nt.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'nt' field" ); - return; - } - String maxAge = msg.getHTTPFieldElement( "Cache-Control", "max-age" ); - if( maxAge == null || maxAge.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'max-age' field" ); - return; - } - String usn = msg.getHTTPHeaderField( "usn" ); - if( usn == null || usn.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'usn' field" ); - return; - } - - USNPerIP.put( usn, from ); - String udn = usn; - int index = udn.indexOf( "::" ); - if ( index != -1 ) udn = udn.substring( 0, index ); - synchronized( REGISTRATION_PROCESS ) { - Set handlers = (Set)aliveRegistered.get( NT_ALL_EVENTS ); - if ( handlers != null ) { - for ( Iterator i = handlers.iterator(); i.hasNext(); ) { - DiscoveryEventHandler eventHandler = (DiscoveryEventHandler)i.next(); - eventHandler.eventSSDPAlive( usn, udn, nt, maxAge, loc ); - } - } - handlers = (Set)aliveRegistered.get( nt ); - if ( handlers != null ) { - for ( Iterator i = handlers.iterator(); i.hasNext(); ) { - DiscoveryEventHandler eventHandler = (DiscoveryEventHandler)i.next(); - eventHandler.eventSSDPAlive( usn, udn, nt, maxAge, loc ); - } - } - } - } else if ( ntsField.equals( NTS_SSDP_BYE_BYE ) ) { - String usn = msg.getHTTPHeaderField( "usn" ); - if( usn == null || usn.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'usn' field" ); - return; - } - String nt = msg.getHTTPHeaderField( "nt" ); - if( nt == null || nt.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'nt' field" ); - return; - } - - InetAddress originalAliveSenderIp = (InetAddress)USNPerIP.get( usn ); - if ( originalAliveSenderIp != null ) { - // we check that the sender ip of message for the usn - // match the sender ip of the alive message for wich the usn - // has been received - if ( !originalAliveSenderIp.equals( from ) ) { - // someone else is trying to say that the usn is leaving - // since IP do not match we skip the message - return; - } - } - - String udn = usn; - int index = udn.indexOf( "::" ); - if ( index != -1 ) udn = udn.substring( 0, index ); - synchronized( REGISTRATION_PROCESS ) { - Set handlers = (Set)byeByeRegistered.get( NT_ALL_EVENTS ); - if ( handlers != null ) { - for ( Iterator i = handlers.iterator(); i.hasNext(); ) { - DiscoveryEventHandler eventHandler = (DiscoveryEventHandler)i.next(); - eventHandler.eventSSDPByeBye( usn, udn, nt ); - } - } - handlers = (Set)byeByeRegistered.get( nt ); - if ( handlers != null ) { - for ( Iterator i = handlers.iterator(); i.hasNext(); ) { - DiscoveryEventHandler eventHandler = (DiscoveryEventHandler)i.next(); - eventHandler.eventSSDPByeBye( usn, udn, nt ); - } - } - } - } else { - log.warn( "Unvalid NTS field value (" + ntsField + ") received in NOTIFY message :" + received ); - } - } - } -} diff --git a/source/net/sbbi/upnp/DiscoveryEventHandler.java b/source/net/sbbi/upnp/DiscoveryEventHandler.java deleted file mode 100644 index 1685a6daa..000000000 --- a/source/net/sbbi/upnp/DiscoveryEventHandler.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -/** - * Interface for object that want to receive events from the - * DiscoveryAdvertisement thread - * @author SuperBonBon - * @version 1.0 - */ - -public interface DiscoveryEventHandler { - - /** - * Called when a device joins the network or advertise it is still alive - * @param usn the device USN (udn::nt) - * @param udn the device UDN - * @param nt the device NT - * @param maxAge the device maxAge - * @param location the device location - */ - public void eventSSDPAlive( String usn, String udn, String nt, String maxAge, java.net.URL location ); - - /** - * Called when a device is leaving the network - * @param usn the device USN (udn::nt) - * @param udn the device UDN - * @param nt the device NT - */ - public void eventSSDPByeBye( String usn, String udn, String nt ); -} diff --git a/source/net/sbbi/upnp/DiscoveryListener.java b/source/net/sbbi/upnp/DiscoveryListener.java deleted file mode 100644 index da5ec04eb..000000000 --- a/source/net/sbbi/upnp/DiscoveryListener.java +++ /dev/null @@ -1,290 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -import java.io.IOException; -import java.net.DatagramPacket; -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.SocketTimeoutException; -import java.net.URL; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This class can be used to listen for UPNP devices responses when a search message is sent by a control point - * ( using the net.sbbi.upnp.Discovery.sendSearchMessage() method ) - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public final class DiscoveryListener implements Runnable { - - private final static Log log = LogFactory.getLog( DiscoveryListener.class ); - - private static boolean MATCH_IP = true; - - static { - String prop = System.getProperty( "net.sbbi.upnp.ddos.matchip" ); - if ( prop != null && prop.equals( "false" ) ) MATCH_IP = false; - } - - private static final int DEFAULT_TIMEOUT = 250; - - private final Map registeredHandlers = new HashMap(); - - private final Object REGISTRATION_PROCESS = new Object(); - - private final static DiscoveryListener singleton = new DiscoveryListener(); - - private boolean inService = false; - private boolean daemon = true; - - private java.net.MulticastSocket skt; - private DatagramPacket input; - - private DiscoveryListener() { - } - - public final static DiscoveryListener getInstance() { - return singleton; - } - - /** - * Sets the listener as a daemon thread - * @param daemon daemon thread - */ - public void setDaemon( boolean daemon ) { - this.daemon = daemon; - } - - /** - * Registers an SSDP response message handler - * @param resultsHandler the SSDP response message handler - * @param searchTarget the search target - * @throws IOException if some errors occurs during SSDP search response messages listener thread startup - */ - public void registerResultsHandler( DiscoveryResultsHandler resultsHandler, String searchTarget ) throws IOException { - synchronized( REGISTRATION_PROCESS ) { - if ( !inService ) startDevicesListenerThread(); - Set handlers = (Set)registeredHandlers.get( searchTarget ); - if ( handlers == null ) { - handlers = new HashSet(); - registeredHandlers.put( searchTarget, handlers ); - } - handlers.add( resultsHandler ); - } - } - - /** - * Unregisters an SSDP response message handler - * @param resultsHandler the SSDP response message handler - * @param searchTarget the search target - */ - public void unRegisterResultsHandler( DiscoveryResultsHandler resultsHandler, String searchTarget ) { - synchronized( REGISTRATION_PROCESS ) { - Set handlers = (Set)registeredHandlers.get( searchTarget ); - if ( handlers != null ) { - handlers.remove( resultsHandler ); - if ( handlers.size() == 0 ) { - registeredHandlers.remove( searchTarget ); - } - } - if ( registeredHandlers.size() == 0 ) { - stopDevicesListenerThread(); - } - } - } - - private void startDevicesListenerThread() throws IOException { - synchronized( singleton ) { - if ( !inService ) { - - this.startMultiCastSocket(); - Thread deamon = new Thread( this, "DiscoveryListener daemon" ); - deamon.setDaemon( daemon ); - deamon.start(); - while ( !inService ) { - // wait for the thread to be started let's wait a few ms - try { - Thread.sleep( 2 ); - } catch( InterruptedException ex ) { - // don t care - } - } - } - } - } - - private void stopDevicesListenerThread() { - synchronized( singleton ) { - inService = false; - } - } - - private void startMultiCastSocket() throws IOException { - int bindPort = Discovery.DEFAULT_SSDP_SEARCH_PORT; - String port = System.getProperty( "net.sbbi.upnp.Discovery.bindPort" ); - if ( port != null ) { - bindPort = Integer.parseInt( port ); - } - - skt = new java.net.MulticastSocket( null ); - skt.bind( new InetSocketAddress( InetAddress.getByName( "0.0.0.0" ), bindPort ) ); - skt.setTimeToLive( Discovery.DEFAULT_TTL ); - skt.setSoTimeout( DEFAULT_TIMEOUT ); - skt.joinGroup( InetAddress.getByName( Discovery.SSDP_IP ) ); - - byte[] buf = new byte[2048]; - input = new DatagramPacket( buf, buf.length ); - - } - - public void run() { - if ( !Thread.currentThread().getName().equals( "DiscoveryListener daemon" ) ) { - throw new RuntimeException( "No right to call this method" ); - } - inService = true; - while ( inService ) { - try { - listenBroadCast(); - } catch ( SocketTimeoutException ex ) { - // ignoring - } catch ( IOException ioEx ) { - log.error( "IO Exception during UPNP DiscoveryListener messages listening thread", ioEx ); - } catch( Exception ex ) { - log.error( "Fatal Error during UPNP DiscoveryListener messages listening thread, thread will exit", ex ); - inService = false; - } - } - - try { - skt.leaveGroup( InetAddress.getByName( Discovery.SSDP_IP ) ); - skt.close(); - } catch ( Exception ex ) { - // ignoring - } - } - - private void listenBroadCast() throws IOException { - - skt.receive( input ); - InetAddress from = input.getAddress(); - String received = new String( input.getData(), input.getOffset(), input.getLength() ); - HttpResponse msg = null; - try { - msg = new HttpResponse( received ); - } catch (IllegalArgumentException ex ) { - // crappy http sent - if ( log.isDebugEnabled() ) log.debug( "Skipping uncompliant HTTP message " + received ); - return; - } - String header = msg.getHeader(); - if ( header != null && header.startsWith( "HTTP/1.1 200 OK" ) && msg.getHTTPHeaderField( "st" ) != null ) { - // probably a search repsonse ! - String deviceDescrLoc = msg.getHTTPHeaderField( "location" ); - if( deviceDescrLoc == null || deviceDescrLoc.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'location' field" ); - return; - } - URL loc = new URL( deviceDescrLoc ); - if ( MATCH_IP ) { - InetAddress locHost = InetAddress.getByName( loc.getHost() ); - if ( !from.equals( locHost ) ) { - log.warn( "Discovery message sender IP " + from + - " does not match device description IP " + locHost + - " skipping device, set the net.sbbi.upnp.ddos.matchip system property" + - " to false to avoid this check" ); - return; - } - } - if ( log.isDebugEnabled() ) log.debug( "Processing " + deviceDescrLoc + " device description location" ); - String st = msg.getHTTPHeaderField( "st" ); - if( st == null || st.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'st' field" ); - return; - } - String usn = msg.getHTTPHeaderField( "usn" ); - if( usn == null || usn.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'usn' field" ); - return; - } - String maxAge = msg.getHTTPFieldElement( "Cache-Control", "max-age" ); - if( maxAge == null || maxAge.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'max-age' field" ); - return; - } - String server = msg.getHTTPHeaderField( "server" ); - if( server == null || server.trim().length() == 0 ) { - if ( log.isDebugEnabled() ) log.debug( "Skipping SSDP message, missing HTTP header 'server' field" ); - return; - } - - String udn = usn; - int index = udn.indexOf( "::" ); - if ( index != -1 ) udn = udn.substring( 0, index ); - synchronized( REGISTRATION_PROCESS ) { - Set handlers = (Set)registeredHandlers.get( st ); - if ( handlers != null ) { - for ( Iterator i = handlers.iterator(); i.hasNext(); ) { - DiscoveryResultsHandler handler = (DiscoveryResultsHandler)i.next(); - handler.discoveredDevice( usn, udn, st, maxAge, loc, server ); - } - } - } - } else { - if ( log.isDebugEnabled() ) log.debug( "Skipping uncompliant HTTP message " + received ); - } - } -} diff --git a/source/net/sbbi/upnp/DiscoveryResultsHandler.java b/source/net/sbbi/upnp/DiscoveryResultsHandler.java deleted file mode 100644 index 1074bcac5..000000000 --- a/source/net/sbbi/upnp/DiscoveryResultsHandler.java +++ /dev/null @@ -1,71 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -/** - * This interface can be use to register against the DiscoveryListener class - * to receive SSDP search responses. - * @author SuperBonBon - * @version 1.0 - */ - -public interface DiscoveryResultsHandler { - - /** - * Method called by the DiscoveryListener class when a search response message has been received from the - * network - * @param usn the device USN - * @param udn the device UDN - * @param nt the device NT - * @param maxAge the message max age - * @param location the device location - * @param firmware the device firmware - */ - public void discoveredDevice( String usn, String udn, String nt, String maxAge, java.net.URL location, String firmware ); - -} diff --git a/source/net/sbbi/upnp/HttpResponse.java b/source/net/sbbi/upnp/HttpResponse.java deleted file mode 100644 index 76235abec..000000000 --- a/source/net/sbbi/upnp/HttpResponse.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -import java.util.HashMap; -import java.util.Map; -import java.util.StringTokenizer; - -/** - * A class to parse an HTTP response message. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class HttpResponse { - - private final String header; - private final Map fields; - private String body; - - - /** - * Constructor of the response, will try to parse the raw response data - * @param rawHttpResponse the raw response data - * @throws IllegalArgumentException if some error occurs during parsing - */ - protected HttpResponse( String rawHttpResponse ) throws IllegalArgumentException { - rawHttpResponse = rawHttpResponse.trim(); - if ( rawHttpResponse == null || rawHttpResponse.length() == 0 ) { - throw new IllegalArgumentException( "Empty HTTP response message" ); - } - boolean bodyParsing = false; - StringBuffer bodyParsed = new StringBuffer(); - fields = new HashMap(); - String[] lines = rawHttpResponse.split( "\\r\\n" ); - this.header = lines[0].trim(); - - for ( int i = 1; i < lines.length; i++ ) { - - String line = lines[i]; - if ( line.length() == 0 ) { - // line break before body - bodyParsing = true; - } else if ( bodyParsing ) { - // we parse the message body - bodyParsed.append( line ).append( "\r\n" ); - } else { - // we parse the header - if ( line.length() > 0 ) { - int delim = line.indexOf( ':' ); - if ( delim != -1 ) { - String key = line.substring( 0, delim ).toUpperCase(); - String value = line.substring( delim + 1 ).trim(); - fields.put( key, value ); - } else { - throw new IllegalArgumentException( "Invalid HTTP message header :" + line ); - } - } - } - } - if ( bodyParsing ) { - body = bodyParsed.toString(); - } - } - - public String getHeader() { - return header; - } - - public String getBody() { - return body; - } - - public String getHTTPFieldElement( String fieldName, String elementName ) throws IllegalArgumentException { - String fieldNameValue = getHTTPHeaderField( fieldName ); - if ( fieldName!= null ) { - - StringTokenizer tokenizer = new StringTokenizer( fieldNameValue.trim(), "," ); - while (tokenizer.countTokens() > 0) { - String nextToken = tokenizer.nextToken().trim(); - if ( nextToken.startsWith( elementName ) ) { - int index = nextToken.indexOf( '=' ); - if ( index != -1 ) { - return nextToken.substring( index + 1 ).trim(); - } - } - } - } - throw new IllegalArgumentException( "HTTP element field " + elementName + " is not present" ); - } - - public String getHTTPHeaderField( String fieldName ) throws IllegalArgumentException { - String field = (String)fields.get( fieldName.toUpperCase() ); - if ( field == null ) { - throw new IllegalArgumentException( "HTTP field " + fieldName + " is not present"); - } - return field; - } - - -} diff --git a/source/net/sbbi/upnp/JXPathParser.java b/source/net/sbbi/upnp/JXPathParser.java deleted file mode 100644 index 4be108a7d..000000000 --- a/source/net/sbbi/upnp/JXPathParser.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -import org.apache.commons.jxpath.xml.DOMParser; -import org.apache.commons.jxpath.xml.XMLParser; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Parser to use with JXPath, this is used to fix some problems encountered - * with some UPNP devices returning buggy xml docs... - * This parser acts like a wrapper and make some chars search and replace - * such as 0x0 with 0x20 to produce a valid XML doc. - * @author SuperBonBon - * @version 1.0 - */ -public class JXPathParser implements XMLParser { - - private final static Log log = LogFactory.getLog( JXPathParser.class ); - - private final char buggyChar = (char)0; - - public Object parseXML( InputStream in ){ - StringBuffer xml = new StringBuffer(); - try { - byte[] buffer = new byte[512]; - int readen = 0; - while ( ( readen = in.read( buffer ) ) != -1 ) { - xml.append( new String( buffer, 0, readen ) ); - } - } catch ( IOException ex ) { - log.error( "IOException occured during XML reception", ex ); - return null; - } - String doc = xml.toString(); - log.debug( "Readen raw xml doc:\n" + doc ); - if ( doc.indexOf( buggyChar ) != -1 ) { - doc = doc.replace( buggyChar, ' ' ); - } - - ByteArrayInputStream in2 = new ByteArrayInputStream( doc.getBytes() ); - DOMParser parser = new DOMParser(); - return parser.parseXML( in2 ) ; - } -} diff --git a/source/net/sbbi/upnp/ServiceEventHandler.java b/source/net/sbbi/upnp/ServiceEventHandler.java deleted file mode 100644 index 480626277..000000000 --- a/source/net/sbbi/upnp/ServiceEventHandler.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -/** - * Interface to implement to receive notifications about state - * variables changes on au UPNP service. The object implementing this interface - * can be used with the ServicesEventing class register method to receive the - * desired notifications. - * @author SuperBonBon - * @version 1.0 - */ - -public interface ServiceEventHandler { - - /** - * Handle a var change, called each time a UPNP service fires a - * state variable eventing message.
- * The code implemented in this method can block the thread. - * @param varName the state variable name - * @param newValue the new state variable value - */ - public void handleStateVariableEvent( String varName, String newValue ); - -} diff --git a/source/net/sbbi/upnp/ServiceEventMessageParser.java b/source/net/sbbi/upnp/ServiceEventMessageParser.java deleted file mode 100644 index b2e422ddf..000000000 --- a/source/net/sbbi/upnp/ServiceEventMessageParser.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -import java.util.HashMap; -import java.util.Map; - -import org.xml.sax.Attributes; - -/** - * Simple SAX handler for UPNP service event message parsing, this message is in SOAP format - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class ServiceEventMessageParser extends org.xml.sax.helpers.DefaultHandler { - - private boolean readPropertyName = false; - - private String currentPropName = null; - - private final Map changedStateVars = new HashMap(); - - protected ServiceEventMessageParser() { - } - - public Map getChangedStateVars() { - return changedStateVars; - } - - public void characters( char[] ch, int start, int length ) { - if ( currentPropName != null ) { - String origChars = (String)changedStateVars.get( currentPropName ); - String newChars = new String( ch, start, length ); - if ( origChars == null ) { - changedStateVars.put( currentPropName, newChars ); - } else { - changedStateVars.put( currentPropName, origChars + newChars ); - } - } - } - - public void startElement( String uri, String localName, String qName, Attributes attributes ) { - if ( localName.equals( "property" ) ) { - readPropertyName = true; - } else if ( readPropertyName ) { - currentPropName = localName; - } - } - - public void endElement( String uri, String localName, String qName ) { - if ( currentPropName != null && localName.equals( currentPropName ) ) { - readPropertyName = false; - currentPropName = null; - } - } - -} - - diff --git a/source/net/sbbi/upnp/ServiceEventSubscription.java b/source/net/sbbi/upnp/ServiceEventSubscription.java deleted file mode 100644 index dbbf9699f..000000000 --- a/source/net/sbbi/upnp/ServiceEventSubscription.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -import java.net.InetAddress; -import java.net.URL; - -/** - * This class is used to provide information about a subscription done - * via the ServicesEventing class - * @author SuperBonBon - * @version 1.0 - */ - -public class ServiceEventSubscription { - - private final String serviceType; - private final String serviceId; - private final URL serviceURL; - private final String SID; - private final InetAddress deviceIp; - private final int durationTime; - - public ServiceEventSubscription( String serviceType, String serviceId, URL serviceURL, - String sid, InetAddress deviceIp, int durationTime ) { - this.serviceType = serviceType; - this.serviceId = serviceId; - this.serviceURL = serviceURL; - SID = sid; - this.deviceIp = deviceIp; - this.durationTime = durationTime; - } - - public InetAddress getDeviceIp() { - return deviceIp; - } - - /** - * Subcription duration in seconds - * @return sub duration time, 0 for an infinite time - */ - public int getDurationTime() { - return durationTime; - } - - public String getServiceId() { - return serviceId; - } - - public String getServiceType() { - return serviceType; - } - - public URL getServiceURL() { - return serviceURL; - } - - /** - * The subscription ID returned by the UPNPDevice - * @return subscription id - */ - public String getSID() { - return SID; - } - -} diff --git a/source/net/sbbi/upnp/ServicesEventing.java b/source/net/sbbi/upnp/ServicesEventing.java deleted file mode 100644 index 7686c50f8..000000000 --- a/source/net/sbbi/upnp/ServicesEventing.java +++ /dev/null @@ -1,445 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp; - -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.StringReader; -import java.net.InetAddress; -import java.net.ServerSocket; -import java.net.Socket; -import java.net.URL; -import java.util.ArrayList; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import net.sbbi.upnp.services.UPNPService; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.xml.sax.InputSource; - -/** - * This class can be used with the ServiceEventHandler interface - * to recieve notifications about state variables changes on - * a given UPNP service. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class ServicesEventing implements Runnable { - - final static Log log = LogFactory.getLog( ServicesEventing.class ); - - private final static ServicesEventing singleton = new ServicesEventing(); - private boolean inService = false; - - private boolean daemon = true; - private int daemonPort = 9999; - - private ServerSocket server = null; - - private final List registered = new ArrayList(); - - private ServicesEventing() { - } - - public final static ServicesEventing getInstance() { - return singleton; - } - - /** - * Set the listeniner thread as a daemon, default to true. - * Only works when no more objects are registered. - * @param daemon the new thread type. - */ - public void setDaemon( boolean daemon ) { - this.daemon = daemon; - } - - /** - * Sets the listener thread port, default to 9999. - * Only works when no more objects are registered. - * @param daemonPort the new listening port - */ - public void setDaemonPort( int daemonPort ) { - this.daemonPort = daemonPort; - } - - /** - * Register state variable events notification for a device service - * @param service the service to register with - * @param handler the registrant object - * @param subscriptionDuration subscription time in seconds, -1 for infinite time - * @return the subscription duration returned by the device, 0 for an infinite duration or -1 if no subscription done - * @throws IOException if some IOException error happens during coms with the device - */ - public int register( UPNPService service, ServiceEventHandler handler, int subscriptionDuration ) throws IOException { - ServiceEventSubscription sub = registerEvent( service, handler, subscriptionDuration ); - if ( sub != null ) { - return sub.getDurationTime(); - } - return -1; - } - - /** - * Register state variable events notification for a device service - * @param service the service to register with - * @param handler the registrant object - * @param subscriptionDuration subscription time in seconds, -1 for infinite time - * @return an ServiceEventSubscription object instance containing all the required info or null if no subscription done - * @throws IOException if some IOException error happens during coms with the device - */ - public ServiceEventSubscription registerEvent( UPNPService service, ServiceEventHandler handler, int subscriptionDuration ) throws IOException { - - URL eventingLoc = service.getEventSubURL(); - - if ( eventingLoc != null ) { - - if ( !inService ) startServicesEventingThread(); - String duration = Integer.toString( subscriptionDuration ); - if ( subscriptionDuration == -1 ) { - duration = "infinite"; - } - - Subscription sub = lookupSubscriber( service, handler ); - if ( sub != null ) { - // allready registered let's try to unregister it - unRegister( service, handler ); - } - - StringBuffer packet = new StringBuffer( 64 ); - packet.append( "SUBSCRIBE " ).append( eventingLoc.getFile() ).append( " HTTP/1.1\r\n" ); - packet.append( "HOST: " ).append( eventingLoc.getHost() ).append( ':' ).append( eventingLoc.getPort() ).append( "\r\n" ); - packet.append( "CALLBACK: \r\n" ); - packet.append( "NT: upnp:event\r\n" ); - packet.append( "Connection: close\r\n" ); - packet.append( "TIMEOUT: Second-" ).append( duration ).append( "\r\n\r\n" ); - - Socket skt = new Socket( eventingLoc.getHost(), eventingLoc.getPort() ); - skt.setSoTimeout( 30000 ); // 30 secs timeout according to the specs - if ( log.isDebugEnabled() ) log.debug( packet ); - OutputStream out = skt.getOutputStream(); - out.write( packet.toString().getBytes() ); - out.flush(); - - InputStream in = skt.getInputStream(); - StringBuffer data = new StringBuffer(); - int readen = 0; - byte[] buffer = new byte[256]; - while ( ( readen = in.read( buffer ) ) != -1 ) { - data.append( new String( buffer, 0, readen ) ); - } - in.close(); - out.close(); - skt.close(); - if ( log.isDebugEnabled() ) log.debug( data.toString() ); - if ( data.toString().trim().length() > 0 ) { - HttpResponse resp = new HttpResponse( data.toString() ); - - if ( resp.getHeader().startsWith( "HTTP/1.1 200 OK" ) ) { - String sid = resp.getHTTPHeaderField( "SID" ); - String actualTimeout = resp.getHTTPHeaderField( "TIMEOUT" ); - int durationTime = 0; - // actualTimeout = Second-xxx or Second-infinite - if ( !actualTimeout.equalsIgnoreCase( "Second-infinite" ) ) { - durationTime = Integer.parseInt( actualTimeout.substring( 7 ) ); - } - sub = new Subscription(); - sub.handler = handler; - sub.sub = new ServiceEventSubscription( service.getServiceType(), service.getServiceId(), - service.getEventSubURL(), sid, skt.getInetAddress(), - durationTime ); - synchronized( registered ) { - registered.add( sub ); - } - return sub.sub; - } - } - } - return null; - - } - - private Subscription lookupSubscriber( UPNPService service, ServiceEventHandler handler ) { - synchronized( registered ) { - for ( Iterator i = registered.iterator(); i.hasNext(); ) { - Subscription sub = (Subscription)i.next(); - - if ( sub.handler == handler && - sub.sub.getServiceId().hashCode() == service.getServiceId().hashCode() && - sub.sub.getServiceType().hashCode() == service.getServiceType().hashCode() && - sub.sub.getServiceURL().equals( service.getEventSubURL() ) ) { - return sub; - } - } - } - return null; - } - - Subscription lookupSubscriber( String sid, InetAddress deviceIp ) { - synchronized( registered ) { - for ( Iterator i = registered.iterator(); i.hasNext(); ) { - Subscription sub = (Subscription)i.next(); - - if ( sub.sub.getSID().equals( sid ) && sub.sub.getDeviceIp().equals( deviceIp ) ) { - return sub; - } - } - } - return null; - } - - Subscription lookupSubscriber( String sid ) { - synchronized( registered ) { - for ( Iterator i = registered.iterator(); i.hasNext(); ) { - Subscription sub = (Subscription)i.next(); - - if ( sub.sub.getSID().equals( sid ) ) { - return sub; - } - } - } - return null; - } - - /** - * Unregisters events notifications from a service - * @param service the service that need to be unregistered - * @param handler the handler that registered for this service - * @return true if unregistered false otherwise ( the given handler never registred for the given service ) - * @throws IOException if some IOException error happens during coms with the device - */ - public boolean unRegister( UPNPService service, ServiceEventHandler handler ) throws IOException { - - URL eventingLoc = service.getEventSubURL(); - - if ( eventingLoc != null ) { - - Subscription sub = lookupSubscriber( service, handler ); - if ( sub != null ) { - synchronized( registered ) { - registered.remove( sub ); - } - if ( registered.size() == 0 ) { - stopServicesEventingThread(); - } - - StringBuffer packet = new StringBuffer( 64 ); - packet.append( "UNSUBSCRIBE " ).append( eventingLoc.getFile() ).append( " HTTP/1.1\r\n" ); - packet.append( "HOST: " ).append( eventingLoc.getHost() ).append( ':' ).append( eventingLoc.getPort() ).append( "\r\n" ); - packet.append( "SID: " ).append( sub.sub.getSID() ).append( "\r\n\r\n" ); - Socket skt = new Socket( eventingLoc.getHost(), eventingLoc.getPort() ); - skt.setSoTimeout( 30000 ); // 30 secs timeout according to the specs - if ( log.isDebugEnabled() ) log.debug( packet ); - OutputStream out = skt.getOutputStream(); - out.write( packet.toString().getBytes() ); - out.flush(); - - InputStream in = skt.getInputStream(); - StringBuffer data = new StringBuffer(); - int readen = 0; - byte[] buffer = new byte[256]; - while ( ( readen = in.read( buffer ) ) != -1 ) { - data.append( new String( buffer, 0, readen ) ); - } - in.close(); - out.close(); - skt.close(); - if ( log.isDebugEnabled() ) log.debug( data.toString() ); - if ( data.toString().trim().length() > 0 ) { - HttpResponse resp = new HttpResponse( data.toString() ); - if ( resp.getHeader().startsWith( "HTTP/1.1 200 OK" ) ) { - return true; - } - } - } - } - return false; - } - - - private void startServicesEventingThread() { - synchronized( singleton ) { - if ( !inService ) { - Thread deamon = new Thread( singleton, "ServicesEventing daemon" ); - deamon.setDaemon( daemon ); - inService = true; - deamon.start(); - } - } - } - - private void stopServicesEventingThread() { - synchronized( singleton ) { - inService = false; - try { - server.close(); - } catch ( IOException ex ) { - // should not happen - } - } - } - - public void run() { - // only the deamon thread is allowed to call such method - if ( !Thread.currentThread().getName().equals( "ServicesEventing daemon" ) ) return; - try { - server = new ServerSocket( daemonPort ); - } catch ( IOException ex ) { - log.error( "Error during daemon server socket on port " + daemonPort + " creation", ex ); - return; - } - while ( inService ) { - try { - Socket skt = server.accept(); - new Thread( new RequestProcessor( skt ) ).start(); - } catch ( IOException ioEx ) { - if ( inService ) { - log.error( "IO Exception during UPNP messages listening thread", ioEx ); - } - } - } - } - - class Subscription { - ServiceEventSubscription sub = null; - ServiceEventHandler handler = null; - } - - class RequestProcessor implements Runnable { - - private final Socket client; - - RequestProcessor(final Socket client) { - this.client = client; - } - - public void run() { - try { - client.setSoTimeout( 30000 ); - InputStream in = client.getInputStream(); - OutputStream out = client.getOutputStream(); - - int readen = 0; - StringBuffer data = new StringBuffer(); - byte[] buffer = new byte[256]; - boolean EOF = false; - while ( !EOF && ( readen = in.read( buffer ) ) != -1 ) { - data.append( new String( buffer, 0, readen ) ); - // avoid a strange behaviour with some impls.. the -1 is never reached and a sockettimeout occurs - // and a 0 byte is sent as the last byte - if ( data.charAt( data.length()-1 ) == (char)0 ) { - EOF = true; - } - } - - String packet = data.toString(); - if ( packet.trim().length() > 0 ) { - - if ( packet.indexOf( (char)0 ) != -1 ) packet = packet.replace( (char)0, ' ' ); - HttpResponse resp = new HttpResponse( packet ); - if ( resp.getHeader().startsWith( "NOTIFY" ) ) { - - String sid = resp.getHTTPHeaderField( "SID" ); - InetAddress deviceIp = client.getInetAddress(); - String postURL = resp.getHTTPHeaderField( "SID" ); - Subscription subscription = null; - if ( sid != null && postURL != null ) { - subscription = lookupSubscriber( sid, deviceIp ); - if ( subscription == null ) { - // not found maybe that the IP is not the same - subscription = lookupSubscriber( sid ); - } - } - if ( subscription != null ) { - // respond ok - out.write( "HTTP/1.1 200 OK\r\n".getBytes() ); - } else { - // unknown sid respond ko - out.write( "HTTP/1.1 412 Precondition Failed\r\n".getBytes() ); - } - - out.flush(); - in.close(); - out.close(); - client.close(); - - if ( subscription != null ) { - // let's parse it - SAXParserFactory saxParFact = SAXParserFactory.newInstance(); - saxParFact.setValidating( false ); - saxParFact.setNamespaceAware( true ); - SAXParser parser = saxParFact.newSAXParser(); - ServiceEventMessageParser msgParser = new ServiceEventMessageParser(); - StringReader stringReader = new StringReader( resp.getBody() ); - InputSource src = new InputSource( stringReader ); - parser.parse( src, msgParser ); - - Map changedStateVars = msgParser.getChangedStateVars(); - for ( Iterator i = changedStateVars.keySet().iterator(); i.hasNext(); ) { - String stateVarName = (String)i.next(); - String stateVarNewVal = (String)changedStateVars.get( stateVarName ); - subscription.handler.handleStateVariableEvent( stateVarName, stateVarNewVal ); - } - } - } - } - } catch ( IOException ioEx ) { - log.error( "IO Exception during client processing thread", ioEx ); - } catch( Exception ex ) { - log.error( "Unexpected error during client processing thread", ex ); - } - } - } -} diff --git a/source/net/sbbi/upnp/devices/DeviceIcon.java b/source/net/sbbi/upnp/devices/DeviceIcon.java deleted file mode 100644 index 7037a496b..000000000 --- a/source/net/sbbi/upnp/devices/DeviceIcon.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.devices; - -import java.net.*; - -/** - * Java Bean for a device icon properties - * @author SuperBonBon - * @version 1.0 - */ - -public class DeviceIcon { - - protected String mimeType; - protected int width; - protected int height; - protected int depth; - protected URL url; - - public String getMimeType() { - return mimeType; - } - - public int getWidth() { - return width; - } - - public int getHeight() { - return height; - } - - public int getDepth() { - return depth; - } - - public URL getUrl() { - return url; - } - -} diff --git a/source/net/sbbi/upnp/devices/UPNPDevice.java b/source/net/sbbi/upnp/devices/UPNPDevice.java deleted file mode 100644 index aea65115c..000000000 --- a/source/net/sbbi/upnp/devices/UPNPDevice.java +++ /dev/null @@ -1,298 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.devices; - -import net.sbbi.upnp.services.*; - -import java.util.*; -import java.net.*; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * This class represents an UPNP device, this device contains a set of services - * that will be needed to access the device functionalities. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class UPNPDevice { - - private final static Log log = LogFactory.getLog( UPNPDevice.class ); - - protected String deviceType; - protected String friendlyName; - protected String manufacturer; - protected URL manufacturerURL; - protected URL presentationURL; - protected String modelDescription; - protected String modelName; - protected String modelNumber; - protected String modelURL; - protected String serialNumber; - protected String UDN; - protected String USN; - protected long UPC; - - protected List deviceIcons; - protected List services; - protected List childDevices; - - protected UPNPDevice parent; - - public URL getManufacturerURL() { - return manufacturerURL; - } - - /** - * Presentation URL - * @return URL the presenation URL, or null if the device does not provide - * such information - */ - public URL getPresentationURL() { - return presentationURL; - } - - public String getModelDescription() { - return modelDescription; - } - - public String getModelName() { - return modelName; - } - - public String getModelNumber() { - return modelNumber; - } - - public String getModelURL() { - return modelURL; - } - - public String getSerialNumber() { - return serialNumber; - } - - public String getUDN() { - return UDN; - } - - public String getUSN(){ - return USN; - } - - public long getUPC() { - return UPC; - } - - public String getDeviceType() { - return deviceType; - } - - public String getFriendlyName() { - return friendlyName; - } - - public String getManufacturer() { - return manufacturer; - } - - public boolean isRootDevice() { - return this instanceof UPNPRootDevice; - } - - /** - * Access to the device icons definitions - * @return a list containing DeviceIcon objects or null if no icons defined - */ - public List getDeviceIcons() { - return deviceIcons; - } - - /** - * Generates a list of all the child ( not only top level, full childrens hierarchy included ) - * UPNPDevice objects for this device. - * @return the generated list or null if no child devices bound - */ - public List getChildDevices() { - if ( childDevices == null ) return null; - List rtrVal = new ArrayList(); - for ( Iterator itr = childDevices.iterator(); itr.hasNext(); ) { - UPNPDevice device = (UPNPDevice)itr.next(); - rtrVal.add( device ); - List found = device.getChildDevices(); - if ( found != null ) { - rtrVal.addAll( found ); - } - } - return rtrVal; - - } - - /** - * Generates a list of all the child ( only top level ) - * UPNPDevice objects for this device. - * @return the generated list or null if no child devices bound - */ - public List getTopLevelChildDevices() { - if ( childDevices == null ) return null; - List rtrVal = new ArrayList(); - for ( Iterator itr = childDevices.iterator(); itr.hasNext(); ) { - UPNPDevice device = (UPNPDevice)itr.next(); - rtrVal.add( device ); - } - return rtrVal; - } - - /** - * Return the parent UPNPDevice, null if the device is an UPNPRootDevice - * @return the parent device instance - */ - public UPNPDevice getDirectParent() { - return parent; - } - - /** - * Looks for a child UPNP device definition file, - * the whole devices tree will be searched, starting from the current - * device node. - * @param deviceURI the device URI to search - * @return An UPNPDevice if anything matches or null - */ - public UPNPDevice getChildDevice( String deviceURI ) { - if ( log.isDebugEnabled() ) log.debug( "searching for device URI:" + deviceURI ); - if ( getDeviceType().equals( deviceURI ) ) return this; - if ( childDevices == null ) return null; - for ( Iterator itr = childDevices.iterator(); itr.hasNext(); ) { - UPNPDevice device = (UPNPDevice)itr.next(); - UPNPDevice found = device.getChildDevice( deviceURI ); - if ( found != null ) { - return found; - } - } - return null; - } - - /** - * Looks for all UPNP device service definitions objects - * @return A list of all device services - */ - public List getServices() { - if ( services == null ) return null; - List rtrVal = new ArrayList(); - rtrVal.addAll( services ); - return rtrVal; - } - - /** - * Looks for a UPNP device service definition object for the given service URI (Type) - * @param serviceURI the URI of the service - * @return A matching UPNPService object or null - */ - public UPNPService getService( String serviceURI ) { - if ( services == null ) return null; - if ( log.isDebugEnabled() ) log.debug( "searching for service URI:" + serviceURI ); - for ( Iterator itr = services.iterator(); itr.hasNext(); ) { - UPNPService service = (UPNPService)itr.next(); - if ( service.getServiceType().equals( serviceURI ) ) { - return service; - } - } - return null; - } - - /** - * Looks for a UPNP device service definition object for the given service ID - * @param serviceURI the ID of the service - * @return A matching UPNPService object or null - */ - public UPNPService getServiceByID( String serviceID ) { - if ( services == null ) return null; - if ( log.isDebugEnabled() ) log.debug( "searching for service ID:" + serviceID ); - for ( Iterator itr = services.iterator(); itr.hasNext(); ) { - UPNPService service = (UPNPService)itr.next(); - if ( service.getServiceId().equals( serviceID ) ) { - return service; - } - } - return null; - } - - /** - * Looks for the all the UPNP device service definition object for the current - * UPNP device object. This method can be used to retreive multiple same kind - * ( same service type ) of services with different services id on a device - * @param serviceURI the URI of the service - * @return A matching List of UPNPService objects or null - */ - public List getServices( String serviceURI ) { - if ( services == null ) return null; - List rtrVal = new ArrayList(); - if ( log.isDebugEnabled() ) log.debug( "searching for services URI:" + serviceURI ); - for ( Iterator itr = services.iterator(); itr.hasNext(); ) { - UPNPService service = (UPNPService)itr.next(); - if ( service.getServiceType().equals( serviceURI ) ) { - rtrVal.add( service ); - } - } - if ( rtrVal.size() == 0 ) { - return null; - } - return rtrVal; - } - - /** - * The toString return the device type - * @return the device type - */ - public String toString() { - return getDeviceType(); - } - -} diff --git a/source/net/sbbi/upnp/devices/UPNPRootDevice.java b/source/net/sbbi/upnp/devices/UPNPRootDevice.java deleted file mode 100644 index d7ece9eaf..000000000 --- a/source/net/sbbi/upnp/devices/UPNPRootDevice.java +++ /dev/null @@ -1,450 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.devices; - -import java.net.*; -import java.util.*; -import java.io.*; - -import org.apache.commons.jxpath.*; -import org.apache.commons.jxpath.xml.*; -import org.apache.commons.logging.*; - -import net.sbbi.upnp.JXPathParser; -import net.sbbi.upnp.services.*; - -/** - * Root UPNP device that is contained in a device definition file. - * Slightly differs from a simple UPNPDevice object. - * This object will contains all the child devices, this is the top - * objet in the UPNP device devices hierarchy. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class UPNPRootDevice extends UPNPDevice { - - private final static Log log = LogFactory.getLog( UPNPRootDevice.class ); - - private int specVersionMajor; - private int specVersionMinor; - private URL URLBase; - private long validityTime; - private long creationTime; - private URL deviceDefLoc; - private String deviceDefLocData; - private String vendorFirmware; - private String discoveryUSN; - private String discoveryUDN; - - private DocumentContainer UPNPDevice; - - /** - * Constructor for the root device, constructs itself from - * An xml device definition file provided by the UPNP device via http normally. - * @param deviceDefLoc the location of the XML device definition file - * using "the urn:schemas-upnp-org:device-1-0" namespace - * @param maxAge the maximum age of this UPNP device in secs before considered to be outdated - * @param vendorFirmware the vendor firmware - * @param discoveryUSN the discovery USN used to find and create this device - * @param discoveryUDN the discovery UDN used to find and create this device - * @throws MalformedURLException if the location URL is invalid and cannot be used to populate this root object and its child devices - * IllegalStateException if the device has an unsupported version, currently only version 1.0 is supported - */ - public UPNPRootDevice( URL deviceDefLoc, String maxAge, String vendorFirmware, String discoveryUSN, String discoveryUDN ) throws MalformedURLException, IllegalStateException { - this( deviceDefLoc, maxAge ); - this.vendorFirmware = vendorFirmware; - this.discoveryUSN = discoveryUSN; - this.discoveryUDN = discoveryUDN; - } - - /** - * Constructor for the root device, constructs itself from - * An xml device definition file provided by the UPNP device via http normally. - * @param deviceDefLoc the location of the XML device definition file - * using "the urn:schemas-upnp-org:device-1-0" namespace - * @param maxAge the maximum age of this UPNP device in secs before considered to be outdated - * @param vendorFirmware the vendor firmware - * @throws MalformedURLException if the location URL is invalid and cannot be used to populate this root object and its child devices - * IllegalStateException if the device has an unsupported version, currently only version 1.0 is supported - */ - public UPNPRootDevice( URL deviceDefLoc, String maxAge, String vendorFirmware ) throws MalformedURLException, IllegalStateException { - this( deviceDefLoc, maxAge ); - this.vendorFirmware = vendorFirmware; - } - - /** - * Constructor for the root device, constructs itself from - * An xml device definition file provided by the UPNP device via http normally. - * @param deviceDefLoc the location of the XML device definition file - * using "the urn:schemas-upnp-org:device-1-0" namespace - * @param maxAge the maximum age in secs of this UPNP device before considered to be outdated - * @throws MalformedURLException if the location URL is invalid and cannot be used to populate this root object and its child devices - * IllegalStateException if the device has an unsupported version, currently only version 1.0 is supported - */ - public UPNPRootDevice( URL deviceDefLoc, String maxAge ) throws MalformedURLException, IllegalStateException { - this.deviceDefLoc = deviceDefLoc; - DocumentContainer.registerXMLParser( DocumentContainer.MODEL_DOM, new JXPathParser() ); - UPNPDevice = new DocumentContainer( deviceDefLoc, DocumentContainer.MODEL_DOM ); - validityTime = Integer.parseInt( maxAge ) * 1000; - creationTime = System.currentTimeMillis(); - - JXPathContext context = JXPathContext.newContext( this ); - Pointer rootPtr = context.getPointer( "UPNPDevice/root" ); - JXPathContext rootCtx = context.getRelativeContext( rootPtr ); - - specVersionMajor = Integer.parseInt( (String)rootCtx.getValue( "specVersion/major" ) ); - specVersionMinor = Integer.parseInt( (String)rootCtx.getValue( "specVersion/minor" ) ); - - if ( !( specVersionMajor == 1 && specVersionMinor == 0 ) ) { - throw new IllegalStateException( "Unsupported device version (" + specVersionMajor + "." + specVersionMinor + ")" ); - } - boolean buildURLBase = true; - String base = null; - try { - base = (String)rootCtx.getValue( "URLBase" ); - if ( base != null && base.trim().length() > 0 ) { - URLBase = new URL( base ); - if ( log.isDebugEnabled() ) log.debug( "device URLBase " + URLBase ); - buildURLBase = false; - } - } catch ( JXPathException ex ) { - // URLBase is not mandatory we assume we use the URL of the device - } catch ( MalformedURLException malformedEx ) { - // crappy urlbase provided - log.warn( "Error occured during device baseURL " + base + " parsing, building it from device default location", malformedEx ); - } - if ( buildURLBase ) { - String URL = deviceDefLoc.getProtocol() + "://" + deviceDefLoc.getHost() + ":" + deviceDefLoc.getPort(); - String path = deviceDefLoc.getPath(); - if ( path != null ) { - int lastSlash = path.lastIndexOf( '/' ); - if ( lastSlash != -1 ) { - URL += path.substring( 0, lastSlash ); - } - } - URLBase = new URL( URL ); - } - Pointer devicePtr = rootCtx.getPointer( "device" ); - JXPathContext deviceCtx = rootCtx.getRelativeContext( devicePtr ); - - fillUPNPDevice( this, null, deviceCtx, URLBase ); - } - - /** - * The validity time for this device in milliseconds, - * @return the number of milliseconds remaining before the device object that has been build is considered to - * be outdated, after this delay the UPNP device should resend an advertisement message or a negative value - * if the device is outdated - */ - public long getValidityTime() { - long elapsed = System.currentTimeMillis() - creationTime; - return validityTime - elapsed; - } - - /** - * Resets the device validity time - * @param newMaxAge the maximum age in secs of this UPNP device before considered to be outdated - */ - public void resetValidityTime( String newMaxAge ) { - validityTime = Integer.parseInt( newMaxAge ) * 1000; - creationTime = System.currentTimeMillis(); - } - - /** - * Retreives the device description file location - * @return an URL - */ - public URL getDeviceDefLoc() { - return deviceDefLoc; - } - - public int getSpecVersionMajor() { - return specVersionMajor; - } - - public int getSpecVersionMinor() { - return specVersionMinor; - } - - public String getVendorFirmware() { - return vendorFirmware; - } - - public String getDiscoveryUSN() { - return discoveryUSN; - } - - public String getDiscoveryUDN() { - return discoveryUDN; - } - - /** - * URL base acces - * @return URL the URL base, or null if the device does not provide - * such information - */ - public URL getURLBase() { - return URLBase; - } - - /** - * Parsing an UPNPdevice description element () in the description XML file - * @param device the device object that will be populated - * @param parent the device parent object - * @param deviceCtx an XPath context for object population - * @param baseURL the base URL of the UPNP device - * @throws MalformedURLException if some URL provided in the description file is invalid - */ - private void fillUPNPDevice( UPNPDevice device, UPNPDevice parent, JXPathContext deviceCtx, URL baseURL ) throws MalformedURLException { - - device.deviceType = getMandatoryData( deviceCtx, "deviceType" ); - if ( log.isDebugEnabled() ) log.debug( "parsing device " + device.deviceType ); - device.friendlyName = getMandatoryData( deviceCtx, "friendlyName" ); - device.manufacturer = getNonMandatoryData( deviceCtx, "manufacturer" ); - String base = getNonMandatoryData( deviceCtx, "manufacturerURL" ); - try { - if ( base != null ) device.manufacturerURL = new URL( base ); - } catch ( java.net.MalformedURLException ex ) { - // crappy data provided, keep the field null - } - try { - device.presentationURL = getURL( getNonMandatoryData( deviceCtx, "presentationURL" ), URLBase ); - } catch ( java.net.MalformedURLException ex ) { - // crappy data provided, keep the field null - } - device.modelDescription = getNonMandatoryData( deviceCtx, "modelDescription" ); - device.modelName = getMandatoryData( deviceCtx, "modelName" ); - device.modelNumber = getNonMandatoryData( deviceCtx, "modelNumber" ); - device.modelURL = getNonMandatoryData( deviceCtx, "modelURL" ); - device.serialNumber = getNonMandatoryData( deviceCtx, "serialNumber" ); - device.UDN = getMandatoryData( deviceCtx, "UDN" ); - device.USN = UDN.concat( "::" ).concat( deviceType ); - String tmp = getNonMandatoryData( deviceCtx, "UPC" ); - if ( tmp != null ) { - try { - device.UPC = Long.parseLong( tmp ); - } catch ( Exception ex ) { - // non all numeric field provided, non upnp compliant device - } - } - device.parent = parent; - - fillUPNPServicesList( device, deviceCtx ); - fillUPNPDeviceIconsList( device, deviceCtx, URLBase ); - - Pointer deviceListPtr; - try { - deviceListPtr = deviceCtx.getPointer( "deviceList" ); - } catch ( JXPathException ex ) { - // no pointers for this device list, this can happen - // if the device has no child devices, simply returning - return; - } - JXPathContext deviceListCtx = deviceCtx.getRelativeContext( deviceListPtr ); - Double arraySize = (Double)deviceListCtx.getValue( "count( device )" ); - device.childDevices = new ArrayList(); - if ( log.isDebugEnabled() ) log.debug( "child devices count is " + arraySize ); - for ( int i = 1; i <= arraySize.intValue(); i++ ) { - Pointer devicePtr = deviceListCtx.getPointer( "device[" + i + "]" ); - JXPathContext childDeviceCtx = deviceListCtx.getRelativeContext( devicePtr ); - UPNPDevice childDevice = new UPNPDevice(); - fillUPNPDevice( childDevice, device, childDeviceCtx, baseURL ); - if ( log.isDebugEnabled() ) log.debug( "adding child device " + childDevice.getDeviceType() ); - device.childDevices.add( childDevice ); - } - } - - private String getMandatoryData( JXPathContext ctx, String ctxFieldName ) { - String value = (String)ctx.getValue( ctxFieldName ); - if ( value != null && value.length() == 0 ) { - throw new JXPathException( "Mandatory field " + ctxFieldName + " not provided, uncompliant UPNP device !!" ); - } - return value; - } - - private String getNonMandatoryData( JXPathContext ctx, String ctxFieldName ) { - String value = null; - try { - value = (String)ctx.getValue( ctxFieldName ); - if ( value != null && value.length() == 0 ) { - value = null; - } - } catch ( JXPathException ex ) { - value = null; - } - return value; - } - - /** - * Parsing an UPNPdevice services list element () in the description XML file - * @param device the device object that will store the services list (UPNPService) objects - * @param deviceCtx an XPath context for object population - * @throws MalformedURLException if some URL provided in the description - * file for a service entry is invalid - */ - private void fillUPNPServicesList( UPNPDevice device, JXPathContext deviceCtx ) throws MalformedURLException { - Pointer serviceListPtr = deviceCtx.getPointer( "serviceList" ); - JXPathContext serviceListCtx = deviceCtx.getRelativeContext( serviceListPtr ); - Double arraySize = (Double)serviceListCtx.getValue( "count( service )" ); - if ( log.isDebugEnabled() ) log.debug( "device services count is " + arraySize ); - device.services = new ArrayList(); - for ( int i = 1; i <= arraySize.intValue(); i++ ) { - - Pointer servicePtr = serviceListCtx.getPointer( "service["+i+"]" ); - JXPathContext serviceCtx = serviceListCtx.getRelativeContext( servicePtr ); - // TODO possibility of bugs if deviceDefLoc contains a file name - URL base = URLBase != null ? URLBase : deviceDefLoc; - UPNPService service = new UPNPService( serviceCtx, base, this ); - device.services.add( service ); - } - } - - /** - * Parsing an UPNPdevice icons list element () in the description XML file - * This list can be null - * @param device the device object that will store the icons list (DeviceIcon) objects - * @param deviceCtx an XPath context for object population - * @throws MalformedURLException if some URL provided in the description - * file for an icon URL - */ - private void fillUPNPDeviceIconsList( UPNPDevice device, JXPathContext deviceCtx, URL baseURL ) throws MalformedURLException { - Pointer iconListPtr; - try { - iconListPtr = deviceCtx.getPointer( "iconList" ); - } catch ( JXPathException ex ) { - // no pointers for icons list, this can happen - // simply returning - return; - } - JXPathContext iconListCtx = deviceCtx.getRelativeContext( iconListPtr ); - Double arraySize = (Double)iconListCtx.getValue( "count( icon )" ); - if ( log.isDebugEnabled() ) log.debug( "device icons count is " + arraySize ); - device.deviceIcons = new ArrayList(); - for ( int i = 1; i <= arraySize.intValue(); i++ ) { - - DeviceIcon ico = new DeviceIcon(); - ico.mimeType = (String)iconListCtx.getValue( "icon["+i+"]/mimetype" ); - ico.width = Integer.parseInt( (String)iconListCtx.getValue( "icon["+i+"]/width" ) ); - ico.height = Integer.parseInt( (String)iconListCtx.getValue( "icon["+i+"]/height" ) ); - ico.depth = Integer.parseInt( (String)iconListCtx.getValue( "icon["+i+"]/depth" ) ); - ico.url = getURL( (String)iconListCtx.getValue( "icon["+i+"]/url" ), baseURL ); - if ( log.isDebugEnabled() ) log.debug( "icon URL is " + ico.url ); - device.deviceIcons.add( ico ); - } - } - - /** - * Parsing an URL from the descriptionXML file - * @param url the string representation fo the URL - * @param baseURL the base device URL, needed if the url param is relative - * @return an URL object defining the url param - * @throws MalformedURLException if the url param or baseURL.toExternalForm() + url - * cannot be parsed to create an URL object - */ - public final static URL getURL( String url, URL baseURL ) throws MalformedURLException { - URL rtrVal; - if ( url == null || url.trim().length() == 0 ) return null; - try { - rtrVal = new URL( url ); - } catch ( MalformedURLException malEx ) { - // maybe that the url is relative, we add the baseURL and reparse it - // if relative then we take the device baser url root and add the url - if ( baseURL != null ) { - url = url.replace( '\\', '/' ); - if ( url.charAt( 0 ) != '/' ) { - // the path is relative to the device baseURL - String externalForm = baseURL.toExternalForm(); - if ( !externalForm.endsWith( "/" ) ) { - externalForm += "/"; - } - rtrVal = new URL( externalForm + url ); - } else { - // the path is not relative - String URLRoot = baseURL.getProtocol() + "://" + baseURL.getHost() + ":" + baseURL.getPort(); - rtrVal = new URL( URLRoot + url ); - } - } else { - throw malEx; - } - } - return rtrVal; - } - - /** - * Retrieves the device definition XML data - * @return the device definition XML data as a String - */ - public String getDeviceDefLocData() { - if ( deviceDefLocData == null ) { - try { - java.io.InputStream in = deviceDefLoc.openConnection().getInputStream(); - int readen = 0; - byte[] buff = new byte[512]; - StringBuffer strBuff = new StringBuffer(); - while( ( readen = in.read( buff ) ) != -1 ) { - strBuff.append( new String( buff, 0, readen ) ); - } - in.close(); - deviceDefLocData = strBuff.toString(); - } catch ( IOException ioEx ) { - return null; - } - } - return deviceDefLocData; - } - - /** - * Used for JXPath parsing, do not use this method - * @return a Container object for Xpath parsing capabilities - */ - public Container getUPNPDevice() { - return UPNPDevice; - } - -} diff --git a/source/net/sbbi/upnp/impls/InternetGatewayDevice.java b/source/net/sbbi/upnp/impls/InternetGatewayDevice.java deleted file mode 100644 index d7b69ee79..000000000 --- a/source/net/sbbi/upnp/impls/InternetGatewayDevice.java +++ /dev/null @@ -1,509 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.impls; - -import java.io.IOException; -import java.net.InetAddress; -import java.net.NetworkInterface; -import java.net.UnknownHostException; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import net.sbbi.upnp.Discovery; -import net.sbbi.upnp.devices.UPNPDevice; -import net.sbbi.upnp.devices.UPNPRootDevice; -import net.sbbi.upnp.messages.ActionMessage; -import net.sbbi.upnp.messages.ActionResponse; -import net.sbbi.upnp.messages.StateVariableMessage; -import net.sbbi.upnp.messages.StateVariableResponse; -import net.sbbi.upnp.messages.UPNPMessageFactory; -import net.sbbi.upnp.messages.UPNPResponseException; -import net.sbbi.upnp.services.UPNPService; - -/** - * This class can be used to access some funtionalities on the - * InternetGatewayDevice on your network without having to know - * anything about the required input/output parameters. - * All device functions are not provided. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class InternetGatewayDevice { - - private final static Log log = LogFactory.getLog( InternetGatewayDevice.class ); - - private UPNPRootDevice igd; - private UPNPMessageFactory msgFactory; - - public InternetGatewayDevice( UPNPRootDevice igd ) throws UnsupportedOperationException { - this( igd, true, true ); - } - - private InternetGatewayDevice( UPNPRootDevice igd, boolean WANIPConnection, boolean WANPPPConnection ) throws UnsupportedOperationException { - this.igd = igd; - UPNPDevice myIGDWANConnDevice = igd.getChildDevice( "urn:schemas-upnp-org:device:WANConnectionDevice:1" ); - if ( myIGDWANConnDevice == null ) { - throw new UnsupportedOperationException( "device urn:schemas-upnp-org:device:WANConnectionDevice:1 not supported by IGD device " + igd.getModelName() ); - } - - UPNPService wanIPSrv = myIGDWANConnDevice.getService( "urn:schemas-upnp-org:service:WANIPConnection:1" ); - UPNPService wanPPPSrv = myIGDWANConnDevice.getService( "urn:schemas-upnp-org:service:WANPPPConnection:1" ); - - if ( ( WANIPConnection && WANPPPConnection ) && ( wanIPSrv == null && wanPPPSrv == null ) ) { - throw new UnsupportedOperationException( "Unable to find any urn:schemas-upnp-org:service:WANIPConnection:1 or urn:schemas-upnp-org:service:WANPPPConnection:1 service" ); - } else if ( ( WANIPConnection && !WANPPPConnection ) && wanIPSrv == null ) { - throw new UnsupportedOperationException( "Unable to find any urn:schemas-upnp-org:service:WANIPConnection:1 service" ); - } else if ( ( !WANIPConnection && WANPPPConnection ) && wanPPPSrv == null ) { - throw new UnsupportedOperationException( "Unable to find any urn:schemas-upnp-org:service:WANPPPConnection:1 service" ); - } - - if ( wanIPSrv != null && wanPPPSrv == null ) { - msgFactory = UPNPMessageFactory.getNewInstance( wanIPSrv ); - } else if ( wanPPPSrv != null && wanIPSrv == null ) { - msgFactory = UPNPMessageFactory.getNewInstance( wanPPPSrv ); - } else { - // Unable to test the following code since no router implementing both IP and PPP connection on hands.. - /*// discover the active WAN interface using the WANCommonInterfaceConfig specs - UPNPDevice wanDevice = igd.getChildDevice( "urn:schemas-upnp-org:device:WANDevice:1" ); - UPNPService configService = wanDevice.getService( "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" ); - if ( configService != null ) { - // retreive the first active connection - ServiceAction act = configService.getUPNPServiceAction( "GetActiveConnection" ); - if ( act != null ) { - UPNPMessageFactory msg = UPNPMessageFactory.getNewInstance( configService ); - String deviceContainer = null; - String serviceID = null; - try { - // always lookup for the first index of active connections. - ActionResponse resp = msg.getMessage( "GetActiveConnection" ).setInputParameter( "NewActiveConnectionIndex", 0 ).service(); - deviceContainer = resp.getOutActionArgumentValue( "NewActiveConnDeviceContainer" ); - serviceID = resp.getOutActionArgumentValue( "NewActiveConnectionServiceID" ); - } catch ( IOException ex ) { - // no response returned - } catch ( UPNPResponseException respEx ) { - // should never happen unless the damn thing is bugged - } - if ( deviceContainer != null && deviceContainer.trim().length() > 0 && - serviceID != null && serviceID.trim().length() > 0 ) { - for ( Iterator i = igd.getChildDevices().iterator(); i.hasNext(); ) { - UPNPDevice dv = (UPNPDevice)i.next(); - - if ( deviceContainer.startsWith( dv.getUDN() ) && - dv.getDeviceType().indexOf( ":WANConnectionDevice:" ) != -1 ) { - myIGDWANConnDevice = dv; - break; - } - } - msgFactory = UPNPMessageFactory.getNewInstance( myIGDWANConnDevice.getServiceByID( serviceID ) ); - } - } - }*/ - // Doing a tricky test with external IP address, the unactive interface should return a null value or none - if ( testWANInterface( wanIPSrv ) ) { - msgFactory = UPNPMessageFactory.getNewInstance( wanIPSrv ); - } else if( testWANInterface( wanPPPSrv ) ) { - msgFactory = UPNPMessageFactory.getNewInstance( wanPPPSrv ); - } - if ( msgFactory == null ) { - // Nothing found using WANCommonInterfaceConfig! IP by default - log.warn( "Unable to detect active WANIPConnection, dfaulting to urn:schemas-upnp-org:service:WANIPConnection:1" ); - msgFactory = UPNPMessageFactory.getNewInstance( wanIPSrv ); - } - } - } - - private boolean testWANInterface( UPNPService srv ) { - UPNPMessageFactory tmp = UPNPMessageFactory.getNewInstance( srv ); - - ActionMessage msg = tmp.getMessage( "GetExternalIPAddress" ); - String ipToParse = null; - try { - ipToParse = msg.service().getOutActionArgumentValue( "NewExternalIPAddress" ); - } catch ( UPNPResponseException ex ) { - // ok probably not the IP interface - } catch ( IOException ex ) { - // not really normal - log.warn( "IOException occured during device detection", ex ); - } - if ( ipToParse != null && ipToParse.length() > 0 && !ipToParse.equals( "0.0.0.0" ) ) { - try { - return InetAddress.getByName( ipToParse ) != null; - } catch ( UnknownHostException ex ) { - // ok a crappy IP provided, definitly the wrong interface.. - } - } - return false; - } - - /** - * Retreives the IDG UNPNRootDevice object - * @return the UNPNRootDevie object bound to this object - */ - public UPNPRootDevice getIGDRootDevice() { - return igd; - } - - /** - * Lookup all the IGD (IP or PPP) devices on the network. If a device implements both - * IP and PPP, the active service will be used for nat mappings. - * @param timeout the timeout in ms to listen for devices response, -1 for default value - * @return an array of devices to play with or null if nothing found. - * @throws IOException if some IO Exception occurs during discovery - */ - public static InternetGatewayDevice[] getDevices( int timeout ) throws IOException { - return lookupDeviceDevices( timeout, Discovery.DEFAULT_TTL, Discovery.DEFAULT_MX, true, true, null ); - } - - /** - * Lookup all the IGD (IP urn:schemas-upnp-org:service:WANIPConnection:1, or PPP urn:schemas-upnp-org:service:WANPPPConnection:1) - * devices for a given network interface. If a device implements both - * IP and PPP, the active service will be used for nat mappings. - * @param timeout the timeout in ms to listen for devices response, -1 for default value - * @param ttl the discovery ttl such as {@link net.sbbi.upnp.Discovery#DEFAULT_TTL} - * @param mx the discovery mx such as {@link net.sbbi.upnp.Discovery#DEFAULT_MX} - * @param ni the network interface where to lookup IGD devices - * @return an array of devices to play with or null if nothing found. - * @throws IOException if some IO Exception occurs during discovery - */ - public static InternetGatewayDevice[] getDevices( int timeout, int ttl, int mx, NetworkInterface ni ) throws IOException { - return lookupDeviceDevices( timeout, ttl, mx, true, true, ni ); - } - - /** - * Lookup all the IGD IP devices on the network (urn:schemas-upnp-org:service:WANIPConnection:1 service) - * @param timeout the timeout in ms to listen for devices response, -1 for default value - * @return an array of devices to play with or null if nothing found or if found devices - * do not have the urn:schemas-upnp-org:service:WANIPConnection:1 service - * @deprecated use generic {@link #getDevices(int)} or {@link #getDevices(int, int, int, NetworkInterface)} methods since this one is not - * usable with all IGD devices ( will only work with devices implementing the urn:schemas-upnp-org:service:WANIPConnection:1 service ) - */ - @Deprecated - public static InternetGatewayDevice[] getIPDevices( int timeout ) throws IOException { - return lookupDeviceDevices( timeout, Discovery.DEFAULT_TTL, Discovery.DEFAULT_MX, true, false, null ); - } - - /** - * Lookup all the IGD PPP devices on the network (urn:schemas-upnp-org:service:WANPPPConnection:1 service) - * @param timeout the timeout in ms to listen for devices response, -1 for default value - * @return an array of devices to play with or null if nothing found or if found devices - * do not have the urn:schemas-upnp-org:service:WANPPPConnection:1 service - * @deprecated use generic {@link #getDevices(int)} or {@link #getDevices(int, int, int, NetworkInterface)} methods since this one is not - * usable with all IGD devices ( will only work with devices implementing the urn:schemas-upnp-org:service:WANPPPConnection:1 service ) - */ - @Deprecated - public static InternetGatewayDevice[] getPPPDevices( int timeout ) throws IOException { - return lookupDeviceDevices( timeout, Discovery.DEFAULT_TTL, Discovery.DEFAULT_MX, false, true, null ); - } - - private static InternetGatewayDevice[] lookupDeviceDevices( int timeout, int ttl, int mx, boolean WANIPConnection, boolean WANPPPConnection, NetworkInterface ni ) throws IOException { - UPNPRootDevice[] devices = null; - InternetGatewayDevice[] rtrVal = null; - if ( timeout == -1 ) { - devices = Discovery.discover( Discovery.DEFAULT_TIMEOUT, ttl, mx, "urn:schemas-upnp-org:device:InternetGatewayDevice:1", ni ); - } else { - devices = Discovery.discover( timeout, ttl, mx, "urn:schemas-upnp-org:device:InternetGatewayDevice:1", ni ); - } - - if ( devices != null ) { - Set valid = new HashSet(); - for ( int i = 0; i < devices.length; i++ ) { - try { - valid.add( new InternetGatewayDevice( devices[i], WANIPConnection, WANPPPConnection ) ); - } catch ( UnsupportedOperationException ex ) { - // the device is either not IP or PPP - if ( log.isDebugEnabled() ) log.debug( "UnsupportedOperationException during discovery " + ex.getMessage() ); - } - } - if ( valid.size() == 0 ) { - return null; - } - rtrVal = new InternetGatewayDevice[valid.size()]; - int i = 0; - for ( Iterator itr = valid.iterator(); itr.hasNext(); ) { - rtrVal[i++] = (InternetGatewayDevice)itr.next(); - } - - } - return rtrVal; - } - - /** - * Retreives the external IP address - * @return a String representing the external IP - * @throws UPNPResponseException if the devices returns an error code - * @throws IOException if some error occurs during communication with the device - */ - public String getExternalIPAddress() throws UPNPResponseException, IOException { - ActionMessage msg = msgFactory.getMessage( "GetExternalIPAddress" ); - return msg.service().getOutActionArgumentValue( "NewExternalIPAddress" ); - } - - /** - * Retreives a generic port mapping entry. - * @param newPortMappingIndex the index to lookup in the nat table of the upnp device - * @return an action response Object containing the following fields : - * NewRemoteHost, NewExternalPort, NewProtocol, NewInternalPort, - * NewInternalClient, NewEnabled, NewPortMappingDescription, NewLeaseDuration or null if the index does not exists - * @throws IOException if some error occurs during communication with the device - * @throws UPNPResponseException if some unexpected error occurs on the UPNP device - */ - public ActionResponse getGenericPortMappingEntry( int newPortMappingIndex ) throws IOException, UPNPResponseException { - - ActionMessage msg = msgFactory.getMessage( "GetGenericPortMappingEntry" ); - msg.setInputParameter( "NewPortMappingIndex", newPortMappingIndex ); - - try { - return msg.service(); - } catch ( UPNPResponseException ex ) { - if ( ex.getDetailErrorCode() == 714 ) { - return null; - } - throw ex; - } - - } - - /** - * Retreives information about a specific port mapping - * @param remoteHost the remote host ip to check, null if wildcard - * @param externalPort the port to check - * @param protocol the protocol for the mapping, either TCP or UDP - * @return an action response Object containing the following fields : - * NewInternalPort, NewInternalClient, NewEnabled, NewPortMappingDescription, NewLeaseDuration or - * null if no such entry exists in the device NAT table - * @throws IOException if some error occurs during communication with the device - * @throws UPNPResponseException if some unexpected error occurs on the UPNP device - */ - public ActionResponse getSpecificPortMappingEntry( String remoteHost, int externalPort, String protocol ) throws IOException, UPNPResponseException { - remoteHost = remoteHost == null ? "" : remoteHost; - checkPortMappingProtocol( protocol ); - checkPortRange( externalPort ); - - ActionMessage msg = msgFactory.getMessage( "GetSpecificPortMappingEntry" ); - msg.setInputParameter( "NewRemoteHost", remoteHost ) - .setInputParameter( "NewExternalPort", externalPort ) - .setInputParameter( "NewProtocol", protocol ); - - try { - return msg.service(); - } catch ( UPNPResponseException ex ) { - if ( ex.getDetailErrorCode() == 714 ) { - return null; - } - throw ex; - } - } - - /** - * Configures a nat entry on the UPNP device. - * @param description the mapping description, null for no description - * @param remoteHost the remote host ip for this entry, null for a wildcard value - * @param internalPort the internal client port where data should be redirected - * @param externalPort the external port to open on the UPNP device an map on the internal client, 0 for a wildcard value - * @param internalClient the internal client ip where data should be redirected - * @param leaseDuration the lease duration in seconds 0 for an infinite time - * @param protocol the protocol, either TCP or UDP - * @return true if the port is mapped false if the mapping is allready done for another internal client - * @throws IOException if some error occurs during communication with the device - * @throws UPNPResponseException if the device does not accept some settings :
- * 402 Invalid Args See UPnP Device Architecture section on Control
- * 501 Action Failed See UPnP Device Architecture section on Control
- * 715 WildCardNotPermittedInSrcIP The source IP address cannot be wild-carded
- * 716 WildCardNotPermittedInExtPort The external port cannot be wild-carded
- * 724 SamePortValuesRequired Internal and External port values must be the same
- * 725 OnlyPermanentLeasesSupported The NAT implementation only supports permanent lease times on port mappings
- * 726 RemoteHostOnlySupportsWildcard RemoteHost must be a wildcard and cannot be a specific IP address or DNS name
- * 727 ExternalPortOnlySupportsWildcard ExternalPort must be a wildcard and cannot be a specific port value - */ - public boolean addPortMapping( String description, String remoteHost, - int internalPort, int externalPort, - String internalClient, int leaseDuration, - String protocol ) throws IOException, UPNPResponseException { - remoteHost = remoteHost == null ? "" : remoteHost; - checkPortMappingProtocol( protocol ); - if ( externalPort != 0 ) { - checkPortRange( externalPort ); - } - checkPortRange( internalPort ); - description = description == null ? "" : description; - if ( leaseDuration < 0 ) throw new IllegalArgumentException( "Invalid leaseDuration (" + leaseDuration + ") value" ); - - ActionMessage msg = msgFactory.getMessage( "AddPortMapping" ); - msg.setInputParameter( "NewRemoteHost", remoteHost ) - .setInputParameter( "NewExternalPort", externalPort ) - .setInputParameter( "NewProtocol", protocol ) - .setInputParameter( "NewInternalPort", internalPort ) - .setInputParameter( "NewInternalClient", internalClient ) - .setInputParameter( "NewEnabled", true ) - .setInputParameter( "NewPortMappingDescription", description ) - .setInputParameter( "NewLeaseDuration", leaseDuration ); - try { - msg.service(); - return true; - } catch ( UPNPResponseException ex ) { - if ( ex.getDetailErrorCode() == 718 ) { - return false; - } - throw ex; - } - } - - /** - * Deletes a port mapping on the IDG device - * @param remoteHost the host ip for which the mapping was done, null value for a wildcard value - * @param externalPort the port to close - * @param protocol the protocol for the mapping, TCP or UDP - * @return true if the port has been unmapped correctly otherwise false ( entry does not exists ). - * @throws IOException if some error occurs during communication with the device - * @throws UPNPResponseException if the devices returns an error message - */ - public boolean deletePortMapping( String remoteHost, int externalPort, String protocol ) throws IOException, UPNPResponseException { - - remoteHost = remoteHost == null ? "" : remoteHost; - checkPortMappingProtocol( protocol ); - checkPortRange( externalPort ); - ActionMessage msg = msgFactory.getMessage( "DeletePortMapping" ); - msg.setInputParameter( "NewRemoteHost", remoteHost ) - .setInputParameter( "NewExternalPort", externalPort ) - .setInputParameter( "NewProtocol", protocol ); - try { - msg.service(); - return true; - } catch ( UPNPResponseException ex ) { - if ( ex.getDetailErrorCode() == 714 ) { - return false; - } - throw ex; - } - } - - /** - * Retreives the current number of mapping in the NAT table - * @return the nat table current number of mappings or null if the device does not allow to query state variables - * @throws IOException if some error occurs during communication with the device - * @throws UPNPResponseException if the devices returns an error message with error code other than 404 - */ - public Integer getNatMappingsCount() throws IOException, UPNPResponseException { - - Integer rtrval = null; - StateVariableMessage natTableSize = msgFactory.getStateVariableMessage( "PortMappingNumberOfEntries" ); - try { - StateVariableResponse resp = natTableSize.service(); - rtrval = Integer.valueOf( resp.getStateVariableValue() ); - } catch ( UPNPResponseException ex ) { - // 404 can happen if device do not implement state variables queries - if ( ex.getDetailErrorCode() != 404 ) { - throw ex; - } - } - return rtrval; - } - - /** - * Computes the total entries in avaliable in the nat table size, not that this method is not guaranteed to work - * with all upnp devices since it is not an generic IGD command - * @return the number of entries or null if the NAT table size cannot be computed for the device - * @throws IOException if some error occurs during communication with the device - * @throws UPNPResponseException if the devices returns an error message with error code other than 713 or 402 - */ - public Integer getNatTableSize() throws IOException, UPNPResponseException { - - // first let's look at the first index.. some crappy devices do not start with index 0 - // we stop at index 50 - int startIndex = -1; - for ( int i = 0; i < 50; i++ ) { - try { - this.getGenericPortMappingEntry( i ); - startIndex = i; - break; - } catch ( UPNPResponseException ex ) { - // some devices return the 402 code - if ( ex.getDetailErrorCode() != 713 && ex.getDetailErrorCode() != 402 ) { - throw ex; - } - } - } - if ( startIndex == -1 ) { - // humm nothing found within the first 200 indexes.. - // returning null - return null; - } - int size = 0; - while ( true ) { - - try { - this.getGenericPortMappingEntry( startIndex++ ); - size++; - } catch ( UPNPResponseException ex ) { - if ( ex.getDetailErrorCode() == 713 || ex.getDetailErrorCode() == 402 ) { - /// ok index unknown - break; - } - throw ex; - } - } - return Integer.valueOf( size ); - } - - private void checkPortMappingProtocol( String prot ) throws IllegalArgumentException { - if ( prot == null || ( !prot.equals( "TCP" ) && !prot.equals( "UDP" ) ) ) - throw new IllegalArgumentException( "PortMappingProtocol must be either TCP or UDP" ); - } - - private void checkPortRange( int port ) throws IllegalArgumentException { - if ( port < 1 || port > 65535 ) - throw new IllegalArgumentException( "Port range must be between 1 and 65535" ); - } - - -} diff --git a/source/net/sbbi/upnp/messages/ActionMessage.java b/source/net/sbbi/upnp/messages/ActionMessage.java deleted file mode 100644 index 6c28f8f9d..000000000 --- a/source/net/sbbi/upnp/messages/ActionMessage.java +++ /dev/null @@ -1,438 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -import java.util.*; -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.xml.sax.*; -import net.sbbi.upnp.services.*; - -import javax.xml.parsers.*; - -/** - * Message object for an UPNP action, simply call setInputParameter() to add - * the required action message params and then service() to receive the ActionResponse - * built with the parsed UPNP device SOAP xml response. - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class ActionMessage { - - private final static Log log = LogFactory.getLog( ActionMessage.class ); - - private final UPNPService service; - private final ServiceAction serviceAction; - private List inputParameters; - - /** - * Protected constuctor so that only messages factories can build it - * @param service the service for which the - * @param serviceAction - */ - protected ActionMessage( UPNPService service, ServiceAction serviceAction ) { - this.service = service; - this.serviceAction = serviceAction; - if ( serviceAction.getInputActionArguments() != null ) { - inputParameters = new ArrayList(); - } - } - - /** - * Method to clear all set input parameters so that - * this object can be reused - */ - public void clearInputParameters() { - inputParameters.clear(); - } - - /** - * Executes the message and retuns the UPNP device response, according to the UPNP specs, - * this method could take up to 30 secs to process ( time allowed for a device to respond to a request ) - * @return a response object containing the UPNP parsed response - * @throws IOException if some IOException occurs during message send and reception process - * @throws UPNPResponseException if an UPNP error message is returned from the server - * or if some parsing exception occurs ( detailErrorCode = 899, detailErrorDescription = SAXException message ) - */ - public ActionResponse service() throws IOException, UPNPResponseException { - ActionResponse rtrVal = null; - UPNPResponseException upnpEx = null; - IOException ioEx = null; - StringBuffer body = new StringBuffer( 256 ); - - body.append( "\r\n" ); - body.append( "" ); - body.append( "" ); - body.append( "" ); - - if ( serviceAction.getInputActionArguments() != null ) { - // this action requires params so we just set them... - for ( Iterator itr = inputParameters.iterator(); itr.hasNext(); ) { - InputParamContainer container = (InputParamContainer)itr.next(); - body.append( '<' ).append( container.name ).append( '>' ).append( container.value ); - body.append( "' ); - } - } - body.append( "' ); - body.append( "" ); - body.append( "" ); - - if ( log.isDebugEnabled() ) log.debug( "POST prepared for URL " + service.getControlURL() ); - URL url = new URL( service.getControlURL().toString() ); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - conn.setDoInput( true ); - conn.setDoOutput( true ); - conn.setUseCaches( false ); - conn.setRequestMethod( "POST" ); - HttpURLConnection.setFollowRedirects( false ); - //conn.setConnectTimeout( 30000 ); - conn.setRequestProperty( "HOST", url.getHost() + ":" + url.getPort() ); - conn.setRequestProperty( "CONTENT-TYPE", "text/xml; charset=\"utf-8\"" ); - conn.setRequestProperty( "CONTENT-LENGTH", Integer.toString( body.length() ) ); - conn.setRequestProperty( "SOAPACTION", "\"" + service.getServiceType() + "#" + serviceAction.getName() + "\"" ); - OutputStream out = conn.getOutputStream(); - out.write( body.toString().getBytes() ); - out.flush(); - out.close(); - conn.connect(); - InputStream input = null; - - if ( log.isDebugEnabled() ) log.debug( "executing query :\n" + body ); - try { - input = conn.getInputStream(); - } catch ( IOException ex ) { - // java can throw an exception if he error code is 500 or 404 or something else than 200 - // but the device sends 500 error message with content that is required - // this content is accessible with the getErrorStream - input = conn.getErrorStream(); - } - - if ( input != null ) { - int response = conn.getResponseCode(); - String responseBody = getResponseBody( input ); - if ( log.isDebugEnabled() ) log.debug( "received response :\n" + responseBody ); - SAXParserFactory saxParFact = SAXParserFactory.newInstance(); - saxParFact.setValidating( false ); - saxParFact.setNamespaceAware( true ); - ActionMessageResponseParser msgParser = new ActionMessageResponseParser( serviceAction ); - StringReader stringReader = new StringReader( responseBody ); - InputSource src = new InputSource( stringReader ); - try { - SAXParser parser = saxParFact.newSAXParser(); - parser.parse( src, msgParser ); - } catch ( ParserConfigurationException confEx ) { - // should never happen - // we throw a runtimeException to notify the env problem - throw new RuntimeException( "ParserConfigurationException during SAX parser creation, please check your env settings:" + confEx.getMessage() ); - } catch ( SAXException saxEx ) { - // kind of tricky but better than nothing.. - upnpEx = new UPNPResponseException( 899, saxEx.getMessage() ); - } finally { - try { - input.close(); - } catch ( IOException ex ) { - // ignore - } - } - if ( upnpEx == null ) { - if ( response == HttpURLConnection.HTTP_OK ) { - rtrVal = msgParser.getActionResponse(); - } else if ( response == HttpURLConnection.HTTP_INTERNAL_ERROR ) { - upnpEx = msgParser.getUPNPResponseException(); - } else { - ioEx = new IOException( "Unexpected server HTTP response:" + response ); - } - } - } - try { - out.close(); - } catch ( IOException ex ) { - // ignore - } - conn.disconnect(); - if ( upnpEx != null ) { - throw upnpEx; - } - if ( rtrVal == null && ioEx == null ) { - ioEx = new IOException( "Unable to receive a response from the UPNP device" ); - } - if ( ioEx != null ) { - throw ioEx; - } - return rtrVal; - } - - private String getResponseBody( InputStream in ) throws IOException { - byte[] buffer = new byte[256]; - int readen = 0; - StringBuffer content = new StringBuffer( 256 ); - while ( ( readen = in.read( buffer ) ) != -1 ) { - content.append( new String( buffer, 0 , readen ) ); - } - // some devices add \0 chars at XML message end - // which causes XML parsing errors... - int len = content.length(); - while ( content.charAt( len-1 ) == '\0' ) { - len--; - content.setLength( len ); - } - return content.toString().trim(); - } - - /** - * The list of input parameters that should be accepted by the device service for this message - * @return a list of required input parameters ServiceActionArgument objects for this message - * or null if the message does not require any input params - */ - public List getInputParameterNames() { - return serviceAction.getInputActionArgumentsNames(); - } - - /** - * The list of output parameters that should be returned by the device service - * @return a list of output parameters ServiceActionArgument objects for this message - * or null if the message does not contains any output params. - */ - public List getOutputParameterNames() { - return serviceAction.getOutputActionArgumentsNames(); - } - - /** - * Set the value of an input parameter before a message service call. If the param name already - * exists, the param value will be overwritten with the new value provided. - * @param parameterName the parameter name - * @param parameterValue the parameter value as an object, primitive object are handled, all other object - * will be assigned with a call to their toString() method call - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, Object parameterValue ) throws IllegalArgumentException { - if ( parameterValue == null ) { - return setInputParameter( parameterName, "" ); - } else if ( parameterValue instanceof Date ) { - return setInputParameter( parameterName, (Date)parameterValue ); - } else if ( parameterValue instanceof Boolean ) { - return setInputParameter( parameterName, ((Boolean)parameterValue).booleanValue() ); - } else if ( parameterValue instanceof Integer ) { - return setInputParameter( parameterName, ((Integer)parameterValue).intValue() ); - } else if ( parameterValue instanceof Byte ) { - return setInputParameter( parameterName, ((Byte)parameterValue).byteValue() ); - } else if ( parameterValue instanceof Short ) { - return setInputParameter( parameterName, ((Short)parameterValue).shortValue() ); - } else if ( parameterValue instanceof Float ) { - return setInputParameter( parameterName, ((Float)parameterValue).floatValue() ); - } else if ( parameterValue instanceof Double ) { - return setInputParameter( parameterName, ((Double)parameterValue).doubleValue() ); - } else if ( parameterValue instanceof Long ) { - return setInputParameter( parameterName, ((Long)parameterValue).longValue() ); - } - return setInputParameter( parameterName, parameterValue.toString() ); - } - - - - /** - * Set the value of an input parameter before a message service call. If the param name already - * exists, the param value will be overwritten with the new value provided - * @param parameterName the parameter name - * @param parameterValue the string parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, String parameterValue ) throws IllegalArgumentException { - if ( serviceAction.getInputActionArguments() == null ) throw new IllegalArgumentException( "No input parameters required for this message" ); - ServiceActionArgument arg = serviceAction.getInputActionArgument( parameterName ); - if ( arg == null ) throw new IllegalArgumentException( "Wrong input argument name for this action:" + parameterName + " available parameters are : " + getInputParameterNames() ); - for ( Iterator i = inputParameters.iterator(); i.hasNext(); ) { - InputParamContainer container = (InputParamContainer)i.next(); - if ( container.name.equals( parameterName ) ) { - container.value = parameterValue; - return this; - } - } - // nothing found add the new value - InputParamContainer container = new InputParamContainer(); - container.name = parameterName; - container.value = parameterValue; - inputParameters.add( container ); - return this; - } - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the date parameter value, will be automatically translated to the correct - * ISO 8601 date format for the given action input param related state variable - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, Date parameterValue ) throws IllegalArgumentException { - if ( serviceAction.getInputActionArguments() == null ) throw new IllegalArgumentException( "No input parameters required for this message" ); - ServiceActionArgument arg = serviceAction.getInputActionArgument( parameterName ); - if ( arg == null ) throw new IllegalArgumentException( "Wrong input argument name for this action:" + parameterName + " available parameters are : " + getInputParameterNames() ); - ServiceStateVariable linkedVar = arg.getRelatedStateVariable(); - if ( linkedVar.getDataType().equals( ServiceStateVariableTypes.TIME ) ) { - return setInputParameter( parameterName, ISO8601Date.getIsoTime( parameterValue ) ); - } else if ( linkedVar.getDataType().equals( ServiceStateVariableTypes.TIME_TZ ) ) { - return setInputParameter( parameterName, ISO8601Date.getIsoTimeZone( parameterValue ) ); - } else if ( linkedVar.getDataType().equals( ServiceStateVariableTypes.DATE ) ) { - return setInputParameter( parameterName, ISO8601Date.getIsoDate( parameterValue ) ); - } else if ( linkedVar.getDataType().equals( ServiceStateVariableTypes.DATETIME ) ) { - return setInputParameter( parameterName, ISO8601Date.getIsoDateTime( parameterValue ) ); - } else if ( linkedVar.getDataType().equals( ServiceStateVariableTypes.DATETIME_TZ ) ) { - return setInputParameter( parameterName, ISO8601Date.getIsoDateTimeZone( parameterValue ) ); - } else { - throw new IllegalArgumentException( "Related input state variable " + linkedVar.getName() + " is not of an date type" ); - } - } - - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the boolean parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, boolean parameterValue ) throws IllegalArgumentException { - return setInputParameter( parameterName, parameterValue ? "1" : "0" ); - } - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the byte parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, byte parameterValue ) throws IllegalArgumentException { - return setInputParameter( parameterName, Byte.toString( parameterValue ) ); - } - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the short parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, short parameterValue ) throws IllegalArgumentException { - return setInputParameter( parameterName, Short.toString( parameterValue ) ); - } - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the integer parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, int parameterValue ) throws IllegalArgumentException { - return setInputParameter( parameterName, Integer.toString( parameterValue ) ); - } - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the long parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, long parameterValue ) throws IllegalArgumentException { - return setInputParameter( parameterName, Long.toString( parameterValue ) ); - } - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the float parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, float parameterValue ) throws IllegalArgumentException { - return setInputParameter( parameterName, Float.toString( parameterValue ) ); - } - - /** - * Set the value of an input parameter before a message service call - * @param parameterName the parameter name - * @param parameterValue the double parameter value - * @return the current ActionMessage object instance - * @throws IllegalArgumentException if the provided parameterName is not valid for this message - * or if no input parameters are required for this message - */ - public ActionMessage setInputParameter( String parameterName, double parameterValue ) throws IllegalArgumentException { - return setInputParameter( parameterName, Double.toString( parameterValue ) ); - } - - /** - * Input params class container - */ - class InputParamContainer { - - String name; - String value; - - } - -} diff --git a/source/net/sbbi/upnp/messages/ActionMessageResponseParser.java b/source/net/sbbi/upnp/messages/ActionMessageResponseParser.java deleted file mode 100644 index 4aa9ae7d1..000000000 --- a/source/net/sbbi/upnp/messages/ActionMessageResponseParser.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.xml.sax.Attributes; - -import net.sbbi.upnp.services.*; - -/** - * Simple SAX handler for UPNP response message parsing, this message is in SOAP format - * @author SuperBonBon - * @version 1.0 - */ - -public class ActionMessageResponseParser extends org.xml.sax.helpers.DefaultHandler { - - private final static Log log = LogFactory.getLog( ActionMessageResponseParser.class ); - - private final static String SOAP_FAULT_EL = "Fault"; - - private final ServiceAction serviceAction; - private final String bodyElementName; - private boolean faultResponse = false; - private UPNPResponseException msgEx; - - private boolean readFaultCode = false; - private boolean readFaultString = false; - private boolean readErrorCode = false; - private boolean readErrorDescription = false; - private boolean parseOutputParams = false; - private ActionResponse result; - private ServiceActionArgument parsedResultOutArg; - - protected ActionMessageResponseParser( ServiceAction serviceAction ) { - this.serviceAction = serviceAction; - bodyElementName = serviceAction.getName() + "Response"; - } - - protected UPNPResponseException getUPNPResponseException() { - return msgEx; - } - - protected ActionResponse getActionResponse() { - return result; - } - - public void characters( char[] ch, int start, int length ) { - if ( parseOutputParams ) { - if ( parsedResultOutArg != null ) { - String origChars = result.getOutActionArgumentValue( parsedResultOutArg.getName() ); - String newChars = new String( ch, start, length ); - if ( origChars == null ) { - result.addResult( parsedResultOutArg, newChars ); - } else { - result.addResult( parsedResultOutArg, origChars + newChars ); - } - } - } else if ( readFaultCode ) { - msgEx.faultCode = new String( ch, start, length ); - readFaultCode = false; - } else if ( readFaultString ) { - msgEx.faultString = new String( ch, start, length ); - readFaultString = false; - } else if ( readErrorCode ) { - String code = new String( ch, start, length ); - try { - msgEx.detailErrorCode = Integer.parseInt( code ); - } catch ( Throwable ex ) { - log.debug( "Error during returned error code " + code + " parsing" ); - } - readErrorCode = false; - } else if ( readErrorDescription ) { - msgEx.detailErrorDescription = new String( ch, start, length ); - readErrorDescription = false; - } - } - - public void startElement( String uri, String localName, String qName, Attributes attributes ) { - if ( parseOutputParams ) { - ServiceActionArgument arg = serviceAction.getActionArgument( localName ); - if ( arg != null && arg.getDirection() == ServiceActionArgument.DIRECTION_OUT ) { - parsedResultOutArg = arg; - result.addResult( parsedResultOutArg, null ); - } else { - parsedResultOutArg = null; - } - } else if ( faultResponse ) { - if ( localName.equals( "faultcode") ) { - readFaultCode = true; - } else if ( localName.equals( "faultstring" ) ) { - readFaultString = true; - } else if ( localName.equals( "errorCode" ) ) { - readErrorCode = true; - } else if ( localName.equals( "errorDescription" ) ) { - readErrorDescription = true; - } - } else if ( localName.equals( SOAP_FAULT_EL ) ) { - msgEx = new UPNPResponseException(); - faultResponse = true; - } else if ( localName.equals( bodyElementName ) ) { - parseOutputParams = true; - result = new ActionResponse(); - } - } - - public void endElement( String uri, String localName, String qName ) { - if ( parsedResultOutArg != null && parsedResultOutArg.getName().equals( localName ) ) { - parsedResultOutArg = null; - } else if ( localName.equals( bodyElementName ) ) { - parseOutputParams = false; - } - } -} diff --git a/source/net/sbbi/upnp/messages/ActionResponse.java b/source/net/sbbi/upnp/messages/ActionResponse.java deleted file mode 100644 index 40da7f5e8..000000000 --- a/source/net/sbbi/upnp/messages/ActionResponse.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -import net.sbbi.upnp.services.ServiceActionArgument; - -import java.util.*; - -/** - * An action respons container Object - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class ActionResponse { - - private final Map outArguments = new HashMap(); - private final Map outArgumentsVals = new HashMap(); - - protected ActionResponse() { - } - - public ServiceActionArgument getOutActionArgument( String actionArgumentName ) { - return (ServiceActionArgument)outArguments.get( actionArgumentName ); - } - - public String getOutActionArgumentValue( String actionArgumentName ) { - return (String)outArgumentsVals.get( actionArgumentName ); - } - - public Set getOutActionArgumentNames() { - return outArguments.keySet(); - } - - /** - * Adds a result to the response, adding an existing result ServiceActionArgument - * will override the ServiceActionArgument value - * @param arg the service action argument - * @param value the arg value - */ - protected void addResult( ServiceActionArgument arg, String value ) { - outArguments.put( arg.getName(), arg ); - outArgumentsVals.put( arg.getName(), value ); - } - - public String toString() { - StringBuffer rtrVal = new StringBuffer(); - for ( Iterator i = outArguments.keySet().iterator(); i.hasNext(); ) { - String name = (String)i.next(); - String value = (String)outArgumentsVals.get( name ); - rtrVal.append( name ).append( '=' ).append( value ); - if ( i.hasNext() ) rtrVal.append( '\n' ); - } - return rtrVal.toString(); - } - -} diff --git a/source/net/sbbi/upnp/messages/StateVariableMessage.java b/source/net/sbbi/upnp/messages/StateVariableMessage.java deleted file mode 100644 index 93fe1546e..000000000 --- a/source/net/sbbi/upnp/messages/StateVariableMessage.java +++ /dev/null @@ -1,204 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -import org.xml.sax.*; -import javax.xml.parsers.*; -import java.io.*; -import java.net.HttpURLConnection; -import java.net.URL; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import net.sbbi.upnp.services.*; - -/** - * This class is used to create state variable messages to - * comminicate with the device - * @author SuperBonBon - * @version 1.0 - */ - -public class StateVariableMessage { - - private final static Log log = LogFactory.getLog( StateVariableMessage.class ); - - private final UPNPService service; - private final ServiceStateVariable serviceStateVar; - - protected StateVariableMessage( UPNPService service, ServiceStateVariable serviceStateVar ) { - this.service = service; - this.serviceStateVar = serviceStateVar; - } - - /** - * Executes the state variable query and retuns the UPNP device response, according to the UPNP specs, - * this method could take up to 30 secs to process ( time allowed for a device to respond to a request ) - * @return a state variable response object containing the variable value - * @throws IOException if some IOException occurs during message send and reception process - * @throws UPNPResponseException if an UPNP error message is returned from the server - * or if some parsing exception occurs ( detailErrorCode = 899, detailErrorDescription = SAXException message ) - */ - public StateVariableResponse service() throws IOException, UPNPResponseException { - StateVariableResponse rtrVal = null; - UPNPResponseException upnpEx = null; - IOException ioEx = null; - StringBuffer body = new StringBuffer( 256 ); - - body.append( "\r\n" ); - body.append( "" ); - body.append( "" ); - body.append( "" ); - body.append( "" ).append( serviceStateVar.getName() ).append( "" ); - body.append( "" ); - body.append( "" ); - body.append( "" ); - - if ( log.isDebugEnabled() ) log.debug( "POST prepared for URL " + service.getControlURL() ); - URL url = new URL( service.getControlURL().toString() ); - HttpURLConnection conn = (HttpURLConnection)url.openConnection(); - conn.setDoInput( true ); - conn.setDoOutput( true ); - conn.setUseCaches( false ); - conn.setRequestMethod( "POST" ); - HttpURLConnection.setFollowRedirects( false ); - //conn.setConnectTimeout( 30000 ); - conn.setRequestProperty( "HOST", url.getHost() + ":" + url.getPort() ); - conn.setRequestProperty( "SOAPACTION", "\"urn:schemas-upnp-org:control-1-0#QueryStateVariable\"" ); - conn.setRequestProperty( "CONTENT-TYPE", "text/xml; charset=\"utf-8\"" ); - conn.setRequestProperty( "CONTENT-LENGTH", Integer.toString( body.length() ) ); - OutputStream out = conn.getOutputStream(); - out.write( body.toString().getBytes() ); - out.flush(); - conn.connect(); - InputStream input = null; - - if ( log.isDebugEnabled() ) log.debug( "executing query :\n" + body ); - try { - input = conn.getInputStream(); - } catch ( IOException ex ) { - // java can throw an exception if he error code is 500 or 404 or something else than 200 - // but the device sends 500 error message with content that is required - // this content is accessible with the getErrorStream - input = conn.getErrorStream(); - } - - if ( input != null ) { - int response = conn.getResponseCode(); - String responseBody = getResponseBody( input ); - if ( log.isDebugEnabled() ) log.debug( "received response :\n" + responseBody ); - SAXParserFactory saxParFact = SAXParserFactory.newInstance(); - saxParFact.setValidating( false ); - saxParFact.setNamespaceAware( true ); - StateVariableResponseParser msgParser = new StateVariableResponseParser( serviceStateVar ); - StringReader stringReader = new StringReader( responseBody ); - InputSource src = new InputSource( stringReader ); - try { - SAXParser parser = saxParFact.newSAXParser(); - parser.parse( src, msgParser ); - } catch ( ParserConfigurationException confEx ) { - // should never happen - // we throw a runtimeException to notify the env problem - throw new RuntimeException( "ParserConfigurationException during SAX parser creation, please check your env settings:" + confEx.getMessage() ); - } catch ( SAXException saxEx ) { - // kind of tricky but better than nothing.. - upnpEx = new UPNPResponseException( 899, saxEx.getMessage() ); - } finally { - try { - input.close(); - } catch ( IOException ex ) { - // ignoring - } - } - if ( upnpEx == null ) { - if ( response == HttpURLConnection.HTTP_OK ) { - rtrVal = msgParser.getStateVariableResponse(); - } else if ( response == HttpURLConnection.HTTP_INTERNAL_ERROR ) { - upnpEx = msgParser.getUPNPResponseException(); - } else { - ioEx = new IOException( "Unexpected server HTTP response:" + response ); - } - } - } - try { - out.close(); - } catch ( IOException ex ) { - // ignore - } - conn.disconnect(); - if ( upnpEx != null ) { - throw upnpEx; - } - if ( rtrVal == null && ioEx == null ) { - ioEx = new IOException( "Unable to receive a response from the UPNP device" ); - } - if ( ioEx != null ) { - throw ioEx; - } - return rtrVal; - } - - private String getResponseBody( InputStream in ) throws IOException { - byte[] buffer = new byte[256]; - int readen = 0; - StringBuffer content = new StringBuffer( 256 ); - while ( ( readen = in.read( buffer ) ) != -1 ) { - content.append( new String( buffer, 0 , readen ) ); - } - // some devices add \0 chars at XML message end - // which causes XML parsing errors... - int len = content.length(); - while ( content.charAt( len-1 ) == '\0' ) { - len--; - content.setLength( len ); - } - return content.toString().trim(); - } -} diff --git a/source/net/sbbi/upnp/messages/StateVariableResponse.java b/source/net/sbbi/upnp/messages/StateVariableResponse.java deleted file mode 100644 index 196f7c036..000000000 --- a/source/net/sbbi/upnp/messages/StateVariableResponse.java +++ /dev/null @@ -1,74 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -import net.sbbi.upnp.services.ServiceStateVariable; - -/** - * This class contains data returned by a state variable query response - * @author SuperBonBon - * @version 1.0 - */ -public class StateVariableResponse { - - protected ServiceStateVariable stateVar; - protected String stateVariableValue; - - protected StateVariableResponse() { - } - - public ServiceStateVariable getStateVar() { - return stateVar; - } - - public String getStateVariableValue() { - return stateVariableValue; - } - - -} diff --git a/source/net/sbbi/upnp/messages/StateVariableResponseParser.java b/source/net/sbbi/upnp/messages/StateVariableResponseParser.java deleted file mode 100644 index 000164ce0..000000000 --- a/source/net/sbbi/upnp/messages/StateVariableResponseParser.java +++ /dev/null @@ -1,154 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.xml.sax.Attributes; -import org.xml.sax.SAXException; - -import net.sbbi.upnp.services.*; - -/** - * Simple SAX handler for UPNP state variable query response message parsing, this message is in SOAP format - * @author SuperBonBon - * @version 1.0 - */ - -public class StateVariableResponseParser extends org.xml.sax.helpers.DefaultHandler { - - private final static Log log = LogFactory.getLog( StateVariableResponseParser.class ); - - private final static String SOAP_FAULT_EL = "Fault"; - - private ServiceStateVariable stateVar; - private boolean faultResponse = false; - private UPNPResponseException msgEx; - - private boolean readFaultCode = false; - private boolean readFaultString = false; - private boolean readErrorCode = false; - private boolean readErrorDescription = false; - private boolean parseStateVar = false; - private StateVariableResponse result; - - protected StateVariableResponseParser( ServiceStateVariable stateVar ) { - this.stateVar = stateVar; - } - - protected UPNPResponseException getUPNPResponseException() { - return msgEx; - } - - protected StateVariableResponse getStateVariableResponse() { - return result; - } - - public void characters( char[] ch, int start, int length ) { - if ( parseStateVar ) { - String origChars = result.stateVariableValue; - String newChars = new String( ch, start, length ); - if ( origChars == null ) { - result.stateVariableValue = newChars; - } else { - result.stateVariableValue = origChars + newChars; - } - } else if ( readFaultCode ) { - msgEx.faultCode = new String( ch, start, length ); - readFaultCode = false; - } else if ( readFaultString ) { - msgEx.faultString = new String( ch, start, length ); - readFaultString = false; - } else if ( readErrorCode ) { - String code = new String( ch, start, length ); - try { - msgEx.detailErrorCode = Integer.parseInt( code ); - } catch ( Throwable ex ) { - log.debug( "Error during returned error code " + code + " parsing" ); - } - readErrorCode = false; - } else if ( readErrorDescription ) { - msgEx.detailErrorDescription = new String( ch, start, length ); - readErrorDescription = false; - } - } - - public void startElement( String uri, String localName, String qName, Attributes attributes ) { - - if ( faultResponse ) { - if ( localName.equals( "faultcode") ) { - readFaultCode = true; - } else if ( localName.equals( "faultstring" ) ) { - readFaultString = true; - } else if ( localName.equals( "errorCode" ) ) { - readErrorCode = true; - } else if ( localName.equals( "errorDescription" ) ) { - readErrorDescription = true; - } - } else if ( localName.equals( SOAP_FAULT_EL ) ) { - msgEx = new UPNPResponseException(); - faultResponse = true; - } else if ( localName.equals( "return" ) || localName.equals( "varName" ) ) { - // some buggy implementations ( intel sample media server ) - // do not use the specs compliant return element name but varName ... - parseStateVar = true; - result = new StateVariableResponse(); - result.stateVar = stateVar; - } - } - - public void endElement( String uri, String localName, String qName ) throws SAXException { - // some buggy implementations ( intel sample media server ) - // do not use the specs compliant return element name but varName ... - if ( localName.equals( "return" ) || localName.equals( "varName" ) ) { - parseStateVar = false; - } - } - -} - diff --git a/source/net/sbbi/upnp/messages/UPNPMessageFactory.java b/source/net/sbbi/upnp/messages/UPNPMessageFactory.java deleted file mode 100644 index 9d40ab372..000000000 --- a/source/net/sbbi/upnp/messages/UPNPMessageFactory.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -import net.sbbi.upnp.services.*; - -/** - * Factory to create UPNP messages to access and communicate with - * a given UPNPDevice service capabilities - * @author SuperBonBon - * @version 1.0 - */ - -public final class UPNPMessageFactory { - - private final UPNPService service; - - /** - * Private constructor since this is a factory. - * @param service the UPNPService that will be used to generate messages by thid factory - */ - private UPNPMessageFactory( UPNPService service ) { - this.service = service; - } - - /** - * Generate a new factory instance for a given device service definition object - * @param service the UPNP service definition object for messages creation - * @return a new message factory - */ - public static UPNPMessageFactory getNewInstance( UPNPService service ) { - return new UPNPMessageFactory( service ); - } - - /** - * Creation of a new ActionMessage to communicate with the UPNP device - * @param serviceActionName the name of a service action, this name is case sensitive - * and matches exactly the name provided by the UPNP device in the XML definition file - * @return a ActionMessage object or null if the action is unknown for this service messages factory - */ - public ActionMessage getMessage( String serviceActionName ) { - ServiceAction serviceAction = service.getUPNPServiceAction( serviceActionName ); - if ( serviceAction != null ) { - return new ActionMessage( service, serviceAction ); - } - return null; - } - - /** - * Creation of a new StateVariableMessage to communicate with the UPNP device, for a service state variable query - * @param serviceStateVariable the name of a service state variable, this name is case sensitive - * and matches exactly the name provided by the UPNP device in the XML definition file - * @return a StateVariableMessage object or null if the state variable is unknown for this service mesages factory - */ - public StateVariableMessage getStateVariableMessage( String serviceStateVariable ) { - ServiceStateVariable stateVar = service.getUPNPServiceStateVariable( serviceStateVariable ); - if ( stateVar != null ) { - return new StateVariableMessage( service, stateVar ); - } - return null; - } - -} diff --git a/source/net/sbbi/upnp/messages/UPNPResponseException.java b/source/net/sbbi/upnp/messages/UPNPResponseException.java deleted file mode 100644 index d3a5e1f48..000000000 --- a/source/net/sbbi/upnp/messages/UPNPResponseException.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.messages; - -/** - * An exception throws when parsing a message if a SOAP fault - * exception is returned. - * @author SuperBonBon - * @version 1.0 - */ -public class UPNPResponseException extends Exception { - - private static final long serialVersionUID = 8313107558129180594L; - - protected String faultCode; - protected String faultString; - protected int detailErrorCode; - protected String detailErrorDescription; - - public UPNPResponseException() { - } - - public UPNPResponseException( int detailErrorCode, String detailErrorDescription ) { - this.detailErrorCode = detailErrorCode; - this.detailErrorDescription = detailErrorDescription; - } - - public String getFaultCode() { - return faultCode == null ? "Client" : faultCode ; - } - - public String getFaultString() { - return faultString == null ? "UPnPError" : faultString; - } - - public int getDetailErrorCode() { - return detailErrorCode; - } - - public String getDetailErrorDescription() { - return detailErrorDescription; - } - - public String getMessage() { - return "Detailed error code :" + detailErrorCode + ", Detailed error description :" + detailErrorDescription; - } - - public String getLocalizedMessage() { - return getMessage(); - } - -} diff --git a/source/net/sbbi/upnp/services/ISO8601Date.java b/source/net/sbbi/upnp/services/ISO8601Date.java deleted file mode 100644 index e89ab9506..000000000 --- a/source/net/sbbi/upnp/services/ISO8601Date.java +++ /dev/null @@ -1,331 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.services; - -import java.util.Calendar; -import java.util.Date; -import java.util.GregorianCalendar; -import java.util.NoSuchElementException; -import java.util.StringTokenizer; -import java.util.TimeZone; - -/** - * ISO8601 Date implementation taken from org.w3c package and modified - * to work with UPNP date types - * @author SuperBonBon - * @version 1.0 - */ - -public class ISO8601Date { - - private static boolean check(StringTokenizer st, String token) throws NumberFormatException { - try { - if (st.nextToken().equals(token)) { - return true; - } else { - throw new NumberFormatException("Missing [" + token + "]"); - } - } catch (NoSuchElementException ex) { - return false; - } - } - - private static Calendar getCalendar( String isodate ) throws NumberFormatException { - // YYYY-MM-DDThh:mm:ss.sTZD or hh:mm:ss.sTZD - // does it contains a date ? - boolean isATime = isodate.indexOf( ':' ) != -1; - boolean isADate = isodate.indexOf( '-' ) != -1 || ( isodate.length() == 4 && !isATime ); - if ( isATime && ! isADate ) { - if ( !isodate.toUpperCase().startsWith( "T" ) ) { - isodate = "T" + isodate; - } - } - StringTokenizer st = new StringTokenizer(isodate, "-T:.+Z", true); - Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - calendar.clear(); - if ( isADate ) { - // Year - if (st.hasMoreTokens()) { - int year = Integer.parseInt(st.nextToken()); - calendar.set(Calendar.YEAR, year); - } else { - return calendar; - } - // Month - if (check(st, "-") && (st.hasMoreTokens())) { - int month = Integer.parseInt(st.nextToken()) - 1; - calendar.set(Calendar.MONTH, month); - } else { - return calendar; - } - // Day - if (check(st, "-") && (st.hasMoreTokens())) { - int day = Integer.parseInt(st.nextToken()); - calendar.set(Calendar.DAY_OF_MONTH, day); - } else { - return calendar; - } - } - // Hour - if ( ( check(st, "T") ) && ( st.hasMoreTokens() ) ) { - int hour = Integer.parseInt(st.nextToken()); - calendar.set(Calendar.HOUR_OF_DAY, hour); - } else { - calendar.set(Calendar.HOUR_OF_DAY, 0); - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - return calendar; - } - // Minutes - if (check(st, ":") && (st.hasMoreTokens())) { - int minutes = Integer.parseInt(st.nextToken()); - calendar.set(Calendar.MINUTE, minutes); - } else { - calendar.set(Calendar.MINUTE, 0); - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - return calendar; - } - - // - // Not mandatory now - // - - // Secondes - if (!st.hasMoreTokens()) { - return calendar; - } - String tok = st.nextToken(); - if (tok.equals(":")) { // secondes - if (st.hasMoreTokens()) { - int secondes = Integer.parseInt(st.nextToken()); - calendar.set(Calendar.SECOND, secondes); - if (!st.hasMoreTokens()) { - return calendar; - } - // frac sec - tok = st.nextToken(); - if (tok.equals(".")) { - // bug fixed, thx to Martin Bottcher - String nt = st.nextToken(); - while (nt.length() < 3) { - nt += "0"; - } - nt = nt.substring(0, 3); // Cut trailing chars.. - int millisec = Integer.parseInt(nt); - // int millisec = Integer.parseInt(st.nextToken()) * 10; - calendar.set(Calendar.MILLISECOND, millisec); - if (!st.hasMoreTokens()) { - return calendar; - } - tok = st.nextToken(); - } else { - calendar.set(Calendar.MILLISECOND, 0); - } - } else { - throw new NumberFormatException("No secondes specified"); - } - } else { - calendar.set(Calendar.SECOND, 0); - calendar.set(Calendar.MILLISECOND, 0); - } - // Timezone - if (!tok.equals("Z")) { // UTC - if (!(tok.equals("+") || tok.equals("-"))) { - throw new NumberFormatException("only Z, + or - allowed"); - } - boolean plus = tok.equals("+"); - if (!st.hasMoreTokens()) { - throw new NumberFormatException("Missing hour field"); - } - int tzhour = Integer.parseInt(st.nextToken()); - int tzmin = 0; - if (check(st, ":") && (st.hasMoreTokens())) { - tzmin = Integer.parseInt(st.nextToken()); - } else { - throw new NumberFormatException("Missing minute field"); - } - if (plus) { - calendar.add(Calendar.HOUR, -tzhour); - calendar.add(Calendar.MINUTE, -tzmin); - } else { - calendar.add(Calendar.HOUR, tzhour); - calendar.add(Calendar.MINUTE, tzmin); - } - } - return calendar; - } - - /** - * Parse the given string in ISO 8601 format and build a Date object. - * @param isodate the date in ISO 8601 format - * @return a Date instance - * @exception InvalidDateException - * if the date is not valid - */ - public static Date parse(String isodate) throws NumberFormatException { - Calendar calendar = getCalendar(isodate); - return calendar.getTime(); - } - - private static String twoDigit(int i) { - if (i >= 0 && i < 10) { - return "0" + i; - } - return String.valueOf(i); - } - - /** - * Generate a ISO 8601 date - * @param date a Date instance - * @return a string representing the date in the ISO 8601 format - */ - public static String getIsoDate(Date date) { - Calendar calendar = new GregorianCalendar(); - calendar.setTime(date); - StringBuffer buffer = new StringBuffer(); - buffer.append(calendar.get(Calendar.YEAR)); - buffer.append('-'); - buffer.append(twoDigit(calendar.get(Calendar.MONTH) + 1)); - buffer.append('-'); - buffer.append(twoDigit(calendar.get(Calendar.DAY_OF_MONTH))); - return buffer.toString(); - } - - /** - * Generate a ISO 8601 date time without timezone - * @param date a Date instance - * @return a string representing the date in the ISO 8601 format - */ - public static String getIsoDateTime(Date date) { - Calendar calendar = new GregorianCalendar(); - calendar.setTime(date); - StringBuffer buffer = new StringBuffer(); - buffer.append(calendar.get(Calendar.YEAR)); - buffer.append('-'); - buffer.append(twoDigit(calendar.get(Calendar.MONTH) + 1)); - buffer.append('-'); - buffer.append(twoDigit(calendar.get(Calendar.DAY_OF_MONTH))); - buffer.append('T'); - buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.MINUTE))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.SECOND))); - buffer.append('.'); - buffer.append(twoDigit(calendar.get(Calendar.MILLISECOND) / 10)); - return buffer.toString(); - } - - /** - * Generate a ISO 8601 date time with timezone - * @param date a Date instance - * @return a string representing the date in the ISO 8601 format - */ - public static String getIsoDateTimeZone(Date date) { - Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - calendar.setTime(date); - StringBuffer buffer = new StringBuffer(); - buffer.append(calendar.get(Calendar.YEAR)); - buffer.append('-'); - buffer.append(twoDigit(calendar.get(Calendar.MONTH) + 1)); - buffer.append('-'); - buffer.append(twoDigit(calendar.get(Calendar.DAY_OF_MONTH))); - buffer.append('T'); - buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.MINUTE))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.SECOND))); - buffer.append('.'); - buffer.append(twoDigit(calendar.get(Calendar.MILLISECOND) / 10)); - buffer.append('Z'); - return buffer.toString(); - } - - /** - * Generate a ISO 8601 time - * @param date a Date instance - * @return a string representing the date in the ISO 8601 format - */ - public static String getIsoTime(Date date) { - Calendar calendar = new GregorianCalendar(); - calendar.setTime(date); - StringBuffer buffer = new StringBuffer(); - buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.MINUTE))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.SECOND))); - buffer.append('.'); - buffer.append(twoDigit(calendar.get(Calendar.MILLISECOND) / 10)); - return buffer.toString(); - } - - /** - * Generate a ISO 8601 time - * @param date a Date instance - * @return a string representing the date in the ISO 8601 format - */ - public static String getIsoTimeZone(Date date) { - Calendar calendar = new GregorianCalendar(TimeZone.getTimeZone("UTC")); - calendar.setTime(date); - StringBuffer buffer = new StringBuffer(); - buffer.append(twoDigit(calendar.get(Calendar.HOUR_OF_DAY))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.MINUTE))); - buffer.append(':'); - buffer.append(twoDigit(calendar.get(Calendar.SECOND))); - buffer.append('.'); - buffer.append(twoDigit(calendar.get(Calendar.MILLISECOND) / 10)); - buffer.append('Z'); - return buffer.toString(); - } - -} diff --git a/source/net/sbbi/upnp/services/ServiceAction.java b/source/net/sbbi/upnp/services/ServiceAction.java deleted file mode 100644 index de9d386d8..000000000 --- a/source/net/sbbi/upnp/services/ServiceAction.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.services; - -import java.util.*; - -/** - * An object to represent a service action proposed by an UPNP service - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class ServiceAction { - - protected String name; - protected UPNPService parent; - private List orderedActionArguments; - private List orderedInputActionArguments; - private List orderedOutputActionArguments; - private List orderedInputActionArgumentsNames; - private List orderedOutputActionArgumentsNames; - - protected ServiceAction() { - } - - public UPNPService getParent() { - return parent; - } - - /** - * The action in and out arguments ServiceActionArgument objects list - * @return the list with ServiceActionArgument objects or null if the action has no params - */ - public List getActionArguments() { - return orderedActionArguments; - } - - /** - * Look for an ServiceActionArgument for a given name - * @param argumentName the argument name - * @return the argument or null if not found or not available - */ - public ServiceActionArgument getActionArgument( String argumentName ) { - if ( orderedActionArguments == null ) return null; - for ( Iterator i = orderedActionArguments.iterator(); i.hasNext(); ) { - ServiceActionArgument arg = (ServiceActionArgument)i.next(); - if ( arg.getName().equals( argumentName ) ) return arg; - } - return null; - } - - protected void setActionArguments( List orderedActionArguments ) { - this.orderedActionArguments = orderedActionArguments; - orderedInputActionArguments = getListForActionArgument( orderedActionArguments, ServiceActionArgument.DIRECTION_IN ); - orderedOutputActionArguments = getListForActionArgument( orderedActionArguments, ServiceActionArgument.DIRECTION_OUT ); - orderedInputActionArgumentsNames = getListForActionArgumentNames( orderedActionArguments, ServiceActionArgument.DIRECTION_IN ); - orderedOutputActionArgumentsNames = getListForActionArgumentNames( orderedActionArguments, ServiceActionArgument.DIRECTION_OUT ); - } - - /** - * Return a list containing input ( when a response is sent ) arguments objects - * @return a list containing input arguments ServiceActionArgument objects or null when nothing - * is needed for such operation - */ - public List getInputActionArguments() { - return orderedInputActionArguments; - } - - /** - * Look for an input ServiceActionArgument for a given name - * @param argumentName the input argument name - * @return the argument or null if not found or not available - */ - public ServiceActionArgument getInputActionArgument( String argumentName ) { - if ( orderedInputActionArguments == null ) return null; - for ( Iterator i = orderedInputActionArguments.iterator(); i.hasNext(); ) { - ServiceActionArgument arg = (ServiceActionArgument)i.next(); - if ( arg.getName().equals( argumentName ) ) return arg; - } - return null; - } - - - /** - * Return a list containing output ( when a response is received ) arguments objects - * @return a list containing output arguments ServiceActionArgument objects or null when nothing - * returned for such operation - */ - public List getOutputActionArguments() { - return orderedOutputActionArguments; - } - - /** - * Look for an output ServiceActionArgument for a given name - * @param argumentName the input argument name - * @return the argument or null if not found or not available - */ - public ServiceActionArgument getOutputActionArgument( String argumentName ) { - if ( orderedOutputActionArguments == null ) return null; - for ( Iterator i = orderedOutputActionArguments.iterator(); i.hasNext(); ) { - ServiceActionArgument arg = (ServiceActionArgument)i.next(); - if ( arg.getName().equals( argumentName ) ) return arg; - } - return null; - } - - /** - * Return a list containing input ( when a response is sent ) arguments names - * @return a list containing input arguments names as Strings or null when nothing - * is needed for such operation - */ - public List getInputActionArgumentsNames() { - return orderedInputActionArgumentsNames; - } - - /** - * Return a list containing output ( when a response is received ) arguments names - * @return a list containing output arguments names as Strings or null when nothing - * returned for such operation - */ - public List getOutputActionArgumentsNames() { - return orderedOutputActionArgumentsNames; - } - - /** - * The action name - * @return The action name - */ - public String getName() { - return name; - } - - private List getListForActionArgument( List args, String direction ) { - if ( args == null ) return null; - List rtrVal = new ArrayList(); - for ( Iterator itr = args.iterator(); itr.hasNext(); ) { - ServiceActionArgument actArg = (ServiceActionArgument)itr.next(); - if ( actArg.getDirection() == direction ) { - rtrVal.add( actArg ); - } - } - if ( rtrVal.size() == 0 ) rtrVal = null; - return rtrVal; - } - - private List getListForActionArgumentNames( List args, String direction ) { - if ( args == null ) return null; - List rtrVal = new ArrayList(); - for ( Iterator itr = args.iterator(); itr.hasNext(); ) { - ServiceActionArgument actArg = (ServiceActionArgument)itr.next(); - if ( actArg.getDirection() == direction ) { - rtrVal.add( actArg.getName() ); - } - } - if ( rtrVal.size() == 0 ) rtrVal = null; - return rtrVal; - } -} diff --git a/source/net/sbbi/upnp/services/ServiceActionArgument.java b/source/net/sbbi/upnp/services/ServiceActionArgument.java deleted file mode 100644 index 4bd1a613e..000000000 --- a/source/net/sbbi/upnp/services/ServiceActionArgument.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.services; - -/** - * An argument for a service action - * @author SuperBonBon - * @version 1.0 - */ -public class ServiceActionArgument { - - public final static String DIRECTION_IN = "in"; - public final static String DIRECTION_OUT = "out"; - - protected ServiceStateVariable relatedStateVariable; - protected String name; - protected String direction; - - /** - * The related service state variable for this ServiceActionArgument - * @return The related service state variable for this ServiceActionArgument - */ - public ServiceStateVariable getRelatedStateVariable() { - return relatedStateVariable; - } - - /** - * The argument name - * @return the argument name - */ - public String getName() { - return name; - } - - /** - * The argument direction - * @return the argument direction (in|out) - */ - public String getDirection() { - return direction; - } -} diff --git a/source/net/sbbi/upnp/services/ServiceStateVariable.java b/source/net/sbbi/upnp/services/ServiceStateVariable.java deleted file mode 100644 index 5a3fb93b1..000000000 --- a/source/net/sbbi/upnp/services/ServiceStateVariable.java +++ /dev/null @@ -1,263 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.services; - -import java.io.IOException; -import java.net.URI; -import java.util.Date; -import java.util.Set; - -import net.sbbi.upnp.messages.StateVariableMessage; -import net.sbbi.upnp.messages.UPNPMessageFactory; -import net.sbbi.upnp.messages.UPNPResponseException; - -/** - * Class to contain a service state variable definition - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class ServiceStateVariable implements ServiceStateVariableTypes { - - private StateVariableMessage stateVarMsg = null; - - protected String name; - protected boolean sendEvents; - protected String dataType; - protected String defaultValue; - - protected String minimumRangeValue; - protected String maximumRangeValue; - protected String stepRangeValue; - protected Set allowedvalues; - protected UPNPService parent; - - protected ServiceStateVariable() { - } - - /** - * Call to the UPNP device to retreive the state variable actual value - * @return the state variable actual value on the device, should be never null, an empty string could be returned by the device - * @throws UPNPResponseException if the device throws an exception during query - * @throws IOException if some IO error with device occurs during query - */ - public String getValue() throws UPNPResponseException, IOException { - if ( stateVarMsg == null ) { - synchronized( this ) { - if ( stateVarMsg == null ) { - UPNPMessageFactory factory = UPNPMessageFactory.getNewInstance( parent ); - stateVarMsg = factory.getStateVariableMessage( name ); - } - } - } - return stateVarMsg.service().getStateVariableValue(); - } - - /** - * State variable name - * @return the state variable name - */ - public String getName() { - return name; - } - - /** - * The parent UPNPService Object - * @return the parent object instance - */ - public UPNPService getParent() { - return parent; - } - - /** - * Boolean to indicate if the variable is sending events when value - * of the var is changing. The events can be subscribed via the {@link net.sbbi.upnp.ServicesEventing} - * class - * @return true if sending events - */ - public boolean isSendEvents() { - return sendEvents; - } - - /** - * The default value of the state variable - * @return the default value representation as an string - */ - public String getDefaultValue() { - return defaultValue; - } - - /** - * The variable UPNP data type - * @return the data type - */ - public String getDataType() { - return dataType; - } - - /** - * The varialbe JAVA data type (using an UPNP->Java mapping) - * @return the class mapped - */ - public Class getDataTypeAsClass() { - return getDataTypeClassMapping( dataType ); - } - - /** - * A set of allowed values (String objects) for the variable - * @return the allowed values or null if none - */ - public Set getAllowedvalues() { - return allowedvalues; - } - - /** - * The minimum value as a string - * @return the minimum value or null if no restriction - */ - public String getMinimumRangeValue() { - return minimumRangeValue; - } - - /** - * The maximum value as a string - * @return the maximum value or null if no restriction - */ - public String getMaximumRangeValue() { - return maximumRangeValue; - } - - /** - * The value step range as a string - * @return the value step raqnge or null if no restriction - */ - public String getStepRangeValue() { - return stepRangeValue; - } - - public static Class getDataTypeClassMapping( String dataType ) { - int hash = dataType.hashCode(); - if ( hash == UI1_INT ) return Short.class; - else if ( hash == UI2_INT ) return Integer.class; - else if ( hash == UI4_INT ) return Long.class; - else if ( hash == I1_INT ) return Byte.class; - else if ( hash == I2_INT ) return Short.class; - else if ( hash == I4_INT ) return Integer.class; - else if ( hash == INT_INT ) return Integer.class; - else if ( hash == R4_INT ) return Float.class; - else if ( hash == R8_INT ) return Double.class; - else if ( hash == NUMBER_INT ) return Double.class; - else if ( hash == FIXED_14_4_INT ) return Double.class; - else if ( hash == FLOAT_INT ) return Float.class; - else if ( hash == CHAR_INT) return Character.class; - else if ( hash == STRING_INT ) return String.class; - else if ( hash == DATE_INT ) return Date.class; - else if ( hash == DATETIME_INT ) return Date.class; - else if ( hash == DATETIME_TZ_INT ) return Date.class; - else if ( hash == TIME_INT ) return Date.class; - else if ( hash == TIME_TZ_INT ) return Date.class; - else if ( hash == BOOLEAN_INT ) return Boolean.class; - else if ( hash == BIN_BASE64_INT ) return String.class; - else if ( hash == BIN_HEX_INT ) return String.class; - else if ( hash == URI_INT ) return URI.class; - else if ( hash == UUID_INT ) return String.class; - return null; - } - - public static String getUPNPDataTypeMapping( String className ) { - if ( className.equals( Short.class.getName() ) || className.equals( "short" )) return I2; - else if ( className.equals( Byte.class.getName() ) || className.equals( "byte" )) return I1; - else if ( className.equals( Integer.class.getName() ) || className.equals( "int" ) ) return INT; - else if ( className.equals( Long.class.getName() ) || className.equals( "long" ) ) return UI4; - else if ( className.equals( Float.class.getName() ) || className.equals( "float" )) return FLOAT; - else if ( className.equals( Double.class.getName() ) || className.equals( "double" ) ) return NUMBER; - else if ( className.equals( Character.class.getName() ) || className.equals( "char" ) ) return CHAR; - else if ( className.equals( String.class.getName() ) || className.equals( "string" ) ) return STRING; - else if ( className.equals( Date.class.getName() ) ) return DATETIME; - else if ( className.equals( Boolean.class.getName() ) || className.equals( "boolean" ) ) return BOOLEAN; - else if ( className.equals( URI.class.getName() ) ) return URI; - return null; - } - - public static Object UPNPToJavaObject( String dataType, String value ) throws Throwable { - if ( value == null ) throw new Exception( "null value" ); - if ( dataType == null ) throw new Exception( "null dataType" ); - int hash = dataType.hashCode(); - if ( hash == UI1_INT ) return Short.valueOf( value ); - else if ( hash == UI2_INT ) return Integer.valueOf( value ); - else if ( hash == UI4_INT ) return Long.valueOf( value ); - else if ( hash == I1_INT ) return Byte.valueOf( value ); - else if ( hash == I2_INT ) return Short.valueOf( value ); - else if ( hash == I4_INT ) return Integer.valueOf( value ); - else if ( hash == INT_INT ) return Integer.valueOf( value ); - else if ( hash == R4_INT ) return Float.valueOf( value ); - else if ( hash == R8_INT ) return Double.valueOf( value ); - else if ( hash == NUMBER_INT ) return Double.valueOf( value ); - else if ( hash == FIXED_14_4_INT ) return Double.valueOf( value ); - else if ( hash == FLOAT_INT ) return Float.valueOf( value ); - else if ( hash == CHAR_INT) return Character.valueOf( value.charAt( 0 ) ); - else if ( hash == STRING_INT ) return value; - else if ( hash == DATE_INT ) return ISO8601Date.parse( value ); - else if ( hash == DATETIME_INT ) return ISO8601Date.parse( value ); - else if ( hash == DATETIME_TZ_INT ) return ISO8601Date.parse( value ); - else if ( hash == TIME_INT ) return ISO8601Date.parse( value ); - else if ( hash == TIME_TZ_INT ) return ISO8601Date.parse( value ); - else if ( hash == BOOLEAN_INT ) { - if ( value.equals( "1" ) || value.equalsIgnoreCase( "yes" ) || value.equals( "true" ) ) { - return Boolean.TRUE; - } - return Boolean.FALSE; - } - else if ( hash == BIN_BASE64_INT ) return value; - else if ( hash == BIN_HEX_INT ) return value; - else if ( hash == URI_INT ) return new URI( value ); - else if ( hash == UUID_INT ) return value; - throw new Exception( "Unhandled data type " + dataType ); - } - -} diff --git a/source/net/sbbi/upnp/services/ServiceStateVariableTypes.java b/source/net/sbbi/upnp/services/ServiceStateVariableTypes.java deleted file mode 100644 index 558d559c0..000000000 --- a/source/net/sbbi/upnp/services/ServiceStateVariableTypes.java +++ /dev/null @@ -1,188 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.services; - -/** - * Interface to defined allowed values for service state variables data types - * @author SuperBonBon - * @version 1.0 - */ -public interface ServiceStateVariableTypes { - - /** - * Unsigned 1 Byte int. Same format as int without leading sign. - */ - public final static String UI1 = "ui1"; - /** - * Unsigned 2 Byte int. Same format as int without leading sign. - */ - public final static String UI2 = "ui2"; - /** - * Unsigned 4 Byte int. Same format as int without leading sign. - */ - public final static String UI4 = "ui4"; - /** - * 1 Byte int. Same format as int. - */ - public final static String I1 = "i1"; - /** - * 2 Byte int. Same format as int. - */ - public final static String I2 = "i2"; - /** - * 4 Byte int. Same format as int. - */ - public final static String I4 = "i4"; - /** - * Fixed point, integer number. May have leading sign. May have leading zeros. - * (No currency symbol.) (No grouping of digits to the left of the decimal, e.g., no commas.) - */ - public final static String INT = "int"; - /** - * 4 Byte float. Same format as float. Must be between 3.40282347E+38 to 1.17549435E-38. - */ - public final static String R4 = "r4"; - /** - * 8 Byte float. Same format as float. Must be between -1.79769313486232E308 and -4.94065645841247E-324 - * for negative values, and between 4.94065645841247E-324 and 1.79769313486232E308 for positive values, - * i.e., IEEE 64-bit (8-Byte) double. - */ - public final static String R8 = "r8"; - /** - * Same as r8. - */ - public final static String NUMBER = "number"; - /** - * Same as r8 but no more than 14 digits to the left of the decimal point and no more than 4 to the right. - */ - public final static String FIXED_14_4 = "fixed.14.4"; - /** - * Floating point number. Mantissa (left of the decimal) and/or exponent may have a leading sign. - * Mantissa and/or exponent may have leading zeros. Decimal character in mantissa is a period, i.e., - * whole digits in mantissa separated from fractional digits by period. Mantissa separated from exponent - * by E. (No currency symbol.) (No grouping of digits in the mantissa, e.g., no commas.) - */ - public final static String FLOAT = "float"; - /** - * Unicode string. One character long. - */ - public final static String CHAR = "char"; - /** - * Unicode string. No limit on length. - */ - public final static String STRING = "string"; - /** - * Date in a subset of ISO 8601 format without time data. - */ - public final static String DATE = "date"; - /** - * Date in ISO 8601 format with optional time but no time zone. - */ - public final static String DATETIME = "dateTime"; - /** - * Date in ISO 8601 format with optional time and optional time zone. - */ - public final static String DATETIME_TZ = "dateTime.tz"; - /** - * Time in a subset of ISO 8601 format with no date and no time zone. - */ - public final static String TIME = "time"; - /** - * Time in a subset of ISO 8601 format with optional time zone but no date. - */ - public final static String TIME_TZ = "time.tz"; - /** - * 0, false, or no for false; 1, true, or yes for true. - */ - public final static String BOOLEAN = "boolean"; - /** - * MIME-style Base64 encoded binary BLOB. Takes 3 Bytes, splits them into 4 parts, - * and maps each 6 bit piece to an octet. (3 octets are encoded as 4.) No limit on size. - */ - public final static String BIN_BASE64 = "bin.base64"; - /** - * Hexadecimal digits representing octets. Treats each nibble as a hex digit and encodes - * as a separate Byte. (1 octet is encoded as 2.) No limit on size. - */ - public final static String BIN_HEX = "bin.hex"; - /** - * Universal Resource Identifier. - */ - public final static String URI = "uri"; - /** - * Universally Unique ID. Hexadecimal digits representing octets. - * Optional embedded hyphens are ignored. - */ - public final static String UUID = "uuid"; - - public final static int UI1_INT = "ui1".hashCode(); - public final static int UI2_INT = "ui2".hashCode(); - public final static int UI4_INT = "ui4".hashCode(); - public final static int I1_INT = "i1".hashCode(); - public final static int I2_INT = "i2".hashCode(); - public final static int I4_INT = "i4".hashCode(); - public final static int INT_INT = "int".hashCode(); - public final static int R4_INT = "r4".hashCode(); - public final static int R8_INT = "r8".hashCode(); - public final static int NUMBER_INT = "number".hashCode(); - public final static int FIXED_14_4_INT = "fixed.14.4".hashCode(); - public final static int FLOAT_INT = "float".hashCode(); - public final static int CHAR_INT = "char".hashCode(); - public final static int STRING_INT = "string".hashCode(); - public final static int DATE_INT = "date".hashCode(); - public final static int DATETIME_INT = "dateTime".hashCode(); - public final static int DATETIME_TZ_INT = "dateTime.tz".hashCode(); - public final static int TIME_INT = "time".hashCode(); - public final static int TIME_TZ_INT = "time.tz".hashCode(); - public final static int BOOLEAN_INT = "boolean".hashCode(); - public final static int BIN_BASE64_INT = "bin.base64".hashCode(); - public final static int BIN_HEX_INT = "bin.hex".hashCode(); - public final static int URI_INT = "uri".hashCode(); - public final static int UUID_INT = "uuid".hashCode(); - -} diff --git a/source/net/sbbi/upnp/services/UPNPService.java b/source/net/sbbi/upnp/services/UPNPService.java deleted file mode 100644 index a762f107b..000000000 --- a/source/net/sbbi/upnp/services/UPNPService.java +++ /dev/null @@ -1,327 +0,0 @@ -/* - * ============================================================================ - * The Apache Software License, Version 1.1 - * ============================================================================ - * - * Copyright (C) 2002 The Apache Software Foundation. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modifica- - * tion, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The end-user documentation included with the redistribution, if any, must - * include the following acknowledgment: "This product includes software - * developed by SuperBonBon Industries (http://www.sbbi.net/)." - * Alternately, this acknowledgment may appear in the software itself, if - * and wherever such third-party acknowledgments normally appear. - * - * 4. The names "UPNPLib" and "SuperBonBon Industries" must not be - * used to endorse or promote products derived from this software without - * prior written permission. For written permission, please contact - * info@sbbi.net. - * - * 5. Products derived from this software may not be called - * "SuperBonBon Industries", nor may "SBBI" appear in their name, - * without prior written permission of SuperBonBon Industries. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE - * APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, - * INDIRECT,INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- - * DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS - * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON - * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * This software consists of voluntary contributions made by many individuals - * on behalf of SuperBonBon Industries. For more information on - * SuperBonBon Industries, please see . - */ -package net.sbbi.upnp.services; - -import org.apache.commons.jxpath.*; -import org.apache.commons.jxpath.xml.*; - -import java.util.*; -import java.io.IOException; -import java.net.*; - -import net.sbbi.upnp.JXPathParser; -import net.sbbi.upnp.devices.*; - -/** - * Representation of an UPNP service - * @author SuperBonBon - * @version 1.0 - */ -@SuppressWarnings("unchecked") -public class UPNPService { - - protected String serviceType; - protected String serviceId; - private int specVersionMajor; - private int specVersionMinor; - protected URL SCPDURL; - protected String SCPDURLData; - protected URL controlURL; - protected URL eventSubURL; - protected UPNPDevice serviceOwnerDevice; - - protected Map UPNPServiceActions; - protected Map UPNPServiceStateVariables; - private final String USN; - - private boolean parsedSCPD = false; - private DocumentContainer UPNPService; - - public UPNPService( JXPathContext serviceCtx, URL baseDeviceURL, UPNPDevice serviceOwnerDevice ) throws MalformedURLException { - this.serviceOwnerDevice = serviceOwnerDevice; - serviceType = (String)serviceCtx.getValue( "serviceType" ); - serviceId = (String)serviceCtx.getValue( "serviceId" ); - SCPDURL = UPNPRootDevice.getURL( (String)serviceCtx.getValue( "SCPDURL" ), baseDeviceURL ); - controlURL = UPNPRootDevice.getURL( (String)serviceCtx.getValue( "controlURL" ), baseDeviceURL ); - eventSubURL = UPNPRootDevice.getURL( (String)serviceCtx.getValue( "eventSubURL" ), baseDeviceURL ); - USN = serviceOwnerDevice.getUDN().concat( "::" ).concat( serviceType ); - } - - public String getServiceType() { - return serviceType; - } - - public String getServiceId() { - return serviceId; - } - - public String getUSN(){ - return USN; - } - - public URL getSCPDURL() { - return SCPDURL; - } - - public URL getControlURL() { - return controlURL; - } - - public URL getEventSubURL() { - return eventSubURL; - } - - public int getSpecVersionMajor() { - lazyInitiate(); - return specVersionMajor; - } - - public int getSpecVersionMinor() { - lazyInitiate(); - return specVersionMinor; - } - - public UPNPDevice getServiceOwnerDevice() { - return serviceOwnerDevice; - } - - /** - * Retreives a service action for its given name - * @param actionName the service action name - * @return a ServiceAction object or null if no matching action for this service has been found - */ - public ServiceAction getUPNPServiceAction( String actionName ) { - lazyInitiate(); - return (ServiceAction)UPNPServiceActions.get( actionName ); - } - - /** - * Retreives a service state variable for its given name - * @param stateVariableName the state variable name - * @return a ServiceStateVariable object or null if no matching state variable has been found - */ - public ServiceStateVariable getUPNPServiceStateVariable( String stateVariableName ) { - lazyInitiate(); - return (ServiceStateVariable)UPNPServiceStateVariables.get( stateVariableName ); - } - - public Iterator getAvailableActionsName() { - lazyInitiate(); - return UPNPServiceActions.keySet().iterator(); - } - - public int getAvailableActionsSize() { - lazyInitiate(); - return UPNPServiceActions.keySet().size(); - } - - public Iterator getAvailableStateVariableName() { - lazyInitiate(); - return UPNPServiceStateVariables.keySet().iterator(); - } - - public int getAvailableStateVariableSize() { - lazyInitiate(); - return UPNPServiceStateVariables.keySet().size(); - } - - private void parseSCPD() { - try { - DocumentContainer.registerXMLParser( DocumentContainer.MODEL_DOM, new JXPathParser() ); - UPNPService = new DocumentContainer( SCPDURL, DocumentContainer.MODEL_DOM ); - JXPathContext context = JXPathContext.newContext( this ); - Pointer rootPtr = context.getPointer( "UPNPService/scpd" ); - JXPathContext rootCtx = context.getRelativeContext( rootPtr ); - - specVersionMajor = Integer.parseInt( (String)rootCtx.getValue( "specVersion/major" ) ); - specVersionMinor = Integer.parseInt( (String)rootCtx.getValue( "specVersion/minor" ) ); - - parseServiceStateVariables( rootCtx ); - - Pointer actionsListPtr = rootCtx.getPointer( "actionList" ); - JXPathContext actionsListCtx = context.getRelativeContext( actionsListPtr ); - Double arraySize = (Double)actionsListCtx.getValue( "count( action )" ); - UPNPServiceActions = new HashMap(); - for ( int i = 1; i <= arraySize.intValue(); i++ ) { - ServiceAction action = new ServiceAction(); - action.name = (String)actionsListCtx.getValue( "action["+i+"]/name" ); - action.parent = this; - Pointer argumentListPtr = null; - try { - argumentListPtr = actionsListCtx.getPointer( "action["+i+"]/argumentList" ); - } catch ( JXPathException ex ) { - // there is no arguments list. - } - if ( argumentListPtr != null ) { - JXPathContext argumentListCtx = actionsListCtx.getRelativeContext( argumentListPtr ); - Double arraySizeArgs = (Double)argumentListCtx.getValue( "count( argument )" ); - - List orderedActionArguments = new ArrayList(); - for ( int z = 1; z <= arraySizeArgs.intValue(); z++ ) { - ServiceActionArgument arg = new ServiceActionArgument(); - arg.name = (String)argumentListCtx.getValue( "argument["+z+"]/name" ); - String direction = (String)argumentListCtx.getValue( "argument["+z+"]/direction" ); - arg.direction = direction.equals( ServiceActionArgument.DIRECTION_IN ) ? ServiceActionArgument.DIRECTION_IN : ServiceActionArgument.DIRECTION_OUT; - String stateVarName = (String)argumentListCtx.getValue( "argument["+z+"]/relatedStateVariable" ); - ServiceStateVariable stateVar = (ServiceStateVariable)UPNPServiceStateVariables.get( stateVarName ); - if ( stateVar == null ) { - throw new IllegalArgumentException( "Unable to find any state variable named " + stateVarName + " for service " + getServiceId() + " action " + action.name + " argument " + arg.name ); - } - arg.relatedStateVariable = stateVar; - orderedActionArguments.add( arg ); - } - - if ( arraySizeArgs.intValue() > 0 ) { - action.setActionArguments( orderedActionArguments ); - } - } - - UPNPServiceActions.put( action.getName(), action ); - } - parsedSCPD = true; - } catch ( Throwable t ) { - throw new RuntimeException( "Error during lazy SCDP file parsing at " + SCPDURL, t ); - } - } - - private void parseServiceStateVariables( JXPathContext rootContext ) { - Pointer serviceStateTablePtr = rootContext.getPointer( "serviceStateTable" ); - JXPathContext serviceStateTableCtx = rootContext.getRelativeContext( serviceStateTablePtr ); - Double arraySize = (Double)serviceStateTableCtx.getValue( "count( stateVariable )" ); - UPNPServiceStateVariables = new HashMap(); - for ( int i = 1; i <= arraySize.intValue(); i++ ) { - ServiceStateVariable srvStateVar = new ServiceStateVariable(); - String sendEventsLcl = null; - try { - sendEventsLcl = (String)serviceStateTableCtx.getValue( "stateVariable["+i+"]/@sendEvents" ); - } catch ( JXPathException defEx ) { - // sendEvents not provided defaulting according to specs to "yes" - sendEventsLcl = "yes"; - } - srvStateVar.parent = this; - srvStateVar.sendEvents = sendEventsLcl.equalsIgnoreCase( "no" ) ? false : true; - srvStateVar.name = (String)serviceStateTableCtx.getValue( "stateVariable["+i+"]/name" ); - srvStateVar.dataType = (String)serviceStateTableCtx.getValue( "stateVariable["+i+"]/dataType" ); - try { - srvStateVar.defaultValue = (String)serviceStateTableCtx.getValue( "stateVariable["+i+"]/defaultValue" ); - } catch ( JXPathException defEx ) { - // can happend since default value is not - } - Pointer allowedValuesPtr = null; - try { - allowedValuesPtr = serviceStateTableCtx.getPointer( "stateVariable["+i+"]/allowedValueList" ); - } catch ( JXPathException ex ) { - // there is no allowed values list. - } - if ( allowedValuesPtr != null ) { - JXPathContext allowedValuesCtx = serviceStateTableCtx.getRelativeContext( allowedValuesPtr ); - Double arraySizeAllowed = (Double)allowedValuesCtx.getValue( "count( allowedValue )" ); - srvStateVar.allowedvalues = new HashSet(); - for ( int z = 1; z <= arraySizeAllowed.intValue(); z++ ) { - String allowedValue = (String)allowedValuesCtx.getValue( "allowedValue["+z+"]" ); - srvStateVar.allowedvalues.add( allowedValue ); - } - } - - Pointer allowedValueRangePtr = null; - try { - allowedValueRangePtr = serviceStateTableCtx.getPointer( "stateVariable["+i+"]/allowedValueRange" ); - } catch ( JXPathException ex ) { - // there is no allowed values list, can happen - } - if ( allowedValueRangePtr != null ) { - - srvStateVar.minimumRangeValue = (String)serviceStateTableCtx.getValue( "stateVariable["+i+"]/allowedValueRange/minimum" ); - srvStateVar.maximumRangeValue = (String)serviceStateTableCtx.getValue( "stateVariable["+i+"]/allowedValueRange/maximum" ); - try { - srvStateVar.stepRangeValue = (String)serviceStateTableCtx.getValue( "stateVariable["+i+"]/allowedValueRange/step" ); - } catch ( JXPathException stepEx ) { - // can happend since step is not mandatory - } - } - UPNPServiceStateVariables.put( srvStateVar.getName(), srvStateVar ); - } - - } - - private void lazyInitiate() { - if ( !parsedSCPD ) - synchronized( this ) { - if ( !parsedSCPD ) - parseSCPD(); - } - } - - /** - * Used for JXPath parsing, do not use this method - * @return a Container object for Xpath parsing capabilities - */ - public Container getUPNPService() { - return UPNPService; - } - - public String getSCDPData() { - if ( SCPDURLData == null ) { - try { - - java.io.InputStream in = SCPDURL.openConnection().getInputStream(); - int readen = 0; - byte[] buff = new byte[512]; - StringBuffer strBuff = new StringBuffer(); - while( ( readen = in.read( buff ) ) != -1 ) { - strBuff.append( new String( buff, 0, readen ) ); - } - in.close(); - SCPDURLData = strBuff.toString(); - } catch ( IOException ioEx ) { - return null; - } - } - return SCPDURLData; - } -} diff --git a/source/net/sbbi/upnp/version.properties b/source/net/sbbi/upnp/version.properties deleted file mode 100644 index d948172d8..000000000 --- a/source/net/sbbi/upnp/version.properties +++ /dev/null @@ -1,8 +0,0 @@ -# please make sur to update those values -# when crating a new release -# especially to create cvs changelogs -release.version=1.0.4 -release.version.cvs.tag=V1_0_4 -release.version.publish.date=20 Nov 2006 -last.release.version.cvs.tag=V1_0_3 -last.release.version.publish.date=14 Feb 2006 \ No newline at end of file diff --git a/source/net/yacy/ai/greedy/Engine.java b/source/net/yacy/ai/greedy/Engine.java index 4d31d5d6c..13f9c168f 100755 --- a/source/net/yacy/ai/greedy/Engine.java +++ b/source/net/yacy/ai/greedy/Engine.java @@ -147,7 +147,7 @@ public class Engine< // apply finding: compute next model // avoid double computation of findings using cached assets if (context.useAssetCache()) { - asset = new Asset(agent.getModel(), challenge.getFinding()); + asset = new Asset(agent.getModel(), challenge.getFinding()); nextModel = assets.get(asset); if (nextModel == null) { // generate model clone and apply finding @@ -170,7 +170,7 @@ public class Engine< nextModel.applyFinding(challenge.getFinding()); nextModel.nextRole(); if (context.feedAssetCache()) { - asset = new Asset(agent.getModel(), challenge.getFinding()); + asset = new Asset(agent.getModel(), challenge.getFinding()); assets.put(asset, nextModel); } } @@ -186,7 +186,7 @@ public class Engine< continue; } // place new model into agent and record finding - nextAgent = new Agent(agent, nextModel, challenge.getFinding()); + nextAgent = new Agent(agent, nextModel, challenge.getFinding()); nextAgent.checkInstanceCount(); // check if we arrived at a termination point diff --git a/source/net/yacy/document/detector/odtDetector.java b/source/net/yacy/document/detector/odtDetector.java deleted file mode 100644 index 6ac9893e7..000000000 --- a/source/net/yacy/document/detector/odtDetector.java +++ /dev/null @@ -1,94 +0,0 @@ -//odtDetector.java -//------------------------ -//part of YaCy -//(C) by Michael Peter Christen; mc@yacy.net -//first published on http://www.anomic.de -//Frankfurt, Germany, 2005 -// -//this file is contributed by Martin Thelian -//last major change: 16.05.2005 -// -//This program is free software; you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation; either version 2 of the License, or -//(at your option) any later version. -// -//This program is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU General Public License for more details. -// -//You should have received a copy of the GNU General Public License -//along with this program; if not, write to the Free Software -//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package net.yacy.document.detector; - -import java.io.File; -import java.io.IOException; -import java.io.InputStream; -import java.util.Map; -import java.util.zip.ZipEntry; -import java.util.zip.ZipFile; - -import net.yacy.kelondro.util.FileUtils; - - -public class odtDetector { - - public String getDisplayName() { - return "ODT MimeType Detector"; - } - - public String[] getHandledExtensions() { - return new String[]{"zip","odt"}; - } - - public String[] getHandledTypes() { - return new String[] { "application/vnd.oasis.opendocument.text", "application/x-vnd.oasis.opendocument.text" }; - } - - public String getName() { - return "odtfiledetector"; - } - - public String getVersion() { - return "0.1"; - } - - @SuppressWarnings("unchecked") - public String[] process(final byte[] data, final int offset, final int length, final long bitmask, final char comparator, final String mimeType, final Map params) { - File dstFile = null; - try { - dstFile = File.createTempFile("mimeTypeParser",".prt"); - FileUtils.copy(data,dstFile); - return process(dstFile, offset, length, bitmask, comparator, mimeType, params); - } catch (final IOException e) { - return null; - } finally { - if (dstFile != null) FileUtils.deletedelete(dstFile); - } - } - - @SuppressWarnings("unchecked") - public String[] process(final File file, final int offset, final int length, final long bitmask, final char comparator, final String mimeType, final Map params) { - try { - // opening the zip file - final ZipFile zipFile = new ZipFile(file); - - // searching for a file named mimetype - final ZipEntry mimeTypeInfo = zipFile.getEntry("mimetype"); - if (mimeTypeInfo == null) return null; - - // read in the content of the file - final InputStream zippedContent = zipFile.getInputStream(mimeTypeInfo); - final String realMimeType = new String(FileUtils.read(zippedContent, (int) mimeTypeInfo.getSize())); - - return new String[]{realMimeType}; - } catch (final Exception e) { - return null; - } - - } - -} diff --git a/source/net/yacy/document/detector/rssDetector.java b/source/net/yacy/document/detector/rssDetector.java deleted file mode 100644 index d67b10dfc..000000000 --- a/source/net/yacy/document/detector/rssDetector.java +++ /dev/null @@ -1,78 +0,0 @@ -//rssDetector.java -//------------------------ -//part of YaCy -//(C) by Michael Peter Christen; mc@yacy.net -//first published on http://www.anomic.de -//Frankfurt, Germany, 2005 -// -//this file is contributed by Martin Thelian -//last major change: 16.05.2005 -// -//This program is free software; you can redistribute it and/or modify -//it under the terms of the GNU General Public License as published by -//the Free Software Foundation; either version 2 of the License, or -//(at your option) any later version. -// -//This program is distributed in the hope that it will be useful, -//but WITHOUT ANY WARRANTY; without even the implied warranty of -//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -//GNU General Public License for more details. -// -//You should have received a copy of the GNU General Public License -//along with this program; if not, write to the Free Software -//Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - -package net.yacy.document.detector; - -import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.InputStream; -import java.util.Map; - -public class rssDetector { - - public String getDisplayName() { - return "RSS MimeType Detector"; - } - - public String[] getHandledExtensions() { - return new String[]{"xml","rss","rdf","atom"}; - } - - public String[] getHandledTypes() { - return new String[] { "text/rss", "application/rdf+xml", "application/rss+xml", "application/atom+xml" }; - } - - public String getName() { - return "rssfiledetector"; - } - - public String getVersion() { - return "0.1"; - } - - @SuppressWarnings("unchecked") - public String[] process(final File file, final int offset, final int length, final long bitmask, final char comparator, final String mimeType, final Map params) { - FileInputStream fileInput = null; - try { - fileInput = new FileInputStream(file); - return detect(fileInput); - } catch (final Exception e) { - return null; - } finally { - if (fileInput != null) try { fileInput.close(); } catch (final Exception e) { /* ignore this */ } - } - } - - @SuppressWarnings("unchecked") - public String[] process(final byte[] data, final int offset, final int length, final long bitmask, final char comparator, final String mimeType, final Map params) { - final ByteArrayInputStream input = new ByteArrayInputStream(data); - return detect(input); - } - - private String[] detect(final InputStream input) { - return new String[]{"application/rss+xml"}; - } - -} diff --git a/source/net/yacy/document/parser/odtParser.java b/source/net/yacy/document/parser/odtParser.java index d3aad25e0..d2f9ddc95 100644 --- a/source/net/yacy/document/parser/odtParser.java +++ b/source/net/yacy/document/parser/odtParser.java @@ -29,7 +29,6 @@ package net.yacy.document.parser; import java.io.File; import java.io.InputStream; -import java.io.Writer; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; @@ -108,8 +107,7 @@ public class odtParser extends AbstractParser implements Idiom { @Override public Document parse(final MultiProtocolURI location, final String mimeType, final String charset, final File dest) throws ParserException, InterruptedException { - Writer writer = null; - File writerFile = null; + CharBuffer writer = null; try { String docDescription = null; String docKeywordStr = null; @@ -179,40 +177,22 @@ public class odtParser extends AbstractParser implements Idiom { // create the parser document Document theDoc = null; - if (writer instanceof CharBuffer) { - final byte[] contentBytes = ((CharBuffer)writer).toString().getBytes("UTF-8"); - theDoc = new Document( - location, - mimeType, - "UTF-8", - languages, - docKeywords, - docLongTitle, - docAuthor, - "", - null, - docDescription, - contentBytes, - null, - null, - false); - } else { - theDoc = new Document( - location, - mimeType, - "UTF-8", - languages, - docKeywords, - docLongTitle, - docAuthor, - "", - null, - docDescription, - writerFile, - null, - null, - false); - } + final byte[] contentBytes = writer.toString().getBytes("UTF-8"); + theDoc = new Document( + location, + mimeType, + "UTF-8", + languages, + docKeywords, + docLongTitle, + docAuthor, + "", + null, + docDescription, + contentBytes, + null, + null, + false); return theDoc; } catch (final Exception e) { if (e instanceof InterruptedException) throw (InterruptedException) e; @@ -221,9 +201,6 @@ public class odtParser extends AbstractParser implements Idiom { // close the writer if (writer != null) try { writer.close(); } catch (final Exception ex) {/* ignore this */} - // delete the file - if (writerFile != null) FileUtils.deletedelete(writerFile); - throw new ParserException("Unexpected error while parsing odt file. " + e.getMessage(),location); } } diff --git a/source/net/yacy/document/parser/ooxmlParser.java b/source/net/yacy/document/parser/ooxmlParser.java index 0003fb0ea..7be61258d 100644 --- a/source/net/yacy/document/parser/ooxmlParser.java +++ b/source/net/yacy/document/parser/ooxmlParser.java @@ -29,7 +29,6 @@ package net.yacy.document.parser; import java.io.File; import java.io.InputStream; -import java.io.Writer; import java.util.Enumeration; import java.util.HashSet; import java.util.Set; @@ -92,8 +91,7 @@ public class ooxmlParser extends AbstractParser implements Idiom { @Override public Document parse(final MultiProtocolURI location, final String mimeType, final String charset, final File dest) throws ParserException, InterruptedException { - Writer writer = null; - File writerFile = null; + CharBuffer writer = null; try { String docDescription = null; String docKeywordStr = null; @@ -166,40 +164,22 @@ public class ooxmlParser extends AbstractParser implements Idiom { // create the parser document Document theDoc = null; - if (writer instanceof CharBuffer) { - final byte[] contentBytes = ((CharBuffer)writer).toString().getBytes("UTF-8"); - theDoc = new Document( - location, - mimeType, - "UTF-8", - languages, - docKeywords, - docLongTitle, - docAuthor, - "", - null, - docDescription, - contentBytes, - null, - null, - false); - } else { - theDoc = new Document( - location, - mimeType, - "UTF-8", - languages, - docKeywords, - docLongTitle, - docAuthor, - "", - null, - docDescription, - writerFile, - null, - null, - false); - } + final byte[] contentBytes = writer.toString().getBytes("UTF-8"); + theDoc = new Document( + location, + mimeType, + "UTF-8", + languages, + docKeywords, + docLongTitle, + docAuthor, + "", + null, + docDescription, + contentBytes, + null, + null, + false); return theDoc; } catch (final Exception e) { if (e instanceof InterruptedException) throw (InterruptedException) e; @@ -207,9 +187,7 @@ public class ooxmlParser extends AbstractParser implements Idiom { // close the writer if (writer != null) try { writer.close(); } catch (final Exception ex) {/* ignore this */} - - // delete the file - if (writerFile != null) FileUtils.deletedelete(writerFile); + Log.logException(e); throw new ParserException("Unexpected error while parsing odt file. " + e.getMessage(),location); } diff --git a/source/net/yacy/document/parser/pdfParser.java b/source/net/yacy/document/parser/pdfParser.java index bb3054cfb..d0c7c8aa5 100644 --- a/source/net/yacy/document/parser/pdfParser.java +++ b/source/net/yacy/document/parser/pdfParser.java @@ -31,7 +31,6 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.UnsupportedEncodingException; -import java.io.Writer; import java.util.HashSet; import java.util.Set; @@ -132,8 +131,7 @@ public class pdfParser extends AbstractParser implements Idiom { docKeywordStr = theDocInfo.getKeywords(); } - Writer writer = null; - File writerFile = null; + CharBuffer writer = null; PDFTextStripper stripper = null; try { // create a writer for output @@ -146,9 +144,7 @@ public class pdfParser extends AbstractParser implements Idiom { Log.logException(e); // close the writer if (writer != null) try { writer.close(); } catch (final Exception ex) {} - - // delete the file - if (writerFile != null) FileUtils.deletedelete(writerFile); + throw new ParserException(e.getMessage(), location); } @@ -157,47 +153,29 @@ public class pdfParser extends AbstractParser implements Idiom { Document theDoc = null; if (docTitle == null) docTitle = docSubject; - - if (writer instanceof CharBuffer) { - byte[] contentBytes; - try { - contentBytes = ((CharBuffer) writer).toString().getBytes("UTF-8"); - } catch (UnsupportedEncodingException e) { - Log.logException(e); - throw new ParserException(e.getMessage(), location); - } - theDoc = new Document( - location, - mimeType, - "UTF-8", - null, - docKeywords, - docTitle, - docAuthor, - docPublisher, - null, - null, - contentBytes, - null, - null, - false); - } else { - theDoc = new Document( - location, - mimeType, - "UTF-8", - null, - docKeywords, - docTitle, - docAuthor, - docPublisher, - null, - null, - writerFile, - null, - null, - false); + + byte[] contentBytes; + try { + contentBytes = writer.toString().getBytes("UTF-8"); + } catch (UnsupportedEncodingException e) { + Log.logException(e); + throw new ParserException(e.getMessage(), location); } + theDoc = new Document( + location, + mimeType, + "UTF-8", + null, + docKeywords, + docTitle, + docAuthor, + docPublisher, + null, + null, + contentBytes, + null, + null, + false); return theDoc; } diff --git a/source/net/yacy/document/parser/tarParser.java b/source/net/yacy/document/parser/tarParser.java index fefb5e312..107e543c8 100644 --- a/source/net/yacy/document/parser/tarParser.java +++ b/source/net/yacy/document/parser/tarParser.java @@ -29,7 +29,6 @@ package net.yacy.document.parser; import java.io.File; import java.io.InputStream; -import java.io.OutputStream; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -84,8 +83,7 @@ public class tarParser extends AbstractParser implements Idiom { public Document parse(final MultiProtocolURI location, final String mimeType, final String charset, InputStream source) throws ParserException, InterruptedException { long docTextLength = 0; - OutputStream docText = null; - File outputFile = null; + ByteBuffer docText = null; Document subDoc = null; try { docText = new ByteBuffer(); @@ -176,41 +174,21 @@ public class tarParser extends AbstractParser implements Idiom { subDoc = null; } - Document result = null; - - if (docText instanceof ByteBuffer) { - result = new Document( - location, - mimeType, - null, - null, - docKeywords.toString().split(" |,"), - docLongTitle.toString(), - "", // TODO: AUTHOR - "", // TODO: publisher - docSections.toArray(new String[docSections.size()]), - docAbstrct.toString(), - ((ByteBuffer)docText).getBytes(), - docAnchors, - docImages, - false); - } else { - result = new Document( - location, - mimeType, - null, - null, - docKeywords.toString().split(" |,"), - docLongTitle.toString(), - "", // TODO: AUTHOR - "", // TODO: publisher - docSections.toArray(new String[docSections.size()]), - docAbstrct.toString(), - outputFile, - docAnchors, - docImages, - false); - } + Document result = new Document( + location, + mimeType, + null, + null, + docKeywords.toString().split(" |,"), + docLongTitle.toString(), + "", // TODO: AUTHOR + "", // TODO: publisher + docSections.toArray(new String[docSections.size()]), + docAbstrct.toString(), + docText.getBytes(), + docAnchors, + docImages, + false); return result; } catch (final Exception e) { @@ -222,9 +200,6 @@ public class tarParser extends AbstractParser implements Idiom { // close the writer if (docText != null) try { docText.close(); } catch (final Exception ex) {/* ignore this */} - // delete the file - if (outputFile != null) FileUtils.deletedelete(outputFile); - throw new ParserException("Unexpected error while parsing tar resource. " + e.getMessage(),location); } } diff --git a/source/net/yacy/document/parser/zipParser.java b/source/net/yacy/document/parser/zipParser.java index f61e3cc0c..aaea575a8 100644 --- a/source/net/yacy/document/parser/zipParser.java +++ b/source/net/yacy/document/parser/zipParser.java @@ -29,7 +29,6 @@ package net.yacy.document.parser; import java.io.File; import java.io.InputStream; -import java.io.OutputStream; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -85,8 +84,7 @@ public class zipParser extends AbstractParser implements Idiom { public Document parse(final MultiProtocolURI location, final String mimeType, final String charset, final InputStream source) throws ParserException, InterruptedException { long docTextLength = 0; - OutputStream docText = null; - File outputFile = null; + ByteBuffer docText = null; Document subDoc = null; try { docText = new ByteBuffer(); @@ -163,42 +161,21 @@ public class zipParser extends AbstractParser implements Idiom { } - Document result = null; - - if (docText instanceof ByteBuffer) { - result = new Document( - location, - mimeType, - null, - null, - docKeywords.toString().split(" |,"), - docLongTitle.toString(), - "", // TODO: AUTHOR - "", // TODO: Publisher - docSections.toArray(new String[docSections.size()]), - docAbstrct.toString(), - ((ByteBuffer)docText).getBytes(), - docAnchors, - docImages, - false); - } else { - result = new Document( - location, - mimeType, - null, - null, - docKeywords.toString().split(" |,"), - docLongTitle.toString(), - "", // TODO: AUTHOR - "", // TODO: Publisher - docSections.toArray(new String[docSections.size()]), - docAbstrct.toString(), - outputFile, - docAnchors, - docImages, - false); - } - + Document result = new Document( + location, + mimeType, + null, + null, + docKeywords.toString().split(" |,"), + docLongTitle.toString(), + "", // TODO: AUTHOR + "", // TODO: Publisher + docSections.toArray(new String[docSections.size()]), + docAbstrct.toString(), + docText.getBytes(), + docAnchors, + docImages, + false); return result; } catch (final Exception e) { if (e instanceof InterruptedException) throw (InterruptedException) e; @@ -209,9 +186,6 @@ public class zipParser extends AbstractParser implements Idiom { // close the writer if (docText != null) try { docText.close(); } catch (final Exception ex) {/* ignore this */} - // delete the file - if (outputFile != null) FileUtils.deletedelete(outputFile); - throw new ParserException("Unexpected error while parsing zip resource. " + e.getClass().getName() + ": "+ e.getMessage(),location); } } diff --git a/source/net/yacy/kelondro/order/CloneableMapIterator.java b/source/net/yacy/kelondro/order/CloneableMapIterator.java index ebe3cafcc..30d46b4f9 100644 --- a/source/net/yacy/kelondro/order/CloneableMapIterator.java +++ b/source/net/yacy/kelondro/order/CloneableMapIterator.java @@ -55,7 +55,7 @@ public class CloneableMapIterator implements CloneableIterator { this.last = null; } - @SuppressWarnings("unchecked") + @SuppressWarnings({ "unchecked", "rawtypes" }) public CloneableMapIterator clone(final Object modifier) { return new CloneableMapIterator(map, modifier); } diff --git a/source/net/yacy/kelondro/rwi/IODispatcher.java b/source/net/yacy/kelondro/rwi/IODispatcher.java index 8d755fb10..dafffe3b4 100644 --- a/source/net/yacy/kelondro/rwi/IODispatcher.java +++ b/source/net/yacy/kelondro/rwi/IODispatcher.java @@ -78,14 +78,14 @@ public class IODispatcher extends Thread { } } } - - @SuppressWarnings("unchecked") + + @SuppressWarnings({ "unchecked", "rawtypes" }) protected synchronized void dump(ReferenceContainerCache cache, File file, ReferenceContainerArray array) { if (dumpQueue == null || controlQueue == null || !this.isAlive()) { Log.logWarning("IODispatcher", "emergency dump of file " + file.getName()); if (!cache.isEmpty()) cache.dump(file, (int) Math.min(MemoryControl.available() / 3, writeBufferSize), true); } else { - DumpJob job = (DumpJob)new DumpJob(cache, file, array); + DumpJob job = new DumpJob(cache, file, array); try { // check if the dispatcher is running if (this.isAlive()) { diff --git a/source/net/yacy/kelondro/util/AttrSeq.java b/source/net/yacy/kelondro/util/AttrSeq.java index 0770e3197..d849717fb 100644 --- a/source/net/yacy/kelondro/util/AttrSeq.java +++ b/source/net/yacy/kelondro/util/AttrSeq.java @@ -432,13 +432,8 @@ public class AttrSeq { } } - private static final long cc = 0; - private static boolean shortmemstate = false; private static boolean shortmem() { - if ((cc % 300) == 0) { - shortmemstate = (MemoryControl.available() < 20000000L); - } - return shortmemstate; + return (MemoryControl.available() < 20000000L); } public static void transcode(final File from_file, final File to_file) throws IOException { diff --git a/source/net/yacy/yacy.java b/source/net/yacy/yacy.java index 71e52d414..79005080f 100644 --- a/source/net/yacy/yacy.java +++ b/source/net/yacy/yacy.java @@ -308,121 +308,118 @@ public final class yacy { server.setName("httpd:"+port); server.setPriority(Thread.MAX_PRIORITY); server.setObeyIntermission(false); - if (server == null) { - Log.logSevere("STARTUP", "Failed to start server. Probably port " + port + " already in use."); - } else { - // first start the server - sb.deployThread("10_httpd", "HTTPD Server/Proxy", "the HTTPD, used as web server and proxy", null, server, 0, 0, 0, 0); - //server.start(); + + // start the server + sb.deployThread("10_httpd", "HTTPD Server/Proxy", "the HTTPD, used as web server and proxy", null, server, 0, 0, 0, 0); + //server.start(); + + // open the browser window + final boolean browserPopUpTrigger = sb.getConfig(SwitchboardConstants.BROWSER_POP_UP_TRIGGER, "true").equals("true"); + if (browserPopUpTrigger) { + final String browserPopUpPage = sb.getConfig(SwitchboardConstants.BROWSER_POP_UP_PAGE, "ConfigBasic.html"); + //boolean properPW = (sb.getConfig("adminAccount", "").length() == 0) && (sb.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "").length() > 0); + //if (!properPW) browserPopUpPage = "ConfigBasic.html"; + final String browserPopUpApplication = sb.getConfig(SwitchboardConstants.BROWSER_POP_UP_APPLICATION, "firefox"); + OS.openBrowser((server.withSSL()?"https":"http") + "://localhost:" + serverCore.getPortNr(port) + "/" + browserPopUpPage, browserPopUpApplication); + } + + // unlock yacyTray browser popup + Tray.lockBrowserPopup = false; - // open the browser window - final boolean browserPopUpTrigger = sb.getConfig(SwitchboardConstants.BROWSER_POP_UP_TRIGGER, "true").equals("true"); - if (browserPopUpTrigger) { - final String browserPopUpPage = sb.getConfig(SwitchboardConstants.BROWSER_POP_UP_PAGE, "ConfigBasic.html"); - //boolean properPW = (sb.getConfig("adminAccount", "").length() == 0) && (sb.getConfig(httpd.ADMIN_ACCOUNT_B64MD5, "").length() > 0); - //if (!properPW) browserPopUpPage = "ConfigBasic.html"; - final String browserPopUpApplication = sb.getConfig(SwitchboardConstants.BROWSER_POP_UP_APPLICATION, "firefox"); - OS.openBrowser((server.withSSL()?"https":"http") + "://localhost:" + serverCore.getPortNr(port) + "/" + browserPopUpPage, browserPopUpApplication); + // Copy the shipped locales into DATA, existing files are overwritten + final File locale_work = sb.getConfigPath("locale.work", "DATA/LOCALE/locales"); + final File locale_source = sb.getConfigPath("locale.source", "locales"); + try{ + final File[] locale_source_files = locale_source.listFiles(); + mkdirsIfNeseccary(locale_work); + File target; + for (int i=0; i < locale_source_files.length; i++){ + target = new File(locale_work, locale_source_files[i].getName()); + if (locale_source_files[i].getName().endsWith(".lng")) { + if (target.exists()) delete(target); + FileUtils.copy(locale_source_files[i], target); + } } - - // unlock yacyTray browser popup - Tray.lockBrowserPopup = false; + Log.logInfo("STARTUP", "Copied the default locales to " + locale_work.toString()); + }catch(final NullPointerException e){ + Log.logSevere("STARTUP", "Nullpointer Exception while copying the default Locales"); + } - // Copy the shipped locales into DATA, existing files are overwritten - final File locale_work = sb.getConfigPath("locale.work", "DATA/LOCALE/locales"); - final File locale_source = sb.getConfigPath("locale.source", "locales"); + //regenerate Locales from Translationlist, if needed + final String lang = sb.getConfig("locale.language", ""); + if (!lang.equals("") && !lang.equals("default")) { //locale is used + String currentRev = ""; try{ - final File[] locale_source_files = locale_source.listFiles(); - mkdirsIfNeseccary(locale_work); - File target; - for (int i=0; i < locale_source_files.length; i++){ - target = new File(locale_work, locale_source_files[i].getName()); - if (locale_source_files[i].getName().endsWith(".lng")) { - if (target.exists()) delete(target); - FileUtils.copy(locale_source_files[i], target); - } - } - Log.logInfo("STARTUP", "Copied the default locales to " + locale_work.toString()); - }catch(final NullPointerException e){ - Log.logSevere("STARTUP", "Nullpointer Exception while copying the default Locales"); + final BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(sb.getConfigPath("locale.translated_html", "DATA/LOCALE/htroot"), lang+"/version" )))); + currentRev = br.readLine(); + br.close(); + }catch(final IOException e){ + //Error } - //regenerate Locales from Translationlist, if needed - final String lang = sb.getConfig("locale.language", ""); - if (!lang.equals("") && !lang.equals("default")) { //locale is used - String currentRev = ""; - try{ - final BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(new File(sb.getConfigPath("locale.translated_html", "DATA/LOCALE/htroot"), lang+"/version" )))); - currentRev = br.readLine(); - br.close(); - }catch(final IOException e){ - //Error + if (!currentRev.equals(sb.getConfig("svnRevision", ""))) try { //is this another version?! + final File sourceDir = new File(sb.getConfig("htRootPath", "htroot")); + final File destDir = new File(sb.getConfigPath("locale.translated_html", "DATA/LOCALE/htroot"), lang); + if (translator.translateFilesRecursive(sourceDir, destDir, new File(locale_work, lang + ".lng"), "html,template,inc", "locale")){ //translate it + //write the new Versionnumber + final BufferedWriter bw = new BufferedWriter(new PrintWriter(new FileWriter(new File(destDir, "version")))); + bw.write(sb.getConfig("svnRevision", "Error getting Version")); + bw.close(); } + } catch (final IOException e) {} + } + // initialize number formatter with this locale + Formatter.setLocale(lang); + + // registering shutdown hook + Log.logConfig("STARTUP", "Registering Shutdown Hook"); + final Runtime run = Runtime.getRuntime(); + run.addShutdownHook(new shutdownHookThread(Thread.currentThread(), sb)); - if (!currentRev.equals(sb.getConfig("svnRevision", ""))) try { //is this another version?! - final File sourceDir = new File(sb.getConfig("htRootPath", "htroot")); - final File destDir = new File(sb.getConfigPath("locale.translated_html", "DATA/LOCALE/htroot"), lang); - if (translator.translateFilesRecursive(sourceDir, destDir, new File(locale_work, lang + ".lng"), "html,template,inc", "locale")){ //translate it - //write the new Versionnumber - final BufferedWriter bw = new BufferedWriter(new PrintWriter(new FileWriter(new File(destDir, "version")))); - bw.write(sb.getConfig("svnRevision", "Error getting Version")); - bw.close(); - } - } catch (final IOException e) {} - } - // initialize number formatter with this locale - Formatter.setLocale(lang); - - // registering shutdown hook - Log.logConfig("STARTUP", "Registering Shutdown Hook"); - final Runtime run = Runtime.getRuntime(); - run.addShutdownHook(new shutdownHookThread(Thread.currentThread(), sb)); - - // save information about available memory after all initializations - //try { - sb.setConfig("memoryFreeAfterInitBGC", MemoryControl.free()); - sb.setConfig("memoryTotalAfterInitBGC", MemoryControl.total()); - System.gc(); - sb.setConfig("memoryFreeAfterInitAGC", MemoryControl.free()); - sb.setConfig("memoryTotalAfterInitAGC", MemoryControl.total()); - //} catch (ConcurrentModificationException e) {} + // save information about available memory after all initializations + //try { + sb.setConfig("memoryFreeAfterInitBGC", MemoryControl.free()); + sb.setConfig("memoryTotalAfterInitBGC", MemoryControl.total()); + System.gc(); + sb.setConfig("memoryFreeAfterInitAGC", MemoryControl.free()); + sb.setConfig("memoryTotalAfterInitAGC", MemoryControl.total()); + //} catch (ConcurrentModificationException e) {} + + // signal finished startup + startupFinishedSync.release(); - // signal finished startup - startupFinishedSync.release(); - - // wait for server shutdown - try { - sb.waitForShutdown(); - } catch (final Exception e) { - Log.logSevere("MAIN CONTROL LOOP", "PANIC: " + e.getMessage(),e); - } - // shut down - if (RowCollection.sortingthreadexecutor != null) RowCollection.sortingthreadexecutor.shutdown(); - Log.logConfig("SHUTDOWN", "caught termination signal"); - server.terminate(false); + // wait for server shutdown + try { + sb.waitForShutdown(); + } catch (final Exception e) { + Log.logSevere("MAIN CONTROL LOOP", "PANIC: " + e.getMessage(),e); + } + // shut down + if (RowCollection.sortingthreadexecutor != null) RowCollection.sortingthreadexecutor.shutdown(); + Log.logConfig("SHUTDOWN", "caught termination signal"); + server.terminate(false); + server.interrupt(); + server.close(); + if (server.isAlive()) try { + // TODO only send request, don't read response (cause server is already down resulting in error) + final DigestURI u = new DigestURI((server.withSSL()?"https":"http")+"://localhost:" + serverCore.getPortNr(port), null); + Client.wget(u.toString(), null, 10000); // kick server + Log.logConfig("SHUTDOWN", "sent termination signal to server socket"); + } catch (final IOException ee) { + Log.logConfig("SHUTDOWN", "termination signal to server socket missed (server shutdown, ok)"); + } + Client.closeAllConnections(); + MultiThreadedHttpConnectionManager.shutdownAll(); + + // idle until the processes are down + if (server.isAlive()) { + //Thread.sleep(2000); // wait a while server.interrupt(); - server.close(); - if (server.isAlive()) try { - // TODO only send request, don't read response (cause server is already down resulting in error) - final DigestURI u = new DigestURI((server.withSSL()?"https":"http")+"://localhost:" + serverCore.getPortNr(port), null); - Client.wget(u.toString(), null, 10000); // kick server - Log.logConfig("SHUTDOWN", "sent termination signal to server socket"); - } catch (final IOException ee) { - Log.logConfig("SHUTDOWN", "termination signal to server socket missed (server shutdown, ok)"); - } - Client.closeAllConnections(); - MultiThreadedHttpConnectionManager.shutdownAll(); - - // idle until the processes are down - if (server.isAlive()) { - //Thread.sleep(2000); // wait a while - server.interrupt(); - MultiThreadedHttpConnectionManager.shutdownAll(); - } MultiThreadedHttpConnectionManager.shutdownAll(); - Log.logConfig("SHUTDOWN", "server has terminated"); - sb.close(); } + MultiThreadedHttpConnectionManager.shutdownAll(); + Log.logConfig("SHUTDOWN", "server has terminated"); + sb.close(); } catch (final Exception e) { Log.logSevere("STARTUP", "Unexpected Error: " + e.getClass().getName(),e); //System.exit(1);