![JAR search and dependency download from the Maven repository](/logo.png)
org.cybergarage.upnp.Service Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of upnp-stack Show documentation
Show all versions of upnp-stack Show documentation
A pure Java Open Source implementation of the UPnP stack for JDK 1.4 or above
The newest version!
/******************************************************************
*
* CyberLink for Java
*
* Copyright (C) Satoshi Konno 2002-2003
*
* File: Service.java
*
* Revision;
*
* 11/28/02
* - first revision.
* 04/12/02
* - Holmes, Arran C
* - Fixed SERVICE_ID constant instead of "serviceId".
* 06/17/03
* - Added notifyAllStateVariables().
* 09/03/03
* - Giordano Sassaroli
* - Problem : The device does not accepts request for services when control or subscription urls are absolute
* - Error : device methods, when requests are received, search for services that have a controlUrl (or eventSubUrl) equal to the request URI
* but request URI must be relative, so they cannot equal absolute urls
* 09/03/03
* - Steven Yen
* - description: to retrieve service information based on information in URLBase and SCPDURL
* - problem: not able to retrieve service information when URLBase is missing and SCPDURL is relative
* - fix: modify to retrieve host information from Header's Location (required) field and update the
* BaseURL tag in the xml so subsequent information retrieval can be done (Steven Yen, 8.27.2003)
* - note: 1. in the case that Header's Location field combine with SCPDURL is not able to retrieve proper
* information, updating BaseURL would not hurt, since exception will be thrown with or without update.
* 2. this problem was discovered when using PC running MS win XP with ICS enabled (gateway).
* It seems that root device xml file does not have BaseURL and SCPDURL are all relative.
* 3. UPnP device architecture states that BaseURL is optional and SCPDURL may be relative as
* specified by UPnP vendor, so MS does not seem to violate the rule.
* 10/22/03
* - Added setActionListener().
* 01/04/04
* - Changed about new QueryListener interface.
* 01/06/04
* - Moved the following methods to StateVariable class.
* getQueryListener()
* setQueryListener()
* performQueryListener()
* - Added new setQueryListener() to set a listner to all state variables.
* 07/02/04
* - Added serviceSearchResponse().
* - Deleted getLocationURL().
* - Fixed announce() to set the root device URL to the LOCATION field.
* 07/31/04
* - Changed notify() to remove the expired subscribers and not to remove the invalid response subscribers for NMPR.
* 10/29/04
* - Fixed a bug when notify() removes the expired devices().
* 03/23/05
* - Added loadSCPD() to load the description from memory.
* 03/30/05
* - Added isSCPDURL().
* - Removed setDescriptionURL() and getDescriptionURL()
* 03/31/05
* - Added getSCPDData().
* 04/25/05
* - Thanks for Mikael Hakman
* - Changed getSCPDData() to add a XML declaration at first line.
* 06/21/05
* - Changed notify() to continue when the subscriber is null.
* 04/12/06
* - Added setUserData() and getUserData() to set a user original data object.
*
******************************************************************/
package org.cybergarage.upnp;
import java.io.File;
import java.io.InputStream;
import java.net.URL;
import java.util.Iterator;
import org.cybergarage.http.HTTP;
import org.cybergarage.http.HTTPResponse;
import org.cybergarage.upnp.control.ActionListener;
import org.cybergarage.upnp.control.QueryListener;
import org.cybergarage.upnp.device.InvalidDescriptionException;
import org.cybergarage.upnp.device.NTS;
import org.cybergarage.upnp.device.ST;
import org.cybergarage.upnp.event.NotifyRequest;
import org.cybergarage.upnp.event.Subscriber;
import org.cybergarage.upnp.event.SubscriberList;
import org.cybergarage.upnp.ssdp.SSDPNotifyRequest;
import org.cybergarage.upnp.ssdp.SSDPNotifySocket;
import org.cybergarage.upnp.ssdp.SSDPPacket;
import org.cybergarage.upnp.xml.ServiceData;
import org.cybergarage.util.Debug;
import org.cybergarage.util.Mutex;
import org.cybergarage.util.StringUtil;
import org.cybergarage.xml.Node;
import org.cybergarage.xml.Parser;
import org.cybergarage.xml.ParserException;
public class Service
{
////////////////////////////////////////////////
// Constants
////////////////////////////////////////////////
public final static String ELEM_NAME = "service";
////////////////////////////////////////////////
// Member
////////////////////////////////////////////////
private Node serviceNode;
public Node getServiceNode()
{
return serviceNode;
}
////////////////////////////////////////////////
// Constructor
////////////////////////////////////////////////
public static final String SCPD_ROOTNODE="scpd";
public static final String SCPD_ROOTNODE_NS="urn:schemas-upnp-org:service-1-0";
public static final String SPEC_VERSION="specVersion";
public static final String MAJOR="major";
public static final String MAJOR_VALUE="1";
public static final String MINOR="minor";
public static final String MINOR_VALUE="0";
public Service(){
this(new Node(ELEM_NAME));
Node sp = new Node(SPEC_VERSION);
Node M =new Node(MAJOR);
M.setValue(MAJOR_VALUE);
sp.addNode(M);
Node m =new Node(MINOR);
m.setValue(MINOR_VALUE);
sp.addNode(m);
//Node scpd = new Node(SCPD_ROOTNODE,SCPD_ROOTNODE_NS); wrong!
Node scpd = new Node(SCPD_ROOTNODE); // better (twa)
scpd.addAttribute("xmlns",SCPD_ROOTNODE_NS); // better (twa)
scpd.addNode(sp);
getServiceData().setSCPDNode(scpd);
}
public Service(Node node)
{
serviceNode = node;
}
////////////////////////////////////////////////
// Mutex
////////////////////////////////////////////////
private Mutex mutex = new Mutex();
public void lock()
{
mutex.lock();
}
public void unlock()
{
mutex.unlock();
}
////////////////////////////////////////////////
// isServiceNode
////////////////////////////////////////////////
public static boolean isServiceNode(Node node)
{
return Service.ELEM_NAME.equals(node.getName());
}
////////////////////////////////////////////////
// Device/Root Node
////////////////////////////////////////////////
private Node getDeviceNode()
{
Node node = getServiceNode().getParentNode();
if (node == null)
return null;
return node.getParentNode();
}
private Node getRootNode()
{
return getServiceNode().getRootNode();
}
////////////////////////////////////////////////
// Device
////////////////////////////////////////////////
public Device getDevice()
{
return new Device(getRootNode(), getDeviceNode());
}
public Device getRootDevice()
{
return getDevice().getRootDevice();
}
////////////////////////////////////////////////
// serviceType
////////////////////////////////////////////////
private final static String SERVICE_TYPE = "serviceType";
public void setServiceType(String value)
{
getServiceNode().setNode(SERVICE_TYPE, value);
}
public String getServiceType()
{
return getServiceNode().getNodeValue(SERVICE_TYPE);
}
////////////////////////////////////////////////
// serviceID
////////////////////////////////////////////////
private final static String SERVICE_ID = "serviceId";
public void setServiceID(String value)
{
getServiceNode().setNode(SERVICE_ID, value);
}
public String getServiceID()
{
return getServiceNode().getNodeValue(SERVICE_ID);
}
////////////////////////////////////////////////
// isURL
////////////////////////////////////////////////
// Thanks for Giordano Sassaroli (09/03/03)
private boolean isURL(String referenceUrl, String url)
{
if (referenceUrl ==null || url == null)
return false;
boolean ret = url.equals(referenceUrl);
if (ret == true)
return true;
String relativeRefUrl = HTTP.toRelativeURL(referenceUrl, false);
ret = url.equals(relativeRefUrl);
if (ret == true)
return true;
return false;
}
////////////////////////////////////////////////
// SCPDURL
////////////////////////////////////////////////
private final static String SCPDURL = "SCPDURL";
public void setSCPDURL(String value)
{
getServiceNode().setNode(SCPDURL, value);
}
public String getSCPDURL()
{
return getServiceNode().getNodeValue(SCPDURL);
}
public boolean isSCPDURL(String url)
{
return isURL(getSCPDURL(), url);
}
////////////////////////////////////////////////
// controlURL
////////////////////////////////////////////////
private final static String CONTROL_URL = "controlURL";
public void setControlURL(String value)
{
getServiceNode().setNode(CONTROL_URL, value);
}
public String getControlURL()
{
return getServiceNode().getNodeValue(CONTROL_URL);
}
public boolean isControlURL(String url)
{
return isURL(getControlURL(), url);
}
////////////////////////////////////////////////
// eventSubURL
////////////////////////////////////////////////
private final static String EVENT_SUB_URL = "eventSubURL";
public void setEventSubURL(String value)
{
getServiceNode().setNode(EVENT_SUB_URL, value);
}
public String getEventSubURL()
{
return getServiceNode().getNodeValue(EVENT_SUB_URL);
}
public boolean isEventSubURL(String url)
{
return isURL(getEventSubURL(), url);
}
////////////////////////////////////////////////
// SCPD node
////////////////////////////////////////////////
public boolean loadSCPD(String scpdStr) throws InvalidDescriptionException
{
try {
Parser parser = UPnP.getXMLParser();
Node scpdNode = parser.parse(scpdStr);
if (scpdNode == null)
return false;
ServiceData data = getServiceData();
data.setSCPDNode(scpdNode);
}
catch (ParserException e) {
throw new InvalidDescriptionException(e);
}
return true;
}
public boolean loadSCPD(File file) throws ParserException
{
Parser parser = UPnP.getXMLParser();
Node scpdNode = parser.parse(file);
if (scpdNode == null)
return false;
ServiceData data = getServiceData();
data.setSCPDNode(scpdNode);
return true;
}
/**
* @since 1.8.0
*/
public boolean loadSCPD(InputStream input) throws ParserException
{
Parser parser = UPnP.getXMLParser();
Node scpdNode = parser.parse(input);
if (scpdNode == null)
return false;
ServiceData data = getServiceData();
data.setSCPDNode(scpdNode);
return true;
}
public void setDescriptionURL(String value)
{
getServiceData().setDescriptionURL(value);
}
public String getDescriptionURL()
{
return getServiceData().getDescriptionURL();
}
private Node getSCPDNode(URL scpdUrl) throws ParserException
{
Parser parser = UPnP.getXMLParser();
return parser.parse(scpdUrl);
}
private Node getSCPDNode(File scpdFile) throws ParserException
{
Parser parser = UPnP.getXMLParser();
return parser.parse(scpdFile);
}
private Node getSCPDNode()
{
ServiceData data = getServiceData();
Node scpdNode = data.getSCPDNode();
if (scpdNode != null)
return scpdNode;
String scpdURLStr = getSCPDURL();
try {
URL scpdUrl = new URL(scpdURLStr);
scpdNode = getSCPDNode(scpdUrl);
}
catch (Exception e1) {
Device rootDev = getRootDevice();
String urlBaseStr = rootDev.getURLBase();
// Thanks for Steven Yen (2003/09/03)
if (urlBaseStr == null || urlBaseStr.length() <= 0) {
String location = rootDev.getLocation();
String locationHost = HTTP.getHost(location);
int locationPort = HTTP.getPort(location);
urlBaseStr = HTTP.getRequestHostURL(locationHost, locationPort);
}
scpdURLStr = HTTP.toRelativeURL(scpdURLStr);
String newScpdURLStr = urlBaseStr + scpdURLStr;
try {
URL newScpdURL = new URL(newScpdURLStr);
scpdNode = getSCPDNode(newScpdURL);
}
catch (Exception e2) {
newScpdURLStr = HTTP.getAbsoluteURL(urlBaseStr, scpdURLStr);
try {
URL newScpdURL = new URL(newScpdURLStr);
scpdNode = getSCPDNode(newScpdURL);
}
catch (Exception e3) {
newScpdURLStr = rootDev.getDescriptionFilePath() + scpdURLStr;
try {
scpdNode = getSCPDNode(new File(newScpdURLStr));
}
catch (Exception e4) {
Debug.warning(e4);
}
}
}
}
data.setSCPDNode(scpdNode);
return scpdNode;
}
public byte[] getSCPDData()
{
Node scpdNode = getSCPDNode();
if (scpdNode == null)
return new byte[0];
// Thanks for Mikael Hakman (04/25/05)
String desc = new String();
desc += UPnP.XML_DECLARATION;
desc += "\n";
desc += scpdNode.toString();
return desc.getBytes();
}
////////////////////////////////////////////////
// actionList
////////////////////////////////////////////////
public ActionList getActionList()
{
ActionList actionList = new ActionList();
Node scdpNode = getSCPDNode();
if (scdpNode == null)
return actionList;
Node actionListNode = scdpNode.getNode(ActionList.ELEM_NAME);
if (actionListNode == null)
return actionList;
int nNode = actionListNode.getNNodes();
for (int n=0; n
*
* Note: This method should be used to create a dynamic
* Device withtout writing any XML that describe the device
.
*
* Note: that no control for duplicate StateVariable is done.
*
* @param var StateVariable that will be added
*
* @author Stefano "Kismet" Lenzi - [email protected] - 2005
*/
public void addStateVariable(StateVariable var) {
//TODO Some test are done not stable
Node stateTableNode = getSCPDNode().getNode(ServiceStateTable.ELEM_NAME);
if (stateTableNode == null){
stateTableNode = new Node(ServiceStateTable.ELEM_NAME);
/*
* Force the node to be the first node inside
*/
//getSCPDNode().insertNode(stateTableNode,0);
getSCPDNode().addNode(stateTableNode);
}
var.setServiceNode(getServiceNode());
stateTableNode.addNode(var.getStateVariableNode());
}
////////////////////////////////////////////////
// userData
////////////////////////////////////////////////
private Object userData = null;
public void setUserData(Object data)
{
userData = data;
}
public Object getUserData()
{
return userData;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy