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:
Roger Riggs 2014-10-27 15:59:12 -04:00
parent 424ccf1771
commit 868afbd8bd
7 changed files with 44 additions and 207 deletions

View File

@ -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

View File

@ -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 \

View File

@ -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);

View File

@ -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.
*/
/**

View File

@ -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 //////////////////////////////////
/**

View File

@ -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