From 7ca3fd9ee8117d9c8f3761ddb5392ecc6cf625f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Sun, 30 Jun 2024 08:10:32 +0200 Subject: [PATCH] Allow interfacing with other adapter frameworks by using a proxy While the Eclipse Adapter Framework is very powerful it currently does not allow to interface with other adaption techniques (e.g. OSGi Converter Specification). This adds a new way to adapt a class of objects to a proxy that then is asked for further adaption. --- .../META-INF/MANIFEST.MF | 2 +- .../eclipse/core/runtime/AdapterProxy.java | 42 +++++++++++++++++++ .../org/eclipse/core/runtime/Adapters.java | 7 ++++ 3 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/AdapterProxy.java diff --git a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF index 4cae74f5d63..77de180a278 100644 --- a/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF +++ b/bundles/org.eclipse.equinox.common/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-SymbolicName: org.eclipse.equinox.common; singleton:=true -Bundle-Version: 3.19.100.qualifier +Bundle-Version: 3.20.0.qualifier Bundle-Localization: plugin Export-Package: org.eclipse.core.internal.boot;x-friends:="org.eclipse.core.resources,org.eclipse.pde.build", org.eclipse.core.internal.runtime;common=split;mandatory:=common; diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/AdapterProxy.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/AdapterProxy.java new file mode 100644 index 00000000000..ac449416569 --- /dev/null +++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/AdapterProxy.java @@ -0,0 +1,42 @@ +package org.eclipse.core.runtime; + +/** + *

+ * An {@link AdapterProxy} can be used to interface the Eclipse Adapter + * Framework with other techniques. To do so one has to provide a generic + * {@link IAdapterFactory} that adapts this other frameworks objects to the + * {@link AdapterProxy} interface, then as a last resort, the Eclipse Adapter + * Framework will ask this proxy as if the original object would have + * implemented {@link IAdaptable}. + *

+ *

+ * One example is the OSGi Converter + * Specification that allows to adapt/convert objects in an extensible way, + * therefore it is not possible to register a "classic" {@link IAdapterFactory} + * because the types that are probably convertible are unknown in advance. Also + * the objects itself can't be made to implement the {@link IAdaptable} + * interface. An implementation then might look like this: + *

+ * + *
+ * @Component
+ * @AdapterTypes(adaptableClass = Object.class, adapterNames = AdapterProxy.class)
+ * public class OSGiConverterProxyFactory implements IAdapterFactory {
+ * 
+ * 	@Reference
+ * 	private Converter converter;
+ * 
+ * 	public  T getAdapter(Object adaptableObject, Class adapterType) {
+ * 		Converting converting = converter.convert(adaptableObject);
+ * 		return converting.to(adapterType);
+ * 	}
+ * 
+ * }
+ * 
+ * + * @since 3.20 + */ +public interface AdapterProxy extends IAdaptable { + // This is a specialized type that do not define any methods +} diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Adapters.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Adapters.java index 9bccf2e021f..a5850ef33ec 100644 --- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Adapters.java +++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Adapters.java @@ -84,6 +84,13 @@ public static T adapt(Object sourceObject, Class adapter, boolean allowAc String adapterId = adapter.getName(); Object result = queryAdapterManager(sourceObject, adapterId, allowActivation); + if (result == null) { + // Last resort, this object is maybe using a different adaption technique + if (queryAdapterManager(sourceObject, AdapterProxy.class.getName(), + allowActivation) instanceof AdapterProxy proxy) { + result = proxy.getAdapter(adapter); + } + } if (result != null) { // Sanity-check if (!adapter.isInstance(result)) {