summaryrefslogtreecommitdiffstats
path: root/bundle-plugin/src/main/scala/com/yahoo/container/plugin/bundle/AnalyzeBundle.scala
diff options
context:
space:
mode:
Diffstat (limited to 'bundle-plugin/src/main/scala/com/yahoo/container/plugin/bundle/AnalyzeBundle.scala')
-rw-r--r--bundle-plugin/src/main/scala/com/yahoo/container/plugin/bundle/AnalyzeBundle.scala72
1 files changed, 72 insertions, 0 deletions
diff --git a/bundle-plugin/src/main/scala/com/yahoo/container/plugin/bundle/AnalyzeBundle.scala b/bundle-plugin/src/main/scala/com/yahoo/container/plugin/bundle/AnalyzeBundle.scala
new file mode 100644
index 00000000000..b9137a3c6bc
--- /dev/null
+++ b/bundle-plugin/src/main/scala/com/yahoo/container/plugin/bundle/AnalyzeBundle.scala
@@ -0,0 +1,72 @@
+// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.container.plugin.bundle
+
+import java.util.jar.{Manifest => JarManifest}
+import java.io.File
+import com.yahoo.container.plugin.osgi.{ExportPackages, ExportPackageParser}
+import ExportPackages.Export
+import collection.immutable.LinearSeq
+import com.yahoo.container.plugin.util.JarFiles
+
+
+/**
+ * @author tonytv
+ */
+object AnalyzeBundle {
+ case class PublicPackages(exports : List[Export], globals : List[String])
+
+ def publicPackagesAggregated(jarFiles : Iterable[File]) = aggregate(jarFiles map {publicPackages(_)})
+
+ def aggregate(publicPackagesList : Iterable[PublicPackages]) =
+ (PublicPackages(List(), List()) /: publicPackagesList) { (a,b) =>
+ PublicPackages(a.exports ++ b.exports, a.globals ++ b.globals)
+ }
+
+ def publicPackages(jarFile: File): PublicPackages = {
+ try {
+
+ (for {
+ manifest <- JarFiles.getManifest(jarFile)
+ if isOsgiManifest(manifest)
+ } yield PublicPackages(parseExports(manifest), parseGlobals(manifest))).
+ getOrElse(PublicPackages(List(), List()))
+
+ } catch {
+ case e : Exception => throw new RuntimeException("Invalid manifest in bundle '%s'".format(jarFile.getPath), e)
+ }
+ }
+
+ def bundleSymbolicName(jarFile: File): Option[String] = {
+ JarFiles.getManifest(jarFile).flatMap(getBundleSymbolicName)
+ }
+
+ private def parseExportsFromAttribute(manifest : JarManifest, attributeName : String) = {
+ (for (export <- getMainAttributeValue(manifest, attributeName)) yield
+ ExportPackageParser.parseAll(export) match {
+ case noSuccess: ExportPackageParser.NoSuccess => throw new RuntimeException(
+ "Failed parsing %s: %s".format(attributeName, noSuccess))
+ case success => success.get
+ }).
+ getOrElse(List())
+ }
+
+ private def parseExports = parseExportsFromAttribute(_ : JarManifest, "Export-Package")
+
+ private def parseGlobals(manifest : JarManifest) = {
+ //TODO: Use separate parser for global packages.
+ val globals = parseExportsFromAttribute(manifest, "Global-Package")
+
+ if (globals map {_.parameters} exists {!_.isEmpty}) {
+ throw new RuntimeException("Parameters not valid for Global-Package.")
+ }
+
+ globals flatMap {_.packageNames}
+ }
+
+ private def getMainAttributeValue(manifest: JarManifest, name: String): Option[String] =
+ Option(manifest.getMainAttributes.getValue(name))
+
+ private def isOsgiManifest = getBundleSymbolicName(_: JarManifest).isDefined
+
+ private def getBundleSymbolicName = getMainAttributeValue(_: JarManifest, "Bundle-SymbolicName")
+}