blob: 095a473d964b2cd13653fe522f56f4b007354dc3 [file] [log] [blame]
/*
* 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);
}
}