diff options
Diffstat (limited to 'standalone-container/src/main/scala/com/yahoo/application/container/impl/ClassLoaderOsgiFramework.scala')
-rw-r--r-- | standalone-container/src/main/scala/com/yahoo/application/container/impl/ClassLoaderOsgiFramework.scala | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/standalone-container/src/main/scala/com/yahoo/application/container/impl/ClassLoaderOsgiFramework.scala b/standalone-container/src/main/scala/com/yahoo/application/container/impl/ClassLoaderOsgiFramework.scala new file mode 100644 index 00000000000..6d45e6fa8a1 --- /dev/null +++ b/standalone-container/src/main/scala/com/yahoo/application/container/impl/ClassLoaderOsgiFramework.scala @@ -0,0 +1,200 @@ +// Copyright 2016 Yahoo Inc. 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.jdisc.application.{OsgiHeader, OsgiFramework} +import java.util +import org.osgi.framework._ +import java.io.InputStream +import util.concurrent.atomic.AtomicInteger +import util.jar.JarFile +import util.{Dictionary, Collections, Hashtable} + +import scala.collection.JavaConversions._ +import com.yahoo.container.standalone.StandaloneContainerApplication +import collection.mutable.ArrayBuffer +import java.net.{URL, URLClassLoader} +import org.osgi.framework.wiring._ +import org.osgi.resource.{Wire, Capability, Requirement} + +/** + * @author tonytv + */ +final class ClassLoaderOsgiFramework extends OsgiFramework { + private val bundleLocations = new ArrayBuffer[URL] + private val bundleList = ArrayBuffer[Bundle](SystemBundleImpl) + private var classLoader: ClassLoader = null + + private val nextBundleId = new AtomicInteger(1) + + override def installBundle(bundleLocation: String) = { + if (bundleLocation != "") { + val url = new URL(bundleLocation) + bundleLocations += url + bundleList += new JarBundleImpl(url) + } + + bundles() + } + + def getClassLoader = { + if (bundleLocations.isEmpty) { + getClass.getClassLoader + } else { + if(classLoader == null) + classLoader = new URLClassLoader(bundleLocations.toArray, getClass.getClassLoader) + + classLoader + } + } + + override def startBundles(bundles: util.List[Bundle], privileged: Boolean) {} + + override def refreshPackages() {} + + override def bundleContext():BundleContext = BundleContextImpl + + override def bundles() = bundleList + + override def start() {} + + override def stop() {} + + private abstract class BundleImpl extends Bundle { + override def getState = Bundle.ACTIVE + + override def start(options: Int) {} + override def start() {} + override def stop(options: Int) {} + override def stop() {} + override def update(input: InputStream) {} + override def update() {} + override def uninstall() {} + + override def getHeaders(locale: String) = getHeaders + + override def getSymbolicName = ClassLoaderOsgiFramework.this.getClass.getName + override def getLocation = getSymbolicName + + override def getRegisteredServices = Array[ServiceReference[_]]() + override def getServicesInUse = getRegisteredServices + + override def hasPermission(permission: Any) = true + + override def getResource(name: String) = getClassLoader.getResource(name) + override def loadClass(name: String) = getClassLoader.loadClass(name) + override def getResources(name: String) = getClassLoader.getResources(name) + + override def getEntryPaths(path: String) = throw new UnsupportedOperationException + override def getEntry(path: String) = throw new UnsupportedOperationException + override def findEntries(path: String, filePattern: String, recurse: Boolean) = throw new UnsupportedOperationException + + override def getLastModified = 1L + + override def getBundleContext = throw new UnsupportedOperationException + override def getSignerCertificates(signersType: Int) = Collections.emptyMap() + + override def adapt[A](`type`: Class[A]): A = { + if (`type` == classOf[BundleRevision]) BundleRevisionImpl.asInstanceOf[A] + else if (`type` == classOf[BundleWiring]) BundleWiringImpl.asInstanceOf[A] + else null.asInstanceOf[A] + } + + override def getDataFile(filename: String) = null + override def compareTo(o: Bundle) = getBundleId compareTo o.getBundleId + } + + private object BundleRevisionImpl extends BundleRevision { + override def getSymbolicName: String = this.getClass.getName + override def getDeclaredRequirements(p1: String): util.List[BundleRequirement] = throw new UnsupportedOperationException + override def getVersion: Version = Version.emptyVersion + override def getWiring: BundleWiring = BundleWiringImpl + override def getDeclaredCapabilities(p1: String): util.List[BundleCapability] = throw new UnsupportedOperationException + override def getTypes: Int = 0 + override def getBundle: Bundle = throw new UnsupportedOperationException + override def getCapabilities(p1: String): util.List[Capability] = throw new UnsupportedOperationException + override def getRequirements(p1: String): util.List[Requirement] = throw new UnsupportedOperationException + } + + private object BundleWiringImpl extends BundleWiring { + override def findEntries(p1: String, p2: String, p3: Int): util.List[URL] = ??? + override def getRequiredResourceWires(p1: String): util.List[Wire] = ??? + override def getResourceCapabilities(p1: String): util.List[Capability] = ??? + override def isCurrent: Boolean = ??? + override def getRequiredWires(p1: String): util.List[BundleWire] = ??? + override def getCapabilities(p1: String): util.List[BundleCapability] = ??? + override def getProvidedResourceWires(p1: String): util.List[Wire] = ??? + override def getProvidedWires(p1: String): util.List[BundleWire] = ??? + override def getRevision: BundleRevision = ??? + override def getResourceRequirements(p1: String): util.List[Requirement] = ??? + override def isInUse: Boolean = ??? + override def listResources(p1: String, p2: String, p3: Int): util.Collection[String] = ??? + override def getClassLoader: ClassLoader = ClassLoaderOsgiFramework.this.getClassLoader + override def getRequirements(p1: String): util.List[BundleRequirement] = ??? + override def getResource: BundleRevision = ??? + override def getBundle: Bundle = ??? + } + + private object SystemBundleImpl extends BundleImpl { + override val getBundleId = 0L + override def getVersion = Version.emptyVersion + override def getHeaders: Dictionary[String, String] = new Hashtable[String, String](Map(OsgiHeader.APPLICATION -> classOf[StandaloneContainerApplication].getName)) + } + + + private class JarBundleImpl(location: URL) extends BundleImpl { + override val getBundleId = nextBundleId.getAndIncrement.asInstanceOf[Long] + + private val headers = retrieveHeaders(location) + + override def getHeaders: Dictionary[String, String] = headers + override val getSymbolicName = headers.get("Bundle-SymbolicName") + override val getVersion = Version.parseVersion(headers.get("Bundle-Version")) + + + private def retrieveHeaders(location: URL) = { + val jarFile = new JarFile(location.getFile) + try { + val attributes = jarFile.getManifest.getMainAttributes + new Hashtable[String, String](attributes.entrySet().map( entry => entry.getKey.toString -> entry.getValue.toString).toMap) + } finally { + jarFile.close() + } + } + } + + private object BundleContextImpl extends BundleContext { + private val bundleImpl = SystemBundleImpl + + override def getProperty(key: String) = null + override def getBundle = bundleImpl + override def installBundle(location: String, input: InputStream) = throw new UnsupportedOperationException + override def installBundle(location: String) = throw new UnsupportedOperationException + + override def getBundle(id: Long) = bundleImpl + override def getBundles = Array(bundleImpl) + override def getBundle(location: String) = bundleImpl + + override def addServiceListener(listener: ServiceListener, filter: String) {} + override def addServiceListener(listener: ServiceListener) {} + override def removeServiceListener(listener: ServiceListener) {} + override def addBundleListener(listener: BundleListener) {} + override def removeBundleListener(listener: BundleListener) {} + + override def addFrameworkListener(listener: FrameworkListener) {} + override def removeFrameworkListener(listener: FrameworkListener) {} + + override def registerService(clazzes: Array[String], service: Any, properties: Dictionary[String, _]) = throw new UnsupportedOperationException + override def registerService(clazz: String, service: Any, properties: Dictionary[String, _]) = null + override def registerService[S](clazz: Class[S], service: S, properties: Dictionary[String, _]) = throw new UnsupportedOperationException + override def getServiceReferences(clazz: String, filter: String) = throw new UnsupportedOperationException + override def getAllServiceReferences(clazz: String, filter: String) = throw new UnsupportedOperationException + override def getServiceReference(clazz: String) = throw new UnsupportedOperationException + override def getServiceReference[S](clazz: Class[S]) = throw new UnsupportedOperationException + override def getServiceReferences[S](clazz: Class[S], filter: String) = Collections.emptyList() + override def getService[S](reference: ServiceReference[S]) = throw new UnsupportedOperationException + override def ungetService(reference: ServiceReference[_]) = throw new UnsupportedOperationException + override def getDataFile(filename: String) = throw new UnsupportedOperationException + override def createFilter(filter: String) = throw new UnsupportedOperationException + + } +} |