| /* |
| * 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.dm.impl.index; |
| |
| import java.io.File; |
| import java.io.InputStream; |
| import java.util.Dictionary; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Map.Entry; |
| |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.BundleException; |
| import org.osgi.framework.BundleListener; |
| import org.osgi.framework.Filter; |
| import org.osgi.framework.FrameworkListener; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.ServiceListener; |
| import org.osgi.framework.ServiceReference; |
| import org.osgi.framework.ServiceRegistration; |
| |
| /** |
| * Base class for bundle context interceptors that keep track of service listeners and delegate incoming changes to them. |
| * |
| * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a> |
| */ |
| public abstract class BundleContextInterceptorBase implements BundleContext, ServiceListener { |
| protected final BundleContext m_context; |
| /** Keeps track of all service listeners and their optional filters. */ |
| private final Map /* <ServiceListener, String> */m_serviceListenerFilterMap = new HashMap(); |
| private long m_currentVersion = 0; |
| private long m_entryVersion = -1; |
| private Entry[] m_serviceListenerFilterMapEntries; |
| |
| public BundleContextInterceptorBase(BundleContext context) { |
| m_context = context; |
| } |
| |
| public String getProperty(String key) { |
| return m_context.getProperty(key); |
| } |
| |
| public Bundle getBundle() { |
| return m_context.getBundle(); |
| } |
| |
| public Bundle installBundle(String location) throws BundleException { |
| return m_context.installBundle(location); |
| } |
| |
| public Bundle installBundle(String location, InputStream input) throws BundleException { |
| return m_context.installBundle(location, input); |
| } |
| |
| public Bundle getBundle(long id) { |
| return m_context.getBundle(id); |
| } |
| |
| public Bundle[] getBundles() { |
| return m_context.getBundles(); |
| } |
| |
| public void addServiceListener(ServiceListener listener, String filter) throws InvalidSyntaxException { |
| synchronized (m_serviceListenerFilterMap) { |
| m_serviceListenerFilterMap.put(listener, filter); |
| m_currentVersion++; |
| } |
| } |
| |
| public void addServiceListener(ServiceListener listener) { |
| synchronized (m_serviceListenerFilterMap) { |
| m_serviceListenerFilterMap.put(listener, null); |
| m_currentVersion++; |
| } |
| } |
| |
| public void removeServiceListener(ServiceListener listener) { |
| synchronized (m_serviceListenerFilterMap) { |
| m_serviceListenerFilterMap.remove(listener); |
| m_currentVersion++; |
| } |
| } |
| |
| public void addBundleListener(BundleListener listener) { |
| m_context.addBundleListener(listener); |
| } |
| |
| public void removeBundleListener(BundleListener listener) { |
| m_context.removeBundleListener(listener); |
| } |
| |
| public void addFrameworkListener(FrameworkListener listener) { |
| m_context.addFrameworkListener(listener); |
| } |
| |
| public void removeFrameworkListener(FrameworkListener listener) { |
| m_context.removeFrameworkListener(listener); |
| } |
| |
| public ServiceRegistration registerService(String[] clazzes, Object service, Dictionary properties) { |
| return m_context.registerService(clazzes, service, properties); |
| } |
| |
| public ServiceRegistration registerService(String clazz, Object service, Dictionary properties) { |
| return m_context.registerService(clazz, service, properties); |
| } |
| |
| public ServiceReference[] getServiceReferences(String clazz, String filter) throws InvalidSyntaxException { |
| return m_context.getServiceReferences(clazz, filter); |
| } |
| |
| public ServiceReference[] getAllServiceReferences(String clazz, String filter) throws InvalidSyntaxException { |
| return m_context.getAllServiceReferences(clazz, filter); |
| } |
| |
| public ServiceReference getServiceReference(String clazz) { |
| return m_context.getServiceReference(clazz); |
| } |
| |
| public Object getService(ServiceReference reference) { |
| return m_context.getService(reference); |
| } |
| |
| public boolean ungetService(ServiceReference reference) { |
| return m_context.ungetService(reference); |
| } |
| |
| public File getDataFile(String filename) { |
| return m_context.getDataFile(filename); |
| } |
| |
| public Filter createFilter(String filter) throws InvalidSyntaxException { |
| return m_context.createFilter(filter); |
| } |
| |
| protected Entry[] synchronizeCollection() { |
| // lazy copy on write: we make a new copy only if writes have changed the collection |
| synchronized (m_serviceListenerFilterMap) { |
| if (m_currentVersion != m_entryVersion) { |
| m_serviceListenerFilterMapEntries = (Entry[]) m_serviceListenerFilterMap.entrySet().toArray(new Entry[m_serviceListenerFilterMap.size()]); |
| m_entryVersion = m_currentVersion; |
| } |
| } |
| return m_serviceListenerFilterMapEntries; |
| } |
| } |