summaryrefslogtreecommitdiffstats
path: root/bundle-plugin/src/main/scala/com/yahoo/container/plugin/mojo/AssembleContainerPluginMojo.scala
blob: 53d0e315ffed74b21cea2c12a095fece805723f2 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.container.plugin.mojo

import java.io.File
import java.nio.channels.Channels
import java.util.jar.JarFile
import java.util.zip.ZipEntry

import com.yahoo.container.plugin.util.{Files, JarFiles}
import org.apache.maven.archiver.{MavenArchiveConfiguration, MavenArchiver}
import org.apache.maven.plugin.AbstractMojo
import org.apache.maven.plugins.annotations.{Component, Mojo, Parameter, ResolutionScope}
import org.apache.maven.project.MavenProject
import org.codehaus.plexus.archiver.Archiver
import org.codehaus.plexus.archiver.jar.JarArchiver

import scala.collection.convert.wrapAsScala._

/**
 * @author  tonytv
 */
@Mojo(name = "assemble-container-plugin", requiresDependencyResolution = ResolutionScope.COMPILE)
class AssembleContainerPluginMojo extends AbstractMojo {
  object withDependencies
  object withoutDependencies

  @Parameter(defaultValue = "${project}")
  var project: MavenProject = null

  @Component(role = classOf[Archiver], hint = "jar")
  var jarArchiver: JarArchiver = null

  @Parameter
  var archiveConfiguration: MavenArchiveConfiguration = new MavenArchiveConfiguration

  @Parameter(alias = "UseCommonAssemblyIds", defaultValue = "false")
  var useCommonAssemblyIds: Boolean = false


   def execute() {
    val jarSuffixes =
      if (useCommonAssemblyIds) Map(withoutDependencies -> ".jar", withDependencies -> "-jar-with-dependencies.jar")
      else Map(withoutDependencies -> "-without-dependencies.jar", withDependencies -> "-deploy.jar")

    val jarFiles = jarSuffixes mapValues jarFileInBuildDirectory(build.getFinalName)

    //force recreating the archive
    archiveConfiguration.setForced(true)
    archiveConfiguration.setManifestFile(new File(new File(project.getBuild.getOutputDirectory), JarFile.MANIFEST_NAME))

    addClassesDirectory()
    createArchive(jarFiles(withoutDependencies))
    project.getArtifact.setFile(jarFiles(withoutDependencies))

    addDependencies()
    createArchive(jarFiles(withDependencies))
  }

  private def jarFileInBuildDirectory(name: String)(jarSuffix: String) = {
    new File(build.getDirectory, name + jarSuffix)
  }

  private def addClassesDirectory() {
    val classesDirectory = new File(build.getOutputDirectory)
    if (classesDirectory.isDirectory) {
      jarArchiver.addDirectory(classesDirectory)
    }
  }

  private def createArchive(jarFile: File) {
    val mavenArchiver = new MavenArchiver
    mavenArchiver.setArchiver(jarArchiver)
    mavenArchiver.setOutputFile(jarFile)
    mavenArchiver.createArchive(project, archiveConfiguration)
  }

  private def addDependencies() {
    Artifacts.getArtifactsToInclude(project).foreach { artifact =>
        if (artifact.getType == "jar") {
          jarArchiver.addFile(artifact.getFile, "dependencies/" + artifact.getFile.getName)
          copyConfigDefinitions(artifact.getFile)
        }
        else
          getLog.warn("Unkown artifact type " + artifact.getType)
    }
  }

  private def copyConfigDefinitions(file: File) {
    JarFiles.withJarFile(file) { jarFile =>
      for {
        entry <- jarFile.entries()
        name = entry.getName
        if name.startsWith("configdefinitions/") && name.endsWith(".def")

      } copyConfigDefinition(jarFile, entry)
    }
  }

  private def copyConfigDefinition(jarFile: JarFile, entry: ZipEntry) {
    JarFiles.withInputStream(jarFile, entry) { input =>
      val defPath = entry.getName.replace("/", File.separator)
      val destinationFile = new File(project.getBuild.getOutputDirectory, defPath)
      destinationFile.getParentFile.mkdirs()

      Files.withFileOutputStream(destinationFile) { output =>
        output.getChannel.transferFrom(Channels.newChannel(input), 0, Long.MaxValue)
      }
      jarArchiver.addFile(destinationFile, entry.getName)
    }
  }

  private def build = project.getBuild
}