Commits

shemnon committed 1206789

jar signing beginnings
* there are hard coded paths
* only a debug key is used, not a legit one

Comments (0)

Files changed (5)

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/JavaFXPlugin.groovy

 import org.gradle.api.artifacts.Configuration
 import org.gradle.api.plugins.JavaPlugin
 import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXCSSToBinTask
+import com.bitbucket.shemnon.javafxplugin.tasks.JavaFXSignJarTask
+import com.bitbucket.shemnon.javafxplugin.tasks.GenKeyTask
 
 
 class JavaFXPlugin implements Plugin<Project> {
                 packaging = 'all'
                 debugKey {
                     alias = 'javafxdebugkey'
-                    dname = 'CN=JavaFX Debug,C=US'
+                    dname = 'CN=JavaFX Gradle Plugin Default Debug Key, O=JavaFX Debug'
                     validity = ((365.25) * 25 as int) // 25 years
                     keypass = 'JavaFX'
                     keystore = new File(project.projectDir, 'debug.keystore')
                     storepass = 'JavaFX'
-                    sigfile = 'JavaFXDebug'
                 }
+                signingMode = 'debug'
             })
 
 
             }
         }
 
-        configureJFXDeployTask(project)
-        configureJavaFXJarTask(project)
         configureJavaFXCSSToBinTask(project)
+        configureJavaFXJarTask(project)
+        configureGenerateDebugKeyTask(project)
+        configureJavaFXSignJarTask(project)
+        configureJFXDeployTask(project)
     }
 
-    private configureJFXDeployTask(Project project) {
-        def task = project.task("jfxDeploy", description: "Processes the JavaFX jars and generates webstart and native packages", type: JavaFXDeployTask)
 
-        task.conventionMapping.packaging = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).packaging }
+    private configureJavaFXCSSToBinTask(Project project) {
+        def task = project.task("cssToBin", description: "Converts CSS to Binary CSS", type: JavaFXCSSToBinTask)
 
-        task.conventionMapping.antJavaFXJar = {convention, aware ->
-            convention.getPlugin(JavaFXPluginConvention).antJavaFXJar }
+        task.conventionMapping.antJavaFXJar = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).antJavaFXJar }
+        task.conventionMapping.jfxrtJar = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).jfxrtJar }
 
-        task.conventionMapping.appID = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).appID }
-        task.conventionMapping.appName = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).appName }
-        task.conventionMapping.mainClass = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).mainClass }
+        task.conventionMapping.distsDir = {convention, aware -> convention.getPlugin(JavaPluginConvention).sourceSets.main.output.resourcesDir}
 
-        task.conventionMapping.inputFiles = {convention, aware -> convention.getPlugin(JavaPluginConvention).sourceSets.main.runtimeClasspath }
         task.conventionMapping.inputFiles = {convention, aware ->
-            FileCollection runtimeClasspath = project.convention.getPlugin(JavaPluginConvention).sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].runtimeClasspath;
-            Configuration providedRuntime = project.configurations[PROVIDED_RUNTIME_CONFIGURATION_NAME];
-            runtimeClasspath  + project.files("$project.libsDir/${project.archivesBaseName}.jar" as File)- providedRuntime
+            project.fileTree(dir: convention.getPlugin(JavaPluginConvention).sourceSets.main.output.resourcesDir, include: '**/*.css')
         }
-        //TODO substract provided runtime
-
-        task.conventionMapping.distsDir = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).distsDir }
 
-        project.tasks.getByName("assemble").dependsOn(task)
-        project.tasks.getByName("jar").enabled = false
     }
 
-
     private configureJavaFXJarTask(Project project) {
         def task = project.task("jfxJar", description: "Jars up the classes and adds JavaFX specific packaging", type: JavaFXJarTask)
 
             compileClasspath + output - providedCompile;
         }
 
-        project.tasks.getByName("jfxDeploy").dependsOn(task)
+        task.dependsOn(project.tasks.getByName("cssToBin"))
+
     }
 
