/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.felix.upnp.basedriver.importer.core.event.structs; | |
import java.util.Dictionary; | |
import java.util.Hashtable; | |
import java.util.Iterator; | |
import java.util.Vector; | |
import org.cybergarage.upnp.Service; | |
import org.osgi.service.upnp.UPnPEventListener; | |
import org.apache.felix.upnp.basedriver.importer.core.MyCtrlPoint; | |
import org.apache.felix.upnp.basedriver.importer.core.event.message.FirstMessage; | |
import org.apache.felix.upnp.basedriver.importer.core.event.message.ListenerModified; | |
/* | |
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> | |
*/ | |
public class Monitor { | |
private Hashtable sidStateVars; | |
private SidsListenersMaps sidListSid; | |
public Monitor() { | |
this.sidListSid = new SidsListenersMaps(); | |
this.sidStateVars = new Hashtable(); | |
} | |
public synchronized void putStateVars(String sid, StateVarsToNotify vars) { | |
sidStateVars.put(sid, vars); | |
Vector listeners = (Vector) sidListSid.getListenersFromSid(sid); | |
if (listeners != null) { | |
sidListSid.updateListeners(sid, vars.getDeviceID(), vars.getServiceID(), vars.getDictionary()); | |
sidListSid.setAlreadyFirst(sid,true); | |
} else { | |
sidListSid.setAlreadyFirst(sid, false); | |
} | |
} | |
public synchronized void updateStateVars(String sid, Dictionary dic) { | |
StateVarsToNotify vars = (StateVarsToNotify) sidStateVars.get(sid); | |
if (vars != null) { | |
vars.updateDic(dic); | |
if (sidListSid.getAlreadyFirst(sid)) { | |
/* | |
* Sends only the changed StateVariable | |
*/ | |
sidListSid.updateListeners(sid, | |
vars.getDeviceID(), vars.getServiceID(), | |
dic); | |
} else { | |
/* | |
* Sends the sholw StateVariable for the service | |
*/ | |
boolean bool = sidListSid.updateListeners(sid, | |
vars.getDeviceID(), vars.getServiceID(), | |
vars.getDictionary()); | |
if (bool) { | |
sidListSid.setAlreadyFirst(sid,true); | |
} | |
} | |
} | |
} | |
/* | |
public synchronized StateVarsToNotify getStateVars(String sid) { | |
return (StateVarsToNotify) sidStateVars.get(sid); | |
} | |
public synchronized void removeStateVars(String sid) { | |
sidStateVars.remove(sid); | |
} | |
*/ | |
public synchronized void addListener(String sid, UPnPEventListener listener) { | |
StateVarsToNotify vars = (StateVarsToNotify) sidStateVars.get(sid); | |
if (vars != null) { | |
/* | |
* Notify the listener whit the whole StateVariables and then | |
* the next time you send only the changed StateVariables | |
*/ | |
listener.notifyUPnPEvent(vars.getDeviceID(), | |
vars.getServiceID(),vars.getDictionary()); | |
} | |
sidListSid.putSid2Listeners(sid, listener); | |
sidListSid.putListener2Sids(listener, sid); | |
} | |
/** | |
* Delete the reference to the listener from the stuctures sid2Listeners and listener2Sids. | |
* Also if no more listner are listening for a UPnP Service that UPnP Service is unscribed. | |
* | |
* @param listener The listener to delete | |
* @param ctrl Needed for reference | |
*/ | |
public synchronized void delListener(UPnPEventListener listener, | |
MyCtrlPoint ctrl/*##renew, SidRenewer sidRenewer*/) { | |
//francesco-renew | |
// State variable clean up -- todo? | |
Vector sids = sidListSid.getSidsFromListener(listener); | |
if (sids != null) { | |
Iterator i = sids.iterator(); | |
while(i.hasNext()){ | |
String sid = (String) i.next(); | |
Vector listeners = | |
sidListSid.getListenersFromSid(sid); | |
listeners.remove(listener); | |
if (listeners.size() == 0) { | |
Service service = | |
ctrl.serviceFromSid(sid); | |
//##renew Renewer renewer = sidRenewer.get((String) sids.elementAt(i)); | |
//##renew renewer.stop(); | |
if (service != null) { | |
boolean ok = ctrl.unsubscribe(service); | |
if (!ok) { | |
//TODO Log?s | |
service.clearSID(); | |
} | |
} | |
sidListSid.setAlreadyFirst(sid,false); | |
sidStateVars.remove(sid); | |
i.remove(); | |
} | |
} | |
sidListSid.removeListenerKey(listener); | |
} | |
} | |
public synchronized void updateListener(ListenerModified msg, | |
SubscriptionQueue subqueue, MyCtrlPoint ctrl/*##renew, SidRenewer sidRenewer*/) { | |
UPnPEventListener listener = msg.getListener(); | |
Vector newServices = msg.getNewServices(); | |
Vector subscribed = new Vector(); | |
Vector notSubscribed = new Vector(); | |
for (int i = 0; i < newServices.size(); i++) { | |
Service ser = (Service) newServices.elementAt(i); | |
if (ser.isSubscribed()) { | |
subscribed.add(ser); | |
} else { | |
notSubscribed.add(ser); | |
} | |
} | |
Vector oldSids = sidListSid.getSidsFromListener(listener); | |
// francesco-renew | |
// check subscribed services | |
if(oldSids==null) return; | |
for (int i = 0; i < notSubscribed.size(); i++) { | |
Service ser = (Service) notSubscribed.elementAt(i); | |
subqueue.enqueue(new FirstMessage(ser, listener)); | |
} | |
for (int i = 0; i < oldSids.size(); i++) { | |
String oldSid = (String) oldSids.elementAt(i); | |
if (!subscribed.contains(oldSid)) { | |
// francesco-renew | |
// to check -- Listner removal from sid2Listener | |
unsubscribeListenerForSid(oldSid,listener,ctrl); | |
} | |
} | |
} | |
/** | |
* Unregister the listener as UPnPListener for the UPnPService with | |
* the spicfied SID | |
* | |
* @param sid | |
* @param listener | |
* @param ctrl | |
*/ | |
private void unsubscribeListenerForSid(String sid, UPnPEventListener listener, MyCtrlPoint ctrl) { | |
Vector listeners = sidListSid.getListenersFromSid(sid); | |
listeners.remove(listener); | |
if(listeners.size()==0){ | |
Service service = ctrl.serviceFromSid(sid); | |
if (service != null) { | |
boolean ok = ctrl.unsubscribe(service); | |
if (!ok) { | |
//TODO Log? | |
service.clearSID(); | |
} | |
} | |
sidListSid.setAlreadyFirst(sid,false); | |
sidStateVars.remove(sid); | |
} | |
Vector sids = sidListSid.getSidsFromListener(listener); | |
sids.remove(sid); | |
if(sids.size()==0){ | |
sidListSid.removeListenerKey(listener); | |
} | |
} | |
public synchronized void delSid(String sid) { | |
Vector listeners = sidListSid.getListenersFromSid(sid); | |
if(listeners==null)return; | |
for (int i = 0; i < listeners.size(); i++) { | |
Vector sids = sidListSid.getSidsFromListener((UPnPEventListener) listeners | |
.elementAt(i)); | |
sids.remove(sid); | |
} | |
sidListSid.removeSidKey(sid); | |
} | |
public synchronized void clearAll(String sid, Service service) { | |
service.clearSID(); | |
delSid(sid); | |
sidStateVars.remove(sid); | |
} | |
} |