| /* |
| * 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); |
| } |
| |
| } |