001/******************************************************************************* 002 * Copyright (c) 2009, 2013 IBM Corporation and others. 003 * All rights reserved. This program and the accompanying materials 004 * are made available under the terms of the Eclipse Public License v1.0 005 * which accompanies this distribution, and is available at 006 * http://www.eclipse.org/legal/epl-v10.html 007 * 008 * Contributors: 009 * IBM Corporation - initial API and implementation 010 * Florian Pirchner - adjustments to osbp code 011 *******************************************************************************/ 012package org.eclipse.osbp.runtime.event; 013 014import java.util.ArrayList; 015import java.util.Collection; 016import java.util.Dictionary; 017import java.util.HashMap; 018import java.util.Hashtable; 019import java.util.Map; 020 021import org.eclipse.osbp.runtime.common.event.IEventBroker; 022import org.osgi.framework.BundleContext; 023import org.osgi.framework.ServiceRegistration; 024import org.osgi.service.component.ComponentContext; 025import org.osgi.service.component.annotations.Activate; 026import org.osgi.service.component.annotations.Component; 027import org.osgi.service.component.annotations.Deactivate; 028import org.osgi.service.component.annotations.Reference; 029import org.osgi.service.component.annotations.ReferenceCardinality; 030import org.osgi.service.event.Event; 031import org.osgi.service.event.EventAdmin; 032import org.osgi.service.event.EventConstants; 033import org.osgi.service.event.EventHandler; 034 035@Component 036public class EventBroker implements IEventBroker { 037 038 // private static final Logger LOGGER = LoggerFactory 039 // .getLogger(EventBroker.class); 040 041 // TBD synchronization 042 private Map<EventHandler, Collection<ServiceRegistration<?>>> registrations = new HashMap<EventHandler, Collection<ServiceRegistration<?>>>(); 043 044 private EventAdmin eventAdmin; 045 046 private ComponentContext context; 047 048 public EventBroker() { 049 // placeholder 050 } 051 052 @Activate 053 protected void activate(ComponentContext context) { 054 this.context = context; 055 } 056 057 @Deactivate 058 protected void deactivate(ComponentContext context) { 059 Collection<Collection<ServiceRegistration<?>>> values = new ArrayList<Collection<ServiceRegistration<?>>>( 060 registrations.values()); 061 registrations.clear(); 062 for (Collection<ServiceRegistration<?>> handled : values) { 063 for (ServiceRegistration<?> registration : handled) { 064 registration.unregister(); 065 } 066 } 067 068 this.context = null; 069 } 070 071 @Reference(cardinality = ReferenceCardinality.MANDATORY, unbind = "unbindEventAdmin") 072 protected void bindEventAdmin(EventAdmin eventAdmin) { 073 this.eventAdmin = eventAdmin; 074 } 075 076 protected void unbindEventAdmin(EventAdmin eventAdmin) { 077 this.eventAdmin = null; 078 } 079 080 @Override 081 public boolean send(String topic, Object data) { 082 Event event = constructEvent(topic, data); 083 eventAdmin.sendEvent(event); 084 return true; 085 } 086 087 @Override 088 public boolean post(String topic, Object data) { 089 Event event = constructEvent(topic, data); 090 eventAdmin.postEvent(event); 091 return true; 092 } 093 094 @SuppressWarnings("unchecked") 095 private Event constructEvent(String topic, Object data) { 096 Event event; 097 if (data instanceof Dictionary<?, ?>) { 098 event = new Event(topic, (Dictionary<String, ?>) data); 099 } else if (data instanceof Map<?, ?>) { 100 event = new Event(topic, (Map<String, ?>) data); 101 } else { 102 Dictionary<String, Object> d = new Hashtable<String, Object>(2); 103 d.put(EventConstants.EVENT_TOPIC, topic); 104 if (data != null) 105 d.put(IEventBroker.DATA, data); 106 event = new Event(topic, d); 107 } 108 return event; 109 } 110 111 @Override 112 public boolean subscribe(String topic, EventHandler eventHandler) { 113 return subscribe(topic, null, eventHandler, false); 114 } 115 116 @Override 117 public boolean subscribe(String topic, String filter, 118 EventHandler eventHandler, boolean headless) { 119 BundleContext bundleContext = context.getBundleContext(); 120 String[] topics = new String[] { topic }; 121 Dictionary<String, Object> d = new Hashtable<String, Object>(); 122 d.put(EventConstants.EVENT_TOPIC, topics); 123 if (filter != null) { 124 d.put(EventConstants.EVENT_FILTER, filter); 125 } 126 ServiceRegistration<?> registration = bundleContext.registerService( 127 EventHandler.class.getName(), eventHandler, d); 128 Collection<ServiceRegistration<?>> handled = registrations 129 .get(eventHandler); 130 if (handled == null) { 131 registrations.put(eventHandler, 132 handled = new ArrayList<ServiceRegistration<?>>()); 133 } 134 handled.add(registration); 135 return true; 136 } 137 138 @Override 139 public boolean unsubscribe(EventHandler eventHandler) { 140 Collection<ServiceRegistration<?>> handled = registrations 141 .remove(eventHandler); 142 if (handled == null || handled.isEmpty()) 143 return false; 144 for (ServiceRegistration<?> r : handled) { 145 r.unregister(); 146 } 147 return true; 148 } 149}