1 /*
   2  * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package com.sun.javafx.tools.ant;
  27 
  28 import com.sun.javafx.tools.packager.PackagerLib;
  29 import com.sun.javafx.tools.packager.SignJarParams;
  30 import java.io.File;
  31 import java.util.ArrayList;
  32 import java.util.List;
  33 import org.apache.tools.ant.BuildException;
  34 import org.apache.tools.ant.Task;
  35 import org.apache.tools.ant.types.FileSet;
  36 
  37 /**
  38  * Sign jar as BLOB (instead of signing every entry separately sign jar
  39  * file as one huge binary object).
  40  * <p>
  41  * This is new signing method in JavaFX. Standard ant signjar task need to
  42  * be used for traditional signing.
  43  * <p>
  44  * Usage examples:
  45  * <pre>
  46  *   &lt;signjar keyStore="${basedir}/sample.jks" destdir="c:/tmp"
  47  *               alias="javafx" storePass="****" keyPass="****"&gt;
  48  *      &lt;fileset dir='${build.dir}/dist/** /*.jar'/&gt;
  49  *   &lt;/signjar&gt;
  50  * </pre>
  51  *
  52  * @ant.task name="signjar" category="javafx"
  53  */
  54 public class FXSignJarTask extends Task {
  55 
  56     private File keyStore;
  57     private String alias;
  58     private String storePass;
  59     private String keyPass;
  60     private String storeType = "jks";
  61     private List<FileSet> fileSets = new ArrayList<FileSet>();
  62     private String deprecatedSourceJar; //deprecated since 2.2
  63     private String sourceJar; //deprecated since 2.2
  64     private String destDir;
  65 
  66     private PackagerLib packager;
  67     private SignJarParams signJarParams;
  68     private boolean verbose = false;
  69 
  70     public FXSignJarTask() {
  71         packager = new PackagerLib();
  72         signJarParams = new SignJarParams();
  73     }
  74     @Override
  75     public void execute() throws BuildException {
  76         signJarParams.setKeyStore(keyStore);
  77         signJarParams.setAlias(alias);
  78         signJarParams.setStorePass(storePass);
  79         signJarParams.setKeyPass(keyPass);
  80         signJarParams.setStoreType(storeType);
  81         signJarParams.setVerbose(verbose);
  82 
  83         if (destDir != null) {
  84             signJarParams.setOutdir(new File(destDir));
  85         }
  86 
  87         if (!fileSets.isEmpty()) {
  88             if (deprecatedSourceJar != null) {
  89                 throw new IllegalArgumentException(
  90                         "Unexpected sourcejar attribute when fileset present");
  91             }
  92             if (sourceJar != null) {
  93                 throw new IllegalArgumentException(
  94                         "Unexpected sourcejar attribute when fileset present");
  95             }
  96         }
  97 
  98         if (sourceJar != null && deprecatedSourceJar != null) {
  99                 throw new IllegalArgumentException(
 100                         "Cannot use both sourcejar and jar attributes. (sourcejar attribute is deprecated).");
 101         }
 102 
 103         for (FileSet fileset: fileSets) {
 104             Utils.addResources(signJarParams, fileset);
 105         }
 106         if (deprecatedSourceJar != null) {
 107             File sourceFile = new File(deprecatedSourceJar);
 108             if (sourceFile.exists()) {
 109                 signJarParams.addResource(new File("."), sourceFile);
 110             }
 111         }
 112         if (sourceJar != null) {
 113             File sourceFile = new File(sourceJar);
 114             if (sourceFile.exists()) {
 115                 //treat as request to copy file to top level folder
 116                 // (i.e. ignore path part)
 117                 //this is consistent with built-in signjar
 118                 signJarParams.addResource(
 119                         sourceFile.getParentFile(), sourceFile.getName());
 120             }
 121         }
 122         try {
 123             signJarParams.validate();
 124             packager.signJar(signJarParams);
 125         } catch (Exception e) {
 126             throw new BuildException(e.getMessage(), e);
 127         }
 128     }
 129 
 130     /**
 131      * The alias to sign under.
 132      *
 133      * @ant.required
 134      */
 135     public void setAlias(String alias) {
 136         this.alias = alias;
 137     }
 138 
 139     public void setVerbose(Boolean verbose) {
 140         this.verbose = verbose;
 141     }
 142 
 143 
 144     /**
 145      * Password for private key.
 146      *
 147      * @ant.required
 148      */
 149     public void setKeyPass(String keyPassword) {
 150         this.keyPass = keyPassword;
 151     }
 152 
 153     /**
 154      * Password for keystore
 155      *
 156      * @ant.required
 157      */
 158     public void setStorePass(String storePassword) {
 159         this.storePass = storePassword;
 160     }
 161 
 162     /**
 163      * Keystore to use.
 164      *
 165      * @ant.required
 166      */
 167     public void setKeyStore(File keyStore) {
 168         this.keyStore = keyStore;
 169     }
 170 
 171     /**
 172      * Keystore type
 173      *
 174      * @ant.not-required Default is "jks".
 175      */
 176     public void setStoreType(String storeType) {
 177         this.storeType = storeType;
 178     }
 179 
 180     public void addFileSet(FileSet fileset) {
 181         fileSets.add(fileset);
 182     }
 183 
 184     /**
 185      * The jar to sign (deprecated since 2.2, use jar attribute)
 186      *
 187      * @ant.not-required Either this or jar attribute or embedded fileset are required.
 188      */
 189     public void setSourceJar(String sourceJar) {
 190         this.deprecatedSourceJar = sourceJar;
 191     }
 192 
 193     /**
 194      * The jar to sign.
 195      *
 196      * @ant.not-required Either this or sourcejar or embedded fileset are required.
 197      */
 198     public void setJar(String sourceJar) {
 199         this.sourceJar = sourceJar;
 200     }
 201 
 202     /**
 203      * Location of output file.
 204      *
 205      * @ant.required
 206      */
 207     public void setDestDir(String destDir) {
 208         this.destDir = destDir;
 209     }
 210 }