/******************************************************************************* * Copyright (c) 2008, 2014 Stuart McCulloch * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Stuart McCulloch - initial API and implementation *******************************************************************************/ package org.eclipse.sisu.peaberry.osgi; import static org.osgi.framework.Constants.OBJECTCLASS; import java.util.Dictionary; import java.util.HashSet; import java.util.Map; import java.util.Set; import org.eclipse.sisu.peaberry.Export; import org.eclipse.sisu.peaberry.Import; import org.eclipse.sisu.peaberry.util.SimpleExport; import org.osgi.framework.BundleContext; import org.osgi.framework.ServiceRegistration; /** * {@link Export} implementation backed by an OSGi {@link ServiceRegistration}. * * @author mcculls@gmail.com (Stuart McCulloch) */ final class OSGiServiceExport<T> extends SimpleExport<T> { private final BundleContext bundleContext; private ServiceRegistration reg; OSGiServiceExport(final BundleContext bundleContext, final Import<T> service) { super(service); this.bundleContext = bundleContext; exportOSGiService(); } @Override public synchronized void put(final T newInstance) { removeOSGiService(); super.put(newInstance); exportOSGiService(); } @Override public synchronized void attributes(final Map<String, ?> newAttributes) { super.attributes(newAttributes); if (null != reg) { reg.setProperties(getProperties(newAttributes)); } } private void exportOSGiService() { final T instance = get(); if (null != instance) { final Dictionary<String, ?> properties = getProperties(attributes()); final String[] interfaceNames = getInterfaceNames(instance, properties); reg = bundleContext.registerService(interfaceNames, instance, properties); } } private void removeOSGiService() { if (null != reg) { try { reg.unregister(); } catch (final RuntimeException re) {/* already gone */} // NOPMD reg = null; } } private static Dictionary<String, ?> getProperties(final Map<String, ?> attributes) { return null == attributes || attributes.isEmpty() ? null : new AttributeDictionary(attributes); } private static String[] getInterfaceNames(final Object instance, final Dictionary<?, ?> properties) { final Object objectClass = null == properties ? null : properties.get(OBJECTCLASS); // check service attributes setting if (objectClass instanceof String[]) { return (String[]) objectClass; } final Set<String> names = new HashSet<String>(); for (Class<?> clazz = instance.getClass(); null != clazz; clazz = clazz.getSuperclass()) { for (final Class<?> i : clazz.getInterfaces()) { names.add(i.getName()); } } return names.toArray(new String[names.size()]); } }