Skip to content

Commit

Permalink
Add Extender that allows bundles to declare a transformer resource
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
laeubi committed Dec 21, 2024
1 parent 5810f68 commit 87d92a4
Show file tree
Hide file tree
Showing 3 changed files with 92 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2
Bundle-Name: %bundleName
Bundle-Vendor: %providerName
Bundle-SymbolicName: org.eclipse.equinox.transforms.hook
Bundle-Version: 1.4.100.qualifier
Bundle-Version: 1.4.200.qualifier
Fragment-Host: org.eclipse.osgi;bundle-version="[3.10.0,4.0.0)"
Bundle-RequiredExecutionEnvironment: JavaSE-17
Bundle-Localization: transformsHook
Expand Down
Original file line number Diff line number Diff line change
@@ -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. <code>/transform.csv</code>) in which case it
* is assumed to use the default replace transformer, or can specify a
* transformation type e.g. <code>xslt;/transform.csv</code>
*/
class TransformerBundleExtender implements BundleTrackerCustomizer<ServiceRegistration<URL>> {

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<URL> 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<URL> registration) {
// state modifications are not relevant here
}

@Override
public void removedBundle(Bundle bundle, BundleEvent event, ServiceRegistration<URL> registration) {
registration.unregister();
}

private static TransformerInfo getTransformerInfo(Bundle bundle) {
Dictionary<String, String> 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<ServiceRegistration<URL>> tracker = new BundleTracker<>(bundleContext, Bundle.RESOLVED,
new TransformerBundleExtender(bundleContext));
tracker.open();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ public void addHooks(HookRegistry hookRegistry) {

public void start(BundleContext context) throws BundleException {
try {
TransformerBundleExtender.start(context);
ReplaceTransformer.register(context, this);
this.transformers = new TransformerList(context, logServices);
} catch (InvalidSyntaxException e) {
throw new BundleException("Problem registering service tracker: transformers", e); //$NON-NLS-1$
Expand Down

0 comments on commit 87d92a4

Please sign in to comment.