544bd260b6
Reviewed-by: naoto
777 lines
32 KiB
Java
777 lines
32 KiB
Java
/*
|
|
* Copyright (c) 2001, 2023, 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.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
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;
|
|
|
|
/**
|
|
* <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) {
|
|
mapList = new HashMap<String, LatitudeAndLongitude>();
|
|
FileReader fr = new FileReader(Main.getMapFile());
|
|
BufferedReader in = new BufferedReader(fr);
|
|
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 != null ? mapList.get(zonename) : null);
|
|
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;
|
|
}
|
|
}
|
|
}
|