-    private configureJavaFXCSSToBinTask(Project project) {
-        def task = project.task("cssToBin", description: "Converts CSS to Binary CSS", type: JavaFXCSSToBinTask)
+    private configureGenerateDebugKeyTask(Project project) {
+        def task = project.task("generateDebugKey", description: "Generates the JAvaFX Debug Key", type: GenKeyTask)
+
+        task.conventionMapping.alias     = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).debugKey.alias }
+        task.conventionMapping.dname     = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).debugKey.dname }
+        task.conventionMapping.validity  = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).debugKey.validity }
+        task.conventionMapping.keypass   = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).debugKey.keypass }
+        task.conventionMapping.keystore  = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).debugKey.keystore }
+        task.conventionMapping.storepass = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).debugKey.storepass }
+    }
+
+    private configureJavaFXSignJarTask(Project project) {
+        def task = project.task("jfxSignJar", description: "Signs the JavaFX jars the JavaFX way", type: JavaFXSignJarTask)
 
         task.conventionMapping.antJavaFXJar = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).antJavaFXJar }
-        task.conventionMapping.jfxrtJar = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).jfxrtJar }
 
-        task.conventionMapping.distsDir = {convention, aware -> convention.getPlugin(JavaPluginConvention).sourceSets.main.output.resourcesDir}
+        ['alias', 'keypass', 'keystore', 'storepass', 'storetype'].each { prop ->
+            task.conventionMapping[prop]  = {convention, aware ->
+                def jfxc = convention.getPlugin(JavaFXPluginConvention);
+                return jfxc["${jfxc.signingMode}Key"][prop]
+            }
+        }
+
+        task.conventionMapping.destdir = {convention, aware -> "$project.libsDir/../signed" as File}
 
         task.conventionMapping.inputFiles = {convention, aware ->
-            project.fileTree(dir: convention.getPlugin(JavaPluginConvention).sourceSets.main.output.resourcesDir, include: '**/*.css')
+            FileCollection runtimeClasspath = project.convention.getPlugin(JavaPluginConvention).sourceSets[SourceSet.MAIN_SOURCE_SET_NAME].runtimeClasspath;
+            Configuration providedRuntime = project.configurations[PROVIDED_RUNTIME_CONFIGURATION_NAME];
+            runtimeClasspath  + project.files("$project.libsDir/${project.archivesBaseName}.jar" as File)- providedRuntime
         }
 
-        project.tasks.getByName("jfxJar").dependsOn(task)
+        task.dependsOn(project.tasks.getByName("jfxJar"))
+        task.dependsOn(project.tasks.getByName("generateDebugKey"))
+    }
+
+    private configureJFXDeployTask(Project project) {
+        def task = project.task("jfxDeploy", description: "Processes the JavaFX jars and generates webstart and native packages", type: JavaFXDeployTask)
+
+        task.conventionMapping.packaging = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).packaging }
+
+        task.conventionMapping.antJavaFXJar = {convention, aware ->
+            convention.getPlugin(JavaFXPluginConvention).antJavaFXJar }
+
+        task.conventionMapping.appID = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).appID }
+        task.conventionMapping.appName = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).appName }
+        task.conventionMapping.mainClass = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).mainClass }
+
+
+        task.conventionMapping.inputFiles = {convention, aware ->
+            project.fileTree("$project.libsDir/../signed").include("*.jar")
+        }
+
+        task.conventionMapping.distsDir = {convention, aware -> convention.getPlugin(JavaFXPluginConvention).distsDir }
+
+        task.dependsOn(project.tasks.getByName("jfxSignJar"))
+        project.tasks.getByName("assemble").dependsOn(task)
+        project.tasks.getByName("jar").enabled = false
     }
 
     public void configureConfigurations(ConfigurationContainer configurationContainer) {
         println "JavaFX ant jar: ${antjfxjar}"
         return antjfxjar
     }
-}
+}

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/JavaFXPluginConvention.groovy

     SigningKeyInfo debugKey
     SigningKeyInfo releaseKey
 
+    String signingMode
 
     // app info
     String appID
     String keypass
     File keystore
     String storepass
