From 9f68d39954e7afe7af340f0acee30b4722878533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christoph=20L=C3=A4ubrich?= Date: Sat, 21 Dec 2024 08:58:18 +0100 Subject: [PATCH] Add Extender that allows bundles to declare a transformer resource Currently it is rather inconvenient to make a transformer list available as it requires to register an URL as service and the service itself also needs to be registered with some properties. This now adds an bundle extender that scans for a header 'Equinox-Transformer' where the value is pointing to a resource in the bundle (optionally specify the transformer type). If such bundle is found the resource is looked up and registered as a service with the required properties so it can be discovered by the transformer. --- .../transforms/TransformerBundleExtender.java | 89 +++++++++++++++++++ .../internal/transforms/TransformerHook.java | 1 + 2 files changed, 90 insertions(+) create mode 100644 bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerBundleExtender.java diff --git a/bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerBundleExtender.java b/bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerBundleExtender.java new file mode 100644 index 0000000000..3e108fb76e --- /dev/null +++ b/bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerBundleExtender.java @@ -0,0 +1,89 @@ +/******************************************************************************* + * Copyright (c) 2024 Christoph Läubrich 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 Läubrich - initial API and implementation + *******************************************************************************/ +package org.eclipse.equinox.internal.transforms; + +import java.net.URL; +import java.util.Dictionary; +import java.util.Map; +import org.osgi.framework.*; +import org.osgi.util.tracker.BundleTracker; +import org.osgi.util.tracker.BundleTrackerCustomizer; + +/** + * Extender that scans for bundle header {@value #EQUINOX_TRANSFORMER_HEADER} + * that declare a bundle wants to transform resources. The header can be either + * a resource in the bundle (e.g. /transform.csv) in which case it + * is assumed to use the default replace transformer, or can specify a + * transformation type e.g. xslt;/transform.csv + */ +class TransformerBundleExtender implements BundleTrackerCustomizer> { + + private static final String EQUINOX_TRANSFORMER_HEADER = "Equinox-Transformer"; //$NON-NLS-1$ + private BundleContext bundleContext; + + public TransformerBundleExtender(BundleContext bundleContext) { + this.bundleContext = bundleContext; + } + + @Override + public ServiceRegistration addingBundle(Bundle bundle, BundleEvent event) { + TransformerInfo info = getTransformerInfo(bundle); + if (info != null) { + return bundleContext.registerService(URL.class, info.url(), + FrameworkUtil.asDictionary(Map.of(TransformTuple.TRANSFORMER_TYPE, info.type()))); + } + return null; + } + + @Override + public void modifiedBundle(Bundle bundle, BundleEvent event, ServiceRegistration registration) { + // state modifications are not relevant here + } + + @Override + public void removedBundle(Bundle bundle, BundleEvent event, ServiceRegistration registration) { + registration.unregister(); + } + + private static TransformerInfo getTransformerInfo(Bundle bundle) { + Dictionary headers = bundle.getHeaders(""); //$NON-NLS-1$ + String header = headers.get(EQUINOX_TRANSFORMER_HEADER); + if (header != null && !header.isBlank()) { + String[] split = header.split(";", 2); //$NON-NLS-1$ + if (split.length == 2) { + URL entry = bundle.getEntry(split[1]); + if (entry != null) { + return new TransformerInfo(split[0], entry); + } + } else { + URL entry = bundle.getEntry(header); + if (entry != null) { + return new TransformerInfo(ReplaceTransformer.TYPE, entry); + } + } + } + return null; + } + + private static record TransformerInfo(String type, URL url) { + + } + + static void start(BundleContext bundleContext) { + BundleTracker> tracker = new BundleTracker<>(bundleContext, + Bundle.RESOLVED | Bundle.ACTIVE | Bundle.STARTING, new TransformerBundleExtender(bundleContext)); + tracker.open(); + } + +} diff --git a/bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerHook.java b/bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerHook.java index 1f0bcea632..97dd356b17 100644 --- a/bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerHook.java +++ b/bundles/org.eclipse.equinox.transforms.hook/src/org/eclipse/equinox/internal/transforms/TransformerHook.java @@ -47,6 +47,7 @@ public void addHooks(HookRegistry hookRegistry) { public void start(BundleContext context) throws BundleException { try { ReplaceTransformer.register(context, this); + TransformerBundleExtender.start(context); this.transformers = new TransformerList(context, logServices); } catch (InvalidSyntaxException e) { throw new BundleException("Problem registering service tracker: transformers", e); //$NON-NLS-1$