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
This commit is contained in:
parent
424ccf1771
commit
868afbd8bd
@ -48,22 +48,6 @@ $(INCLUDE_DST_OS_DIR)/%.h: \
|
||||
|
||||
################################################################################
|
||||
|
||||
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
|
||||
|
@ -54,14 +54,12 @@ PROFILE_1_JRE_LIB_FILES := \
|
||||
$(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 \
|
||||
|
@ -61,13 +61,14 @@ import static java.time.temporal.ChronoField.EPOCH_DAY;
|
||||
|
||||
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 @@ import sun.util.logging.PlatformLogger;
|
||||
* 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 @@ public final class HijrahChronology extends AbstractChronology implements Serial
|
||||
* 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 @@ public final class HijrahChronology extends AbstractChronology implements Serial
|
||||
/**
|
||||
* 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 @@ public final class HijrahChronology extends AbstractChronology implements Serial
|
||||
*/
|
||||
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 @@ public final class HijrahChronology extends AbstractChronology implements Serial
|
||||
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 @@ public final class HijrahChronology extends AbstractChronology implements Serial
|
||||
}
|
||||
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 @@ public final class HijrahChronology extends AbstractChronology implements Serial
|
||||
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);
|
||||
|
@ -97,8 +97,7 @@ class JapaneseImperialCalendar extends Calendar {
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -177,44 +177,6 @@ public abstract class CalendarSystem {
|
||||
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 //////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user