1 /*
   2  * Copyright (c) 2017, 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 /**
  25  * @test
  26  * @bug 8054214 8173423 8177776
  27  * @summary Create an equivalent test case for JDK9's SupplementalJapaneseEraTest
  28  * @library /lib/testlibrary
  29  * @run testng SupplementalJapaneseEraTest
  30  */
  31 
  32 import java.io.BufferedReader;
  33 import java.io.BufferedWriter;
  34 import java.io.IOException;
  35 import java.nio.file.FileVisitResult;
  36 import java.nio.file.Files;
  37 import java.nio.file.Path;
  38 import java.nio.file.Paths;
  39 import java.nio.file.SimpleFileVisitor;
  40 import java.nio.file.StandardCopyOption;
  41 import java.nio.file.attribute.BasicFileAttributes;
  42 import java.text.SimpleDateFormat;
  43 import java.time.chrono.JapaneseChronology;
  44 import java.time.chrono.JapaneseDate;
  45 import java.time.chrono.JapaneseEra;
  46 import java.time.format.DateTimeFormatterBuilder;
  47 import java.time.format.TextStyle;
  48 import java.util.Calendar;
  49 import java.util.Date;
  50 import java.util.GregorianCalendar;
  51 import static java.util.GregorianCalendar.*;
  52 import java.util.Locale;
  53 import java.util.Properties;
  54 import java.util.TimeZone;
  55 
  56 import jdk.testlibrary.ProcessTools;
  57 import org.testng.annotations.BeforeTest;
  58 import org.testng.annotations.Test;
  59 import static org.testng.Assert.*;
  60 
  61 public class SupplementalJapaneseEraTest {
  62     private static final Locale WAREKI_LOCALE = Locale.forLanguageTag("ja-JP-u-ca-japanese");
  63     private static final String NEW_ERA_NAME = "NewEra";
  64     private static final String NEW_ERA_ABBR = "N.E.";
  65     private static final int NEW_ERA_YEAR = 200;
  66     private static final int NEW_ERA_MONTH = FEBRUARY;
  67     private static final int NEW_ERA_DAY = 11;
  68     private static int errors = 0;
  69 
  70     @BeforeTest
  71     public void prepareTestJDK() throws IOException {
  72         Path src = Paths.get(System.getProperty("test.jdk")).toAbsolutePath();
  73         Path dst = Paths.get("testjava").toAbsolutePath();
  74         Files.walkFileTree(src, new CopyFileVisitor(src, dst));
  75     }
  76 
  77     @Test
  78     public void invokeTestJDK() throws Throwable {
  79         assertTrue(ProcessTools.executeCommand(
  80             Paths.get("testjava", "bin", "java").toAbsolutePath().toString(),
  81             "-cp",
  82             System.getProperty("test.classes"),
  83             "SupplementalJapaneseEraTest")
  84             .getExitValue() == 0);
  85     }
  86 
  87     public static void main(String[] args) {
  88         testProperty();
  89 
  90         if (errors != 0) {
  91             throw new RuntimeException("test failed");
  92         }
  93     }
  94 
  95     // copied from JDK9's test
  96     private static void testProperty() {
  97         Calendar jcal = new Calendar.Builder()
  98             .setCalendarType("japanese")
  99             .setFields(YEAR, 1, DAY_OF_YEAR, 1)
 100             .build();
 101         Date firstDayOfEra = jcal.getTime();
 102 
 103         jcal.set(ERA, jcal.get(ERA) - 1); // previous era
 104         jcal.set(YEAR, 1);
 105         jcal.set(DAY_OF_YEAR, 1);
 106         Calendar cal = new GregorianCalendar();
 107         cal.setTimeInMillis(jcal.getTimeInMillis());
 108         cal.add(YEAR, 199);
 109         int year = cal.get(YEAR);
 110 
 111         SimpleDateFormat sdf;
 112         String expected, got;
 113 
 114         // test long era name
 115         sdf = new SimpleDateFormat("GGGG y-MM-dd", WAREKI_LOCALE);
 116         got = sdf.format(firstDayOfEra);
 117         expected = NEW_ERA_NAME + " 1-02-11";
 118         if (!expected.equals(got)) {
 119             System.err.printf("GGGG y-MM-dd: got=\"%s\", expected=\"%s\"%n", got, expected);
 120             errors++;
 121         }
 122 
 123         // test era abbreviation
 124         sdf = new SimpleDateFormat("G y-MM-dd", WAREKI_LOCALE);
 125         got = sdf.format(firstDayOfEra);
 126         expected = NEW_ERA_ABBR+" 1-02-11";
 127         if (!expected.equals(got)) {
 128             System.err.printf("G y-MM-dd: got=\"%s\", expected=\"%s\"%n", got, expected);
 129             errors++;
 130         }
 131 
 132         // confirm the gregorian year
 133         sdf = new SimpleDateFormat("y", Locale.US);
 134         int y = Integer.parseInt(sdf.format(firstDayOfEra));
 135         if (y != year) {
 136             System.err.printf("Gregorian year: got=%d, expected=%d%n", y, year);
 137             errors++;
 138         }
 139 
 140         // test java.time.chrono.JapaneseEra
 141         JapaneseDate jdate = JapaneseDate.of(year, 2, 11);
 142         got = jdate.toString();
 143         expected = "Japanese " + NEW_ERA_NAME + " 1-02-11";
 144         if (!expected.equals(got)) {
 145             System.err.printf("JapaneseDate: got=\"%s\", expected=\"%s\"%n", got, expected);
 146             errors++;
 147         }
 148         JapaneseEra jera = jdate.getEra();
 149         got = jera.getDisplayName(TextStyle.FULL, Locale.US);
 150         if (!NEW_ERA_NAME.equals(got)) {
 151             System.err.printf("JapaneseEra (FULL): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_NAME);
 152             errors++;
 153         }
 154         got = jera.getDisplayName(TextStyle.SHORT, Locale.US);
 155         if (!NEW_ERA_NAME.equals(got)) {
 156             System.err.printf("JapaneseEra (SHORT): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_NAME);
 157             errors++;
 158         }
 159         got = jera.getDisplayName(TextStyle.NARROW, Locale.US);
 160         if (!NEW_ERA_ABBR.equals(got)) {
 161             System.err.printf("JapaneseEra (NARROW): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_ABBR);
 162             errors++;
 163         }
 164         got = jera.getDisplayName(TextStyle.NARROW_STANDALONE, Locale.US);
 165         if (!NEW_ERA_ABBR.equals(got)) {
 166             System.err.printf("JapaneseEra (NARROW_STANDALONE): got=\"%s\", expected=\"%s\"%n", got, NEW_ERA_ABBR);
 167             errors++;
 168         }
 169 
 170         // test long/abbreviated names with java.time.format
 171         got = new DateTimeFormatterBuilder()
 172             .appendPattern("GGGG")
 173             .appendLiteral(" ")
 174             .appendPattern("G")
 175             .toFormatter(Locale.US)
 176             .withChronology(JapaneseChronology.INSTANCE)
 177             .format(jdate);
 178         expected = NEW_ERA_NAME + " " + NEW_ERA_ABBR;
 179         if (!expected.equals(got)) {
 180             System.err.printf("java.time formatter long/abbr names: got=\"%s\", expected=\"%s\"%n", got, expected);
 181             errors++;
 182         }
 183     }
 184 
 185     private static class CopyFileVisitor extends SimpleFileVisitor<Path> {
 186         private final Path copyFrom;
 187         private final Path copyTo;
 188         private final Path calProps = Paths.get("calendars.properties");
 189         private final String JA_CAL_KEY = "calendar.japanese.eras";
 190 
 191         public CopyFileVisitor(Path copyFrom, Path copyTo) {
 192             this.copyFrom = copyFrom;
 193             this.copyTo = copyTo;
 194         }
 195 
 196         @Override
 197         public FileVisitResult preVisitDirectory(Path file,
 198                 BasicFileAttributes attrs) throws IOException {
 199             Path relativePath = copyFrom.relativize(file);
 200             Path destination = copyTo.resolve(relativePath);
 201             if (!destination.toFile().exists()) {
 202                 Files.createDirectories(destination);
 203             }
 204             return FileVisitResult.CONTINUE;
 205         }
 206 
 207         @Override
 208         public FileVisitResult visitFile(Path file,
 209                 BasicFileAttributes attrs) throws IOException {
 210             if (!file.toFile().isFile()) {
 211                 return FileVisitResult.CONTINUE;
 212             }
 213             Path relativePath = copyFrom.relativize(file);
 214             Path destination = copyTo.resolve(relativePath);
 215             if (relativePath.getFileName().equals(calProps)) {
 216                 modifyCalendarProperties(file, destination);
 217             } else {
 218                 Files.copy(file, destination, StandardCopyOption.COPY_ATTRIBUTES);
 219             }
 220             return FileVisitResult.CONTINUE;
 221         }
 222 
 223         private void modifyCalendarProperties(Path src, Path dst) throws IOException {
 224             Properties p = new Properties();
 225             try (BufferedReader br = Files.newBufferedReader(src)) {
 226                 p.load(br);
 227             }
 228 
 229             String eras = p.getProperty(JA_CAL_KEY);
 230             if (eras != null) {
 231                 p.setProperty(JA_CAL_KEY,
 232                     eras +
 233                     "; name=" + SupplementalJapaneseEraTest.NEW_ERA_NAME +
 234                     ",abbr=" + SupplementalJapaneseEraTest.NEW_ERA_ABBR +
 235                     ",since=" + since());
 236             }
 237             try (BufferedWriter bw = Files.newBufferedWriter(dst)) {
 238                 p.store(bw, "test calendars.properties for supplemental Japanese era");
 239             }
 240         }
 241 
 242         private long since() {
 243             return new Calendar.Builder()
 244                 .setCalendarType("japanese")
 245                 .setTimeZone(TimeZone.getTimeZone("GMT"))
 246                 .setDate(SupplementalJapaneseEraTest.NEW_ERA_YEAR,
 247                     SupplementalJapaneseEraTest.NEW_ERA_MONTH,
 248                     SupplementalJapaneseEraTest.NEW_ERA_DAY)
 249                 .build()
 250                 .getTimeInMillis();
 251         }
 252     }
 253 }