-    String sigfile
+    String storetype
 
 
     public SigningKeyInfo(Closure configure) {

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/GenKeyTask.groovy

+/*
+ * Copyright (c) 2011-2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin.tasks;
+
+import org.gradle.api.internal.ConventionTask
+import org.gradle.api.tasks.OutputFile
+import org.gradle.api.tasks.TaskAction
+import org.gradle.process.ExecResult
+import org.gradle.process.internal.DefaultExecAction
+import org.gradle.process.internal.ExecAction
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dannoferrin
+ * Date: 3/8/11
+ * Time: 9:07 PM
+ */
+class GenKeyTask extends ConventionTask {
+
+    @TaskAction
+    processResources() {
+        if (getKeystore().exists()) return
+
+        ExecAction aaptExec = new DefaultExecAction()
+        aaptExec.workingDir = project.projectDir
+        aaptExec.executable = "${System.properties['java.home']}/bin/keytool"
+
+        def args = []
+        args << '-genkeypair'
+        ['alias', 'dname', 'validity', 'keypass', 'keystore', 'storepass'].each {
+            if (this[it]) {
+                args << "-$it" << this[it] as String
+            }
+        }
+
+        // [-v]
+        // [-protected]
+        // [-keyalg <keyalg>]
+        // [-keysize <keysize>]
+        // [-sigalg <sigalg>]
+        // [-storetype <storetype>]
+        // [-providername <name>]
+        // [-providerclass <provider_class_name> [-providerarg <arg>]] ...
+        // [-providerpath <pathlist>]
+
+
+        aaptExec.args = args
+
+        ExecResult exec = aaptExec.execute()
+        exec.assertNormalExitValue()
+    }
+
+    @OutputFile
+    File keystore
+
+    String alias
+    String dname
+    Integer validity // conventions don't play nice with primitives
+    String keypass
+    String storepass
+}

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/JavaFXDeployTask.groovy

                     //FIXME fallback
             )
             resources {
-                getInputFiles().each {
+                getInputFiles().filter() { it.file } each {
                     fileset(file: it)
                 }
 

plugin/src/main/groovy/com/bitbucket/shemnon/javafxplugin/tasks/JavaFXSignJarTask.groovy

+/*
+ * Copyright (c) 2012, Danno Ferrin
+ *   All rights reserved.
+ *
+ *   Redistribution and use in source and binary forms, with or without
+ *   modification, are permitted provided that the following conditions are met:
+ *       * Redistributions of source code must retain the above copyright
+ *         notice, this list of conditions and the following disclaimer.
+ *       * Redistributions in binary form must reproduce the above copyright
+ *         notice, this list of conditions and the following disclaimer in the
+ *         documentation and/or other materials provided with the distribution.
+ *       * Neither the name of Danno Ferrin nor the
+ *         names of contributors may be used to endorse or promote products
+ *         derived from this software without specific prior written permission.
+ *
+ *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ *   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *   WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *   DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
+ *   DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ *   LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ *   ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ *   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.bitbucket.shemnon.javafxplugin.tasks;
+
+
+import org.gradle.api.file.FileCollection
+import org.gradle.api.internal.ConventionTask
+import org.gradle.api.tasks.InputFiles
+import org.gradle.api.tasks.TaskAction
+import org.gradle.api.tasks.OutputDirectory
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: dannoferrin
+ * Date: 3/5/11
+ * Time: 7:18 AM
+ */
+public class JavaFXSignJarTask extends ConventionTask {
+
+    @TaskAction
+    processResources() {
+
+        project.mkdir(getDestdir())
+
+        ant.taskdef(name: 'fxSignJar',
+                classname: 'com.sun.javafx.tools.ant.FXSignJarTask',
+                classpath: getAntJavaFXJar().asPath)
+
+
+        ant.fxSignJar(
+                makeAttributes()
+        ) {
+            getInputFiles().filter { it.file && it.name.endsWith(".jar") } each {
+                println it
+                fileset(file: it)
+            }
+        }
+    }
+
+    String alias
+    String keypass
+    File keystore
+    String storepass
+    String storetype
+    String verbose = "true"
+
+    FileCollection antJavaFXJar
+
+    @OutputDirectory
+    File destdir
+
+    @InputFiles
+    FileCollection inputFiles
+
+    private Map makeAttributes() {
+        def result = [:]
+        ['alias', 'keypass', 'keystore', 'storepass', 'storetype', 'verbose', 'destdir', 'verbose'].each {
+            if (this[it]) {
+                result[it] = this[it]
+            }
+        }
+        return result
+    }
+}