1 /*
   2  * Copyright (c) 2016, 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.*;
  27 import java.util.ArrayList;
  28 import java.util.Enumeration;
  29 import java.util.List;
  30 import java.util.jar.JarEntry;
  31 import java.util.jar.JarFile;
  32 import java.util.jar.JarOutputStream;
  33 import java.util.jar.Manifest;
  34 
  35 /**
  36  * Common library for various test jar file utility functions.
  37  */
  38 public final class JarUtils {
  39 
  40     private static final int BUFFER_SIZE = 1024;
  41 
  42     /**
  43      * Create jar file with specified files.
  44      */
  45     public static void createJar(String dest, String... files)
  46             throws IOException {
  47         try (JarOutputStream jos = new JarOutputStream(
  48                 new FileOutputStream(dest), new Manifest())) {
  49             for (String file : files) {
  50                 System.out.println(String.format("Adding %s to %s",
  51                         file, dest));
  52 
  53                 // add an archive entry, and write a file
  54                 jos.putNextEntry(new JarEntry(file));
  55                 try (FileInputStream fis = new FileInputStream(file)) {
  56                     transferToOutputStream(fis, jos);
  57                 }
  58             }
  59         }
  60         System.out.println();
  61     }
  62 
  63     /**
  64      * Add specified files to existing jar file.
  65      */
  66     public static void updateJar(String src, String dest, String... files)
  67             throws IOException {
  68         try (JarOutputStream jos = new JarOutputStream(
  69                 new FileOutputStream(dest))) {
  70 
  71             // copy each old entry into destination unless the entry name
  72             // is in the updated list
  73             List<String> updatedFiles = new ArrayList<>();
  74             try (JarFile srcJarFile = new JarFile(src)) {
  75                 Enumeration<JarEntry> entries = srcJarFile.entries();
  76                 while (entries.hasMoreElements()) {
  77                     JarEntry entry = entries.nextElement();
  78                     String name = entry.getName();
  79                     boolean found = false;
  80                     for (String file : files) {
  81                         if (name.equals(file)) {
  82                             updatedFiles.add(file);
  83                             found = true;
  84                             break;
  85                         }
  86                     }
  87 
  88                     if (found) {
  89                         System.out.println(String.format("Updating %s with %s",
  90                                 dest, name));
  91                         jos.putNextEntry(new JarEntry(name));
  92                         try (FileInputStream fis = new FileInputStream(name)) {
  93                             transferToOutputStream(fis, jos);
  94                         }
  95                     } else {
  96                         System.out.println(String.format("Copying %s to %s",
  97                                 name, dest));
  98                         jos.putNextEntry(entry);
  99                         transferToOutputStream(srcJarFile.getInputStream(entry),
 100                                 jos);
 101                     }
 102                 }
 103             }
 104 
 105             // append new files
 106             for (String file : files) {
 107                 if (!updatedFiles.contains(file)) {
 108                     System.out.println(String.format("Adding %s with %s",
 109                             dest, file));
 110                     jos.putNextEntry(new JarEntry(file));
 111                     try (FileInputStream fis = new FileInputStream(file)) {
 112                         transferToOutputStream(fis, jos);
 113                     }
 114                 }
 115             }
 116         }
 117         System.out.println();
 118     }
 119 
 120     private static void transferToOutputStream(InputStream is, OutputStream os)
 121             throws IOException  {
 122         byte[] buffer = new byte[BUFFER_SIZE];
 123         int read;
 124         while ((read = is.read(buffer, 0, BUFFER_SIZE)) >= 0) {
 125             os.write(buffer, 0, read);
 126         }
 127     }
 128 }