com.yahoo.application.container.impl.ClassLoaderOsgiFramework Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.application.container.impl;
import com.yahoo.container.standalone.StandaloneContainerApplication;
import com.yahoo.jdisc.application.OsgiFramework;
import com.yahoo.jdisc.application.OsgiHeader;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Filter;
import org.osgi.framework.FrameworkListener;
import org.osgi.framework.ServiceFactory;
import org.osgi.framework.ServiceListener;
import org.osgi.framework.ServiceObjects;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleRequirement;
import org.osgi.framework.wiring.BundleRevision;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.resource.Capability;
import org.osgi.resource.Requirement;
import org.osgi.resource.Wire;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.net.URLClassLoader;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.jar.Attributes;
import java.util.jar.JarFile;
/**
* A (mock) OSGI implementation which loads classes from the system classpath
*
* @author Tony Vaagenes
* @author ollivir
*/
public final class ClassLoaderOsgiFramework implements OsgiFramework {
private final BundleContextImpl bundleContextImpl = new BundleContextImpl();
private final SystemBundleImpl systemBundleImpl = new SystemBundleImpl();
private final BundleWiringImpl bundleWiringImpl = new BundleWiringImpl();
private final List bundleLocations = new ArrayList<>();
private final List bundleList = new ArrayList<>(List.of(systemBundleImpl));
private ClassLoader classLoader = null;
private final AtomicInteger nextBundleId = new AtomicInteger(1);
@Override
public List installBundle(String bundleLocation) {
if (bundleLocation != null && ! bundleLocation.isEmpty()) {
try {
URL url = new URL(bundleLocation);
bundleLocations.add(url);
bundleList.add(new JarBundleImpl(url));
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return bundles();
}
private ClassLoader getClassLoader() {
if (bundleLocations.isEmpty()) {
return getClass().getClassLoader();
} else {
if (classLoader == null) {
classLoader = new URLClassLoader(bundleLocations.toArray(new URL[0]), getClass().getClassLoader());
}
return classLoader;
}
}
@Override
public void startBundles(List bundles, boolean privileged) {
}
@Override
public void refreshPackages() {
}
@Override
public BundleContext bundleContext() {
return bundleContextImpl;
}
@Override
public List bundles() {
return bundleList;
}
@Override
public List getBundles(Bundle requestingBundle) {
return bundleList;
}
@Override
public void allowDuplicateBundles(Collection bundles) { }
@Override
public void start() {
}
@Override
public void stop() {
}
private abstract class BundleImpl implements Bundle {
@Override
public int getState() {
return Bundle.ACTIVE;
}
@Override
public void start(int options) {
}
@Override
public void start() {
}
@Override
public void stop(int options) {
}
@Override
public void stop() {
}
@Override
public void update(InputStream input) {
}
@Override
public void update() {
}
@Override
public void uninstall() {
}
@Override
public Dictionary getHeaders(String locale) {
return getHeaders();
}
@Override
public String getSymbolicName() {
return ClassLoaderOsgiFramework.this.getClass().getName();
}
@Override
public String getLocation() {
return getSymbolicName();
}
@Override
public ServiceReference>[] getRegisteredServices() {
return new ServiceReference>[0];
}
@Override
public ServiceReference>[] getServicesInUse() {
return getRegisteredServices();
}
@Override
public boolean hasPermission(Object permission) {
return true;
}
@Override
public URL getResource(String name) {
return getClassLoader().getResource(name);
}
@Override
public Class> loadClass(String name) throws ClassNotFoundException {
return getClassLoader().loadClass(name);
}
@Override
public Enumeration getResources(String name) throws IOException {
return getClassLoader().getResources(name);
}
@Override
public Enumeration getEntryPaths(String path) {
throw new UnsupportedOperationException();
}
@Override
public URL getEntry(String path) {
throw new UnsupportedOperationException();
}
@Override
public Enumeration findEntries(String path, String filePattern, boolean recurse) {
throw new UnsupportedOperationException();
}
@Override
public long getLastModified() {
return 1L;
}
@Override
public BundleContext getBundleContext() {
throw new UnsupportedOperationException();
}
@Override
public Map> getSignerCertificates(int signersType) {
return Map.of();
}
@Override
@SuppressWarnings("unchecked")
public T adapt(Class clazz) {
if (clazz.equals(BundleRevision.class)) {
return (T) new BundleRevisionImpl();
} else if (clazz.equals(BundleWiring.class)) {
return (T) new BundleWiringImpl();
} else {
return null;
}
}
@Override
public File getDataFile(String filename) {
return null;
}
@Override
public int compareTo(Bundle o) {
return Long.compare(getBundleId(), o.getBundleId());
}
}
private class BundleRevisionImpl implements BundleRevision {
@Override
public String getSymbolicName() {
return this.getClass().getName();
}
@Override
public List getDeclaredRequirements(String p1) {
throw new UnsupportedOperationException();
}
@Override
public Version getVersion() {
return Version.emptyVersion;
}
@Override
public BundleWiring getWiring() {
return bundleWiringImpl;
}
@Override
public List getDeclaredCapabilities(String p1) {
throw new UnsupportedOperationException();
}
@Override
public int getTypes() {
return 0;
}
@Override
public Bundle getBundle() {
throw new UnsupportedOperationException();
}
@Override
public List getCapabilities(String p1) {
throw new UnsupportedOperationException();
}
@Override
public List getRequirements(String p1) {
throw new UnsupportedOperationException();
}
}
private class BundleWiringImpl implements BundleWiring {
@Override
public List findEntries(String p1, String p2, int p3) {
throw new UnsupportedOperationException();
}
@Override
public List getRequiredResourceWires(String p1) {
throw new UnsupportedOperationException();
}
@Override
public List getResourceCapabilities(String p1) {
throw new UnsupportedOperationException();
}
@Override
public boolean isCurrent() {
throw new UnsupportedOperationException();
}
@Override
public List getRequiredWires(String p1) {
throw new UnsupportedOperationException();
}
@Override
public List getCapabilities(String p1) {
throw new UnsupportedOperationException();
}
@Override
public List getProvidedResourceWires(String p1) {
throw new UnsupportedOperationException();
}
@Override
public List getProvidedWires(String p1) {
throw new UnsupportedOperationException();
}
@Override
public BundleRevision getRevision() {
throw new UnsupportedOperationException();
}
@Override
public List getResourceRequirements(String p1) {
throw new UnsupportedOperationException();
}
@Override
public boolean isInUse() {
throw new UnsupportedOperationException();
}
@Override
public Collection listResources(String p1, String p2, int p3) {
throw new UnsupportedOperationException();
}
@Override
public ClassLoader getClassLoader() {
return ClassLoaderOsgiFramework.this.getClassLoader();
}
@Override
public List getRequirements(String p1) {
throw new UnsupportedOperationException();
}
@Override
public BundleRevision getResource() {
throw new UnsupportedOperationException();
}
@Override
public Bundle getBundle() {
throw new UnsupportedOperationException();
}
}
private class SystemBundleImpl extends BundleImpl {
@Override
public long getBundleId() {
return 0L;
}
@Override
public Version getVersion() {
return Version.emptyVersion;
}
@Override
public Dictionary getHeaders() {
Hashtable ret = new Hashtable<>();
ret.put(OsgiHeader.APPLICATION, StandaloneContainerApplication.class.getName());
return ret;
}
}
private class JarBundleImpl extends BundleImpl {
private final long bundleId;
private final Dictionary headers;
JarBundleImpl(URL location) throws IOException {
this.bundleId = (long) nextBundleId.getAndIncrement();
this.headers = retrieveHeaders(location);
}
@Override
public long getBundleId() {
return bundleId;
}
@Override
public Dictionary getHeaders() {
return headers;
}
@Override
public String getSymbolicName() {
return headers.get("Bundle-SymbolicName");
}
@Override
public Version getVersion() {
return Version.parseVersion(headers.get("Bundle-Version"));
}
private Dictionary retrieveHeaders(URL location) throws IOException {
try (JarFile jarFile = new JarFile(location.getFile())) {
Attributes attributes = jarFile.getManifest().getMainAttributes();
Hashtable ret = new Hashtable<>();
attributes.forEach((k, v) -> ret.put(k.toString(), v.toString()));
return ret;
}
}
}
private class BundleContextImpl implements BundleContext {
@Override
public String getProperty(String key) {
return null;
}
@Override
public Bundle getBundle() {
return systemBundleImpl;
}
@Override
public Bundle installBundle(String location, InputStream input) {
throw new UnsupportedOperationException();
}
@Override
public Bundle installBundle(String location) {
throw new UnsupportedOperationException();
}
@Override
public Bundle getBundle(long id) {
return systemBundleImpl;
}
@Override
public Bundle[] getBundles() {
return new Bundle[] { systemBundleImpl };
}
@Override
public Bundle getBundle(String location) {
return systemBundleImpl;
}
@Override
public void addServiceListener(ServiceListener listener, String filter) {
}
@Override
public void addServiceListener(ServiceListener listener) {
}
@Override
public void removeServiceListener(ServiceListener listener) {
}
@Override
public void addBundleListener(BundleListener listener) {
}
@Override
public void removeBundleListener(BundleListener listener) {
}
@Override
public void addFrameworkListener(FrameworkListener listener) {
}
@Override
public void removeFrameworkListener(FrameworkListener listener) {
}
@Override
public ServiceRegistration> registerService(String[] classes, Object service, Dictionary properties) {
throw new UnsupportedOperationException();
}
@Override
public ServiceRegistration> registerService(String clazz, Object service, Dictionary properties) {
return null;
}
@Override
public ServiceRegistration registerService(Class clazz, S service, Dictionary properties) {
throw new UnsupportedOperationException();
}
@Override
public ServiceReference>[] getServiceReferences(String clazz, String filter) {
throw new UnsupportedOperationException();
}
@Override
public ServiceReference>[] getAllServiceReferences(String clazz, String filter) {
throw new UnsupportedOperationException();
}
@Override
public ServiceReference> getServiceReference(String clazz) {
throw new UnsupportedOperationException();
}
@Override
public ServiceReference getServiceReference(Class clazz) {
throw new UnsupportedOperationException();
}
@Override
public Collection> getServiceReferences(Class clazz, String filter) {
return new ArrayList<>();
}
@Override
public S getService(ServiceReference reference) {
throw new UnsupportedOperationException();
}
@Override
public boolean ungetService(ServiceReference> reference) {
throw new UnsupportedOperationException();
}
@Override
public File getDataFile(String filename) {
throw new UnsupportedOperationException();
}
@Override
public Filter createFilter(String filter) {
throw new UnsupportedOperationException();
}
@Override
public ServiceRegistration registerService(Class aClass, ServiceFactory serviceFactory,
Dictionary dictionary) {
throw new UnsupportedOperationException();
}
@Override
public ServiceObjects getServiceObjects(ServiceReference serviceReference) {
throw new UnsupportedOperationException();
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy