8008348: The leftover jdk/make/tools/javazic causes build problems with hs25-b19 control
To remove jdk/make/tools/javazic from the jdk repo Reviewed-by: alanb
This commit is contained in:
parent
381aecb7c2
commit
c64f5833d2
@ -1,43 +0,0 @@
|
||||
#
|
||||
# Copyright (c) 1998, 2005, 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.
|
||||
#
|
||||
|
||||
#
|
||||
# Makefile for building the javazic tool
|
||||
#
|
||||
|
||||
BUILDDIR = ../..
|
||||
PACKAGE = build.tools.javazic
|
||||
PRODUCT = javazic
|
||||
PROGRAM = javazic
|
||||
include $(BUILDDIR)/common/Defs.gmk
|
||||
|
||||
BUILDTOOL_SOURCE_ROOT = $(BUILDDIR)/tools/src
|
||||
BUILDTOOL_MAIN = $(PKGDIR)/Main.java
|
||||
|
||||
#
|
||||
# Build tool jar rules.
|
||||
#
|
||||
include $(BUILDDIR)/common/BuildToolJar.gmk
|
||||
|
@ -1,70 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
/**
|
||||
* <code>BackEnd</code> is an abstract base class for a back-end of compiling
|
||||
* Olson's zoneinfo database and generating Java zoneinfo database.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
abstract class BackEnd {
|
||||
|
||||
/**
|
||||
* Receives each zone's TimeZone information which was created by
|
||||
* {@link Zoneinfo#parse} in class <code>Zoneinfo</code>,
|
||||
* and processes it.
|
||||
*
|
||||
* @param tz Timezone object for each zone
|
||||
* @return 0 if no error occurred, otherwise 1.
|
||||
*/
|
||||
abstract int processZoneinfo(Timezone tz);
|
||||
|
||||
/**
|
||||
* Receives whole information which is generated by JavaZic's front-end
|
||||
* in the form of Mapping object and generates all Java zone information
|
||||
* files.
|
||||
*
|
||||
* @param m Mappings object which is generated by
|
||||
* {@link Main#compile() Main.compile()}.
|
||||
* @return 0 if no error occurred, otherwise 1.
|
||||
*/
|
||||
abstract int generateSrc(Mappings m);
|
||||
|
||||
/**
|
||||
* Decides which backend class should be used and returns its instance.
|
||||
* @return an instance of backend class
|
||||
*/
|
||||
static BackEnd getBackEnd() {
|
||||
if (Zoneinfo.isYearForTimeZoneDataSpecified) {
|
||||
return new Simple();
|
||||
} else if (Main.outputDoc) {
|
||||
return new GenDoc();
|
||||
} else {
|
||||
return new Gen();
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.zip.CRC32;
|
||||
|
||||
/**
|
||||
* Checksum provides methods for calculating a CRC32 value for a
|
||||
* transitions table.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public class Checksum extends CRC32
|
||||
{
|
||||
/**
|
||||
* Updates the CRC32 value from each byte of the given int
|
||||
* value. The bytes are used in the big endian order.
|
||||
* @param val the int value
|
||||
*/
|
||||
public void update(int val) {
|
||||
byte[] b = new byte[4];
|
||||
b[0] = (byte)((val >>> 24) & 0xff);
|
||||
b[1] = (byte)((val >>> 16) & 0xff);
|
||||
b[2] = (byte)((val >>> 8) & 0xff);
|
||||
b[3] = (byte)(val & 0xff);
|
||||
update(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the CRC32 value from each byte of the given long
|
||||
* value. The bytes are used in the big endian order.
|
||||
* @param val the long value
|
||||
*/
|
||||
void update(long val) {
|
||||
byte[] b = new byte[8];
|
||||
b[0] = (byte)((val >>> 56) & 0xff);
|
||||
b[1] = (byte)((val >>> 48) & 0xff);
|
||||
b[2] = (byte)((val >>> 40) & 0xff);
|
||||
b[3] = (byte)((val >>> 32) & 0xff);
|
||||
b[4] = (byte)((val >>> 24) & 0xff);
|
||||
b[5] = (byte)((val >>> 16) & 0xff);
|
||||
b[6] = (byte)((val >>> 8) & 0xff);
|
||||
b[7] = (byte)(val & 0xff);
|
||||
update(b);
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2004, 2006, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
/**
|
||||
* Day of week enum.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
enum DayOfWeek {
|
||||
SUNDAY("Sun"),
|
||||
MONDAY("Mon"),
|
||||
TUESDAY("Tue"),
|
||||
WEDNESDAY("Wed"),
|
||||
THURSDAY("Thu"),
|
||||
FRIDAY("Fri"),
|
||||
SATURDAY("Sat");
|
||||
|
||||
private final String abbr;
|
||||
|
||||
private DayOfWeek(String abbr) {
|
||||
this.abbr = abbr;
|
||||
}
|
||||
|
||||
String getAbbr() {
|
||||
return abbr;
|
||||
}
|
||||
|
||||
int value() {
|
||||
return ordinal() + 1;
|
||||
}
|
||||
}
|
@ -1,347 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import sun.util.calendar.ZoneInfoFile;
|
||||
|
||||
/**
|
||||
* <code>Gen</code> is one of back-end classes of javazic, and generates
|
||||
* ZoneInfoMappings and zone-specific file for each zone.
|
||||
*/
|
||||
class Gen extends BackEnd {
|
||||
|
||||
/**
|
||||
* Generates datafile in binary TLV format for each time zone.
|
||||
* Regarding contents of output files, see {@link ZoneInfoFile}.
|
||||
*
|
||||
* @param Timezone
|
||||
* @return 0 if no errors, or 1 if error occurred.
|
||||
*/
|
||||
int processZoneinfo(Timezone tz) {
|
||||
try {
|
||||
int size;
|
||||
String outputDir = Main.getOutputDir();
|
||||
String zonefile = ZoneInfoFile.getFileName(tz.getName());
|
||||
|
||||
/* If outputDir doesn't end with file-separator, adds it. */
|
||||
if (!outputDir.endsWith(File.separator)) {
|
||||
outputDir += File.separatorChar;
|
||||
}
|
||||
|
||||
/* If zonefile includes file-separator, it's treated as part of
|
||||
* pathname. And make directory if necessary.
|
||||
*/
|
||||
int index = zonefile.lastIndexOf(File.separatorChar);
|
||||
if (index != -1) {
|
||||
outputDir += zonefile.substring(0, index+1);
|
||||
}
|
||||
File outD = new File(outputDir);
|
||||
outD.mkdirs();
|
||||
|
||||
FileOutputStream fos =
|
||||
new FileOutputStream(outputDir + zonefile.substring(index+1));
|
||||
DataOutputStream dos = new DataOutputStream(fos);
|
||||
|
||||
/* Output Label */
|
||||
dos.write(ZoneInfoFile.JAVAZI_LABEL, 0,
|
||||
ZoneInfoFile.JAVAZI_LABEL.length);
|
||||
|
||||
/* Output Version of ZoneInfoFile */
|
||||
dos.writeByte(ZoneInfoFile.JAVAZI_VERSION);
|
||||
|
||||
List<Long> transitions = tz.getTransitions();
|
||||
if (transitions != null) {
|
||||
List<Integer> dstOffsets = tz.getDstOffsets();
|
||||
List<Integer> offsets = tz.getOffsets();
|
||||
|
||||
if ((dstOffsets == null && offsets != null) ||
|
||||
(dstOffsets != null && offsets == null)) {
|
||||
Main.panic("Data not exist. (dstOffsets or offsets)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Output Transition records */
|
||||
dos.writeByte(ZoneInfoFile.TAG_Transition);
|
||||
size = transitions.size();
|
||||
dos.writeShort((size * 8) & 0xFFFF);
|
||||
int dstoffset;
|
||||
for (int i = 0; i < size; i++) {
|
||||
/* if DST offset is 0, this means DST isn't used.
|
||||
* (NOT: offset's index is 0.)
|
||||
*/
|
||||
if ((dstoffset = dstOffsets.get(i).intValue()) == -1) {
|
||||
dstoffset = 0;
|
||||
}
|
||||
|
||||
dos.writeLong((transitions.get(i).longValue() << 12)
|
||||
| (dstoffset << 4)
|
||||
| offsets.get(i).intValue());
|
||||
|
||||
}
|
||||
|
||||
/* Output data for GMTOffset */
|
||||
List<Integer> gmtoffset = tz.getGmtOffsets();
|
||||
dos.writeByte(ZoneInfoFile.TAG_Offset);
|
||||
size = gmtoffset.size();
|
||||
dos.writeShort((size * 4) & 0xFFFF);
|
||||
for (int i = 0; i < size; i++) {
|
||||
dos.writeInt(gmtoffset.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
/* Output data for SimpleTimeZone */
|
||||
List<RuleRec> stz = tz.getLastRules();
|
||||
if (stz != null) {
|
||||
RuleRec[] rr = new RuleRec[2];
|
||||
boolean wall = true;
|
||||
|
||||
rr[0] = stz.get(0);
|
||||
rr[1] = stz.get(1);
|
||||
|
||||
dos.writeByte(ZoneInfoFile.TAG_SimpleTimeZone);
|
||||
wall = rr[0].getTime().isWall() && rr[1].getTime().isWall();
|
||||
if (wall) {
|
||||
dos.writeShort(32);
|
||||
} else {
|
||||
dos.writeShort(40);
|
||||
}
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
dos.writeInt(rr[i].getMonthNum() - 1); // 0-based month number
|
||||
dos.writeInt(rr[i].getDay().getDayForSimpleTimeZone());
|
||||
dos.writeInt(rr[i].getDay().getDayOfWeekForSimpleTimeZoneInt());
|
||||
dos.writeInt((int)rr[i].getTime().getTime());
|
||||
if (!wall) {
|
||||
dos.writeInt((rr[i].getTime().getType() & 0xFF) - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Output RawOffset */
|
||||
dos.writeByte(ZoneInfoFile.TAG_RawOffset);
|
||||
dos.writeShort(4);
|
||||
dos.writeInt(tz.getRawOffset());
|
||||
|
||||
/* Output willGMTOffsetChange flag */
|
||||
if (tz.willGMTOffsetChange()) {
|
||||
dos.writeByte(ZoneInfoFile.TAG_GMTOffsetWillChange);
|
||||
dos.writeShort(1);
|
||||
dos.writeByte(1);
|
||||
}
|
||||
|
||||
/* Output LastDSTSaving */
|
||||
dos.writeByte(ZoneInfoFile.TAG_LastDSTSaving);
|
||||
dos.writeShort(2);
|
||||
dos.writeShort(tz.getLastDSTSaving()/1000);
|
||||
|
||||
/* Output checksum */
|
||||
dos.writeByte(ZoneInfoFile.TAG_CRC32);
|
||||
dos.writeShort(4);
|
||||
dos.writeInt(tz.getCRC32());
|
||||
|
||||
fos.close();
|
||||
dos.close();
|
||||
} catch(IOException e) {
|
||||
Main.panic("IO error: "+e.getMessage());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates ZoneInfoMappings in binary TLV format for each zone.
|
||||
* Regarding contents of output files, see {@link ZoneInfoFile}.
|
||||
*
|
||||
* @param Mappings
|
||||
* @return 0 if no errors, or 1 if error occurred.
|
||||
*/
|
||||
int generateSrc(Mappings map) {
|
||||
try {
|
||||
int index;
|
||||
int block_size;
|
||||
int roi_size;
|
||||
long fp;
|
||||
String outputDir = Main.getOutputDir();
|
||||
|
||||
/* If outputDir doesn't end with file-separator, adds it. */
|
||||
if (!outputDir.endsWith(File.separator)) {
|
||||
outputDir += File.separatorChar;
|
||||
}
|
||||
|
||||
File outD = new File(outputDir);
|
||||
outD.mkdirs();
|
||||
|
||||
/* Open ZoneInfoMapping file to write. */
|
||||
RandomAccessFile raf =
|
||||
new RandomAccessFile(outputDir + ZoneInfoFile.JAVAZM_FILE_NAME, "rw");
|
||||
|
||||
/* Whether rawOffsetIndex list exists or not. */
|
||||
List<Integer> roi = map.getRawOffsetsIndex();
|
||||
if (roi == null) {
|
||||
Main.panic("Data not exist. (rawOffsetsIndex)");
|
||||
return 1;
|
||||
}
|
||||
roi_size = roi.size();
|
||||
|
||||
/* Whether rawOffsetIndexTable list exists or not. */
|
||||
List<Set<String>> roit = map.getRawOffsetsIndexTable();
|
||||
if (roit == null || roit.size() != roi_size) {
|
||||
Main.panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size");
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Output Label */
|
||||
raf.write(ZoneInfoFile.JAVAZM_LABEL, 0,
|
||||
ZoneInfoFile.JAVAZM_LABEL.length);
|
||||
|
||||
/* Output Version */
|
||||
raf.writeByte(ZoneInfoFile.JAVAZM_VERSION);
|
||||
|
||||
index = ZoneInfoFile.JAVAZM_LABEL.length + 2;
|
||||
|
||||
/* Output Version of Olson's tzdata */
|
||||
byte[] b = Main.getVersionName().getBytes("UTF-8");
|
||||
raf.writeByte(ZoneInfoFile.TAG_TZDataVersion);
|
||||
raf.writeShort((b.length+1) & 0xFFFF);
|
||||
raf.write(b);
|
||||
raf.writeByte(0x00);
|
||||
index += b.length + 4;
|
||||
|
||||
/* Output ID list. */
|
||||
raf.writeByte(ZoneInfoFile.TAG_ZoneIDs);
|
||||
block_size = 2;
|
||||
raf.writeShort(block_size & 0xFFFF);
|
||||
short nID = 0;
|
||||
raf.writeShort(nID & 0xFFFF);
|
||||
for (int i = 0; i < roi_size; i++) {
|
||||
for (String key : roit.get(i)) {
|
||||
byte size = (byte)key.getBytes("UTF-8").length;
|
||||
raf.writeByte(size & 0xFF);
|
||||
raf.write(key.getBytes("UTF-8"), 0, size);
|
||||
block_size += 1 + size;
|
||||
nID++;
|
||||
}
|
||||
}
|
||||
fp = raf.getFilePointer();
|
||||
raf.seek(index);
|
||||
raf.writeShort((block_size) & 0xFFFF);
|
||||
raf.writeShort(nID & 0xFFFF);
|
||||
raf.seek(fp);
|
||||
|
||||
/* Output sorted rawOffset list. */
|
||||
raf.writeByte(ZoneInfoFile.TAG_RawOffsets);
|
||||
index += 3 + block_size;
|
||||
block_size = roi_size * 4;
|
||||
raf.writeShort(block_size & 0xFFFF);
|
||||
for (int i = 0; i < roi_size; i++) {
|
||||
raf.writeInt(Integer.parseInt(roi.get(i).toString()));
|
||||
}
|
||||
|
||||
/* Output sorted rawOffsetIndex list. */
|
||||
raf.writeByte(ZoneInfoFile.TAG_RawOffsetIndices);
|
||||
index += 3 + block_size;
|
||||
block_size = 0;
|
||||
raf.writeShort(block_size & 0xFFFF);
|
||||
int num;
|
||||
for (int i = 0; i < roi_size; i++) {
|
||||
num = roit.get(i).size();
|
||||
block_size += num;
|
||||
for (int j = 0; j < num; j++) {
|
||||
raf.writeByte(i);
|
||||
}
|
||||
}
|
||||
fp = raf.getFilePointer();
|
||||
raf.seek(index);
|
||||
raf.writeShort((block_size) & 0xFFFF);
|
||||
raf.seek(fp);
|
||||
|
||||
/* Whether alias list exists or not. */
|
||||
Map<String,String> a = map.getAliases();
|
||||
if (a == null) {
|
||||
Main.panic("Data not exist. (aliases)");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Output ID list. */
|
||||
raf.writeByte(ZoneInfoFile.TAG_ZoneAliases);
|
||||
index += 3 + block_size;
|
||||
block_size = 2;
|
||||
raf.writeShort(block_size & 0xFFFF);
|
||||
raf.writeShort(a.size() & 0xFFFF);
|
||||
for (String key : a.keySet()) {
|
||||
String alias = a.get(key);
|
||||
byte key_size = (byte)key.length();
|
||||
byte alias_size = (byte)alias.length();
|
||||
raf.writeByte(key_size & 0xFF);
|
||||
raf.write(key.getBytes("UTF-8"), 0, key_size);
|
||||
raf.writeByte(alias_size & 0xFF);
|
||||
raf.write(alias.getBytes("UTF-8"), 0, alias_size);
|
||||
block_size += 2 + key_size + alias_size;
|
||||
}
|
||||
fp = raf.getFilePointer();
|
||||
raf.seek(index);
|
||||
raf.writeShort((block_size) & 0xFFFF);
|
||||
raf.seek(fp);
|
||||
|
||||
/* Output the exclude list if it exists. */
|
||||
List<String> excludedZones = map.getExcludeList();
|
||||
if (excludedZones != null) {
|
||||
raf.writeByte(ZoneInfoFile.TAG_ExcludedZones);
|
||||
index += 3 + block_size;
|
||||
block_size = 2;
|
||||
raf.writeShort(block_size & 0xFFFF); // place holder
|
||||
raf.writeShort(excludedZones.size()); // the number of excluded zones
|
||||
for (String name : excludedZones) {
|
||||
byte size = (byte) name.length();
|
||||
raf.writeByte(size); // byte length
|
||||
raf.write(name.getBytes("UTF-8"), 0, size); // zone name
|
||||
block_size += 1 + size;
|
||||
}
|
||||
fp = raf.getFilePointer();
|
||||
raf.seek(index);
|
||||
raf.writeShort(block_size & 0xFFFF);
|
||||
raf.seek(fp);
|
||||
}
|
||||
|
||||
/* Close ZoneInfoMapping file. */
|
||||
raf.close();
|
||||
} catch(IOException e) {
|
||||
Main.panic("IO error: "+e.getMessage());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,781 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2011, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
import sun.util.calendar.ZoneInfoFile;
|
||||
|
||||
/**
|
||||
* <code>GenDoc</code> is one of back-end classes of javazic, and generates
|
||||
* index.html and other html files which prints the detailed time zone
|
||||
* information for each zone.
|
||||
*/
|
||||
class GenDoc extends BackEnd {
|
||||
|
||||
private static final String docDir = "doc";
|
||||
|
||||
private static final String header1 =
|
||||
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"" +
|
||||
"\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" +
|
||||
"<HTML>\n<HEAD>\n<!-- Generated by javazic on ";
|
||||
private static final String header2 =
|
||||
"-->\n<TITLE>\n" +
|
||||
"Java Platform, Standard Edition - TimeZone information based on ";
|
||||
private static final String header3 =
|
||||
"-->\n<TITLE>\n" +
|
||||
"Java Platform, Standard Edition TimeZone - ";
|
||||
private static final String header4 =
|
||||
"</TITLE>\n" +
|
||||
"</HEAD>\n\n";
|
||||
|
||||
private static final String body1 =
|
||||
"<BODY BGCOLOR=\"white\">\n";
|
||||
private static final String body2 =
|
||||
"</BODY>\n";
|
||||
|
||||
private static final String footer =
|
||||
"</HTML>\n";
|
||||
|
||||
|
||||
// list of time zone name and zonefile name/real time zone name
|
||||
// e.g.
|
||||
// key (String) : value (String)
|
||||
// "America/Denver" : "America/Denver.html" (real time zone)
|
||||
// "America/Shiprock" : "America/Denver" (alias)
|
||||
TreeMap<String,String> timezoneList = new TreeMap<String,String>();
|
||||
|
||||
// list of time zone's display name and time zone name
|
||||
// e.g.
|
||||
// key (String) : value (String)
|
||||
// "Tokyo, Asia" : "Asia/Tokyo"
|
||||
// "Marengo, Indiana, America" : "America/Indiana/Marengo"
|
||||
// (aliases included)
|
||||
TreeMap<String,String> displayNameList = new TreeMap<String,String>();
|
||||
|
||||
// list of top level regions
|
||||
// e.g.
|
||||
// key (String) : value (String)
|
||||
// "America" : "America.html"
|
||||
// (including entries in America/Indiana/, America/Kentucky/, ...)
|
||||
TreeMap<String,String> regionList = new TreeMap<String,String>();
|
||||
|
||||
// mapping list from zone name to latitude & longitude
|
||||
// This list is generated from zone.tab.
|
||||
// e.g.
|
||||
// key (String) : value (LatitudeAndLongitude object)
|
||||
// "Asia/Tokyo" : latitude=35.3916, longitude=13.9444
|
||||
// (aliases not included)
|
||||
HashMap<String,LatitudeAndLongitude> mapList = null;
|
||||
|
||||
// SortedMap of zone IDs sorted by their GMT offsets. If zone's GMT
|
||||
// offset will change in the future, its last known offset is
|
||||
// used.
|
||||
SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<Integer, Set<String>>();
|
||||
|
||||
/**
|
||||
* Generates HTML document for each zone.
|
||||
* @param Timezone
|
||||
* @return 0 if no errors, or 1 if error occurred.
|
||||
*/
|
||||
int processZoneinfo(Timezone tz) {
|
||||
try {
|
||||
int size;
|
||||
int index;
|
||||
String outputDir = Main.getOutputDir();
|
||||
String zonename = tz.getName();
|
||||
String zonefile = ZoneInfoFile.getFileName(zonename) + ".html";
|
||||
List<RuleRec> stz = tz.getLastRules();
|
||||
timezoneList.put(zonename, zonefile);
|
||||
displayNameList.put(transform(zonename), zonename);
|
||||
|
||||
// Populate zonesByOffset. (Zones that will change their
|
||||
// GMT offsets are also added to zonesByOffset here.)
|
||||
int lastKnownOffset = tz.getRawOffset();
|
||||
Set<String> set = zonesByOffset.get(lastKnownOffset);
|
||||
if (set == null) {
|
||||
set = new TreeSet<String>();
|
||||
zonesByOffset.put(lastKnownOffset, set);
|
||||
}
|
||||
set.add(zonename);
|
||||
|
||||
/* If outputDir doesn't end with file-separator, adds it. */
|
||||
if (!outputDir.endsWith(File.separator)) {
|
||||
outputDir += File.separatorChar;
|
||||
}
|
||||
outputDir += docDir + File.separatorChar;
|
||||
|
||||
index = zonename.indexOf('/');
|
||||
if (index != -1) {
|
||||
regionList.put(zonename.substring(0, index),
|
||||
zonename.substring(0, index) + ".html");
|
||||
}
|
||||
|
||||
/* If zonefile includes file-separator, it's treated as part of
|
||||
* pathname. And make directory if necessary.
|
||||
*/
|
||||
index = zonefile.lastIndexOf('/');
|
||||
if (index != -1) {
|
||||
zonefile.replace('/', File.separatorChar);
|
||||
outputDir += zonefile.substring(0, index+1);
|
||||
}
|
||||
File outD = new File(outputDir);
|
||||
outD.mkdirs();
|
||||
|
||||
/* If mapfile is available, add a link to the appropriate map */
|
||||
if ((mapList == null) && (Main.getMapFile() != null)) {
|
||||
FileReader fr = new FileReader(Main.getMapFile());
|
||||
BufferedReader in = new BufferedReader(fr);
|
||||
mapList = new HashMap<String,LatitudeAndLongitude>();
|
||||
String line;
|
||||
while ((line = in.readLine()) != null) {
|
||||
// skip blank and comment lines
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
StringTokenizer tokens = new StringTokenizer(line);
|
||||
String token = tokens.nextToken(); /* We don't use the first token. */
|
||||
token = tokens.nextToken();
|
||||
LatitudeAndLongitude location = new LatitudeAndLongitude(token);
|
||||
token = tokens.nextToken();
|
||||
mapList.put(token, location);
|
||||
}
|
||||
in.close();
|
||||
}
|
||||
|
||||
/* Open zoneinfo file to write. */
|
||||
FileWriter fw = new FileWriter(outputDir + zonefile.substring(index+1));
|
||||
BufferedWriter out = new BufferedWriter(fw);
|
||||
|
||||
out.write(header1 + new Date() + header3 + zonename + header4);
|
||||
out.write(body1 + "<FONT size=\"+2\"><B>" + zonename + "</B></FONT>");
|
||||
LatitudeAndLongitude location = mapList.get(zonename);
|
||||
if (location != null) {
|
||||
int deg, min, sec;
|
||||
|
||||
deg = location.getLatDeg();
|
||||
min = location.getLatMin();
|
||||
sec = location.getLatSec();
|
||||
if (deg < 0) {
|
||||
min = -min;
|
||||
sec = -sec;
|
||||
} else if (min < 0) {
|
||||
sec = -sec;
|
||||
}
|
||||
out.write(" " +
|
||||
"<A HREF=\"http://www.mapquest.com/maps/map.adp?" +
|
||||
"latlongtype=degrees" +
|
||||
"&latdeg=" + deg +
|
||||
"&latmin=" + min +
|
||||
"&latsec=" + sec);
|
||||
|
||||
deg = location.getLongDeg();
|
||||
min = location.getLongMin();
|
||||
sec = location.getLongSec();
|
||||
if (deg < 0) {
|
||||
min = -min;
|
||||
sec = -sec;
|
||||
} else if (min < 0) {
|
||||
sec = -sec;
|
||||
}
|
||||
out.write("&longdeg=" + deg +
|
||||
"&longmin=" + min +
|
||||
"&longsec=" + sec +
|
||||
"\" target=\"_blank\">[map]</A>");
|
||||
}
|
||||
out.write("\n<P>\n");
|
||||
|
||||
List<ZoneRec> zone = tz.getZones();
|
||||
List<RuleRec> rule = tz.getRules();
|
||||
if (rule != null && zone != null) {
|
||||
out.write("<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">\n" +
|
||||
"<TR>\n" +
|
||||
"<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\"><BR>" +
|
||||
"<A HREF=\"#Rules\">Rules</A><BR></TD>\n" +
|
||||
"<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\">" +
|
||||
"<A HREF=\"#Zone\"><BR>Zone<BR></A></TD>\n" +
|
||||
"</TR>\n</TABLE>\n");
|
||||
}
|
||||
|
||||
/* Output Rule records. */
|
||||
if (rule != null) {
|
||||
size = rule.size();
|
||||
out.write("<P>\n<A NAME=\"Rules\">" +
|
||||
"<FONT SIZE=\"+1\"><B>Rules</B></FONT></A>\n" +
|
||||
"<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
|
||||
"<TR BGCOLOR=\"#CCCCFF\">\n" +
|
||||
"<TD>NAME</TD><TD>FROM</TD><TD>TO</TD><TD>TYPE</TD>" +
|
||||
"<TD>IN</TD><TD>ON</TD><TD>AT</TD><TD>SAVE</TD>" +
|
||||
"<TD>LETTER/S</TD><TD>NOTES</TD>\n</TR>\n");
|
||||
for (int i = 0; i < size; i++) {
|
||||
out.write("<TR BGCOLOR=\"#FFFFFF\">\n");
|
||||
StringTokenizer st = new StringTokenizer(rule.get(i).getLine());
|
||||
String s;
|
||||
if (st.hasMoreTokens()) { /* RULE - truncated */
|
||||
st.nextToken();
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* NAME */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* FROM */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* TO */
|
||||
s = st.nextToken();
|
||||
if (s.equals("min") || s.equals("max")) {
|
||||
out.write("<TD><FONT COLOR=\"red\">" + s + "</FONT></TD>");
|
||||
} else {
|
||||
out.write("<TD>" + s + "</TD>");
|
||||
}
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* TYPE */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* IN */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* ON */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* AT */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* SAVE */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* LETTER/S */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* NOTES */
|
||||
s = st.nextToken();
|
||||
while (st.hasMoreTokens()) {
|
||||
s += " " + st.nextToken();
|
||||
}
|
||||
index = s.indexOf('#');
|
||||
out.write("<TD>" + s.substring(index+1) + "</TD>\n");
|
||||
} else {
|
||||
out.write("<TD> </TD>\n");
|
||||
}
|
||||
out.write("</TR>\n");
|
||||
}
|
||||
out.write("</TABLE>\n<P> <P>\n");
|
||||
}
|
||||
|
||||
/* Output Zone records. */
|
||||
if (zone != null) {
|
||||
size = zone.size();
|
||||
out.write("<P>\n<A NAME=\"Zone\">" +
|
||||
"<FONT SIZE=\"+1\"><B>Zone</B></FONT></A>\n" +
|
||||
"<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
|
||||
"<TR BGCOLOR=\"#CCCCFF\">\n<TD>GMTOFF</TD>" +
|
||||
"<TD>RULES</TD><TD>FORMAT</TD><TD>UNTIL</TD>" +
|
||||
"<TD>NOTES</TD>\n</TR>\n");
|
||||
for (int i = 0; i < size; i++) {
|
||||
out.write("<TR>\n");
|
||||
StringTokenizer st = new StringTokenizer(zone.get(i).getLine());
|
||||
String s = st.nextToken();
|
||||
if (s.equals("Zone")) { /* NAME */
|
||||
s = st.nextToken();
|
||||
s = st.nextToken();
|
||||
}
|
||||
out.write("<TD>" + s + "</TD>"); /* GMTOFFSET */
|
||||
if (st.hasMoreTokens()) { /* RULES */
|
||||
out.write("<TD>" + st.nextToken() + "</TD>");
|
||||
}
|
||||
if (st.hasMoreTokens()) { /* FORMAT */
|
||||
s = st.nextToken();
|
||||
index = s.indexOf('#');
|
||||
if (index != -1) {
|
||||
if (index != 0) {
|
||||
out.write("<TD>" + s.substring(0, index-1) +
|
||||
"</TD>"); /* FORMAT */
|
||||
s = s.substring(index+1);
|
||||
} else {
|
||||
out.write("<TD> </TD>"); /* FORMAT */
|
||||
}
|
||||
while (st.hasMoreTokens()) {
|
||||
s += " " + st.nextToken();
|
||||
}
|
||||
out.write("<TD> </TD>"); /* UNTIL */
|
||||
out.write("<TD>" + s + "</TD>\n</TR>\n"); /* NOTES */
|
||||
continue;
|
||||
} else {
|
||||
out.write("<TD>" + s + "</TD>"); /* FORMAT */
|
||||
}
|
||||
}
|
||||
|
||||
if (st.hasMoreTokens()) { /* UNTIL */
|
||||
s = st.nextToken();
|
||||
while (st.hasMoreTokens()) {
|
||||
s += " " + st.nextToken();
|
||||
}
|
||||
index = s.indexOf('#');
|
||||
if (index != -1) {
|
||||
if (index != 0) {
|
||||
out.write("<TD>" + s.substring(0, index-1) +
|
||||
"</TD>"); /* UNTIL */
|
||||
} else {
|
||||
out.write("<TD> </TD>"); /* UNTIL */
|
||||
}
|
||||
out.write("<TD>" + s.substring(index+1) +
|
||||
"</TD>\n"); /* NOTES */
|
||||
} else {
|
||||
out.write("<TD>" + s + "</TD>"); /* UNTIL */
|
||||
out.write("<TD> </TD>\n"); /* NOTES */
|
||||
}
|
||||
} else {
|
||||
out.write("<TD> </TD>"); /* UNTIL */
|
||||
out.write("<TD> </TD>\n"); /* NOTES */
|
||||
}
|
||||
out.write("</TR>\n");
|
||||
}
|
||||
out.write("</TABLE>\n");
|
||||
}
|
||||
out.write(body2 + footer);
|
||||
|
||||
out.close();
|
||||
fw.close();
|
||||
} catch(IOException e) {
|
||||
Main.panic("IO error: "+e.getMessage());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates index.html and other top-level frame files.
|
||||
* @param Mappings
|
||||
* @return 0 if no errors, or 1 if error occurred.
|
||||
*/
|
||||
int generateSrc(Mappings map) {
|
||||
try {
|
||||
int len;
|
||||
Object o[];
|
||||
String outputDir = Main.getOutputDir();
|
||||
FileWriter fw1, fw2;
|
||||
BufferedWriter out1, out2;
|
||||
|
||||
/* Whether alias list exists or not. */
|
||||
Map<String,String> a = map.getAliases();
|
||||
if (a == null) {
|
||||
Main.panic("Data not exist. (aliases)");
|
||||
return 1;
|
||||
}
|
||||
|
||||
timezoneList.putAll(a);
|
||||
|
||||
/* If outputDir doesn't end with file-separator, adds it. */
|
||||
if (!outputDir.endsWith(File.separator)) {
|
||||
outputDir += File.separatorChar;
|
||||
}
|
||||
outputDir += docDir + File.separatorChar;
|
||||
|
||||
File outD = new File(outputDir);
|
||||
outD.mkdirs();
|
||||
|
||||
/* Creates index.html */
|
||||
fw1 = new FileWriter(outputDir + "index.html", false);
|
||||
out1 = new BufferedWriter(fw1);
|
||||
|
||||
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
||||
header4 +
|
||||
"<FRAMESET cols=\"20%,80%\">\n" +
|
||||
"<FRAMESET rows=\"30%,70%\">\n" +
|
||||
"<FRAME src=\"overview-frame.html\" name=\"TimeZoneListFrame\">\n" +
|
||||
"<FRAME src=\"allTimeZone-frame1.html\" name=\"allTimeZoneFrame\">\n" +
|
||||
"</FRAMESET>" +
|
||||
"<FRAME src=\"overview-summary.html\" name=\"rightFrame\">\n" +
|
||||
"</FRAMESET>\n" +
|
||||
"<NOFRAMES>\n" +
|
||||
"<H2>\nFrame Alert\n</H2>\n\n" +
|
||||
"<P>\n\n" +
|
||||
"This document is designed to be viewed using the frames feature. If you see this\n" +
|
||||
"message, you are using a non-frame-capable web client.\n" +
|
||||
"<BR>\n" +
|
||||
"Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n" +
|
||||
"</NOFRAMES>\n" + footer);
|
||||
|
||||
out1.close();
|
||||
fw1.close();
|
||||
|
||||
|
||||
/* Creates overview-frame.html */
|
||||
fw1 = new FileWriter(outputDir + "overview-frame.html", false);
|
||||
out1 = new BufferedWriter(fw1);
|
||||
|
||||
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
||||
header4 + body1 +
|
||||
"<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n" +
|
||||
"<TD NOWRAP><FONT size=\"+1\">\n" +
|
||||
"<B>Java<sup><font size=-2>TM</font></sup> Platform<br>Standard Ed.</B></FONT></TD>\n" +
|
||||
"</TR>\n</TABLE>\n\n" +
|
||||
"<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n<TD NOWRAP>" +
|
||||
"<P>\n<FONT size=\"+1\">\nAll Time Zones Sorted By:</FONT>\n<BR>\n" +
|
||||
" <A HREF=\"allTimeZone-frame1.html\" TARGET=\"allTimeZoneFrame\">GMT offsets</A></FONT>\n<BR>\n" +
|
||||
" <A HREF=\"allTimeZone-frame2.html\" TARGET=\"allTimeZoneFrame\">Zone names</A></FONT>\n<BR>" +
|
||||
" <A HREF=\"allTimeZone-frame3.html\" TARGET=\"allTimeZoneFrame\">City names</A></FONT>\n" +
|
||||
"<P>\n<FONT size=\"+1\">\nContinents and Oceans</FONT>\n<BR>\n");
|
||||
|
||||
for (String regionKey : regionList.keySet()) {
|
||||
out1.write(" <A HREF=\"" + regionList.get(regionKey) +
|
||||
"\" TARGET=\"allTimeZoneFrame\">" + regionKey +
|
||||
"</A><BR>\n");
|
||||
|
||||
fw2 = new FileWriter(outputDir + regionList.get(regionKey),
|
||||
false);
|
||||
out2 = new BufferedWriter(fw2);
|
||||
|
||||
out2.write(header1 + new Date() + header3 + regionKey +
|
||||
header4 + body1 + "<FONT size=\"+1\"><B>" +
|
||||
regionKey + "</B></FONT>\n<BR>\n<TABLE>\n<TR>\n<TD>");
|
||||
|
||||
boolean found = false;
|
||||
for (String timezoneKey : timezoneList.keySet()) {
|
||||
int regionIndex = timezoneKey.indexOf('/');
|
||||
if (regionIndex == -1 ||
|
||||
!regionKey.equals(timezoneKey.substring(0, regionIndex))) {
|
||||
if (found) {
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
found = true;
|
||||
if (a.containsKey(timezoneKey)) {
|
||||
Object realName = a.get(timezoneKey);
|
||||
while (a.containsKey(realName)) {
|
||||
realName = a.get(realName);
|
||||
}
|
||||
out2.write(timezoneKey +
|
||||
" (alias for " + "<A HREF=\"" +
|
||||
timezoneList.get(realName) +
|
||||
"\" TARGET=\"rightFrame\">" +
|
||||
realName + "</A>)");
|
||||
} else {
|
||||
out2.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
||||
"\" TARGET=\"rightFrame\">" + timezoneKey +
|
||||
"</A>");
|
||||
}
|
||||
out2.write("<BR>\n");
|
||||
}
|
||||
out2.write("</TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
||||
|
||||
out2.close();
|
||||
fw2.close();
|
||||
}
|
||||
out1.write("</FONT></TD>\n</TR></TABLE>\n" + body2 + footer);
|
||||
|
||||
out1.close();
|
||||
fw1.close();
|
||||
|
||||
|
||||
/* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */
|
||||
fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html", false);
|
||||
out1 = new BufferedWriter(fw1);
|
||||
|
||||
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
||||
header4 + body1 +
|
||||
"<FONT size=\"+1\"><B>Sorted by GMT offsets</B></FONT>\n" +
|
||||
"<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
|
||||
"<TR>\n<TD NOWRAP>\n");
|
||||
|
||||
List<Integer> roi = map.getRawOffsetsIndex();
|
||||
List<Set<String>> roit = map.getRawOffsetsIndexTable();
|
||||
|
||||
int index = 0;
|
||||
for (Integer offset : zonesByOffset.keySet()) {
|
||||
int off = roi.get(index);
|
||||
Set<String> perRO = zonesByOffset.get(offset);
|
||||
if (offset == off) {
|
||||
// Merge aliases into zonesByOffset
|
||||
perRO.addAll(roit.get(index));
|
||||
}
|
||||
index++;
|
||||
|
||||
for (String timezoneKey : perRO) {
|
||||
out1.write("<TR>\n<TD><FONT SIZE=\"-1\">(" +
|
||||
Time.toGMTFormat(offset.toString()) +
|
||||
")</FONT></TD>\n<TD>");
|
||||
|
||||
if (a.containsKey(timezoneKey)) {
|
||||
Object realName = a.get(timezoneKey);
|
||||
while (a.containsKey(realName)) {
|
||||
realName = a.get(realName);
|
||||
}
|
||||
out1.write(timezoneKey +
|
||||
" (alias for " + "<A HREF=\"" +
|
||||
timezoneList.get(realName) +
|
||||
"\" TARGET=\"rightFrame\">" + realName +
|
||||
"</A>)");
|
||||
} else {
|
||||
out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
||||
"\" TARGET=\"rightFrame\">" + timezoneKey +
|
||||
"</A>");
|
||||
}
|
||||
out1.write("</TD>\n</TR>\n");
|
||||
}
|
||||
}
|
||||
out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
||||
|
||||
out1.close();
|
||||
fw1.close();
|
||||
|
||||
|
||||
/* Creates allTimeZone-frame2.html (Sorted by zone names) */
|
||||
fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html", false);
|
||||
out1 = new BufferedWriter(fw1);
|
||||
|
||||
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
||||
header4 + body1 +
|
||||
"<FONT size=\"+1\"><B>Sorted by zone names</B></FONT>\n" +
|
||||
"<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
|
||||
"<TR>\n<TD NOWRAP>\n");
|
||||
o = timezoneList.keySet().toArray();
|
||||
len = timezoneList.size();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object timezoneKey = o[i];
|
||||
if (a.containsKey(timezoneKey)) {
|
||||
Object realName = a.get(timezoneKey);
|
||||
while (a.containsKey(realName)) {
|
||||
realName = a.get(realName);
|
||||
}
|
||||
out1.write(timezoneKey +
|
||||
" (alias for " +
|
||||
"<A HREF=\"" + timezoneList.get(realName) +
|
||||
"\" TARGET=\"rightFrame\">" + realName +
|
||||
"</A>)");
|
||||
} else {
|
||||
out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
||||
"\" TARGET=\"rightFrame\">" + timezoneKey +
|
||||
"</A>");
|
||||
}
|
||||
out1.write("<BR> \n");
|
||||
}
|
||||
out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
||||
|
||||
out1.close();
|
||||
fw1.close();
|
||||
|
||||
/* Creates allTimeZone-frame3.html (Sorted by city names) */
|
||||
fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html", false);
|
||||
out1 = new BufferedWriter(fw1);
|
||||
|
||||
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
||||
header4 + body1 +
|
||||
"<FONT size=\"+1\"><B>Sorted by city names</B></FONT>\n" +
|
||||
"<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
|
||||
"<TR>\n<TD NOWRAP>\n");
|
||||
|
||||
Set<String> aliasSet = a.keySet();
|
||||
len = aliasSet.size();
|
||||
String aliasNames[] = aliasSet.toArray(new String[0]);
|
||||
for (int i = 0; i < len; i++) {
|
||||
displayNameList.put(transform(aliasNames[i]),
|
||||
aliasNames[i]);
|
||||
}
|
||||
|
||||
o = displayNameList.keySet().toArray();
|
||||
len = displayNameList.size();
|
||||
for (int i = 0; i < len; i++) {
|
||||
Object displayName = o[i];
|
||||
Object timezoneKey = displayNameList.get(o[i]);
|
||||
if (a.containsKey(timezoneKey)) {
|
||||
Object realName = a.get(timezoneKey);
|
||||
while (a.containsKey(realName)) {
|
||||
realName = a.get(realName);
|
||||
}
|
||||
out1.write(displayName +
|
||||
" (alias for " +
|
||||
"<A HREF=\"" + timezoneList.get(realName) +
|
||||
"\" TARGET=\"rightFrame\">" + realName +
|
||||
"</A>)");
|
||||
} else {
|
||||
out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
||||
"\" TARGET=\"rightFrame\">" + displayName +
|
||||
"</A>");
|
||||
}
|
||||
out1.write("<BR> \n");
|
||||
}
|
||||
|
||||
out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
||||
|
||||
out1.close();
|
||||
fw1.close();
|
||||
|
||||
/* Creates overview-summary.html */
|
||||
fw1 = new FileWriter(outputDir + "overview-summary.html", false);
|
||||
out1 = new BufferedWriter(fw1);
|
||||
|
||||
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
||||
header4 + body1 +
|
||||
"<p>This is the list of time zones generated from <B>" +
|
||||
Main.getVersionName() + "</B> for Java Platform, " +
|
||||
"Standard Edition. The source code can be obtained " +
|
||||
"from ftp site <a href=\"ftp://elsie.nci.nih.gov/pub/\">" +
|
||||
"ftp://elsie.nci.nih.gov/pub/</a>. A total of <B>" +
|
||||
len +
|
||||
"</B> time zones and aliases are supported " +
|
||||
"in this edition. For the " +
|
||||
"format of rules and zones, refer to the zic " +
|
||||
"(zoneinfo compiler) man page on " +
|
||||
"Solaris or Linux.</p>\n" +
|
||||
"<p>Note that the time zone data is not " +
|
||||
"a public interface of the Java Platform. No " +
|
||||
"applications should rely on the time zone data of " +
|
||||
"this document. Time zone names and data " +
|
||||
"may change without any prior notice.</p>\n" +
|
||||
body2 + footer);
|
||||
|
||||
out1.close();
|
||||
fw1.close();
|
||||
} catch(IOException e) {
|
||||
Main.panic("IO error: "+e.getMessage());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
String transform(String s) {
|
||||
int index = s.lastIndexOf("/");
|
||||
|
||||
/* If the string doesn't include any delimiter, return */
|
||||
if (index == -1) {
|
||||
return s;
|
||||
}
|
||||
|
||||
int lastIndex = index;
|
||||
String str = s.substring(index+1);
|
||||
do {
|
||||
index = s.substring(0, lastIndex).lastIndexOf('/');
|
||||
str += ", " + s.substring(index+1, lastIndex);
|
||||
lastIndex = index;
|
||||
} while (index > -1);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
static class LatitudeAndLongitude {
|
||||
|
||||
private int latDeg, latMin, latSec, longDeg, longMin, longSec;
|
||||
|
||||
LatitudeAndLongitude(String s) {
|
||||
try {
|
||||
// First of all, check the string has the correct format:
|
||||
// either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS
|
||||
|
||||
if (!s.startsWith("+") && !s.startsWith("-")) {
|
||||
Main.warning("Wrong latitude&longitude data: " + s);
|
||||
return;
|
||||
}
|
||||
int index;
|
||||
if (((index = s.lastIndexOf("+")) <= 0) &&
|
||||
((index = s.lastIndexOf("-")) <= 0)) {
|
||||
Main.warning("Wrong latitude&longitude data: " + s);
|
||||
return;
|
||||
}
|
||||
|
||||
if (index == 5) {
|
||||
latDeg = Integer.parseInt(s.substring(1, 3));
|
||||
latMin = Integer.parseInt(s.substring(3, 5));
|
||||
latSec = 0;
|
||||
} else if (index == 7) {
|
||||
latDeg = Integer.parseInt(s.substring(1, 3));
|
||||
latMin = Integer.parseInt(s.substring(3, 5));
|
||||
latSec = Integer.parseInt(s.substring(5, 7));
|
||||
} else {
|
||||
Main.warning("Wrong latitude&longitude data: " + s);
|
||||
return;
|
||||
}
|
||||
if (s.startsWith("-")){
|
||||
latDeg = -latDeg;
|
||||
latMin = -latMin;
|
||||
latSec = -latSec;
|
||||
}
|
||||
|
||||
int len = s.length();
|
||||
if (index == 5 && len == 11) {
|
||||
longDeg = Integer.parseInt(s.substring(index+1, index+4));
|
||||
longMin = Integer.parseInt(s.substring(index+4, index+6));
|
||||
longSec = 0;
|
||||
} else if (index == 7 && len == 15) {
|
||||
longDeg = Integer.parseInt(s.substring(index+1, index+4));
|
||||
longMin = Integer.parseInt(s.substring(index+4, index+6));
|
||||
longSec = Integer.parseInt(s.substring(index+6, index+8));
|
||||
} else {
|
||||
Main.warning("Wrong latitude&longitude data: " + s);
|
||||
return;
|
||||
}
|
||||
if (s.charAt(index) == '-'){
|
||||
longDeg = -longDeg;
|
||||
longMin = -longMin;
|
||||
longSec = -longSec;
|
||||
}
|
||||
} catch(Exception e) {
|
||||
Main.warning("LatitudeAndLongitude() Parse error: " + s);
|
||||
}
|
||||
}
|
||||
|
||||
int getLatDeg() {
|
||||
return latDeg;
|
||||
}
|
||||
|
||||
int getLatMin() {
|
||||
return latMin;
|
||||
}
|
||||
|
||||
int getLatSec() {
|
||||
return latSec;
|
||||
}
|
||||
|
||||
int getLongDeg() {
|
||||
return longDeg;
|
||||
}
|
||||
|
||||
int getLongMin() {
|
||||
return longMin;
|
||||
}
|
||||
|
||||
int getLongSec() {
|
||||
return longSec;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,238 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Main class for the javazic time zone data compiler.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
public class Main {
|
||||
|
||||
private static boolean verbose = false;
|
||||
static boolean outputDoc = false;
|
||||
|
||||
private List<String> ziFiles = new ArrayList<String>();
|
||||
private static String zoneNamesFile = null;
|
||||
private static String versionName = "unknown";
|
||||
private static String outputDir = "zoneinfo";
|
||||
private static String mapFile = null;
|
||||
|
||||
/**
|
||||
* Parses the specified arguments and sets up the variables.
|
||||
* @param argv the arguments
|
||||
*/
|
||||
void processArgs(String[] argv) {
|
||||
for (int i = 0; i < argv.length; i++) {
|
||||
String arg = argv[i];
|
||||
if (arg.startsWith("-h")) {
|
||||
usage();
|
||||
System.exit(0);
|
||||
} else if (arg.equals("-d")) {
|
||||
outputDir = argv[++i];
|
||||
} else if (arg.equals("-v")) {
|
||||
verbose = true;
|
||||
} else if (arg.equals("-V")) {
|
||||
versionName = argv[++i];
|
||||
} else if (arg.equals("-doc")) {
|
||||
outputDoc = true;
|
||||
} else if (arg.equals("-map")) {
|
||||
outputDoc = true;
|
||||
mapFile = argv[++i];
|
||||
} else if (arg.equals("-f")) {
|
||||
zoneNamesFile = argv[++i];
|
||||
} else if (arg.equals("-S")) {
|
||||
try {
|
||||
Zoneinfo.setYear(Integer.parseInt(argv[++i]));
|
||||
} catch (Exception e) {
|
||||
error("invalid year: " + argv[i]);
|
||||
usage();
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
boolean isStartYear = arg.equals("-s");
|
||||
if (isStartYear || arg.equals("-e")) {
|
||||
try {
|
||||
int year = Integer.parseInt(argv[++i]);
|
||||
if (isStartYear) {
|
||||
Zoneinfo.setStartYear(year);
|
||||
} else {
|
||||
Zoneinfo.setEndYear(year);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error("invalid year: " + argv[i]);
|
||||
usage();
|
||||
System.exit(1);
|
||||
}
|
||||
} else {
|
||||
// the rest of args are zoneinfo source files
|
||||
while (i < argv.length) {
|
||||
ziFiles.add(argv[i++]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses zoneinfo source files
|
||||
*/
|
||||
int compile() {
|
||||
int nFiles = ziFiles.size();
|
||||
int status = 0;
|
||||
Mappings maps = new Mappings();
|
||||
BackEnd backend = BackEnd.getBackEnd();
|
||||
|
||||
for (int i = 0; i < nFiles; i++) {
|
||||
Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i));
|
||||
|
||||
for (String key : frontend.getZones().keySet()) {
|
||||
info(key);
|
||||
|
||||
Timezone tz = frontend.phase2(key);
|
||||
status |= backend.processZoneinfo(tz);
|
||||
}
|
||||
|
||||
maps.add(frontend);
|
||||
}
|
||||
|
||||
// special code for dealing with the conflicting name "MET"
|
||||
Zone.addMET();
|
||||
|
||||
maps.resolve();
|
||||
|
||||
status |= backend.generateSrc(maps);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
public static void main(String[] argv) {
|
||||
Main zic = new Main();
|
||||
|
||||
/*
|
||||
* Parse args
|
||||
*/
|
||||
zic.processArgs(argv);
|
||||
|
||||
/*
|
||||
* Read target zone names
|
||||
*/
|
||||
if (zoneNamesFile != null) {
|
||||
Zone.readZoneNames(zoneNamesFile);
|
||||
}
|
||||
|
||||
int status = zic.compile();
|
||||
|
||||
System.exit(status);
|
||||
}
|
||||
|
||||
void usage() {
|
||||
System.err.println("Usage: javazic [options] file...\n"+
|
||||
" -f namefile file containing zone names\n"+
|
||||
" to be generated (ie, generating subset)\n"+
|
||||
" -d dir output directory\n"+
|
||||
" -v verbose\n"+
|
||||
" -V datavers specifies the tzdata version string\n"+
|
||||
" (eg, \"tzdata2000g\")"+
|
||||
" -S year output only SimleTimeZone data of that year\n"+
|
||||
" -s year start year (default: 1900)\n"+
|
||||
" -e year end year (default: 2037)\n"+
|
||||
" -doc generates HTML documents\n"+
|
||||
" -map mapfile generates HTML documents with map information\n"+
|
||||
" file... zoneinfo source file(s)");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the output directory path name
|
||||
*/
|
||||
static String getOutputDir() {
|
||||
return outputDir;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the map file's path and name
|
||||
*/
|
||||
static String getMapFile() {
|
||||
return mapFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time zone data version string specified by the -V
|
||||
* option. If it is not specified, "unknown" is returned.
|
||||
* @return the time zone data version string
|
||||
*/
|
||||
static String getVersionName() {
|
||||
return versionName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the specified fatal error message and calls {@link
|
||||
* java.lang.System#exit System.exit(1)}.
|
||||
* @param msg the fatal error message
|
||||
*/
|
||||
static void panic(String msg) {
|
||||
printMessage("fatal error", msg);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the specified error message.
|
||||
* @param msg the error message
|
||||
*/
|
||||
static void error(String msg) {
|
||||
printMessage("error", msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the specified warning message.
|
||||
* @param msg the warning message
|
||||
*/
|
||||
static void warning(String msg) {
|
||||
printMessage("warning", msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the informative message.
|
||||
* @param msg the informative message
|
||||
*/
|
||||
static void info(String msg) {
|
||||
if (verbose) {
|
||||
printMessage(null, msg);
|
||||
}
|
||||
}
|
||||
|
||||
private static void printMessage(String type, String msg) {
|
||||
if (type != null) {
|
||||
type += ": ";
|
||||
} else {
|
||||
type = "";
|
||||
}
|
||||
System.err.println("javazic: " + type + msg);
|
||||
}
|
||||
}
|
@ -1,197 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2012, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* <code>Mappings</code> generates two Maps and a List which are used by
|
||||
* javazic BackEnd.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class Mappings {
|
||||
// All aliases specified by Link statements. It's alias name to
|
||||
// real name mappings.
|
||||
private Map<String,String> aliases;
|
||||
|
||||
private List<Integer> rawOffsetsIndex;
|
||||
|
||||
private List<Set<String>> rawOffsetsIndexTable;
|
||||
|
||||
// Zone names to be excluded from rawOffset table. Those have GMT
|
||||
// offsets to change some future time.
|
||||
private List<String> excludeList;
|
||||
|
||||
/**
|
||||
* Constructor creates some necessary instances.
|
||||
*/
|
||||
Mappings() {
|
||||
aliases = new TreeMap<String,String>();
|
||||
rawOffsetsIndex = new LinkedList<Integer>();
|
||||
rawOffsetsIndexTable = new LinkedList<Set<String>>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates aliases and rawOffsets tables.
|
||||
* @param zi a Zoneinfo containing Zones
|
||||
*/
|
||||
void add(Zoneinfo zi) {
|
||||
Map<String,Zone> zones = zi.getZones();
|
||||
|
||||
for (String zoneName : zones.keySet()) {
|
||||
Zone zone = zones.get(zoneName);
|
||||
String zonename = zone.getName();
|
||||
int rawOffset = zone.get(zone.size()-1).getGmtOffset();
|
||||
|
||||
// If the GMT offset of this Zone will change in some
|
||||
// future time, this Zone is added to the exclude list.
|
||||
boolean isExcluded = false;
|
||||
for (int i = 0; i < zone.size(); i++) {
|
||||
ZoneRec zrec = zone.get(i);
|
||||
if ((zrec.getGmtOffset() != rawOffset)
|
||||
&& (zrec.getUntilTime(0) > Time.getCurrentTime())) {
|
||||
if (excludeList == null) {
|
||||
excludeList = new ArrayList<String>();
|
||||
}
|
||||
excludeList.add(zone.getName());
|
||||
isExcluded = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!rawOffsetsIndex.contains(new Integer(rawOffset))) {
|
||||
// Find the index to insert this raw offset zones
|
||||
int n = rawOffsetsIndex.size();
|
||||
int i;
|
||||
for (i = 0; i < n; i++) {
|
||||
if (rawOffsetsIndex.get(i) > rawOffset) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
rawOffsetsIndex.add(i, rawOffset);
|
||||
|
||||
Set<String> perRawOffset = new TreeSet<String>();
|
||||
if (!isExcluded) {
|
||||
perRawOffset.add(zonename);
|
||||
}
|
||||
rawOffsetsIndexTable.add(i, perRawOffset);
|
||||
} else if (!isExcluded) {
|
||||
int i = rawOffsetsIndex.indexOf(new Integer(rawOffset));
|
||||
Set<String> perRawOffset = rawOffsetsIndexTable.get(i);
|
||||
perRawOffset.add(zonename);
|
||||
}
|
||||
}
|
||||
|
||||
Map<String,String> a = zi.getAliases();
|
||||
// If there are time zone names which refer to any of the
|
||||
// excluded zones, add those names to the excluded list.
|
||||
if (excludeList != null) {
|
||||
for (String zoneName : a.keySet()) {
|
||||
String realname = a.get(zoneName);
|
||||
if (excludeList.contains(realname)) {
|
||||
excludeList.add(zoneName);
|
||||
}
|
||||
}
|
||||
}
|
||||
aliases.putAll(a);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds valid aliases to one of per-RawOffset table and removes
|
||||
* invalid aliases from aliases List. Aliases referring to
|
||||
* excluded zones are not added to a per-RawOffset table.
|
||||
*/
|
||||
void resolve() {
|
||||
int index = rawOffsetsIndexTable.size();
|
||||
List<String> toBeRemoved = new ArrayList<String>();
|
||||
for (String key : aliases.keySet()) {
|
||||
boolean validname = false;
|
||||
for (int j = 0; j < index; j++) {
|
||||
Set<String> perRO = rawOffsetsIndexTable.get(j);
|
||||
boolean isExcluded = (excludeList == null) ?
|
||||
false : excludeList.contains(key);
|
||||
|
||||
if ((perRO.contains(aliases.get(key)) || isExcluded)
|
||||
&& Zone.isTargetZone(key)) {
|
||||
validname = true;
|
||||
if (!isExcluded) {
|
||||
perRO.add(key);
|
||||
Main.info("Alias <"+key+"> added to the list.");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!validname) {
|
||||
Main.info("Alias <"+key+"> removed from the list.");
|
||||
toBeRemoved.add(key);
|
||||
}
|
||||
}
|
||||
|
||||
// Remove zones, if any, from the list.
|
||||
for (String key : toBeRemoved) {
|
||||
aliases.remove(key);
|
||||
}
|
||||
// Eliminate any alias-to-alias mappings. For example, if
|
||||
// there are A->B and B->C, A->B is changed to A->C.
|
||||
Map<String, String> newMap = new HashMap<String, String>();
|
||||
for (String key : aliases.keySet()) {
|
||||
String realid = aliases.get(key);
|
||||
String leaf = realid;
|
||||
while (aliases.get(leaf) != null) {
|
||||
leaf = aliases.get(leaf);
|
||||
}
|
||||
if (!realid.equals(leaf)) {
|
||||
newMap.put(key, leaf);
|
||||
}
|
||||
}
|
||||
aliases.putAll(newMap);
|
||||
}
|
||||
|
||||
Map<String,String> getAliases() {
|
||||
return(aliases);
|
||||
}
|
||||
|
||||
List<Integer> getRawOffsetsIndex() {
|
||||
return(rawOffsetsIndex);
|
||||
}
|
||||
|
||||
List<Set<String>> getRawOffsetsIndexTable() {
|
||||
return(rawOffsetsIndexTable);
|
||||
}
|
||||
|
||||
List<String> getExcludeList() {
|
||||
return excludeList;
|
||||
}
|
||||
}
|
@ -1,94 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Month enum handles month related manipulation.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
enum Month {
|
||||
JANUARY("Jan"),
|
||||
FEBRUARY("Feb"),
|
||||
MARCH("Mar"),
|
||||
APRIL("Apr"),
|
||||
MAY("May"),
|
||||
JUNE("Jun"),
|
||||
JULY("Jul"),
|
||||
AUGUST("Aug"),
|
||||
SEPTEMBER("Sep"),
|
||||
OCTOBER("Oct"),
|
||||
NOVEMBER("Nov"),
|
||||
DECEMBER("Dec");
|
||||
|
||||
private final String abbr;
|
||||
|
||||
private static final Map<String,Month> abbreviations
|
||||
= new HashMap<String,Month>(12);
|
||||
|
||||
static {
|
||||
for (Month m : Month.values()) {
|
||||
abbreviations.put(m.abbr, m);
|
||||
}
|
||||
}
|
||||
|
||||
private Month(String abbr) {
|
||||
this.abbr = abbr;
|
||||
}
|
||||
|
||||
int value() {
|
||||
return ordinal() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the specified string as a month abbreviation.
|
||||
* @param name the month abbreviation
|
||||
* @return the Month value
|
||||
*/
|
||||
static Month parse(String name) {
|
||||
Month m = abbreviations.get(name);
|
||||
if (m != null) {
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param month the nunmth number (1-based)
|
||||
* @return the month name in uppercase of the specified month
|
||||
*/
|
||||
static String toString(int month) {
|
||||
if (month >= JANUARY.value() && month <= DECEMBER.value()) {
|
||||
return "Calendar." + Month.values()[month - 1];
|
||||
}
|
||||
throw new IllegalArgumentException("wrong month number: " + month);
|
||||
}
|
||||
}
|
@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Rule manipulates Rule records.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class Rule {
|
||||
|
||||
private List<RuleRec> list;
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Constructs a Rule which consists of a Rule record list. The
|
||||
* specified name is given to this Rule.
|
||||
* @param name the Rule name
|
||||
*/
|
||||
Rule(String name) {
|
||||
this.name = name;
|
||||
list = new ArrayList<RuleRec>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Added a RuleRec to the Rule record list.
|
||||
*/
|
||||
void add(RuleRec rec) {
|
||||
list.add(rec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Rule name
|
||||
*/
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all rule records that cover the given year.
|
||||
*
|
||||
* @param year the year number for which the rule is applicable.
|
||||
* @return rules in List that are collated in time. If no rule is found, an empty
|
||||
* List is returned.
|
||||
*/
|
||||
List<RuleRec> getRules(int year) {
|
||||
List<RuleRec> rules = new ArrayList<RuleRec>(3);
|
||||
for (RuleRec rec : list) {
|
||||
if (year >= rec.getFromYear() && year <= rec.getToYear()) {
|
||||
if ((rec.isOdd() && year % 2 == 0) || (rec.isEven() && year % 2 == 1))
|
||||
continue;
|
||||
rules.add(rec);
|
||||
}
|
||||
}
|
||||
int n = rules.size();
|
||||
if (n <= 1) {
|
||||
return rules;
|
||||
}
|
||||
if (n == 2) {
|
||||
RuleRec rec1 = rules.get(0);
|
||||
RuleRec rec2 = rules.get(1);
|
||||
if (rec1.getMonthNum() > rec2.getMonthNum()) {
|
||||
rules.set(0, rec2);
|
||||
rules.set(1, rec1);
|
||||
} else if (rec1.getMonthNum() == rec2.getMonthNum()) {
|
||||
// TODO: it's not accurate to ignore time types (STD, WALL, UTC)
|
||||
long t1 = Time.getLocalTime(year, rec1.getMonth(),
|
||||
rec1.getDay(), rec1.getTime().getTime());
|
||||
long t2 = Time.getLocalTime(year, rec2.getMonth(),
|
||||
rec2.getDay(), rec2.getTime().getTime());
|
||||
if (t1 > t2) {
|
||||
rules.set(0, rec2);
|
||||
rules.set(1, rec1);
|
||||
}
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
final int y = year;
|
||||
RuleRec[] recs = new RuleRec[rules.size()];
|
||||
rules.toArray(recs);
|
||||
Arrays.sort(recs, new Comparator<RuleRec>() {
|
||||
public int compare(RuleRec r1, RuleRec r2) {
|
||||
int n = r1.getMonthNum() - r2.getMonthNum();
|
||||
if (n != 0) {
|
||||
return n;
|
||||
}
|
||||
// TODO: it's not accurate to ignore time types (STD, WALL, UTC)
|
||||
long t1 = Time.getLocalTime(y, r1.getMonth(),
|
||||
r1.getDay(), r1.getTime().getTime());
|
||||
long t2 = Time.getLocalTime(y, r2.getMonth(),
|
||||
r2.getDay(), r2.getTime().getTime());
|
||||
return (int)(t1 - t2);
|
||||
}
|
||||
public boolean equals(Object o) {
|
||||
return this == o;
|
||||
}
|
||||
});
|
||||
rules.clear();
|
||||
for (int i = 0; i < n; i++) {
|
||||
rules.add(recs[i]);
|
||||
}
|
||||
return rules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets rule records that have either "max" or cover the endYear
|
||||
* value in its DST schedule.
|
||||
*
|
||||
* @return rules that contain last DST schedule. An empty
|
||||
* ArrayList is returned if no last rules are found.
|
||||
*/
|
||||
List<RuleRec> getLastRules() {
|
||||
RuleRec start = null;
|
||||
RuleRec end = null;
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
RuleRec rec = list.get(i);
|
||||
if (rec.isLastRule()) {
|
||||
if (rec.getSave() > 0) {
|
||||
start = rec;
|
||||
} else {
|
||||
end = rec;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (start == null || end == null) {
|
||||
int endYear = Zoneinfo.getEndYear();
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
RuleRec rec = list.get(i);
|
||||
if (endYear >= rec.getFromYear() && endYear <= rec.getToYear()) {
|
||||
if (start == null && rec.getSave() > 0) {
|
||||
start = rec;
|
||||
} else {
|
||||
if (end == null && rec.getSave() == 0) {
|
||||
end = rec;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<RuleRec> r = new ArrayList<RuleRec>(2);
|
||||
if (start == null || end == null) {
|
||||
if (start != null || end != null) {
|
||||
Main.warning("found last rules for "+name+" inconsistent.");
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
r.add(start);
|
||||
r.add(end);
|
||||
return r;
|
||||
}
|
||||
}
|
@ -1,190 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2010, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* RuleDay class represents the value of the "ON" field. The day of
|
||||
* week values start from 1 following the {@link java.util.Calendar}
|
||||
* convention.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class RuleDay {
|
||||
private static final Map<String,DayOfWeek> abbreviations = new HashMap<String,DayOfWeek>(7);
|
||||
static {
|
||||
for (DayOfWeek day : DayOfWeek.values()) {
|
||||
abbreviations.put(day.getAbbr(), day);
|
||||
}
|
||||
}
|
||||
|
||||
private String dayName = null;
|
||||
private DayOfWeek dow;
|
||||
private boolean lastOne = false;
|
||||
private int soonerOrLater = 0;
|
||||
private int thanDayOfMonth; // day of month (e.g., 8 for "Sun>=8")
|
||||
|
||||
RuleDay() {
|
||||
}
|
||||
|
||||
RuleDay(int day) {
|
||||
thanDayOfMonth = day;
|
||||
}
|
||||
|
||||
int getDay() {
|
||||
return thanDayOfMonth;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the day of week value (1-based)
|
||||
*/
|
||||
int getDayOfWeekNum() {
|
||||
return dow.value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this rule day represents the last day of
|
||||
* week. (e.g., lastSun).
|
||||
*/
|
||||
boolean isLast() {
|
||||
return lastOne;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this rule day represents the day of week on or
|
||||
* later than (after) the {@link #getDay}. (e.g., Sun>=1)
|
||||
*/
|
||||
boolean isLater() {
|
||||
return soonerOrLater > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this rule day represents the day of week on or
|
||||
* earlier than (before) the {@link #getDay}. (e.g., Sun<=15)
|
||||
*/
|
||||
boolean isEarlier() {
|
||||
return soonerOrLater < 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this rule day represents an exact day.
|
||||
*/
|
||||
boolean isExact() {
|
||||
return soonerOrLater == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the "ON" field and constructs a RuleDay.
|
||||
* @param day an "ON" field string (e.g., "Sun>=1")
|
||||
* @return a RuleDay representing the given "ON" field
|
||||
*/
|
||||
static RuleDay parse(String day) {
|
||||
RuleDay d = new RuleDay();
|
||||
if (day.startsWith("last")) {
|
||||
d.lastOne = true;
|
||||
d.dayName = day.substring(4);
|
||||
d.dow = getDOW(d.dayName);
|
||||
} else {
|
||||
int index;
|
||||
if ((index = day.indexOf(">=")) != -1) {
|
||||
d.dayName = day.substring(0, index);
|
||||
d.dow = getDOW(d.dayName);
|
||||
d.soonerOrLater = 1; // greater or equal
|
||||
d.thanDayOfMonth = Integer.parseInt(day.substring(index+2));
|
||||
} else if ((index = day.indexOf("<=")) != -1) {
|
||||
d.dayName = day.substring(0, index);
|
||||
d.dow = getDOW(d.dayName);
|
||||
d.soonerOrLater = -1; // less or equal
|
||||
d.thanDayOfMonth = Integer.parseInt(day.substring(index+2));
|
||||
} else {
|
||||
// it should be an integer value.
|
||||
d.thanDayOfMonth = Integer.parseInt(day);
|
||||
}
|
||||
}
|
||||
return d;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this RuleDay to the SimpleTimeZone day rule.
|
||||
* @return the converted SimpleTimeZone day rule
|
||||
*/
|
||||
int getDayForSimpleTimeZone() {
|
||||
if (isLast()) {
|
||||
return -1;
|
||||
}
|
||||
return isEarlier() ? -getDay() : getDay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts this RuleDay to the SimpleTimeZone day-of-week rule.
|
||||
* @return the SimpleTimeZone day-of-week rule value
|
||||
*/
|
||||
int getDayOfWeekForSimpleTimeZoneInt() {
|
||||
if (isEarlier() || isLater()) {
|
||||
return -getDayOfWeekNum();
|
||||
}
|
||||
return isLast() ? getDayOfWeekNum() : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the string representation of the {@link
|
||||
* #getDayOfWeekForSimpleTimeZoneInt} value
|
||||
*/
|
||||
String getDayOfWeekForSimpleTimeZone() {
|
||||
int d = getDayOfWeekForSimpleTimeZoneInt();
|
||||
if (d == 0) {
|
||||
return "0";
|
||||
}
|
||||
String sign = "";
|
||||
if (d < 0) {
|
||||
sign = "-";
|
||||
d = -d;
|
||||
}
|
||||
return sign + toString(d);
|
||||
}
|
||||
|
||||
private static DayOfWeek getDOW(String abbr) {
|
||||
return abbreviations.get(abbr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the specified day of week value to the day-of-week
|
||||
* name defined in {@link java.util.Calenda}.
|
||||
* @param dow 1-based day of week value
|
||||
* @return the Calendar day of week name with "Calendar." prefix.
|
||||
* @throws IllegalArgumentException if the specified dow value is out of range.
|
||||
*/
|
||||
static String toString(int dow) {
|
||||
if (dow >= DayOfWeek.SUNDAY.value() && dow <= DayOfWeek.SATURDAY.value()) {
|
||||
return "Calendar." + DayOfWeek.values()[dow - 1];
|
||||
}
|
||||
throw new IllegalArgumentException("wrong Day_of_Week number: " + dow);
|
||||
}
|
||||
}
|
@ -1,232 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* RuleRec class represents one record of the Rule set.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class RuleRec {
|
||||
private int fromYear;
|
||||
private int toYear;
|
||||
private String type;
|
||||
private Month inMonth;
|
||||
private RuleDay onDay;
|
||||
private Time atTime;
|
||||
private int save;
|
||||
private String letters;
|
||||
private String line;
|
||||
private boolean isLastRule;
|
||||
|
||||
int getFromYear() {
|
||||
return fromYear;
|
||||
}
|
||||
|
||||
int getToYear() {
|
||||
return toYear;
|
||||
}
|
||||
|
||||
Month getMonth() {
|
||||
return inMonth;
|
||||
}
|
||||
|
||||
int getMonthNum() {
|
||||
return inMonth.value();
|
||||
}
|
||||
|
||||
RuleDay getDay() {
|
||||
return onDay;
|
||||
}
|
||||
|
||||
Time getTime() {
|
||||
return atTime;
|
||||
}
|
||||
|
||||
int getSave() {
|
||||
return save;
|
||||
}
|
||||
|
||||
String getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the line from the text file.
|
||||
* @param line the text of the line
|
||||
*/
|
||||
void setLine(String line) {
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the rule type is "odd".
|
||||
*/
|
||||
boolean isOdd() {
|
||||
return "odd".equals(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the rule type is "even".
|
||||
*/
|
||||
boolean isEven() {
|
||||
return "even".equals(type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if this rule record is the last DST schedule rule.
|
||||
*
|
||||
* @return true if this rule record has "max" as TO (year).
|
||||
*/
|
||||
boolean isLastRule() {
|
||||
return isLastRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the unadjusted until time of the specified ZoneRec
|
||||
* is the same as the transition time of this rule in the same
|
||||
* year as the ZoneRec until year.
|
||||
*
|
||||
* @param zrec ZoneRec to compare to
|
||||
* @param save the amount of daylight saving in milliseconds
|
||||
* @param gmtOffset the GMT offset value in milliseconds
|
||||
* @return true if the unadjusted until time is the same as rule's
|
||||
* transition time.
|
||||
*/
|
||||
boolean isSameTransition(ZoneRec zrec, int save, int gmtOffset) {
|
||||
long until, transition;
|
||||
|
||||
if (zrec.getUntilTime().getType() != atTime.getType()) {
|
||||
until = zrec.getLocalUntilTime(save, gmtOffset);
|
||||
transition = Time.getLocalTime(zrec.getUntilYear(),
|
||||
getMonth(),
|
||||
getDay(),
|
||||
save,
|
||||
gmtOffset,
|
||||
atTime);
|
||||
} else {
|
||||
until = zrec.getLocalUntilTime();
|
||||
transition = Time.getLocalTime(zrec.getUntilYear(),
|
||||
getMonth(),
|
||||
getDay(),
|
||||
atTime.getTime());
|
||||
}
|
||||
|
||||
return until == transition;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Rule line and returns a RuleRec object.
|
||||
*
|
||||
* @param tokens a StringTokenizer object that should contain a
|
||||
* token for the "FROM" field and the rest.
|
||||
* @return a RuleRec object.
|
||||
*/
|
||||
static RuleRec parse(StringTokenizer tokens) {
|
||||
RuleRec rec = new RuleRec();
|
||||
try {
|
||||
// FROM
|
||||
String token = tokens.nextToken();
|
||||
try {
|
||||
rec.fromYear = Integer.parseInt(token);
|
||||
} catch (NumberFormatException e) {
|
||||
// it's not integer
|
||||
if ("min".equals(token) || "minimum".equals(token)) {
|
||||
rec.fromYear = Zoneinfo.getMinYear();
|
||||
} else if ("max".equals(token) || "maximum".equals(token)) {
|
||||
rec.fromYear = Zoneinfo.getMaxYear();
|
||||
} else {
|
||||
Main.panic("invalid year value: "+token);
|
||||
}
|
||||
}
|
||||
|
||||
// TO
|
||||
token = tokens.nextToken();
|
||||
rec.isLastRule = false;
|
||||
try {
|
||||
rec.toYear = Integer.parseInt(token);
|
||||
} catch (NumberFormatException e) {
|
||||
// it's not integer
|
||||
if ("min".equals(token) || "minimum".equals(token)) {
|
||||
rec.fromYear = Zoneinfo.getMinYear();
|
||||
} else if ("max".equals(token) || "maximum".equals(token)) {
|
||||
rec.toYear = Integer.MAX_VALUE;
|
||||
rec.isLastRule = true;
|
||||
} else if ("only".equals(token)) {
|
||||
rec.toYear = rec.fromYear;
|
||||
} else {
|
||||
Main.panic("invalid year value: "+token);
|
||||
}
|
||||
}
|
||||
|
||||
// TYPE
|
||||
rec.type = tokens.nextToken();
|
||||
|
||||
// IN
|
||||
rec.inMonth = Month.parse(tokens.nextToken());
|
||||
|
||||
// ON
|
||||
rec.onDay = RuleDay.parse(tokens.nextToken());
|
||||
|
||||
// AT
|
||||
rec.atTime = Time.parse(tokens.nextToken());
|
||||
|
||||
// SAVE
|
||||
rec.save = (int) Time.parse(tokens.nextToken()).getTime();
|
||||
|
||||
// LETTER/S
|
||||
rec.letters = tokens.nextToken();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the transition time of the given year under this rule.
|
||||
* @param year the year value
|
||||
* @param gmtOffset the GMT offset value in milliseconds
|
||||
* @param save the amount of daylight save time
|
||||
* @return the transition time in milliseconds of the given year in UTC.
|
||||
*/
|
||||
long getTransitionTime(int year, int gmtOffset, int save) {
|
||||
long time = Time.getLocalTime(year, getMonth(),
|
||||
getDay(), atTime.getTime());
|
||||
if (atTime.isSTD()) {
|
||||
time -= gmtOffset;
|
||||
} else if (atTime.isWall()) {
|
||||
time -= gmtOffset + save;
|
||||
}
|
||||
return time;
|
||||
}
|
||||
|
||||
private static int getInt(StringTokenizer tokens) {
|
||||
String token = tokens.nextToken();
|
||||
return Integer.parseInt(token);
|
||||
}
|
||||
}
|
@ -1,188 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.SortedMap;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* <code>Simple</code> generates TimeZoneData, which had been used as internal
|
||||
* data of TimeZone before J2SDK1.3.
|
||||
* Since J2SDK1.4 doesn't need TimeZoneData, this class is for maintenance
|
||||
* of old JDK release.
|
||||
*/
|
||||
class Simple extends BackEnd {
|
||||
|
||||
/**
|
||||
* Zone records which are applied for given year.
|
||||
*/
|
||||
private static Map<String,ZoneRec> lastZoneRecs = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Rule records which are applied for given year.
|
||||
*/
|
||||
private static Map<String,List<RuleRec>> lastRules = new TreeMap<>();
|
||||
|
||||
/**
|
||||
* zone IDs sorted by their GMT offsets. If zone's GMT
|
||||
* offset will change in the future, its last known offset is
|
||||
* used.
|
||||
*/
|
||||
private SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<>();
|
||||
|
||||
/**
|
||||
* Sets last Rule records and Zone records for given timezone to
|
||||
* each Map.
|
||||
*
|
||||
* @param tz Timezone object for each zone
|
||||
* @return always 0
|
||||
*/
|
||||
int processZoneinfo(Timezone tz) {
|
||||
String zonename = tz.getName();
|
||||
|
||||
lastRules.put(zonename, tz.getLastRules());
|
||||
lastZoneRecs.put(zonename, tz.getLastZoneRec());
|
||||
|
||||
// Populate zonesByOffset. (Zones that will change their
|
||||
// GMT offsets are also added to zonesByOffset here.)
|
||||
int lastKnownOffset = tz.getRawOffset();
|
||||
Set<String> set = zonesByOffset.get(lastKnownOffset);
|
||||
if (set == null) {
|
||||
set = new TreeSet<>();
|
||||
zonesByOffset.put(lastKnownOffset, set);
|
||||
}
|
||||
set.add(zonename);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates TimeZoneData to output SimpleTimeZone data.
|
||||
* @param map Mappings object which is generated by {@link Main#compile}.
|
||||
* @return 0 if no error occurred, otherwise 1.
|
||||
*/
|
||||
int generateSrc(Mappings map) {
|
||||
try {
|
||||
File outD = new File(Main.getOutputDir());
|
||||
outD.mkdirs();
|
||||
|
||||
FileWriter fw =
|
||||
new FileWriter(new File(outD, "TimeZoneData.java"), false);
|
||||
BufferedWriter out = new BufferedWriter(fw);
|
||||
|
||||
out.write("import java.util.SimpleTimeZone;\n\n");
|
||||
out.write(" static SimpleTimeZone zones[] = {\n");
|
||||
|
||||
Map<String,String> a = map.getAliases();
|
||||
List<Integer> roi = map.getRawOffsetsIndex();
|
||||
List<Set<String>> roit = map.getRawOffsetsIndexTable();
|
||||
|
||||
int index = 0;
|
||||
for (int offset : zonesByOffset.keySet()) {
|
||||
int o = roi.get(index);
|
||||
Set<String> set = zonesByOffset.get(offset);
|
||||
if (offset == o) {
|
||||
// Merge aliases into zonesByOffset
|
||||
set.addAll(roit.get(index));
|
||||
}
|
||||
index++;
|
||||
|
||||
for (String key : set) {
|
||||
ZoneRec zrec;
|
||||
String realname;
|
||||
List<RuleRec> stz;
|
||||
if ((realname = a.get(key)) != null) {
|
||||
// if this alias is not targeted, ignore it.
|
||||
if (!Zone.isTargetZone(key)) {
|
||||
continue;
|
||||
}
|
||||
stz = lastRules.get(realname);
|
||||
zrec = lastZoneRecs.get(realname);
|
||||
} else {
|
||||
stz = lastRules.get(key);
|
||||
zrec = lastZoneRecs.get(key);
|
||||
}
|
||||
|
||||
out.write("\t//--------------------------------------------------------------------\n");
|
||||
String s = Time.toFormedString(offset);
|
||||
out.write("\tnew SimpleTimeZone(" +
|
||||
Time.toFormedString(offset) + ", \"" + key + "\"");
|
||||
if (realname != null) {
|
||||
out.write(" /* " + realname + " */");
|
||||
}
|
||||
|
||||
if (stz == null) {
|
||||
out.write("),\n");
|
||||
} else {
|
||||
RuleRec rr0 = stz.get(0);
|
||||
RuleRec rr1 = stz.get(1);
|
||||
|
||||
out.write(",\n\t " + Month.toString(rr0.getMonthNum()) +
|
||||
", " + rr0.getDay().getDayForSimpleTimeZone() + ", " +
|
||||
rr0.getDay().getDayOfWeekForSimpleTimeZone() + ", " +
|
||||
Time.toFormedString((int)rr0.getTime().getTime()) + ", " +
|
||||
rr0.getTime().getTypeForSimpleTimeZone() + ",\n" +
|
||||
|
||||
"\t " + Month.toString(rr1.getMonthNum()) + ", " +
|
||||
rr1.getDay().getDayForSimpleTimeZone() + ", " +
|
||||
rr1.getDay().getDayOfWeekForSimpleTimeZone() + ", " +
|
||||
Time.toFormedString((int)rr1.getTime().getTime())+ ", " +
|
||||
rr1.getTime().getTypeForSimpleTimeZone() + ",\n" +
|
||||
|
||||
"\t " + Time.toFormedString(rr0.getSave()) + "),\n");
|
||||
|
||||
out.write("\t// " + rr0.getLine() + "\n");
|
||||
out.write("\t// " + rr1.getLine() + "\n");
|
||||
}
|
||||
|
||||
String zline = zrec.getLine();
|
||||
if (zline.indexOf("Zone") == -1) {
|
||||
zline = "Zone " + key + "\t" + zline.trim();
|
||||
}
|
||||
out.write("\t// " + zline + "\n");
|
||||
}
|
||||
}
|
||||
out.write(" };\n");
|
||||
|
||||
out.close();
|
||||
fw.close();
|
||||
} catch(IOException e) {
|
||||
Main.panic("IO error: "+e.getMessage());
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
@ -1,343 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.Locale;
|
||||
import sun.util.calendar.CalendarDate;
|
||||
import sun.util.calendar.CalendarSystem;
|
||||
import sun.util.calendar.Gregorian;
|
||||
|
||||
/**
|
||||
* Time class represents the "AT" field and other time related information.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class Time {
|
||||
|
||||
static final Gregorian gcal = CalendarSystem.getGregorianCalendar();
|
||||
|
||||
// type is wall clock time
|
||||
private static final int WALL = 1;
|
||||
|
||||
// type is standard time
|
||||
private static final int STD = 2;
|
||||
|
||||
// type is UTC
|
||||
private static final int UTC = 3;
|
||||
|
||||
// type of representing time
|
||||
private int type;
|
||||
|
||||
/**
|
||||
* Time from the EPOCH in milliseconds
|
||||
*/
|
||||
private long time;
|
||||
|
||||
/**
|
||||
* Current time in milliseconds
|
||||
*/
|
||||
private static final long currentTime = System.currentTimeMillis();
|
||||
|
||||
Time() {
|
||||
time = 0L;
|
||||
}
|
||||
|
||||
Time(long time) {
|
||||
this.time = time;
|
||||
}
|
||||
|
||||
void setType(int type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
int getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
static long getCurrentTime() {
|
||||
return currentTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the time is represented in wall-clock time.
|
||||
*/
|
||||
boolean isWall() {
|
||||
return type == WALL;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the time is represented in standard time.
|
||||
*/
|
||||
boolean isSTD() {
|
||||
return type == STD;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the time is represented in UTC time.
|
||||
*/
|
||||
boolean isUTC() {
|
||||
return type == UTC;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the type to a string that represents the type in the
|
||||
* SimpleTimeZone time mode. (e.g., "SimpleTimeZone.WALL_TIME").
|
||||
* @return the converted string or null if the type is undefined.
|
||||
*/
|
||||
String getTypeForSimpleTimeZone() {
|
||||
String stz = "SimpleTimeZone.";
|
||||
if (isWall()) {
|
||||
return stz+"WALL_TIME";
|
||||
}
|
||||
else if (isSTD()) {
|
||||
return stz+"STANDARD_TIME";
|
||||
}
|
||||
else if (isUTC()) {
|
||||
return stz+"UTC_TIME";
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given Gregorian calendar field values to local time.
|
||||
* Local time is represented by the amount of milliseconds from
|
||||
* January 1, 1970 0:00 GMT.
|
||||
* @param year the year value
|
||||
* @param month the Month value
|
||||
* @param day the day represented by {@link RuleDay}
|
||||
* @param save the amount of daylight time in milliseconds
|
||||
* @param gmtOffset the GMT offset in milliseconds
|
||||
* @param time the time of the day represented by {@link Time}
|
||||
* @return local time
|
||||
*/
|
||||
static long getLocalTime(int year, Month month, RuleDay day, int save,
|
||||
int gmtOffset, Time time) {
|
||||
long t = time.getTime();
|
||||
|
||||
if (time.isSTD())
|
||||
t = time.getTime() + save;
|
||||
else if (time.isUTC())
|
||||
t = time.getTime() + save + gmtOffset;
|
||||
|
||||
return getLocalTime(year, month, day, t);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given Gregorian calendar field values to local time.
|
||||
* Local time is represented by the amount of milliseconds from
|
||||
* January 1, 1970 0:00 GMT.
|
||||
* @param year the year value
|
||||
* @param month the Month value
|
||||
* @param day the day value
|
||||
* @param time the time of the day in milliseconds
|
||||
* @return local time
|
||||
*/
|
||||
static long getLocalTime(int year, Month month, int day, long time) {
|
||||
CalendarDate date = gcal.newCalendarDate(null);
|
||||
date.setDate(year, month.value(), day);
|
||||
long millis = gcal.getTime(date);
|
||||
return millis + time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to <code>getLocalTime(year, month, day, (long)time)</code>.
|
||||
* @param year the year value
|
||||
* @param month the Month value
|
||||
* @param day the day value
|
||||
* @param time the time of the day in milliseconds
|
||||
* @return local time
|
||||
*/
|
||||
static long getLocalTime(int year, Month month, int day, int time) {
|
||||
return getLocalTime(year, month, day, (long)time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Equivalent to {@link #getLocalTime(int, Month, RuleDay, int)
|
||||
* getLocalTime(year, month, day, (int) time)}.
|
||||
* @param year the year value
|
||||
* @param month the Month value
|
||||
* @param day the day represented by {@link RuleDay}
|
||||
* @param time the time of the day represented by {@link Time}
|
||||
* @return local time
|
||||
*/
|
||||
static long getLocalTime(int year, Month month, RuleDay day, long time) {
|
||||
return getLocalTime(year, month, day, (int) time);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given Gregorian calendar field values to local time.
|
||||
* Local time is represented by the amount of milliseconds from
|
||||
* January 1, 1970 0:00 GMT.
|
||||
* @param year the year value
|
||||
* @param month the Month value
|
||||
* @param day the day represented by {@link RuleDay}
|
||||
* @param time the time of the day represented by {@link Time}
|
||||
* @return local time
|
||||
*/
|
||||
static long getLocalTime(int year, Month month, RuleDay day, int time) {
|
||||
CalendarDate cdate = gcal.newCalendarDate(null);
|
||||
int monthValue = month.value();
|
||||
|
||||
if (day.isLast()) { // e.g., "lastSun"
|
||||
cdate.setDate(year, monthValue, 1);
|
||||
cdate.setDayOfMonth(gcal.getMonthLength(cdate));
|
||||
cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
|
||||
} else if (day.isLater()) { // e.g., "Sun>=1"
|
||||
cdate.setDate(year, monthValue, day.getDay());
|
||||
cdate = gcal.getNthDayOfWeek(1, day.getDayOfWeekNum(), cdate);
|
||||
} else if (day.isExact()) {
|
||||
cdate.setDate(year, monthValue, day.getDay());
|
||||
} else if (day.isEarlier()) { // e.g., "Sun<=15"
|
||||
cdate.setDate(year, monthValue, day.getDay());
|
||||
cdate = gcal.getNthDayOfWeek(-1, day.getDayOfWeekNum(), cdate);
|
||||
} else {
|
||||
Main.panic("invalid day type: " + day);
|
||||
}
|
||||
return gcal.getTime(cdate) + time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the given "AT" field and constructs a Time object.
|
||||
* @param the "AT" field string
|
||||
* @return the Time object
|
||||
*/
|
||||
static Time parse(String time) {
|
||||
int sign;
|
||||
int index = 0;
|
||||
Time tm;
|
||||
|
||||
if (time.charAt(0) == '-') {
|
||||
sign = -1;
|
||||
index++;
|
||||
} else {
|
||||
sign = 1;
|
||||
}
|
||||
int val = 0;
|
||||
int num = 0;
|
||||
int countDelim = 0;
|
||||
while (index < time.length()) {
|
||||
char c = time.charAt(index++);
|
||||
if (c == ':') {
|
||||
val = val * 60 + num;
|
||||
countDelim++;
|
||||
num = 0;
|
||||
continue;
|
||||
}
|
||||
int d = Character.digit(c, 10);
|
||||
if (d == -1) {
|
||||
--index;
|
||||
break;
|
||||
}
|
||||
num = num * 10 + d;
|
||||
}
|
||||
val = val * 60 + num;
|
||||
// convert val to second
|
||||
for (; countDelim < 2; countDelim++) {
|
||||
val *= 60;
|
||||
}
|
||||
tm = new Time((long)val * 1000 * sign);
|
||||
if (index < time.length()) {
|
||||
char c = time.charAt(index++);
|
||||
if (c == 's') {
|
||||
tm.setType(Time.STD);
|
||||
} else if (c == 'u' || c == 'g' || c == 'z') {
|
||||
tm.setType(Time.UTC);
|
||||
} else if (c == 'w') {
|
||||
tm.setType(Time.WALL);
|
||||
} else {
|
||||
Main.panic("unknown time mode: "+c);
|
||||
}
|
||||
} else {
|
||||
tm.setType(Time.WALL);
|
||||
}
|
||||
return tm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given milliseconds string to a "[+-]hh:mm" string.
|
||||
* @param ms the milliseconds string
|
||||
*/
|
||||
static String toGMTFormat(String ms) {
|
||||
long sec = Long.parseLong(ms) / 1000;
|
||||
char sign;
|
||||
if (sec < 0) {
|
||||
sign = '-';
|
||||
sec = -sec;
|
||||
} else {
|
||||
sign = '+';
|
||||
}
|
||||
return String.format((Locale)null, "%c%02d:%02d",
|
||||
sign, sec/3600, (sec%3600)/60);
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the given millisecond value to a string for a
|
||||
* SimpleTimeZone parameter.
|
||||
* @param ms the millisecond value
|
||||
* @return the string in a human readable form
|
||||
*/
|
||||
static String toFormedString(int ms) {
|
||||
StringBuilder s = new StringBuilder();
|
||||
boolean minus = false;
|
||||
|
||||
if (ms < 0) {
|
||||
s.append("-");
|
||||
minus = true;
|
||||
ms = -ms;
|
||||
} else if (ms == 0) {
|
||||
return "0";
|
||||
}
|
||||
|
||||
int hour = ms / (60 * 60 * 1000);
|
||||
ms %= (60 * 60 * 1000);
|
||||
int minute = ms / (60 * 1000);
|
||||
|
||||
if (hour != 0) {
|
||||
if (minus && minute != 0) {
|
||||
s.append("(");
|
||||
}
|
||||
s.append(Integer.toString(hour) + "*ONE_HOUR");
|
||||
}
|
||||
|
||||
if (minute != 0) {
|
||||
if (hour != 0) {
|
||||
s.append("+");
|
||||
}
|
||||
s.append(Integer.toString(minute) + "*ONE_MINUTE");
|
||||
if (minus && hour != 0) {
|
||||
s.append(")");
|
||||
}
|
||||
}
|
||||
|
||||
return s.toString();
|
||||
}
|
||||
}
|
@ -1,454 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Timezone represents all information of a single point of time to
|
||||
* generate its time zone database.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class Timezone {
|
||||
/**
|
||||
* zone name of this time zone
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* transition time values in UTC (millisecond)
|
||||
*/
|
||||
private List<Long> transitions;
|
||||
|
||||
/**
|
||||
* All offset values in millisecond
|
||||
* @see sun.util.calendar.ZoneInfo
|
||||
*/
|
||||
private List<Integer> offsets;
|
||||
|
||||
/**
|
||||
* Indices of GMT offset values (both raw and raw+saving)
|
||||
* at transitions
|
||||
*/
|
||||
private List<Integer> gmtOffsets;
|
||||
|
||||
/**
|
||||
* Indices of regular or "direct" saving time values
|
||||
* at transitions
|
||||
*/
|
||||
private List<Integer> dstOffsets;
|
||||
|
||||
/**
|
||||
* Zone records of this time zone
|
||||
*/
|
||||
private List<ZoneRec> usedZoneRecs;
|
||||
|
||||
/**
|
||||
* Rule records referred to by this time zone
|
||||
*/
|
||||
private List<RuleRec> usedRuleRecs;
|
||||
|
||||
/**
|
||||
* Type of DST rules in this time zone
|
||||
*/
|
||||
private int dstType;
|
||||
static final int UNDEF_DST = 0; // DST type not set yet
|
||||
static final int NO_DST = 1; // never observed DST
|
||||
static final int LAST_DST = 2; // last rule ends in DST (all year round DST-only)
|
||||
static final int X_DST = 3; // used to observe DST
|
||||
static final int DST = 4; // observing DST regularly
|
||||
|
||||
/**
|
||||
* Raw GMT offset of this time zone in the last rule
|
||||
*/
|
||||
private int rawOffset;
|
||||
|
||||
/**
|
||||
* The CRC32 value of the transitions data
|
||||
*/
|
||||
private int crc32;
|
||||
|
||||
/**
|
||||
* The last ZoneRec
|
||||
*/
|
||||
private ZoneRec lastZoneRec;
|
||||
|
||||
/**
|
||||
* The last DST rules. lastRules[0] is the DST start
|
||||
* rule. lastRules[1] is the DST end rules.
|
||||
*/
|
||||
private List<RuleRec> lastRules;
|
||||
|
||||
/**
|
||||
* The amount of DST saving value (millisecond) in the last DST
|
||||
* rule.
|
||||
*/
|
||||
private int lastSaving;
|
||||
|
||||
/**
|
||||
* true if the raw offset will change in the future time.
|
||||
*/
|
||||
private boolean willRawOffsetChange = false;
|
||||
|
||||
|
||||
/**
|
||||
* Constracts a Timezone object with the given zone name.
|
||||
* @param name the zone name
|
||||
*/
|
||||
Timezone(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the number of transitions
|
||||
*/
|
||||
int getNTransitions() {
|
||||
if (transitions == null) {
|
||||
return 0;
|
||||
}
|
||||
return transitions.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the zone name
|
||||
*/
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all rule records that have been referred to
|
||||
* by this time zone.
|
||||
* @return the rule records list
|
||||
*/
|
||||
List<RuleRec> getRules() {
|
||||
return usedRuleRecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of all zone records that have been referred to
|
||||
* by this time zone.
|
||||
* @return the zone records list
|
||||
*/
|
||||
List<ZoneRec> getZones() {
|
||||
return usedZoneRecs;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the transition table (list)
|
||||
*/
|
||||
List<Long> getTransitions() {
|
||||
return transitions;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the offsets list
|
||||
*/
|
||||
List<Integer> getOffsets() {
|
||||
return offsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the DST saving offsets list
|
||||
*/
|
||||
List<Integer> getDstOffsets() {
|
||||
return dstOffsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the GMT offsets list
|
||||
*/
|
||||
List<Integer> getGmtOffsets() {
|
||||
return gmtOffsets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the checksum (crc32) value of the trasition table
|
||||
*/
|
||||
int getCRC32() {
|
||||
return crc32;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if the GMT offset of this time zone would change
|
||||
* after the time zone database has been generated, false, otherwise.
|
||||
*/
|
||||
boolean willGMTOffsetChange() {
|
||||
return willRawOffsetChange;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last known GMT offset value in milliseconds
|
||||
*/
|
||||
int getRawOffset() {
|
||||
return rawOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets time zone's GMT offset to <code>offset</code>.
|
||||
* @param offset the GMT offset value in milliseconds
|
||||
*/
|
||||
void setRawOffset(int offset) {
|
||||
rawOffset = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets time zone's GMT offset value to <code>offset</code>. If
|
||||
* <code>startTime</code> is future time, then the {@link
|
||||
* #willRawOffsetChange} value is set to true.
|
||||
* @param offset the GMT offset value in milliseconds
|
||||
* @param startTime the UTC time at which the GMT offset is in effective
|
||||
*/
|
||||
void setRawOffset(int offset, long startTime) {
|
||||
// if this rawOffset is for the future time, let the run-time
|
||||
// look for the current GMT offset.
|
||||
if (startTime > Time.getCurrentTime()) {
|
||||
willRawOffsetChange = true;
|
||||
}
|
||||
setRawOffset(offset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified transition information to the end of the transition table.
|
||||
* @param time the UTC time at which this transition happens
|
||||
* @param offset the total amount of the offset from GMT in milliseconds
|
||||
* @param dstOffset the amount of time in milliseconds saved at this transition
|
||||
*/
|
||||
void addTransition(long time, int offset, int dstOffset) {
|
||||
if (transitions == null) {
|
||||
transitions = new ArrayList<Long>();
|
||||
offsets = new ArrayList<Integer>();
|
||||
dstOffsets = new ArrayList<Integer>();
|
||||
}
|
||||
transitions.add(time);
|
||||
offsets.add(offset);
|
||||
dstOffsets.add(dstOffset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the type of historical daylight saving time
|
||||
* observation. For example, China used to observed daylight
|
||||
* saving time, but it no longer does. Then, X_DST is set to the
|
||||
* China time zone.
|
||||
* @param type the type of daylight saving time
|
||||
*/
|
||||
void setDSTType(int type) {
|
||||
dstType = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the type of historical daylight saving time
|
||||
* observation.
|
||||
*/
|
||||
int getDSTType() {
|
||||
return dstType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified zone record to the zone records list.
|
||||
* @param rec the zone record
|
||||
*/
|
||||
void addUsedRec(ZoneRec rec) {
|
||||
if (usedZoneRecs == null) {
|
||||
usedZoneRecs = new ArrayList<ZoneRec>();
|
||||
}
|
||||
usedZoneRecs.add(rec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified rule record to the rule records list.
|
||||
* @param rec the rule record
|
||||
*/
|
||||
void addUsedRec(RuleRec rec) {
|
||||
if (usedRuleRecs == null) {
|
||||
usedRuleRecs = new ArrayList<RuleRec>();
|
||||
}
|
||||
// if the last used rec is the same as the given rec, avoid
|
||||
// putting the same rule.
|
||||
int n = usedRuleRecs.size();
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (usedRuleRecs.get(i).equals(rec)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
usedRuleRecs.add(rec);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last zone record for this time zone.
|
||||
* @param the last zone record
|
||||
*/
|
||||
void setLastZoneRec(ZoneRec zrec) {
|
||||
lastZoneRec = zrec;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last zone record for this time zone.
|
||||
*/
|
||||
ZoneRec getLastZoneRec() {
|
||||
return lastZoneRec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last rule records for this time zone. Those are used
|
||||
* for generating SimpleTimeZone parameters.
|
||||
* @param rules the last rule records
|
||||
*/
|
||||
void setLastRules(List<RuleRec> rules) {
|
||||
int n = rules.size();
|
||||
if (n > 0) {
|
||||
lastRules = rules;
|
||||
RuleRec rec = rules.get(0);
|
||||
int offset = rec.getSave();
|
||||
if (offset > 0) {
|
||||
setLastDSTSaving(offset);
|
||||
} else {
|
||||
System.err.println("\t No DST starting rule in the last rules.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last rule records for this time zone.
|
||||
*/
|
||||
List<RuleRec> getLastRules() {
|
||||
return lastRules;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the last daylight saving amount.
|
||||
* @param the daylight saving amount
|
||||
*/
|
||||
void setLastDSTSaving(int offset) {
|
||||
lastSaving = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the last daylight saving amount.
|
||||
*/
|
||||
int getLastDSTSaving() {
|
||||
return lastSaving;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the CRC32 value from the transition table and sets
|
||||
* the value to <code>crc32</code>.
|
||||
*/
|
||||
void checksum() {
|
||||
if (transitions == null) {
|
||||
crc32 = 0;
|
||||
return;
|
||||
}
|
||||
Checksum sum = new Checksum();
|
||||
for (int i = 0; i < transitions.size(); i++) {
|
||||
int offset = offsets.get(i);
|
||||
// adjust back to make the transition in local time
|
||||
sum.update(transitions.get(i) + offset);
|
||||
sum.update(offset);
|
||||
sum.update(dstOffsets.get(i));
|
||||
}
|
||||
crc32 = (int)sum.getValue();
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes unnecessary transitions for Java time zone support.
|
||||
*/
|
||||
void optimize() {
|
||||
// if there is only one offset, delete all transitions. This
|
||||
// could happen if only time zone abbreviations changed.
|
||||
if (gmtOffsets.size() == 1) {
|
||||
transitions = null;
|
||||
usedRuleRecs = null;
|
||||
setDSTType(NO_DST);
|
||||
return;
|
||||
}
|
||||
for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
|
||||
if (transitions.get(i) == transitions.get(i+1)) {
|
||||
transitions.remove(i);
|
||||
offsets.remove(i);
|
||||
dstOffsets.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < (transitions.size() - 2); i++) { // don't remove the last one
|
||||
if (offsets.get(i) == offsets.get(i+1)
|
||||
&& dstOffsets.get(i) == dstOffsets.get(i+1)) {
|
||||
transitions.remove(i+1);
|
||||
offsets.remove(i+1);
|
||||
dstOffsets.remove(i+1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the specified offset value from GMT in the GMT offsets
|
||||
* table and returns its index. The offset value includes the base
|
||||
* GMT offset and any additional daylight saving if applicable. If
|
||||
* the same value as the specified offset is already in the table,
|
||||
* its index is returned.
|
||||
* @param offset the offset value in milliseconds
|
||||
* @return the index to the offset value in the GMT offsets table.
|
||||
*/
|
||||
int getOffsetIndex(int offset) {
|
||||
return getOffsetIndex(offset, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stores the specified daylight saving value in the GMT offsets
|
||||
* table and returns its index. If the same value as the specified
|
||||
* offset is already in the table, its index is returned. If 0 is
|
||||
* specified, it's not stored in the table and -1 is returned.
|
||||
* @param offset the offset value in milliseconds
|
||||
* @return the index to the specified offset value in the GMT
|
||||
* offsets table, or -1 if 0 is specified.
|
||||
*/
|
||||
int getDstOffsetIndex(int offset) {
|
||||
if (offset == 0) {
|
||||
return -1;
|
||||
}
|
||||
return getOffsetIndex(offset, 1);
|
||||
}
|
||||
|
||||
private int getOffsetIndex(int offset, int index) {
|
||||
if (gmtOffsets == null) {
|
||||
gmtOffsets = new ArrayList<Integer>();
|
||||
}
|
||||
for (int i = index; i < gmtOffsets.size(); i++) {
|
||||
if (offset == gmtOffsets.get(i)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
if (gmtOffsets.size() < index) {
|
||||
gmtOffsets.add(0);
|
||||
}
|
||||
gmtOffsets.add(offset);
|
||||
return gmtOffsets.size() - 1;
|
||||
}
|
||||
}
|
@ -1,168 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Zone holds information corresponding to a "Zone" part of a time
|
||||
* zone definition file.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class Zone {
|
||||
// zone name (e.g., "America/Los_Angeles")
|
||||
private String name;
|
||||
|
||||
// zone records
|
||||
private List<ZoneRec> list;
|
||||
|
||||
// target zone names for this compilation
|
||||
private static Set<String> targetZones;
|
||||
|
||||
/**
|
||||
* Constructs a Zone with the specified zone name.
|
||||
* @param name the zone name
|
||||
*/
|
||||
Zone(String name) {
|
||||
this.name = name;
|
||||
list = new ArrayList<ZoneRec>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads time zone names to be generated, called "target zone
|
||||
* name", from the specified text file and creats an internal hash
|
||||
* table to keep those names. It's assumed that one text line
|
||||
* contains a zone name or comments if it starts with
|
||||
* '#'. Comments can't follow a zone name in a single line.
|
||||
* @param fileName the text file name
|
||||
*/
|
||||
static void readZoneNames(String fileName) {
|
||||
if (fileName == null) {
|
||||
return;
|
||||
}
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
FileReader fr = new FileReader(fileName);
|
||||
in = new BufferedReader(fr);
|
||||
} catch (FileNotFoundException e) {
|
||||
Main.panic("can't open file: " + fileName);
|
||||
}
|
||||
targetZones = new HashSet<String>();
|
||||
String line;
|
||||
|
||||
try {
|
||||
while ((line = in.readLine()) != null) {
|
||||
line = line.trim();
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
if (!targetZones.add(line)) {
|
||||
Main.warning("duplicated target zone name: " + line);
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
} catch (IOException e) {
|
||||
Main.panic("IO error: "+e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the specified zone is one of the target zones.
|
||||
* If no target zones are specified, this method always returns
|
||||
* true for any zone name.
|
||||
* @param zoneName the zone name
|
||||
* @return true if the specified name is a target zone.
|
||||
*/
|
||||
static boolean isTargetZone(String zoneName) {
|
||||
if (targetZones == null) {
|
||||
return true;
|
||||
}
|
||||
return targetZones.contains(zoneName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Forces to add "MET" to the target zone table. This is because
|
||||
* there is a conflict between Java zone name "WET" and Olson zone
|
||||
* name.
|
||||
*/
|
||||
static void addMET() {
|
||||
if (targetZones != null) {
|
||||
targetZones.add("MET");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the zone name
|
||||
*/
|
||||
String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the specified zone record to the zone record list.
|
||||
*/
|
||||
void add(ZoneRec rec) {
|
||||
list.add(rec);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param index the index at which the zone record in the list is returned.
|
||||
* @return the zone record specified by the index.
|
||||
*/
|
||||
ZoneRec get(int index) {
|
||||
return list.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the size of the zone record list
|
||||
*/
|
||||
int size() {
|
||||
return list.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the reference to a rule in each zone record.
|
||||
* @param zi the Zoneinfo object with which the rule reference is
|
||||
* resolved.
|
||||
*/
|
||||
void resolve(Zoneinfo zi) {
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
ZoneRec rec = list.get(i);
|
||||
rec.resolve(zi);
|
||||
}
|
||||
}
|
||||
}
|
@ -1,252 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2004, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* ZoneRec hold information of time zone corresponding to each text
|
||||
* line of the "Zone" part.
|
||||
*
|
||||
* @since 1.4
|
||||
*/
|
||||
class ZoneRec {
|
||||
private int gmtOffset;
|
||||
private String ruleName;
|
||||
private int directSave;
|
||||
private Rule ruleRef;
|
||||
private String format;
|
||||
private boolean hasUntil;
|
||||
private int untilYear;
|
||||
private Month untilMonth;
|
||||
private RuleDay untilDay;
|
||||
private Time untilTime;
|
||||
private long untilInMillis;
|
||||
private String line;
|
||||
|
||||
/**
|
||||
* @return the "UNTIL" value in milliseconds
|
||||
*/
|
||||
Time getUntilTime() {
|
||||
return untilTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the GMT offset value in milliseconds
|
||||
*/
|
||||
int getGmtOffset() {
|
||||
return gmtOffset;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the rule name to which this zone record refers
|
||||
*/
|
||||
String getRuleName() {
|
||||
return ruleName;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the amount of saving time directly defined in the
|
||||
* "RULES/SAVE" field.
|
||||
*/
|
||||
int getDirectSave() {
|
||||
return directSave;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this zone record has a reference to a rule
|
||||
*/
|
||||
boolean hasRuleReference() {
|
||||
return ruleRef != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "FORMAT" field string of this zone record. This
|
||||
* @return the "FORMAT" field
|
||||
*/
|
||||
String getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the year in the "UNTIL" field
|
||||
*/
|
||||
int getUntilYear() {
|
||||
return untilYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "UNTIL" field value in milliseconds from Janurary
|
||||
* 1, 1970 0:00 GMT.
|
||||
* @param currentSave the amount of daylight saving in
|
||||
* milliseconds that is used to adjust wall-clock time.
|
||||
* @return the milliseconds value of the "UNTIL" field
|
||||
*/
|
||||
long getUntilTime(int currentSave) {
|
||||
if (untilTime.isWall()) {
|
||||
return untilInMillis - currentSave;
|
||||
}
|
||||
return untilInMillis;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "UNTIL" time in milliseconds without adjusting GMT
|
||||
* offsets or daylight saving.
|
||||
* @return local "UNTIL" time in milliseconds
|
||||
*/
|
||||
long getLocalUntilTime() {
|
||||
return Time.getLocalTime(untilYear,
|
||||
untilMonth,
|
||||
untilDay,
|
||||
untilTime.getTime());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving.
|
||||
* @return the "UNTIL" time after the adjustment
|
||||
*/
|
||||
long getLocalUntilTime(int save, int gmtOffset) {
|
||||
return Time.getLocalTime(untilYear,
|
||||
untilMonth,
|
||||
untilDay,
|
||||
save,
|
||||
gmtOffset,
|
||||
untilTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the text line of this zone record
|
||||
*/
|
||||
String getLine() {
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the specified text line to this zone record
|
||||
*/
|
||||
void setLine(String line) {
|
||||
this.line = line;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true if this zone record has the "UNTIL" field
|
||||
*/
|
||||
boolean hasUntil() {
|
||||
return this.hasUntil;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjusts the "UNTIL" time to GMT offset if this zone record has
|
||||
* it. <code>untilTime</code> is not adjusted to daylight saving
|
||||
* in this method.
|
||||
*/
|
||||
void adjustTime() {
|
||||
if (!hasUntil()) {
|
||||
return;
|
||||
}
|
||||
if (untilTime.isSTD() || untilTime.isWall()) {
|
||||
// adjust to gmt offset only here. adjust to real
|
||||
// wall-clock time when tracking rules
|
||||
untilInMillis -= gmtOffset;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the reference to the Rule object
|
||||
*/
|
||||
Rule getRuleRef() {
|
||||
return ruleRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the reference to a Rule and adjusts its "UNTIL" time
|
||||
* to GMT offset.
|
||||
*/
|
||||
void resolve(Zoneinfo zi) {
|
||||
if (ruleName != null && (!"-".equals(ruleName))) {
|
||||
ruleRef = zi.getRule(ruleName);
|
||||
}
|
||||
adjustTime();
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a Zone text line that is described by a StringTokenizer.
|
||||
* @param tokens represents tokens of a Zone text line
|
||||
* @return the zone record produced by parsing the text
|
||||
*/
|
||||
static ZoneRec parse(StringTokenizer tokens) {
|
||||
ZoneRec rec = new ZoneRec();
|
||||
try {
|
||||
rec.gmtOffset = (int) Time.parse(tokens.nextToken()).getTime();
|
||||
String token = tokens.nextToken();
|
||||
char c = token.charAt(0);
|
||||
if (c >= '0' && c <= '9') {
|
||||
rec.directSave = (int) Time.parse(token).getTime();
|
||||
} else {
|
||||
rec.ruleName = token;
|
||||
}
|
||||
rec.format = tokens.nextToken();
|
||||
if (tokens.hasMoreTokens()) {
|
||||
rec.hasUntil = true;
|
||||
rec.untilYear = Integer.parseInt(tokens.nextToken());
|
||||
if (tokens.hasMoreTokens()) {
|
||||
rec.untilMonth = Month.parse(tokens.nextToken());
|
||||
} else {
|
||||
rec.untilMonth = Month.JANUARY;
|
||||
}
|
||||
if (tokens.hasMoreTokens()) {
|
||||
rec.untilDay = RuleDay.parse(tokens.nextToken());
|
||||
} else {
|
||||
rec.untilDay = new RuleDay(1);
|
||||
}
|
||||
if (tokens.hasMoreTokens()) {
|
||||
rec.untilTime = Time.parse(tokens.nextToken());
|
||||
} else {
|
||||
rec.untilTime = Time.parse("0:00");
|
||||
}
|
||||
rec.untilInMillis = rec.getLocalUntilTime();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// TODO: error reporting
|
||||
e.printStackTrace();
|
||||
}
|
||||
return rec;
|
||||
}
|
||||
|
||||
private static void panic(String msg) {
|
||||
Main.panic(msg);
|
||||
}
|
||||
}
|
@ -1,569 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, 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.
|
||||
*/
|
||||
|
||||
package build.tools.javazic;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
/**
|
||||
* Zoneinfo provides javazic compiler front-end functionality.
|
||||
* @since 1.4
|
||||
*/
|
||||
class Zoneinfo {
|
||||
|
||||
private static final int minYear = 1900;
|
||||
private static final int maxYear = 2037;
|
||||
private static final long minTime = Time.getLocalTime(minYear, Month.JANUARY, 1, 0);
|
||||
private static int startYear = minYear;
|
||||
private static int endYear = maxYear;
|
||||
|
||||
/**
|
||||
* True if javazic should generate a list of SimpleTimeZone
|
||||
* instances for the SimpleTimeZone-based time zone support.
|
||||
*/
|
||||
static boolean isYearForTimeZoneDataSpecified = false;
|
||||
|
||||
/**
|
||||
* Zone name to Zone mappings
|
||||
*/
|
||||
private Map<String,Zone> zones;
|
||||
|
||||
/**
|
||||
* Rule name to Rule mappings
|
||||
*/
|
||||
private Map<String,Rule> rules;
|
||||
|
||||
/**
|
||||
* Alias name to real name mappings
|
||||
*/
|
||||
private Map<String,String> aliases;
|
||||
|
||||
/**
|
||||
* Constracts a Zoneinfo.
|
||||
*/
|
||||
Zoneinfo() {
|
||||
zones = new HashMap<String,Zone>();
|
||||
rules = new HashMap<String,Rule>();
|
||||
aliases = new HashMap<String,String>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given zone to the list of Zones.
|
||||
* @param zone Zone to be added to the list.
|
||||
*/
|
||||
void add(Zone zone) {
|
||||
String name = zone.getName();
|
||||
zones.put(name, zone);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the given rule to the list of Rules.
|
||||
* @param rule Rule to be added to the list.
|
||||
*/
|
||||
void add(Rule rule) {
|
||||
String name = rule.getName();
|
||||
rules.put(name, rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* Puts the specifid name pair to the alias table.
|
||||
* @param name1 an alias time zone name
|
||||
* @param name2 the real time zone of the alias name
|
||||
*/
|
||||
void putAlias(String name1, String name2) {
|
||||
aliases.put(name1, name2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the given year for SimpleTimeZone list output.
|
||||
* This method is called when the -S option is specified.
|
||||
* @param year the year for which SimpleTimeZone list should be generated
|
||||
*/
|
||||
static void setYear(int year) {
|
||||
setStartYear(year);
|
||||
setEndYear(year);
|
||||
isYearForTimeZoneDataSpecified = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the start year.
|
||||
* @param year the start year value
|
||||
* @throws IllegalArgumentException if the specified year value is
|
||||
* smaller than the minimum year or greater than the end year.
|
||||
*/
|
||||
static void setStartYear(int year) {
|
||||
if (year < minYear || year > endYear) {
|
||||
throw new IllegalArgumentException("invalid start year specified: " + year);
|
||||
}
|
||||
startYear = year;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the start year value
|
||||
*/
|
||||
static int getStartYear() {
|
||||
return startYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the end year.
|
||||
* @param year the end year value
|
||||
* @throws IllegalArgumentException if the specified year value is
|
||||
* smaller than the start year or greater than the maximum year.
|
||||
*/
|
||||
static void setEndYear(int year) {
|
||||
if (year < startYear || year > maxYear) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
endYear = year;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the end year value
|
||||
*/
|
||||
static int getEndYear() {
|
||||
return endYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the minimum year value
|
||||
*/
|
||||
static int getMinYear() {
|
||||
return minYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the maximum year value
|
||||
*/
|
||||
static int getMaxYear() {
|
||||
return maxYear;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the alias table
|
||||
*/
|
||||
Map<String,String> getAliases() {
|
||||
return aliases;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the Zone list
|
||||
*/
|
||||
Map<String,Zone> getZones() {
|
||||
return zones;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Zone specified by name.
|
||||
* @param name a zone name
|
||||
*/
|
||||
Zone getZone(String name) {
|
||||
return zones.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a Rule specified by name.
|
||||
* @param name a rule name
|
||||
*/
|
||||
Rule getRule(String name) {
|
||||
return rules.get(name);
|
||||
}
|
||||
|
||||
private static String line;
|
||||
|
||||
private static int lineNum;
|
||||
|
||||
/**
|
||||
* Parses the specified time zone data file and creates a Zoneinfo
|
||||
* that has all Rules, Zones and Links (aliases) information.
|
||||
* @param fname the time zone data file name
|
||||
* @return a Zoneinfo object
|
||||
*/
|
||||
static Zoneinfo parse(String fname) {
|
||||
BufferedReader in = null;
|
||||
try {
|
||||
FileReader fr = new FileReader(fname);
|
||||
in = new BufferedReader(fr);
|
||||
} catch (FileNotFoundException e) {
|
||||
panic("can't open file: "+fname);
|
||||
}
|
||||
Zoneinfo zi = new Zoneinfo();
|
||||
boolean continued = false;
|
||||
Zone zone = null;
|
||||
String l;
|
||||
lineNum = 0;
|
||||
|
||||
try {
|
||||
while ((line = in.readLine()) != null) {
|
||||
lineNum++;
|
||||
// skip blank and comment lines
|
||||
if (line.length() == 0 || line.charAt(0) == '#') {
|
||||
continue;
|
||||
}
|
||||
|
||||
// trim trailing comments
|
||||
int rindex = line.lastIndexOf('#');
|
||||
if (rindex != -1) {
|
||||
// take the data part of the line
|
||||
l = line.substring(0, rindex);
|
||||
} else {
|
||||
l = line;
|
||||
}
|
||||
|
||||
StringTokenizer tokens = new StringTokenizer(l);
|
||||
if (!tokens.hasMoreTokens()) {
|
||||
continue;
|
||||
}
|
||||
String token = tokens.nextToken();
|
||||
|
||||
if (continued || "Zone".equals(token)) {
|
||||
if (zone == null) {
|
||||
if (!tokens.hasMoreTokens()) {
|
||||
panic("syntax error: zone no more token");
|
||||
}
|
||||
token = tokens.nextToken();
|
||||
// if the zone name is in "GMT+hh" or "GMT-hh"
|
||||
// format, ignore it due to spec conflict.
|
||||
if (token.startsWith("GMT+") || token.startsWith("GMT-")) {
|
||||
continue;
|
||||
}
|
||||
zone = new Zone(token);
|
||||
} else {
|
||||
// no way to push the current token back...
|
||||
tokens = new StringTokenizer(l);
|
||||
}
|
||||
|
||||
ZoneRec zrec = ZoneRec.parse(tokens);
|
||||
zrec.setLine(line);
|
||||
zone.add(zrec);
|
||||
if ((continued = zrec.hasUntil()) == false) {
|
||||
if (Zone.isTargetZone(zone.getName())) {
|
||||
// zone.resolve(zi);
|
||||
zi.add(zone);
|
||||
}
|
||||
zone = null;
|
||||
}
|
||||
} else if ("Rule".equals(token)) {
|
||||
if (!tokens.hasMoreTokens()) {
|
||||
panic("syntax error: rule no more token");
|
||||
}
|
||||
token = tokens.nextToken();
|
||||
Rule rule = zi.getRule(token);
|
||||
if (rule == null) {
|
||||
rule = new Rule(token);
|
||||
zi.add(rule);
|
||||
}
|
||||
RuleRec rrec = RuleRec.parse(tokens);
|
||||
rrec.setLine(line);
|
||||
rule.add(rrec);
|
||||
} else if ("Link".equals(token)) {
|
||||
// Link <newname> <oldname>
|
||||
try {
|
||||
String name1 = tokens.nextToken();
|
||||
String name2 = tokens.nextToken();
|
||||
|
||||
// if the zone name is in "GMT+hh" or "GMT-hh"
|
||||
// format, ignore it due to spec conflict with
|
||||
// custom time zones. Also, ignore "ROC" for
|
||||
// PC-ness.
|
||||
if (name2.startsWith("GMT+") || name2.startsWith("GMT-")
|
||||
|| "ROC".equals(name2)) {
|
||||
continue;
|
||||
}
|
||||
zi.putAlias(name2, name1);
|
||||
} catch (Exception e) {
|
||||
panic("syntax error: no more token for Link");
|
||||
}
|
||||
}
|
||||
}
|
||||
in.close();
|
||||
} catch (IOException ex) {
|
||||
panic("IO error: " + ex.getMessage());
|
||||
}
|
||||
|
||||
return zi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Interprets a zone and constructs a Timezone object that
|
||||
* contains enough information on GMT offsets and DST schedules to
|
||||
* generate a zone info database.
|
||||
*
|
||||
* @param zoneName the zone name for which a Timezone object is
|
||||
* constructed.
|
||||
*
|
||||
* @return a Timezone object that contains all GMT offsets and DST
|
||||
* rules information.
|
||||
*/
|
||||
Timezone phase2(String zoneName) {
|
||||
Timezone tz = new Timezone(zoneName);
|
||||
Zone zone = getZone(zoneName);
|
||||
zone.resolve(this);
|
||||
|
||||
// TODO: merge phase2's for the regular and SimpleTimeZone ones.
|
||||
if (isYearForTimeZoneDataSpecified) {
|
||||
ZoneRec zrec = zone.get(zone.size()-1);
|
||||
tz.setLastZoneRec(zrec);
|
||||
tz.setRawOffset(zrec.getGmtOffset());
|
||||
if (zrec.hasRuleReference()) {
|
||||
/*
|
||||
* This part assumes that the specified year is covered by
|
||||
* the rules referred to by the last zone record.
|
||||
*/
|
||||
List<RuleRec> rrecs = zrec.getRuleRef().getRules(startYear);
|
||||
|
||||
if (rrecs.size() == 2) {
|
||||
// make sure that one is a start rule and the other is
|
||||
// an end rule.
|
||||
RuleRec r0 = rrecs.get(0);
|
||||
RuleRec r1 = rrecs.get(1);
|
||||
if (r0.getSave() == 0 && r1.getSave() > 0) {
|
||||
rrecs.set(0, r1);
|
||||
rrecs.set(1, r0);
|
||||
} else if (!(r0.getSave() > 0 && r1.getSave() == 0)) {
|
||||
rrecs = null;
|
||||
Main.error(zoneName + ": rules for " + startYear + " not found.");
|
||||
}
|
||||
} else {
|
||||
rrecs = null;
|
||||
}
|
||||
if (rrecs != null) {
|
||||
tz.setLastRules(rrecs);
|
||||
}
|
||||
}
|
||||
return tz;
|
||||
}
|
||||
|
||||
int gmtOffset;
|
||||
int year = minYear;
|
||||
int fromYear = year;
|
||||
long fromTime = Time.getLocalTime(startYear,
|
||||
Month.JANUARY,
|
||||
1, 0);
|
||||
|
||||
// take the index 0 for the GMT offset of the last zone record
|
||||
ZoneRec zrec = zone.get(zone.size()-1);
|
||||
tz.getOffsetIndex(zrec.getGmtOffset());
|
||||
|
||||
int currentSave = 0;
|
||||
boolean usedZone;
|
||||
for (int zindex = 0; zindex < zone.size(); zindex++) {
|
||||
zrec = zone.get(zindex);
|
||||
usedZone = false;
|
||||
gmtOffset = zrec.getGmtOffset();
|
||||
int stdOffset = zrec.getDirectSave();
|
||||
|
||||
// If this is the last zone record, take the last rule info.
|
||||
if (!zrec.hasUntil()) {
|
||||
tz.setRawOffset(gmtOffset, fromTime);
|
||||
if (zrec.hasRuleReference()) {
|
||||
tz.setLastRules(zrec.getRuleRef().getLastRules());
|
||||
} else if (stdOffset != 0) {
|
||||
// in case the last rule is all year round DST-only
|
||||
// (Asia/Amman once announced this rule.)
|
||||
tz.setLastDSTSaving(stdOffset);
|
||||
}
|
||||
}
|
||||
if (!zrec.hasRuleReference()) {
|
||||
if (!zrec.hasUntil() || zrec.getUntilTime(stdOffset) >= fromTime) {
|
||||
tz.addTransition(fromTime,
|
||||
tz.getOffsetIndex(gmtOffset+stdOffset),
|
||||
tz.getDstOffsetIndex(stdOffset));
|
||||
usedZone = true;
|
||||
}
|
||||
currentSave = stdOffset;
|
||||
// optimization in case the last rule is fixed.
|
||||
if (!zrec.hasUntil()) {
|
||||
if (tz.getNTransitions() > 0) {
|
||||
if (stdOffset == 0) {
|
||||
tz.setDSTType(Timezone.X_DST);
|
||||
} else {
|
||||
tz.setDSTType(Timezone.LAST_DST);
|
||||
}
|
||||
long time = Time.getLocalTime(maxYear,
|
||||
Month.JANUARY, 1, 0);
|
||||
time -= zrec.getGmtOffset();
|
||||
tz.addTransition(time,
|
||||
tz.getOffsetIndex(gmtOffset+stdOffset),
|
||||
tz.getDstOffsetIndex(stdOffset));
|
||||
tz.addUsedRec(zrec);
|
||||
} else {
|
||||
tz.setDSTType(Timezone.NO_DST);
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
Rule rule = zrec.getRuleRef();
|
||||
boolean fromTimeUsed = false;
|
||||
currentSave = 0;
|
||||
year_loop:
|
||||
for (year = getMinYear(); year <= endYear; year++) {
|
||||
if (zrec.hasUntil() && year > zrec.getUntilYear()) {
|
||||
break;
|
||||
}
|
||||
List<RuleRec> rules = rule.getRules(year);
|
||||
if (rules.size() > 0) {
|
||||
for (int i = 0; i < rules.size(); i++) {
|
||||
RuleRec rrec = rules.get(i);
|
||||
long transition = rrec.getTransitionTime(year,
|
||||
gmtOffset,
|
||||
currentSave);
|
||||
if (zrec.hasUntil()) {
|
||||
if (transition >= zrec.getUntilTime(currentSave)) {
|
||||
break year_loop;
|
||||
}
|
||||
}
|
||||
|
||||
if (fromTimeUsed == false) {
|
||||
if (fromTime <= transition) {
|
||||
fromTimeUsed = true;
|
||||
|
||||
if (fromTime != minTime) {
|
||||
int prevsave;
|
||||
|
||||
ZoneRec prevzrec = zone.get(zindex - 1);
|
||||
|
||||
// See if until time in the previous
|
||||
// ZoneRec is the same thing as the
|
||||
// local time in the next rule.
|
||||
// (examples are Asia/Ashkhabad in 1991,
|
||||
// Europe/Riga in 1989)
|
||||
|
||||
if (i > 0) {
|
||||
prevsave = rules.get(i-1).getSave();
|
||||
} else {
|
||||
List<RuleRec> prevrules = rule.getRules(year-1);
|
||||
|
||||
if (prevrules.size() > 0) {
|
||||
prevsave = prevrules.get(prevrules.size()-1).getSave();
|
||||
} else {
|
||||
prevsave = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (rrec.isSameTransition(prevzrec, prevsave, gmtOffset)) {
|
||||
currentSave = rrec.getSave();
|
||||
tz.addTransition(fromTime,
|
||||
tz.getOffsetIndex(gmtOffset+currentSave),
|
||||
tz.getDstOffsetIndex(currentSave));
|
||||
tz.addUsedRec(rrec);
|
||||
usedZone = true;
|
||||
continue;
|
||||
}
|
||||
if (!prevzrec.hasRuleReference()
|
||||
|| rule != prevzrec.getRuleRef()
|
||||
|| (rule == prevzrec.getRuleRef()
|
||||
&& gmtOffset != prevzrec.getGmtOffset())) {
|
||||
int save = (fromTime == transition) ? rrec.getSave() : currentSave;
|
||||
tz.addTransition(fromTime,
|
||||
tz.getOffsetIndex(gmtOffset+save),
|
||||
tz.getDstOffsetIndex(save));
|
||||
tz.addUsedRec(rrec);
|
||||
usedZone = true;
|
||||
}
|
||||
} else { // fromTime == minTime
|
||||
int save = rrec.getSave();
|
||||
tz.addTransition(minTime,
|
||||
tz.getOffsetIndex(gmtOffset),
|
||||
tz.getDstOffsetIndex(0));
|
||||
|
||||
tz.addTransition(transition,
|
||||
tz.getOffsetIndex(gmtOffset+save),
|
||||
tz.getDstOffsetIndex(save));
|
||||
|
||||
tz.addUsedRec(rrec);
|
||||
usedZone = true;
|
||||
}
|
||||
} else if (year == fromYear && i == rules.size()-1) {
|
||||
int save = rrec.getSave();
|
||||
tz.addTransition(fromTime,
|
||||
tz.getOffsetIndex(gmtOffset+save),
|
||||
tz.getDstOffsetIndex(save));
|
||||
}
|
||||
}
|
||||
|
||||
currentSave = rrec.getSave();
|
||||
if (fromTime < transition) {
|
||||
tz.addTransition(transition,
|
||||
tz.getOffsetIndex(gmtOffset+currentSave),
|
||||
tz.getDstOffsetIndex(currentSave));
|
||||
tz.addUsedRec(rrec);
|
||||
usedZone = true;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (year == fromYear) {
|
||||
tz.addTransition(fromTime,
|
||||
tz.getOffsetIndex(gmtOffset+currentSave),
|
||||
tz.getDstOffsetIndex(currentSave));
|
||||
fromTimeUsed = true;
|
||||
}
|
||||
if (year == endYear && !zrec.hasUntil()) {
|
||||
if (tz.getNTransitions() > 0) {
|
||||
// Assume that this Zone stopped DST
|
||||
tz.setDSTType(Timezone.X_DST);
|
||||
long time = Time.getLocalTime(maxYear, Month.JANUARY,
|
||||
1, 0);
|
||||
time -= zrec.getGmtOffset();
|
||||
tz.addTransition(time,
|
||||
tz.getOffsetIndex(gmtOffset),
|
||||
tz.getDstOffsetIndex(0));
|
||||
usedZone = true;
|
||||
} else {
|
||||
tz.setDSTType(Timezone.NO_DST);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (usedZone) {
|
||||
tz.addUsedRec(zrec);
|
||||
}
|
||||
if (zrec.hasUntil() && zrec.getUntilTime(currentSave) > fromTime) {
|
||||
fromTime = zrec.getUntilTime(currentSave);
|
||||
fromYear = zrec.getUntilYear();
|
||||
year = zrec.getUntilYear();
|
||||
}
|
||||
}
|
||||
|
||||
if (tz.getDSTType() == Timezone.UNDEF_DST) {
|
||||
tz.setDSTType(Timezone.DST);
|
||||
}
|
||||
tz.optimize();
|
||||
tz.checksum();
|
||||
return tz;
|
||||
}
|
||||
|
||||
private static void panic(String msg) {
|
||||
Main.panic(msg);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user