blob: 28a05afb9aca49d76ef9eeece8cbbf2be52efad6 [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.sample.tv;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.Dictionary;
import java.util.Iterator;
import java.util.Properties;
import java.util.Vector;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.Filter;
import org.osgi.framework.ServiceEvent;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceReference;
import org.osgi.service.upnp.UPnPDevice;
import org.osgi.service.upnp.UPnPEventListener;
import org.osgi.service.upnp.UPnPService;
import org.osgi.service.upnp.UPnPStateVariable;
/*
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
public class UPnPEventNotifier implements PropertyChangeListener,ServiceListener {
BundleContext context;
UPnPDevice device;
UPnPService service;
EventSource source;
Properties UPnPTargetListener;
String deviceId;
String serviceId;
Vector upnpListeners = new Vector();
public UPnPEventNotifier(BundleContext context,UPnPDevice device,UPnPService service,EventSource source){
this.context=context;
this.device=device;
this.service=service;
this.source=source;
this.serviceId=service.getId();
setupUPnPListenerHouseKeeping(device);
}
/**
* @param deviceId
*/
private void setupUPnPListenerHouseKeeping(UPnPDevice device) {
UPnPTargetListener = new Properties();
Dictionary dict = device.getDescriptions(null);
deviceId = (String) dict.get(UPnPDevice.ID);
UPnPTargetListener.put(UPnPDevice.ID,deviceId);
UPnPTargetListener.put(UPnPService.ID,serviceId);
UPnPTargetListener.put(UPnPDevice.TYPE,dict.get(UPnPDevice.TYPE));
UPnPTargetListener.put(UPnPService.TYPE,service.getType());
String ANY_UPnPEventListener = "("+Constants.OBJECTCLASS+"="+UPnPEventListener.class.getName()+")";
ServiceReference[] listeners = null;
try {
listeners = context.getServiceReferences(UPnPEventListener.class.getName(),null);
if (listeners != null){
for (int i = 0;i<listeners.length;i++){
ServiceReference sr = listeners[i];
Filter filter = (Filter) sr.getProperty(UPnPEventListener.UPNP_FILTER);
if (filter == null) addNewListener(sr);
else {
if (filter.match(UPnPTargetListener))
addNewListener(sr);
}
}
}
} catch (Exception ex) {
System.out.println(ex);
}
try {
//String filter = "(&" + ANY_UPnPEventListener + deviceId_Filter + ")";
String filter = ANY_UPnPEventListener;
context.addServiceListener(this,filter);
} catch (Exception ex) {
System.out.println(ex);
}
if (source!=null){
UPnPStateVariable[] vars = service.getStateVariables();
if (vars != null){
for (int i=0;i<vars.length;i++)
if(vars[i].sendsEvents())
source.addPropertyChangeListener(vars[i].getName(),this);
}
}
}
/* (non-Javadoc)
* @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
*/
public void propertyChange(PropertyChangeEvent evt) {
Iterator list = upnpListeners.iterator();
String property = evt.getPropertyName();
Object value = evt.getNewValue();
String valueString = value.toString();
final Properties events = new Properties();
events.put(property,valueString);
while (list.hasNext()){
final ServiceReference sr = (ServiceReference)list.next();
String[] props =sr.getPropertyKeys();
new Thread(null,null,"Notifier"){
public void run(){
try {
UPnPEventListener listener = (UPnPEventListener) context.getService(sr);
listener.notifyUPnPEvent(deviceId,serviceId,events);
context.ungetService(sr);
} catch (Exception ex){
System.out.println("TV UPnPEventNotifier Err: " +ex);
System.out.println("context: " +context);
System.out.println("listener: " +context.getService(sr));
System.out.println("sr: " +sr);
}
}
}.start();
}
}
/* (non-Javadoc)
* @see org.osgi.framework.ServiceListener#serviceChanged(org.osgi.framework.ServiceEvent)
*/
public void serviceChanged(ServiceEvent e) {
switch(e.getType()){
case ServiceEvent.REGISTERED:{
ServiceReference sr = e.getServiceReference();
Filter filter = (Filter) sr.getProperty(UPnPEventListener.UPNP_FILTER);
if (filter == null) addNewListener(sr);
else {
if (filter.match(UPnPTargetListener))
addNewListener(sr);
}
};break;
case ServiceEvent.MODIFIED:{
ServiceReference sr = e.getServiceReference();
Filter filter = (Filter) sr.getProperty(UPnPEventListener.UPNP_FILTER);
removeListener(sr);
if (filter == null)
addNewListener(sr);
else {
if (filter.match(UPnPTargetListener))
addNewListener(sr);
}
};break;
case ServiceEvent.UNREGISTERING:{
removeListener(e.getServiceReference());
};break;
}
}
/**
* @param reference
*/
private void removeListener(ServiceReference reference) {
upnpListeners.remove(reference);
}
/**
* @param reference
*/
private void addNewListener(ServiceReference reference) {
upnpListeners.add(reference);
UPnPStateVariable[] vars = service.getStateVariables();
if (vars != null){
for (int i=0;i<vars.length;i++)
if(vars[i].sendsEvents()){
Object value = ((UPnPStateVariableDescriptor) vars[i]).getValue();
propertyChange(new PropertyChangeEvent(this,vars[i].getName(),value,value));
}
}
}
public void destroy(){
context.removeServiceListener(this);
upnpListeners.removeAllElements();
}
}