1 /*
   2  * Copyright (c) 2010, 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.
   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 import java.io.File;
  25 import java.io.FileOutputStream;
  26 import java.io.IOException;
  27 import java.util.ArrayList;
  28 import java.util.Collections;
  29 import java.util.HashMap;
  30 import java.util.List;
  31 import java.util.TimeZone;
  32 import java.util.jar.JarEntry;
  33 import java.util.jar.JarFile;
  34 import java.util.jar.JarOutputStream;
  35 
  36 /*
  37  * @test
  38  * @bug 6966740
  39  * @summary verify identical timestamps, unpacked in any timezone
  40  * @compile -XDignore.symbol.file Utils.java TimeStamp.java
  41  * @run main/othervm TimeStamp
  42  * @author ksrini
  43  */
  44 
  45 /**
  46  * First we pack the file in some time zone say India, then we unpack the  file
  47  * in the current time zone, and ensure the timestamp recorded in the unpacked
  48  * jar are the same.
  49  */
  50 public class TimeStamp {
  51     static final TimeZone tz = TimeZone.getDefault();
  52 
  53 
  54     public static void main(String... args) throws IOException {
  55 
  56         // make a local copy of our test file
  57         File srcFile = Utils.locateJar("golden.jar");
  58         File goldenFile = new File("golden.jar");
  59         Utils.copyFile(srcFile, goldenFile);
  60 
  61         JarFile goldenJarFile = new JarFile(goldenFile);
  62         File packFile = new File("golden.pack");
  63 
  64         // set the test timezone and pack the file
  65         TimeZone.setDefault(TimeZone.getTimeZone("IST"));
  66         Utils.pack(goldenJarFile, packFile);
  67         TimeZone.setDefault(tz);   // reset the timezone
  68 
  69         // unpack in the  test timezone
  70         File istFile = new File("golden.jar.java.IST");
  71         unpackJava(packFile, istFile);
  72         verifyJar(goldenFile, istFile);
  73         istFile.delete();
  74 
  75         // unpack in some other timezone
  76         File pstFile = new File("golden.jar.java.PST");
  77         unpackJava(packFile, pstFile);
  78         verifyJar(goldenFile, pstFile);
  79         pstFile.delete();
  80 
  81         // repeat the test for unpack200 tool.
  82         istFile = new File("golden.jar.native.IST");
  83         unpackNative(packFile, istFile);
  84         verifyJar(goldenFile, istFile);
  85         istFile.delete();
  86 
  87         pstFile = new File("golden.jar.native.PST");
  88         unpackNative(packFile, pstFile);
  89         verifyJar(goldenFile, pstFile);
  90         pstFile.delete();
  91     }
  92 
  93     static void unpackNative(File packFile, File outFile) {
  94         String name = outFile.getName();
  95         String tzname = name.substring(name.lastIndexOf(".") + 1);
  96         HashMap<String, String> env = new HashMap<>();
  97         switch(tzname) {
  98             case "PST":
  99                 env.put("TZ", "US/Pacific");
 100                 break;
 101             case "IST":
 102                 env.put("TZ", "Asia/Calcutta");
 103                 break;
 104             default:
 105                 throw new RuntimeException("not implemented: " + tzname);
 106         }
 107         List<String> cmdsList = new ArrayList<>();
 108         cmdsList.add(Utils.getUnpack200Cmd());
 109         cmdsList.add(packFile.getName());
 110         cmdsList.add(outFile.getName());
 111         Utils.runExec(cmdsList, env);
 112     }
 113 
 114     static void unpackJava(File packFile, File outFile) throws IOException {
 115         String name = outFile.getName();
 116         String tzname = name.substring(name.lastIndexOf(".") + 1);
 117         JarOutputStream jos = null;
 118         try {
 119             TimeZone.setDefault(TimeZone.getTimeZone(tzname));
 120             jos = new JarOutputStream(new FileOutputStream(outFile));
 121             System.out.println("Using timezone: " + TimeZone.getDefault());
 122             Utils.unpackj(packFile, jos);
 123         } finally {
 124             Utils.close(jos);
 125             TimeZone.setDefault(tz); // always reset
 126         }
 127     }
 128 
 129     static void verifyJar(File f1, File f2) throws IOException {
 130         int errors = 0;
 131         JarFile jf1 = null;
 132         JarFile jf2 = null;
 133         try {
 134             jf1 = new JarFile(f1);
 135             jf2 = new JarFile(f2);
 136             System.out.println("Verifying: " + f1 + " and " + f2);
 137             for (JarEntry je1 : Collections.list(jf1.entries())) {
 138                 JarEntry je2 = jf2.getJarEntry(je1.getName());
 139                 if (je1.getTime() != je2.getTime()) {
 140                     System.out.println("Error:");
 141                     System.out.println("  expected:" + jf1.getName() + ":"
 142                             + je1.getName() + ":" + je1.getTime());
 143                     System.out.println("  obtained:" + jf2.getName() + ":"
 144                             + je2.getName() + ":" + je2.getTime());
 145                     errors++;
 146                 }
 147             }
 148         } finally {
 149             Utils.close(jf1);
 150             Utils.close(jf2);
 151         }
 152         Utils.cleanup();
 153         if (errors > 0) {
 154             throw new RuntimeException("FAIL:" + errors + " error(s) encounted");
 155         }
 156     }
 157 }