1 /*
   2  * Copyright (c) 2015, 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.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 package jdk.testlibrary;
  25 
  26 import java.io.FileInputStream;
  27 import java.io.FileNotFoundException;
  28 import java.io.FileOutputStream;
  29 import java.io.IOException;
  30 import java.util.ArrayList;
  31 import java.util.Enumeration;
  32 import java.util.List;
  33 import java.util.jar.JarEntry;
  34 import java.util.jar.JarFile;
  35 import java.util.jar.JarOutputStream;
  36 import java.util.jar.Manifest;
  37 
  38 /**
  39  * Common library for various test jar file utility functions.
  40  */
  41 public final class JarUtils {
  42 
  43     /**
  44      * Create jar file with specified files. If a specified file does not exist,
  45      * a new jar entry will be created with the file name itself as the content.
  46      */
  47     public static void createJar(String dest, String... files)
  48             throws IOException {
  49         try (JarOutputStream jos = new JarOutputStream(
  50                 new FileOutputStream(dest), new Manifest())) {
  51             for (String file : files) {
  52                 System.out.println(String.format("Adding %s to %s",
  53                         file, dest));
  54 
  55                 // add an archive entry, and write a file
  56                 jos.putNextEntry(new JarEntry(file));
  57                 try (FileInputStream fis = new FileInputStream(file)) {
  58                     fis.transferTo(jos);
  59                 } catch (FileNotFoundException e) {
  60                     jos.write(file.getBytes());
  61                 }
  62             }
  63         }
  64         System.out.println();
  65     }
  66 
  67     /**
  68      * Add or remove specified files to existing jar file. If a specified file
  69      * to be updated or added does not exist, the jar entry will be created
  70      * with the file name itself as the content.
  71      *
  72      * @param src the original jar file name
  73      * @param dest the new jar file name
  74      * @param files the files to update. The list is broken into 2 groups
  75      *              by a "-" string. The files before in the 1st group will
  76      *              be either updated or added. The files in the 2nd group
  77      *              will be removed. If no "-" exists, all files belong to
  78      *              the 1st group.
  79      */
  80     public static void updateJar(String src, String dest, String... files)
  81             throws IOException {
  82         try (JarOutputStream jos = new JarOutputStream(
  83                 new FileOutputStream(dest))) {
  84 
  85             // copy each old entry into destination unless the entry name
  86             // is in the updated list
  87             List<String> updatedFiles = new ArrayList<>();
  88             try (JarFile srcJarFile = new JarFile(src)) {
  89                 Enumeration<JarEntry> entries = srcJarFile.entries();
  90                 while (entries.hasMoreElements()) {
  91                     JarEntry entry = entries.nextElement();
  92                     String name = entry.getName();
  93                     boolean found = false;
  94                     boolean update = true;
  95                     for (String file : files) {
  96                         if (file.equals("-")) {
  97                             update = false;
  98                         } else if (name.equals(file)) {
  99                             updatedFiles.add(file);
 100                             found = true;
 101                             break;
 102                         }
 103                     }
 104 
 105                     if (found) {
 106                         if (update) {
 107                             System.out.println(String.format("Updating %s with %s",
 108                                     dest, name));
 109                             jos.putNextEntry(new JarEntry(name));
 110                             try (FileInputStream fis = new FileInputStream(name)) {
 111                                 fis.transferTo(jos);
 112                             } catch (FileNotFoundException e) {
 113                                 jos.write(name.getBytes());
 114                             }
 115                         } else {
 116                             System.out.println(String.format("Removing %s from %s",
 117                                     name, dest));
 118                         }
 119                     } else {
 120                         System.out.println(String.format("Copying %s to %s",
 121                                 name, dest));
 122                         jos.putNextEntry(entry);
 123                         srcJarFile.getInputStream(entry).transferTo(jos);
 124                     }
 125                 }
 126             }
 127 
 128             // append new files
 129             for (String file : files) {
 130                 if (file.equals("-")) {
 131                     break;
 132                 }
 133                 if (!updatedFiles.contains(file)) {
 134                     System.out.println(String.format("Adding %s with %s",
 135                             dest, file));
 136                     jos.putNextEntry(new JarEntry(file));
 137                     try (FileInputStream fis = new FileInputStream(file)) {
 138                         fis.transferTo(jos);
 139                     } catch (FileNotFoundException e) {
 140                         jos.write(file.getBytes());
 141                     }
 142                 }
 143             }
 144         }
 145         System.out.println();
 146     }
 147 
 148 }