org.eclipse.core.internal.runtime.AdapterFactoryBridge Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of aspectjtools Show documentation
Show all versions of aspectjtools Show documentation
AspectJ tools most notably contains the AspectJ compiler (AJC). AJC applies aspects to Java classes during
compilation, fully replacing Javac for plain Java classes and also compiling native AspectJ or annotation-based
@AspectJ syntax. Furthermore, AJC can weave aspects into existing class files in a post-compile binary weaving step.
This library is a superset of AspectJ weaver and hence also of AspectJ runtime.
/*******************************************************************************
* Copyright (c) 2020 Christoph Laeubrich and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*
* Contributors:
* Christoph Laeubrich - initial API and implementation
*******************************************************************************/
package org.eclipse.core.internal.runtime;
import java.util.Collection;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IAdapterManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* Acts as abridge between {@link IAdapterManager} services registered in the OSGi-Service-Registry and AdapterManager
*
*/
public class AdapterFactoryBridge implements ServiceTrackerCustomizer {
private BundleContext bundleContext;
public AdapterFactoryBridge(BundleContext bundleContext) {
this.bundleContext = bundleContext;
}
@Override
public LazyAdapterFactory addingService(ServiceReference reference) {
String[] adaptableClasses = getMultiProperty(reference, IAdapterFactory.SERVICE_PROPERTY_ADAPTABLE_CLASS);
String[] adapterNames = getMultiProperty(reference, IAdapterFactory.SERVICE_PROPERTY_ADAPTER_NAMES);
LazyAdapterFactory proxy;
if (adapterNames.length == 0 && reference.getProperty(IAdapterFactory.SERVICE_PROPERTY_ADAPTER_NAMES) == null) {
proxy = new LazyAdapterFactory(reference, bundleContext);
} else {
proxy = new LazyAdapterFactoryExtServiceProxy(adapterNames, reference, bundleContext);
}
AdapterManager manager = AdapterManager.getDefault();
for (String adaptableClass : adaptableClasses) {
manager.registerFactory(proxy, adaptableClass);
}
manager.flushLookup();
return proxy;
}
private static String[] getMultiProperty(ServiceReference reference, String propertyName) {
Object property = reference.getProperty(propertyName);
if (property instanceof String) {
String string = (String) property;
if (string.length() > 0) {
return new String[] {string};
}
} else if (property instanceof String[]) {
return (String[]) property;
} else if (property instanceof Collection) {
Collection collection = (Collection) property;
return collection.stream().filter(String.class::isInstance).map(String.class::cast).toArray(String[]::new);
}
return new String[0];
}
@Override
public void modifiedService(ServiceReference reference, LazyAdapterFactory proxy) {
String[] adaptableClasses = getMultiProperty(reference, IAdapterFactory.SERVICE_PROPERTY_ADAPTABLE_CLASS);
AdapterManager manager = AdapterManager.getDefault();
manager.unregisterAdapters(proxy);
if (proxy instanceof LazyAdapterFactoryExtServiceProxy) {
LazyAdapterFactoryExtServiceProxy lazy = (LazyAdapterFactoryExtServiceProxy) proxy;
lazy.adapterNames = getMultiProperty(reference, IAdapterFactory.SERVICE_PROPERTY_ADAPTER_NAMES);
}
for (String adaptableClass : adaptableClasses) {
manager.registerFactory(proxy, adaptableClass);
}
manager.flushLookup();
}
@Override
public void removedService(ServiceReference reference, LazyAdapterFactory proxy) {
AdapterManager manager = AdapterManager.getDefault();
manager.unregisterAdapters(proxy);
proxy.dispose();
}
public static class LazyAdapterFactory implements IAdapterFactory {
IAdapterFactory service;
volatile boolean disposed;
private final ServiceReference reference;
private final BundleContext bundleContext;
LazyAdapterFactory(ServiceReference reference, BundleContext bundleContext) {
this.reference = reference;
this.bundleContext = bundleContext;
}
@Override
public T getAdapter(Object adaptableObject, Class adapterType) {
if (!disposed) {
IAdapterFactory factory = getFactoryService();
if (factory != null) {
return factory.getAdapter(adaptableObject, adapterType);
}
}
return null;
}
@Override
public Class[] getAdapterList() {
if (!disposed) {
IAdapterFactory factory = getFactoryService();
if (factory != null) {
return factory.getAdapterList();
}
}
return new Class[0];
}
synchronized IAdapterFactory getFactoryService() {
if (service == null && !disposed) {
service = bundleContext.getService(reference);
}
return service;
}
synchronized void dispose() {
disposed = true;
if (service != null) {
service = null;
bundleContext.ungetService(reference);
}
}
}
private static final class LazyAdapterFactoryExtServiceProxy extends LazyAdapterFactory implements IAdapterFactoryExt {
volatile String[] adapterNames;
LazyAdapterFactoryExtServiceProxy(String[] adapterNames, ServiceReference reference, BundleContext bundleContext) {
super(reference, bundleContext);
this.adapterNames = adapterNames;
}
@Override
public synchronized IAdapterFactory loadFactory(boolean force) {
if (force) {
return getFactoryService();
}
return service;
}
@Override
public String[] getAdapterNames() {
return adapterNames.clone();
}
}
}