8048124: Read hijra-config-umalqura.properties as a resource
8061533: HijrahChronology should use Integer.parseInt
Removed use of calendar.properties to configure calendars, move UmmAlQura calendar to resource; minor cleanup using parseInt
Reviewed-by: alanb, chegar
diff --git a/jdk/make/copy/Copy-java.base.gmk b/jdk/make/copy/Copy-java.base.gmk
index 9ca5544..fd9a0ef 100644
--- a/jdk/make/copy/Copy-java.base.gmk
+++ b/jdk/make/copy/Copy-java.base.gmk
@@ -48,22 +48,6 @@
################################################################################
-CALENDARS_SRC := $(JDK_TOPDIR)/src/java.base/share/conf
-
-$(LIB_DST_DIR)/calendars.properties: $(CALENDARS_SRC)/calendars.properties
- $(call install-file)
-
-BASE_CONF_FILES += $(LIB_DST_DIR)/calendars.properties
-
-$(LIB_DST_DIR)/hijrah-config-umalqura.properties: $(CALENDARS_SRC)/hijrah-config-umalqura.properties
- $(MKDIR) -p $(@D)
- $(RM) $@
- $(CP) $< $@
-
-BASE_CONF_FILES += $(LIB_DST_DIR)/hijrah-config-umalqura.properties
-
-################################################################################
-
ifneq ($(findstring $(OPENJDK_TARGET_OS), windows aix),)
TZMAPPINGS_SRC := $(JDK_TOPDIR)/src/java.base/$(OPENJDK_TARGET_OS)/conf
diff --git a/jdk/make/profile-includes.txt b/jdk/make/profile-includes.txt
index a3c7985..226b1ed 100644
--- a/jdk/make/profile-includes.txt
+++ b/jdk/make/profile-includes.txt
@@ -54,14 +54,12 @@
$(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm$(SHARED_LIBRARY_SUFFIX) \
$(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/$(LIBRARY_PREFIX)jvm.diz \
$(OPENJDK_TARGET_CPU_LEGACY_LIB)/server/Xusage.txt \
- calendars.properties \
classlist \
ext/localedata.jar \
ext/meta-index \
ext/sunec.jar \
ext/sunjce_provider.jar \
ext/sunpkcs11.jar \
- hijrah-config-umalqura.properties \
jce.jar \
jsse.jar \
logging.properties \
diff --git a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java
index 7c5005f..c6c6d4a 100644
--- a/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java
+++ b/jdk/src/java.base/share/classes/java/time/chrono/HijrahChronology.java
@@ -61,13 +61,14 @@
import java.io.File;
import java.io.FileInputStream;
+import java.io.FilePermission;
import java.io.IOException;
import java.io.InputStream;
import java.io.InvalidObjectException;
import java.io.ObjectInputStream;
import java.io.Serializable;
import java.security.AccessController;
-import java.security.PrivilegedActionException;
+import java.security.PrivilegedAction;
import java.time.Clock;
import java.time.DateTimeException;
import java.time.Instant;
@@ -145,29 +146,7 @@
* property resource that defines the {@code ID}, the {@code calendar type},
* the start of the calendar, the alignment with the
* ISO calendar, and the length of each month for a range of years.
- * The variants are identified in the {@code calendars.properties} file.
- * The new properties are prefixed with {@code "calendars.hijrah."}:
- * <table cellpadding="2" border="0" summary="Configuration of Hijrah Calendar Variants">
- * <thead>
- * <tr class="tableSubHeadingColor">
- * <th class="colFirst" align="left">Property Name</th>
- * <th class="colFirst" align="left">Property value</th>
- * <th class="colLast" align="left">Description </th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr class="altColor">
- * <td>calendars.hijrah.{ID}</td>
- * <td>The property resource defining the {@code {ID}} variant</td>
- * <td>The property resource is located with the {@code calendars.properties} file</td>
- * </tr>
- * <tr class="rowColor">
- * <td>calendars.hijrah.{ID}.type</td>
- * <td>The calendar type</td>
- * <td>LDML defines the calendar type names</td>
- * </tr>
- * </tbody>
- * </table>
+ * The variants are loaded by HijrahChronology as a resource from hijrah-config-<calendar-type>.properties.
* <p>
* The Hijrah property resource is a set of properties that describe the calendar.
* The syntax is defined by {@code java.util.Properties#load(Reader)}.
@@ -279,91 +258,41 @@
* Computed by {@link #createEpochMonths}.
*/
private transient int maxYearLength;
- /**
- * A reference to the properties stored in
- * ${java.home}/lib/calendars.properties
- */
- private final transient static Properties calendarProperties;
/**
- * Prefix of property names for Hijrah calendar variants.
+ * Prefix of resource names for Hijrah calendar variants.
*/
- private static final String PROP_PREFIX = "calendar.hijrah.";
- /**
- * Suffix of property names containing the calendar type of a variant.
- */
- private static final String PROP_TYPE_SUFFIX = ".type";
+ private static final String RESOURCE_PREFIX = "hijrah-config-";
/**
- * Static initialization of the predefined calendars found in the
- * lib/calendars.properties file.
+ * Suffix of resource names for Hijrah calendar variants.
+ */
+ private static final String RESOURCE_SUFFIX = ".properties";
+
+ /**
+ * Static initialization of the built-in calendars.
+ * The data is not loaded until it is used.
*/
static {
- try {
- calendarProperties = sun.util.calendar.BaseCalendar.getCalendarProperties();
- } catch (IOException ioe) {
- throw new InternalError("Can't initialize lib/calendars.properties", ioe);
- }
-
- try {
- INSTANCE = new HijrahChronology("Hijrah-umalqura");
- // Register it by its aliases
- AbstractChronology.registerChrono(INSTANCE, "Hijrah");
- AbstractChronology.registerChrono(INSTANCE, "islamic");
- } catch (DateTimeException ex) {
- // Absence of Hijrah calendar is fatal to initializing this class.
- PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono");
- logger.severe("Unable to initialize Hijrah calendar: Hijrah-umalqura", ex);
- throw new RuntimeException("Unable to initialize Hijrah-umalqura calendar", ex.getCause());
- }
- registerVariants();
+ INSTANCE = new HijrahChronology("Hijrah-umalqura", "islamic-umalqura");
+ // Register it by its aliases
+ AbstractChronology.registerChrono(INSTANCE, "Hijrah");
+ AbstractChronology.registerChrono(INSTANCE, "islamic");
}
/**
- * For each Hijrah variant listed, create the HijrahChronology and register it.
- * Exceptions during initialization are logged but otherwise ignored.
- */
- private static void registerVariants() {
- for (String name : calendarProperties.stringPropertyNames()) {
- if (name.startsWith(PROP_PREFIX)) {
- String id = name.substring(PROP_PREFIX.length());
- if (id.indexOf('.') >= 0) {
- continue; // no name or not a simple name of a calendar
- }
- if (id.equals(INSTANCE.getId())) {
- continue; // do not duplicate the default
- }
- try {
- // Create and register the variant
- HijrahChronology chrono = new HijrahChronology(id);
- AbstractChronology.registerChrono(chrono);
- } catch (DateTimeException ex) {
- // Log error and continue
- PlatformLogger logger = PlatformLogger.getLogger("java.time.chrono");
- logger.severe("Unable to initialize Hijrah calendar: " + id, ex);
- }
- }
- }
- }
-
- /**
- * Create a HijrahChronology for the named variant.
- * The resource and calendar type are retrieved from properties
- * in the {@code calendars.properties}.
- * The property names are {@code "calendar.hijrah." + id}
- * and {@code "calendar.hijrah." + id + ".type"}
+ * Create a HijrahChronology for the named variant and type.
+ *
* @param id the id of the calendar
- * @throws DateTimeException if the calendar type is missing from the properties file.
- * @throws IllegalArgumentException if the id is empty
+ * @param calType the typeId of the calendar
+ * @throws IllegalArgumentException if the id or typeId is empty
*/
- private HijrahChronology(String id) throws DateTimeException {
+ private HijrahChronology(String id, String calType) {
if (id.isEmpty()) {
throw new IllegalArgumentException("calendar id is empty");
}
- String propName = PROP_PREFIX + id + PROP_TYPE_SUFFIX;
- String calType = calendarProperties.getProperty(propName);
- if (calType == null || calType.isEmpty()) {
- throw new DateTimeException("calendarType is missing or empty for: " + propName);
+ if (calType.isEmpty()) {
+ throw new IllegalArgumentException("calendar typeId is empty");
}
this.typeId = id;
this.calendarType = calType;
@@ -866,30 +795,26 @@
/**
* Return the configuration properties from the resource.
* <p>
- * The default location of the variant configuration resource is:
+ * The location of the variant configuration resource is:
* <pre>
- * "$java.home/lib/" + resource-name
+ * "/java/time/chrono/hijrah-config-" + calendarType + ".properties"
* </pre>
*
- * @param resource the name of the calendar property resource
+ * @param calendarType the calendarType of the calendar variant
* @return a Properties containing the properties read from the resource.
* @throws Exception if access to the property resource fails
*/
- private static Properties readConfigProperties(final String resource) throws Exception {
- try {
- return AccessController
- .doPrivileged((java.security.PrivilegedExceptionAction<Properties>)
- () -> {
- String libDir = System.getProperty("java.home") + File.separator + "lib";
- File file = new File(libDir, resource);
- Properties props = new Properties();
- try (InputStream is = new FileInputStream(file)) {
- props.load(is);
- }
- return props;
- });
- } catch (PrivilegedActionException pax) {
- throw pax.getException();
+ private Properties readConfigProperties(final String calendarType) throws Exception {
+ String resourceName = RESOURCE_PREFIX + calendarType + RESOURCE_SUFFIX;
+ PrivilegedAction<InputStream> getResourceAction = () -> HijrahChronology.class.getResourceAsStream(resourceName);
+ FilePermission perm = new FilePermission("<<ALL FILES>>", "read");
+ try (InputStream is = AccessController.doPrivileged(getResourceAction, null, perm)) {
+ if (is == null) {
+ throw new RuntimeException("Hijrah calendar resource not found: /java/time/chrono/" + resourceName);
+ }
+ Properties props = new Properties();
+ props.load(is);
+ return props;
}
}
@@ -906,9 +831,7 @@
*/
private void loadCalendarData() {
try {
- String resourceName = calendarProperties.getProperty(PROP_PREFIX + typeId);
- Objects.requireNonNull(resourceName, "Resource missing for calendar: " + PROP_PREFIX + typeId);
- Properties props = readConfigProperties(resourceName);
+ Properties props = readConfigProperties(calendarType);
Map<Integer, int[]> years = new HashMap<>();
int minYear = Integer.MAX_VALUE;
@@ -937,7 +860,7 @@
default:
try {
// Everything else is either a year or invalid
- int year = Integer.valueOf(key);
+ int year = Integer.parseInt(key);
int[] months = parseMonths((String) entry.getValue());
years.put(year, months);
maxYear = Math.max(maxYear, year);
@@ -1045,7 +968,7 @@
}
for (int i = 0; i < 12; i++) {
try {
- months[i] = Integer.valueOf(numbers[i]);
+ months[i] = Integer.parseInt(numbers[i]);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException("bad key: " + numbers[i]);
}
@@ -1067,9 +990,9 @@
throw new IllegalArgumentException("date must be yyyy-MM-dd");
}
int[] ymd = new int[3];
- ymd[0] = Integer.valueOf(string.substring(0, 4));
- ymd[1] = Integer.valueOf(string.substring(5, 7));
- ymd[2] = Integer.valueOf(string.substring(8, 10));
+ ymd[0] = Integer.parseInt(string, 0, 4, 10);
+ ymd[1] = Integer.parseInt(string, 5, 7, 10);
+ ymd[2] = Integer.parseInt(string, 8, 10, 10);
return ymd;
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("date must be yyyy-MM-dd", ex);
diff --git a/jdk/src/java.base/share/conf/hijrah-config-umalqura.properties b/jdk/src/java.base/share/classes/java/time/chrono/hijrah-config-islamic-umalqura.properties
similarity index 100%
rename from jdk/src/java.base/share/conf/hijrah-config-umalqura.properties
rename to jdk/src/java.base/share/classes/java/time/chrono/hijrah-config-islamic-umalqura.properties
diff --git a/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java b/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java
index 81b769a..c66518a 100644
--- a/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java
+++ b/jdk/src/java.base/share/classes/java/util/JapaneseImperialCalendar.java
@@ -97,8 +97,7 @@
*
* This implementation uses
* sun.util.calendar.LocalGregorianCalendar to perform most of the
- * calendar calculations. LocalGregorianCalendar is configurable
- * and reads <JRE_HOME>/lib/calendars.properties at the start-up.
+ * calendar calculations.
*/
/**
diff --git a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
index 589f552..811eae7 100644
--- a/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
+++ b/jdk/src/java.base/share/classes/sun/util/calendar/CalendarSystem.java
@@ -177,44 +177,6 @@
return (cs == null) ? cal : cs;
}
- /**
- * Returns a {@link Properties} loaded from lib/calendars.properties.
- *
- * @return a {@link Properties} loaded from lib/calendars.properties
- * @throws IOException if an error occurred when reading from the input stream
- * @throws IllegalArgumentException if the input stream contains any malformed
- * Unicode escape sequences
- */
- public static Properties getCalendarProperties() throws IOException {
- Properties calendarProps = null;
- try {
- String homeDir = AccessController.doPrivileged(
- new sun.security.action.GetPropertyAction("java.home"));
- final String fname = homeDir + File.separator + "lib" + File.separator
- + "calendars.properties";
- calendarProps = AccessController.doPrivileged(new PrivilegedExceptionAction<Properties>() {
- @Override
- public Properties run() throws IOException {
- Properties props = new Properties();
- try (FileInputStream fis = new FileInputStream(fname)) {
- props.load(fis);
- }
- return props;
- }
- });
- } catch (PrivilegedActionException e) {
- Throwable cause = e.getCause();
- if (cause instanceof IOException) {
- throw (IOException) cause;
- } else if (cause instanceof IllegalArgumentException) {
- throw (IllegalArgumentException) cause;
- }
- // Should not happen
- throw new InternalError(cause);
- }
- return calendarProps;
- }
-
//////////////////////////////// Calendar API //////////////////////////////////
/**
diff --git a/jdk/src/java.base/share/conf/calendars.properties b/jdk/src/java.base/share/conf/calendars.properties
deleted file mode 100644
index 46bb0e2..0000000
--- a/jdk/src/java.base/share/conf/calendars.properties
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
-# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
-#
-# This code is free software; you can redistribute it and/or modify it
-# under the terms of the GNU General Public License version 2 only, as
-# published by the Free Software Foundation. Oracle designates this
-# particular file as subject to the "Classpath" exception as provided
-# by Oracle in the LICENSE file that accompanied this code.
-#
-# This code is distributed in the hope that it will be useful, but WITHOUT
-# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
-# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-# version 2 for more details (a copy is included in the LICENSE file that
-# accompanied this code).
-#
-# You should have received a copy of the GNU General Public License version
-# 2 along with this work; if not, write to the Free Software Foundation,
-# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
-# or visit www.oracle.com if you need additional information or have any
-# questions.
-#
-
-#
-# Hijrah calendars
-#
-calendar.hijrah.Hijrah-umalqura: hijrah-config-umalqura.properties
-calendar.hijrah.Hijrah-umalqura.type: islamic-umalqura