15658
|
1 |
/*
|
|
2 |
* Copyright (c) 2001, 2011, Oracle and/or its affiliates. All rights reserved.
|
|
3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
4 |
*
|
|
5 |
* This code is free software; you can redistribute it and/or modify it
|
|
6 |
* under the terms of the GNU General Public License version 2 only, as
|
|
7 |
* published by the Free Software Foundation. Oracle designates this
|
|
8 |
* particular file as subject to the "Classpath" exception as provided
|
|
9 |
* by Oracle in the LICENSE file that accompanied this code.
|
|
10 |
*
|
|
11 |
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
13 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
14 |
* version 2 for more details (a copy is included in the LICENSE file that
|
|
15 |
* accompanied this code).
|
|
16 |
*
|
|
17 |
* You should have received a copy of the GNU General Public License version
|
|
18 |
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
19 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
20 |
*
|
|
21 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
22 |
* or visit www.oracle.com if you need additional information or have any
|
|
23 |
* questions.
|
|
24 |
*/
|
|
25 |
|
|
26 |
import java.io.BufferedReader;
|
|
27 |
import java.io.BufferedWriter;
|
|
28 |
import java.io.File;
|
|
29 |
import java.io.FileReader;
|
|
30 |
import java.io.FileWriter;
|
|
31 |
import java.io.IOException;
|
|
32 |
import java.util.Date;
|
|
33 |
import java.util.HashMap;
|
|
34 |
import java.util.List;
|
|
35 |
import java.util.Map;
|
|
36 |
import java.util.Set;
|
|
37 |
import java.util.SortedMap;
|
|
38 |
import java.util.StringTokenizer;
|
|
39 |
import java.util.TreeMap;
|
|
40 |
import java.util.TreeSet;
|
|
41 |
|
|
42 |
/**
|
|
43 |
* <code>GenDoc</code> is one of back-end classes of javazic, and generates
|
|
44 |
* index.html and other html files which prints the detailed time zone
|
|
45 |
* information for each zone.
|
|
46 |
*/
|
|
47 |
class GenDoc extends BackEnd {
|
|
48 |
|
|
49 |
private static final String docDir = "doc";
|
|
50 |
|
|
51 |
private static final String header1 =
|
|
52 |
"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\"" +
|
|
53 |
"\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n" +
|
|
54 |
"<HTML>\n<HEAD>\n<!-- Generated by javazic on ";
|
|
55 |
private static final String header2 =
|
|
56 |
"-->\n<TITLE>\n" +
|
|
57 |
"Java Platform, Standard Edition - TimeZone information based on ";
|
|
58 |
private static final String header3 =
|
|
59 |
"-->\n<TITLE>\n" +
|
|
60 |
"Java Platform, Standard Edition TimeZone - ";
|
|
61 |
private static final String header4 =
|
|
62 |
"</TITLE>\n" +
|
|
63 |
"</HEAD>\n\n";
|
|
64 |
|
|
65 |
private static final String body1 =
|
|
66 |
"<BODY BGCOLOR=\"white\">\n";
|
|
67 |
private static final String body2 =
|
|
68 |
"</BODY>\n";
|
|
69 |
|
|
70 |
private static final String footer =
|
|
71 |
"</HTML>\n";
|
|
72 |
|
|
73 |
|
|
74 |
// list of time zone name and zonefile name/real time zone name
|
|
75 |
// e.g.
|
|
76 |
// key (String) : value (String)
|
|
77 |
// "America/Denver" : "America/Denver.html" (real time zone)
|
|
78 |
// "America/Shiprock" : "America/Denver" (alias)
|
|
79 |
TreeMap<String,String> timezoneList = new TreeMap<String,String>();
|
|
80 |
|
|
81 |
// list of time zone's display name and time zone name
|
|
82 |
// e.g.
|
|
83 |
// key (String) : value (String)
|
|
84 |
// "Tokyo, Asia" : "Asia/Tokyo"
|
|
85 |
// "Marengo, Indiana, America" : "America/Indiana/Marengo"
|
|
86 |
// (aliases included)
|
|
87 |
TreeMap<String,String> displayNameList = new TreeMap<String,String>();
|
|
88 |
|
|
89 |
// list of top level regions
|
|
90 |
// e.g.
|
|
91 |
// key (String) : value (String)
|
|
92 |
// "America" : "America.html"
|
|
93 |
// (including entries in America/Indiana/, America/Kentucky/, ...)
|
|
94 |
TreeMap<String,String> regionList = new TreeMap<String,String>();
|
|
95 |
|
|
96 |
// mapping list from zone name to latitude & longitude
|
|
97 |
// This list is generated from zone.tab.
|
|
98 |
// e.g.
|
|
99 |
// key (String) : value (LatitudeAndLongitude object)
|
|
100 |
// "Asia/Tokyo" : latitude=35.3916, longitude=13.9444
|
|
101 |
// (aliases not included)
|
|
102 |
HashMap<String,LatitudeAndLongitude> mapList = null;
|
|
103 |
|
|
104 |
// SortedMap of zone IDs sorted by their GMT offsets. If zone's GMT
|
|
105 |
// offset will change in the future, its last known offset is
|
|
106 |
// used.
|
|
107 |
SortedMap<Integer, Set<String>> zonesByOffset = new TreeMap<Integer, Set<String>>();
|
|
108 |
|
|
109 |
/**
|
|
110 |
* Generates HTML document for each zone.
|
|
111 |
* @param Timezone
|
|
112 |
* @return 0 if no errors, or 1 if error occurred.
|
|
113 |
*/
|
|
114 |
int processZoneinfo(Timezone tz) {
|
|
115 |
try {
|
|
116 |
int size;
|
|
117 |
int index;
|
|
118 |
String outputDir = Main.getOutputDir();
|
|
119 |
String zonename = tz.getName();
|
|
120 |
String zonefile = ZoneInfoFile.getFileName(zonename) + ".html";
|
|
121 |
List<RuleRec> stz = tz.getLastRules();
|
|
122 |
timezoneList.put(zonename, zonefile);
|
|
123 |
displayNameList.put(transform(zonename), zonename);
|
|
124 |
|
|
125 |
// Populate zonesByOffset. (Zones that will change their
|
|
126 |
// GMT offsets are also added to zonesByOffset here.)
|
|
127 |
int lastKnownOffset = tz.getRawOffset();
|
|
128 |
Set<String> set = zonesByOffset.get(lastKnownOffset);
|
|
129 |
if (set == null) {
|
|
130 |
set = new TreeSet<String>();
|
|
131 |
zonesByOffset.put(lastKnownOffset, set);
|
|
132 |
}
|
|
133 |
set.add(zonename);
|
|
134 |
|
|
135 |
/* If outputDir doesn't end with file-separator, adds it. */
|
|
136 |
if (!outputDir.endsWith(File.separator)) {
|
|
137 |
outputDir += File.separatorChar;
|
|
138 |
}
|
|
139 |
outputDir += docDir + File.separatorChar;
|
|
140 |
|
|
141 |
index = zonename.indexOf('/');
|
|
142 |
if (index != -1) {
|
|
143 |
regionList.put(zonename.substring(0, index),
|
|
144 |
zonename.substring(0, index) + ".html");
|
|
145 |
}
|
|
146 |
|
|
147 |
/* If zonefile includes file-separator, it's treated as part of
|
|
148 |
* pathname. And make directory if necessary.
|
|
149 |
*/
|
|
150 |
index = zonefile.lastIndexOf('/');
|
|
151 |
if (index != -1) {
|
|
152 |
zonefile.replace('/', File.separatorChar);
|
|
153 |
outputDir += zonefile.substring(0, index+1);
|
|
154 |
}
|
|
155 |
File outD = new File(outputDir);
|
|
156 |
outD.mkdirs();
|
|
157 |
|
|
158 |
/* If mapfile is available, add a link to the appropriate map */
|
|
159 |
if ((mapList == null) && (Main.getMapFile() != null)) {
|
|
160 |
FileReader fr = new FileReader(Main.getMapFile());
|
|
161 |
BufferedReader in = new BufferedReader(fr);
|
|
162 |
mapList = new HashMap<String,LatitudeAndLongitude>();
|
|
163 |
String line;
|
|
164 |
while ((line = in.readLine()) != null) {
|
|
165 |
// skip blank and comment lines
|
|
166 |
if (line.length() == 0 || line.charAt(0) == '#') {
|
|
167 |
continue;
|
|
168 |
}
|
|
169 |
StringTokenizer tokens = new StringTokenizer(line);
|
|
170 |
String token = tokens.nextToken(); /* We don't use the first token. */
|
|
171 |
token = tokens.nextToken();
|
|
172 |
LatitudeAndLongitude location = new LatitudeAndLongitude(token);
|
|
173 |
token = tokens.nextToken();
|
|
174 |
mapList.put(token, location);
|
|
175 |
}
|
|
176 |
in.close();
|
|
177 |
}
|
|
178 |
|
|
179 |
/* Open zoneinfo file to write. */
|
|
180 |
FileWriter fw = new FileWriter(outputDir + zonefile.substring(index+1));
|
|
181 |
BufferedWriter out = new BufferedWriter(fw);
|
|
182 |
|
|
183 |
out.write(header1 + new Date() + header3 + zonename + header4);
|
|
184 |
out.write(body1 + "<FONT size=\"+2\"><B>" + zonename + "</B></FONT>");
|
|
185 |
LatitudeAndLongitude location = mapList.get(zonename);
|
|
186 |
if (location != null) {
|
|
187 |
int deg, min, sec;
|
|
188 |
|
|
189 |
deg = location.getLatDeg();
|
|
190 |
min = location.getLatMin();
|
|
191 |
sec = location.getLatSec();
|
|
192 |
if (deg < 0) {
|
|
193 |
min = -min;
|
|
194 |
sec = -sec;
|
|
195 |
} else if (min < 0) {
|
|
196 |
sec = -sec;
|
|
197 |
}
|
|
198 |
out.write(" " +
|
|
199 |
"<A HREF=\"http://www.mapquest.com/maps/map.adp?" +
|
|
200 |
"latlongtype=degrees" +
|
|
201 |
"&latdeg=" + deg +
|
|
202 |
"&latmin=" + min +
|
|
203 |
"&latsec=" + sec);
|
|
204 |
|
|
205 |
deg = location.getLongDeg();
|
|
206 |
min = location.getLongMin();
|
|
207 |
sec = location.getLongSec();
|
|
208 |
if (deg < 0) {
|
|
209 |
min = -min;
|
|
210 |
sec = -sec;
|
|
211 |
} else if (min < 0) {
|
|
212 |
sec = -sec;
|
|
213 |
}
|
|
214 |
out.write("&longdeg=" + deg +
|
|
215 |
"&longmin=" + min +
|
|
216 |
"&longsec=" + sec +
|
|
217 |
"\" target=\"_blank\">[map]</A>");
|
|
218 |
}
|
|
219 |
out.write("\n<P>\n");
|
|
220 |
|
|
221 |
List<ZoneRec> zone = tz.getZones();
|
|
222 |
List<RuleRec> rule = tz.getRules();
|
|
223 |
if (rule != null && zone != null) {
|
|
224 |
out.write("<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">\n" +
|
|
225 |
"<TR>\n" +
|
|
226 |
"<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\"><BR>" +
|
|
227 |
"<A HREF=\"#Rules\">Rules</A><BR></TD>\n" +
|
|
228 |
"<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\">" +
|
|
229 |
"<A HREF=\"#Zone\"><BR>Zone<BR></A></TD>\n" +
|
|
230 |
"</TR>\n</TABLE>\n");
|
|
231 |
}
|
|
232 |
|
|
233 |
/* Output Rule records. */
|
|
234 |
if (rule != null) {
|
|
235 |
size = rule.size();
|
|
236 |
out.write("<P>\n<A NAME=\"Rules\">" +
|
|
237 |
"<FONT SIZE=\"+1\"><B>Rules</B></FONT></A>\n" +
|
|
238 |
"<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
|
|
239 |
"<TR BGCOLOR=\"#CCCCFF\">\n" +
|
|
240 |
"<TD>NAME</TD><TD>FROM</TD><TD>TO</TD><TD>TYPE</TD>" +
|
|
241 |
"<TD>IN</TD><TD>ON</TD><TD>AT</TD><TD>SAVE</TD>" +
|
|
242 |
"<TD>LETTER/S</TD><TD>NOTES</TD>\n</TR>\n");
|
|
243 |
for (int i = 0; i < size; i++) {
|
|
244 |
out.write("<TR BGCOLOR=\"#FFFFFF\">\n");
|
|
245 |
StringTokenizer st = new StringTokenizer(rule.get(i).getLine());
|
|
246 |
String s;
|
|
247 |
if (st.hasMoreTokens()) { /* RULE - truncated */
|
|
248 |
st.nextToken();
|
|
249 |
}
|
|
250 |
if (st.hasMoreTokens()) { /* NAME */
|
|
251 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
252 |
}
|
|
253 |
if (st.hasMoreTokens()) { /* FROM */
|
|
254 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
255 |
}
|
|
256 |
if (st.hasMoreTokens()) { /* TO */
|
|
257 |
s = st.nextToken();
|
|
258 |
if (s.equals("min") || s.equals("max")) {
|
|
259 |
out.write("<TD><FONT COLOR=\"red\">" + s + "</FONT></TD>");
|
|
260 |
} else {
|
|
261 |
out.write("<TD>" + s + "</TD>");
|
|
262 |
}
|
|
263 |
}
|
|
264 |
if (st.hasMoreTokens()) { /* TYPE */
|
|
265 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
266 |
}
|
|
267 |
if (st.hasMoreTokens()) { /* IN */
|
|
268 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
269 |
}
|
|
270 |
if (st.hasMoreTokens()) { /* ON */
|
|
271 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
272 |
}
|
|
273 |
if (st.hasMoreTokens()) { /* AT */
|
|
274 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
275 |
}
|
|
276 |
if (st.hasMoreTokens()) { /* SAVE */
|
|
277 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
278 |
}
|
|
279 |
if (st.hasMoreTokens()) { /* LETTER/S */
|
|
280 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
281 |
}
|
|
282 |
if (st.hasMoreTokens()) { /* NOTES */
|
|
283 |
s = st.nextToken();
|
|
284 |
while (st.hasMoreTokens()) {
|
|
285 |
s += " " + st.nextToken();
|
|
286 |
}
|
|
287 |
index = s.indexOf('#');
|
|
288 |
out.write("<TD>" + s.substring(index+1) + "</TD>\n");
|
|
289 |
} else {
|
|
290 |
out.write("<TD> </TD>\n");
|
|
291 |
}
|
|
292 |
out.write("</TR>\n");
|
|
293 |
}
|
|
294 |
out.write("</TABLE>\n<P> <P>\n");
|
|
295 |
}
|
|
296 |
|
|
297 |
/* Output Zone records. */
|
|
298 |
if (zone != null) {
|
|
299 |
size = zone.size();
|
|
300 |
out.write("<P>\n<A NAME=\"Zone\">" +
|
|
301 |
"<FONT SIZE=\"+1\"><B>Zone</B></FONT></A>\n" +
|
|
302 |
"<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n" +
|
|
303 |
"<TR BGCOLOR=\"#CCCCFF\">\n<TD>GMTOFF</TD>" +
|
|
304 |
"<TD>RULES</TD><TD>FORMAT</TD><TD>UNTIL</TD>" +
|
|
305 |
"<TD>NOTES</TD>\n</TR>\n");
|
|
306 |
for (int i = 0; i < size; i++) {
|
|
307 |
out.write("<TR>\n");
|
|
308 |
StringTokenizer st = new StringTokenizer(zone.get(i).getLine());
|
|
309 |
String s = st.nextToken();
|
|
310 |
if (s.equals("Zone")) { /* NAME */
|
|
311 |
s = st.nextToken();
|
|
312 |
s = st.nextToken();
|
|
313 |
}
|
|
314 |
out.write("<TD>" + s + "</TD>"); /* GMTOFFSET */
|
|
315 |
if (st.hasMoreTokens()) { /* RULES */
|
|
316 |
out.write("<TD>" + st.nextToken() + "</TD>");
|
|
317 |
}
|
|
318 |
if (st.hasMoreTokens()) { /* FORMAT */
|
|
319 |
s = st.nextToken();
|
|
320 |
index = s.indexOf('#');
|
|
321 |
if (index != -1) {
|
|
322 |
if (index != 0) {
|
|
323 |
out.write("<TD>" + s.substring(0, index-1) +
|
|
324 |
"</TD>"); /* FORMAT */
|
|
325 |
s = s.substring(index+1);
|
|
326 |
} else {
|
|
327 |
out.write("<TD> </TD>"); /* FORMAT */
|
|
328 |
}
|
|
329 |
while (st.hasMoreTokens()) {
|
|
330 |
s += " " + st.nextToken();
|
|
331 |
}
|
|
332 |
out.write("<TD> </TD>"); /* UNTIL */
|
|
333 |
out.write("<TD>" + s + "</TD>\n</TR>\n"); /* NOTES */
|
|
334 |
continue;
|
|
335 |
} else {
|
|
336 |
out.write("<TD>" + s + "</TD>"); /* FORMAT */
|
|
337 |
}
|
|
338 |
}
|
|
339 |
|
|
340 |
if (st.hasMoreTokens()) { /* UNTIL */
|
|
341 |
s = st.nextToken();
|
|
342 |
while (st.hasMoreTokens()) {
|
|
343 |
s += " " + st.nextToken();
|
|
344 |
}
|
|
345 |
index = s.indexOf('#');
|
|
346 |
if (index != -1) {
|
|
347 |
if (index != 0) {
|
|
348 |
out.write("<TD>" + s.substring(0, index-1) +
|
|
349 |
"</TD>"); /* UNTIL */
|
|
350 |
} else {
|
|
351 |
out.write("<TD> </TD>"); /* UNTIL */
|
|
352 |
}
|
|
353 |
out.write("<TD>" + s.substring(index+1) +
|
|
354 |
"</TD>\n"); /* NOTES */
|
|
355 |
} else {
|
|
356 |
out.write("<TD>" + s + "</TD>"); /* UNTIL */
|
|
357 |
out.write("<TD> </TD>\n"); /* NOTES */
|
|
358 |
}
|
|
359 |
} else {
|
|
360 |
out.write("<TD> </TD>"); /* UNTIL */
|
|
361 |
out.write("<TD> </TD>\n"); /* NOTES */
|
|
362 |
}
|
|
363 |
out.write("</TR>\n");
|
|
364 |
}
|
|
365 |
out.write("</TABLE>\n");
|
|
366 |
}
|
|
367 |
out.write(body2 + footer);
|
|
368 |
|
|
369 |
out.close();
|
|
370 |
fw.close();
|
|
371 |
} catch(IOException e) {
|
|
372 |
Main.panic("IO error: "+e.getMessage());
|
|
373 |
return 1;
|
|
374 |
}
|
|
375 |
|
|
376 |
return 0;
|
|
377 |
}
|
|
378 |
|
|
379 |
/**
|
|
380 |
* Generates index.html and other top-level frame files.
|
|
381 |
* @param Mappings
|
|
382 |
* @return 0 if no errors, or 1 if error occurred.
|
|
383 |
*/
|
|
384 |
int generateSrc(Mappings map) {
|
|
385 |
try {
|
|
386 |
int len;
|
|
387 |
Object o[];
|
|
388 |
String outputDir = Main.getOutputDir();
|
|
389 |
FileWriter fw1, fw2;
|
|
390 |
BufferedWriter out1, out2;
|
|
391 |
|
|
392 |
/* Whether alias list exists or not. */
|
|
393 |
Map<String,String> a = map.getAliases();
|
|
394 |
if (a == null) {
|
|
395 |
Main.panic("Data not exist. (aliases)");
|
|
396 |
return 1;
|
|
397 |
}
|
|
398 |
|
|
399 |
timezoneList.putAll(a);
|
|
400 |
|
|
401 |
/* If outputDir doesn't end with file-separator, adds it. */
|
|
402 |
if (!outputDir.endsWith(File.separator)) {
|
|
403 |
outputDir += File.separatorChar;
|
|
404 |
}
|
|
405 |
outputDir += docDir + File.separatorChar;
|
|
406 |
|
|
407 |
File outD = new File(outputDir);
|
|
408 |
outD.mkdirs();
|
|
409 |
|
|
410 |
/* Creates index.html */
|
|
411 |
fw1 = new FileWriter(outputDir + "index.html", false);
|
|
412 |
out1 = new BufferedWriter(fw1);
|
|
413 |
|
|
414 |
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
|
415 |
header4 +
|
|
416 |
"<FRAMESET cols=\"20%,80%\">\n" +
|
|
417 |
"<FRAMESET rows=\"30%,70%\">\n" +
|
|
418 |
"<FRAME src=\"overview-frame.html\" name=\"TimeZoneListFrame\">\n" +
|
|
419 |
"<FRAME src=\"allTimeZone-frame1.html\" name=\"allTimeZoneFrame\">\n" +
|
|
420 |
"</FRAMESET>" +
|
|
421 |
"<FRAME src=\"overview-summary.html\" name=\"rightFrame\">\n" +
|
|
422 |
"</FRAMESET>\n" +
|
|
423 |
"<NOFRAMES>\n" +
|
|
424 |
"<H2>\nFrame Alert\n</H2>\n\n" +
|
|
425 |
"<P>\n\n" +
|
|
426 |
"This document is designed to be viewed using the frames feature. If you see this\n" +
|
|
427 |
"message, you are using a non-frame-capable web client.\n" +
|
|
428 |
"<BR>\n" +
|
|
429 |
"Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n" +
|
|
430 |
"</NOFRAMES>\n" + footer);
|
|
431 |
|
|
432 |
out1.close();
|
|
433 |
fw1.close();
|
|
434 |
|
|
435 |
|
|
436 |
/* Creates overview-frame.html */
|
|
437 |
fw1 = new FileWriter(outputDir + "overview-frame.html", false);
|
|
438 |
out1 = new BufferedWriter(fw1);
|
|
439 |
|
|
440 |
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
|
441 |
header4 + body1 +
|
|
442 |
"<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n" +
|
|
443 |
"<TD NOWRAP><FONT size=\"+1\">\n" +
|
|
444 |
"<B>Java<sup><font size=-2>TM</font></sup> Platform<br>Standard Ed.</B></FONT></TD>\n" +
|
|
445 |
"</TR>\n</TABLE>\n\n" +
|
|
446 |
"<TABLE BORDER=\"0\" WIDTH=\"100%\">\n<TR>\n<TD NOWRAP>" +
|
|
447 |
"<P>\n<FONT size=\"+1\">\nAll Time Zones Sorted By:</FONT>\n<BR>\n" +
|
|
448 |
" <A HREF=\"allTimeZone-frame1.html\" TARGET=\"allTimeZoneFrame\">GMT offsets</A></FONT>\n<BR>\n" +
|
|
449 |
" <A HREF=\"allTimeZone-frame2.html\" TARGET=\"allTimeZoneFrame\">Zone names</A></FONT>\n<BR>" +
|
|
450 |
" <A HREF=\"allTimeZone-frame3.html\" TARGET=\"allTimeZoneFrame\">City names</A></FONT>\n" +
|
|
451 |
"<P>\n<FONT size=\"+1\">\nContinents and Oceans</FONT>\n<BR>\n");
|
|
452 |
|
|
453 |
for (String regionKey : regionList.keySet()) {
|
|
454 |
out1.write(" <A HREF=\"" + regionList.get(regionKey) +
|
|
455 |
"\" TARGET=\"allTimeZoneFrame\">" + regionKey +
|
|
456 |
"</A><BR>\n");
|
|
457 |
|
|
458 |
fw2 = new FileWriter(outputDir + regionList.get(regionKey),
|
|
459 |
false);
|
|
460 |
out2 = new BufferedWriter(fw2);
|
|
461 |
|
|
462 |
out2.write(header1 + new Date() + header3 + regionKey +
|
|
463 |
header4 + body1 + "<FONT size=\"+1\"><B>" +
|
|
464 |
regionKey + "</B></FONT>\n<BR>\n<TABLE>\n<TR>\n<TD>");
|
|
465 |
|
|
466 |
boolean found = false;
|
|
467 |
for (String timezoneKey : timezoneList.keySet()) {
|
|
468 |
int regionIndex = timezoneKey.indexOf('/');
|
|
469 |
if (regionIndex == -1 ||
|
|
470 |
!regionKey.equals(timezoneKey.substring(0, regionIndex))) {
|
|
471 |
if (found) {
|
|
472 |
break;
|
|
473 |
} else {
|
|
474 |
continue;
|
|
475 |
}
|
|
476 |
}
|
|
477 |
|
|
478 |
found = true;
|
|
479 |
if (a.containsKey(timezoneKey)) {
|
|
480 |
Object realName = a.get(timezoneKey);
|
|
481 |
while (a.containsKey(realName)) {
|
|
482 |
realName = a.get(realName);
|
|
483 |
}
|
|
484 |
out2.write(timezoneKey +
|
|
485 |
" (alias for " + "<A HREF=\"" +
|
|
486 |
timezoneList.get(realName) +
|
|
487 |
"\" TARGET=\"rightFrame\">" +
|
|
488 |
realName + "</A>)");
|
|
489 |
} else {
|
|
490 |
out2.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
|
491 |
"\" TARGET=\"rightFrame\">" + timezoneKey +
|
|
492 |
"</A>");
|
|
493 |
}
|
|
494 |
out2.write("<BR>\n");
|
|
495 |
}
|
|
496 |
out2.write("</TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
|
497 |
|
|
498 |
out2.close();
|
|
499 |
fw2.close();
|
|
500 |
}
|
|
501 |
out1.write("</FONT></TD>\n</TR></TABLE>\n" + body2 + footer);
|
|
502 |
|
|
503 |
out1.close();
|
|
504 |
fw1.close();
|
|
505 |
|
|
506 |
|
|
507 |
/* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */
|
|
508 |
fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html", false);
|
|
509 |
out1 = new BufferedWriter(fw1);
|
|
510 |
|
|
511 |
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
|
512 |
header4 + body1 +
|
|
513 |
"<FONT size=\"+1\"><B>Sorted by GMT offsets</B></FONT>\n" +
|
|
514 |
"<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
|
|
515 |
"<TR>\n<TD NOWRAP>\n");
|
|
516 |
|
|
517 |
List<Integer> roi = map.getRawOffsetsIndex();
|
|
518 |
List<Set<String>> roit = map.getRawOffsetsIndexTable();
|
|
519 |
|
|
520 |
int index = 0;
|
|
521 |
for (Integer offset : zonesByOffset.keySet()) {
|
|
522 |
int off = roi.get(index);
|
|
523 |
Set<String> perRO = zonesByOffset.get(offset);
|
|
524 |
if (offset == off) {
|
|
525 |
// Merge aliases into zonesByOffset
|
|
526 |
perRO.addAll(roit.get(index));
|
|
527 |
}
|
|
528 |
index++;
|
|
529 |
|
|
530 |
for (String timezoneKey : perRO) {
|
|
531 |
out1.write("<TR>\n<TD><FONT SIZE=\"-1\">(" +
|
|
532 |
Time.toGMTFormat(offset.toString()) +
|
|
533 |
")</FONT></TD>\n<TD>");
|
|
534 |
|
|
535 |
if (a.containsKey(timezoneKey)) {
|
|
536 |
Object realName = a.get(timezoneKey);
|
|
537 |
while (a.containsKey(realName)) {
|
|
538 |
realName = a.get(realName);
|
|
539 |
}
|
|
540 |
out1.write(timezoneKey +
|
|
541 |
" (alias for " + "<A HREF=\"" +
|
|
542 |
timezoneList.get(realName) +
|
|
543 |
"\" TARGET=\"rightFrame\">" + realName +
|
|
544 |
"</A>)");
|
|
545 |
} else {
|
|
546 |
out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
|
547 |
"\" TARGET=\"rightFrame\">" + timezoneKey +
|
|
548 |
"</A>");
|
|
549 |
}
|
|
550 |
out1.write("</TD>\n</TR>\n");
|
|
551 |
}
|
|
552 |
}
|
|
553 |
out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
|
554 |
|
|
555 |
out1.close();
|
|
556 |
fw1.close();
|
|
557 |
|
|
558 |
|
|
559 |
/* Creates allTimeZone-frame2.html (Sorted by zone names) */
|
|
560 |
fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html", false);
|
|
561 |
out1 = new BufferedWriter(fw1);
|
|
562 |
|
|
563 |
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
|
564 |
header4 + body1 +
|
|
565 |
"<FONT size=\"+1\"><B>Sorted by zone names</B></FONT>\n" +
|
|
566 |
"<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
|
|
567 |
"<TR>\n<TD NOWRAP>\n");
|
|
568 |
o = timezoneList.keySet().toArray();
|
|
569 |
len = timezoneList.size();
|
|
570 |
for (int i = 0; i < len; i++) {
|
|
571 |
Object timezoneKey = o[i];
|
|
572 |
if (a.containsKey(timezoneKey)) {
|
|
573 |
Object realName = a.get(timezoneKey);
|
|
574 |
while (a.containsKey(realName)) {
|
|
575 |
realName = a.get(realName);
|
|
576 |
}
|
|
577 |
out1.write(timezoneKey +
|
|
578 |
" (alias for " +
|
|
579 |
"<A HREF=\"" + timezoneList.get(realName) +
|
|
580 |
"\" TARGET=\"rightFrame\">" + realName +
|
|
581 |
"</A>)");
|
|
582 |
} else {
|
|
583 |
out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
|
584 |
"\" TARGET=\"rightFrame\">" + timezoneKey +
|
|
585 |
"</A>");
|
|
586 |
}
|
|
587 |
out1.write("<BR> \n");
|
|
588 |
}
|
|
589 |
out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
|
590 |
|
|
591 |
out1.close();
|
|
592 |
fw1.close();
|
|
593 |
|
|
594 |
/* Creates allTimeZone-frame3.html (Sorted by city names) */
|
|
595 |
fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html", false);
|
|
596 |
out1 = new BufferedWriter(fw1);
|
|
597 |
|
|
598 |
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
|
599 |
header4 + body1 +
|
|
600 |
"<FONT size=\"+1\"><B>Sorted by city names</B></FONT>\n" +
|
|
601 |
"<BR>\n\n" + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n" +
|
|
602 |
"<TR>\n<TD NOWRAP>\n");
|
|
603 |
|
|
604 |
Set<String> aliasSet = a.keySet();
|
|
605 |
len = aliasSet.size();
|
|
606 |
String aliasNames[] = aliasSet.toArray(new String[0]);
|
|
607 |
for (int i = 0; i < len; i++) {
|
|
608 |
displayNameList.put(transform(aliasNames[i]),
|
|
609 |
aliasNames[i]);
|
|
610 |
}
|
|
611 |
|
|
612 |
o = displayNameList.keySet().toArray();
|
|
613 |
len = displayNameList.size();
|
|
614 |
for (int i = 0; i < len; i++) {
|
|
615 |
Object displayName = o[i];
|
|
616 |
Object timezoneKey = displayNameList.get(o[i]);
|
|
617 |
if (a.containsKey(timezoneKey)) {
|
|
618 |
Object realName = a.get(timezoneKey);
|
|
619 |
while (a.containsKey(realName)) {
|
|
620 |
realName = a.get(realName);
|
|
621 |
}
|
|
622 |
out1.write(displayName +
|
|
623 |
" (alias for " +
|
|
624 |
"<A HREF=\"" + timezoneList.get(realName) +
|
|
625 |
"\" TARGET=\"rightFrame\">" + realName +
|
|
626 |
"</A>)");
|
|
627 |
} else {
|
|
628 |
out1.write("<A HREF=\"" + timezoneList.get(timezoneKey) +
|
|
629 |
"\" TARGET=\"rightFrame\">" + displayName +
|
|
630 |
"</A>");
|
|
631 |
}
|
|
632 |
out1.write("<BR> \n");
|
|
633 |
}
|
|
634 |
|
|
635 |
out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2 + footer);
|
|
636 |
|
|
637 |
out1.close();
|
|
638 |
fw1.close();
|
|
639 |
|
|
640 |
/* Creates overview-summary.html */
|
|
641 |
fw1 = new FileWriter(outputDir + "overview-summary.html", false);
|
|
642 |
out1 = new BufferedWriter(fw1);
|
|
643 |
|
|
644 |
out1.write(header1 + new Date() + header2 + Main.getVersionName() +
|
|
645 |
header4 + body1 +
|
|
646 |
"<p>This is the list of time zones generated from <B>" +
|
|
647 |
Main.getVersionName() + "</B> for Java Platform, " +
|
|
648 |
"Standard Edition. The source code can be obtained " +
|
|
649 |
"from ftp site <a href=\"ftp://elsie.nci.nih.gov/pub/\">" +
|
|
650 |
"ftp://elsie.nci.nih.gov/pub/</a>. A total of <B>" +
|
|
651 |
len +
|
|
652 |
"</B> time zones and aliases are supported " +
|
|
653 |
"in this edition. For the " +
|
|
654 |
"format of rules and zones, refer to the zic " +
|
|
655 |
"(zoneinfo compiler) man page on " +
|
|
656 |
"Solaris or Linux.</p>\n" +
|
|
657 |
"<p>Note that the time zone data is not " +
|
|
658 |
"a public interface of the Java Platform. No " +
|
|
659 |
"applications should rely on the time zone data of " +
|
|
660 |
"this document. Time zone names and data " +
|
|
661 |
"may change without any prior notice.</p>\n" +
|
|
662 |
body2 + footer);
|
|
663 |
|
|
664 |
out1.close();
|
|
665 |
fw1.close();
|
|
666 |
} catch(IOException e) {
|
|
667 |
Main.panic("IO error: "+e.getMessage());
|
|
668 |
return 1;
|
|
669 |
}
|
|
670 |
|
|
671 |
return 0;
|
|
672 |
}
|
|
673 |
|
|
674 |
String transform(String s) {
|
|
675 |
int index = s.lastIndexOf("/");
|
|
676 |
|
|
677 |
/* If the string doesn't include any delimiter, return */
|
|
678 |
if (index == -1) {
|
|
679 |
return s;
|
|
680 |
}
|
|
681 |
|
|
682 |
int lastIndex = index;
|
|
683 |
String str = s.substring(index+1);
|
|
684 |
do {
|
|
685 |
index = s.substring(0, lastIndex).lastIndexOf('/');
|
|
686 |
str += ", " + s.substring(index+1, lastIndex);
|
|
687 |
lastIndex = index;
|
|
688 |
} while (index > -1);
|
|
689 |
|
|
690 |
return str;
|
|
691 |
}
|
|
692 |
|
|
693 |
static class LatitudeAndLongitude {
|
|
694 |
|
|
695 |
private int latDeg, latMin, latSec, longDeg, longMin, longSec;
|
|
696 |
|
|
697 |
LatitudeAndLongitude(String s) {
|
|
698 |
try {
|
|
699 |
// First of all, check the string has the correct format:
|
|
700 |
// either +-DDMM+-DDDMM or +-DDMMSS+-DDDMMSS
|
|
701 |
|
|
702 |
if (!s.startsWith("+") && !s.startsWith("-")) {
|
|
703 |
Main.warning("Wrong latitude&longitude data: " + s);
|
|
704 |
return;
|
|
705 |
}
|
|
706 |
int index;
|
|
707 |
if (((index = s.lastIndexOf("+")) <= 0) &&
|
|
708 |
((index = s.lastIndexOf("-")) <= 0)) {
|
|
709 |
Main.warning("Wrong latitude&longitude data: " + s);
|
|
710 |
return;
|
|
711 |
}
|
|
712 |
|
|
713 |
if (index == 5) {
|
|
714 |
latDeg = Integer.parseInt(s.substring(1, 3));
|
|
715 |
latMin = Integer.parseInt(s.substring(3, 5));
|
|
716 |
latSec = 0;
|
|
717 |
} else if (index == 7) {
|
|
718 |
latDeg = Integer.parseInt(s.substring(1, 3));
|
|
719 |
latMin = Integer.parseInt(s.substring(3, 5));
|
|
720 |
latSec = Integer.parseInt(s.substring(5, 7));
|
|
721 |
} else {
|
|
722 |
Main.warning("Wrong latitude&longitude data: " + s);
|
|
723 |
return;
|
|
724 |
}
|
|
725 |
if (s.startsWith("-")){
|
|
726 |
latDeg = -latDeg;
|
|
727 |
latMin = -latMin;
|
|
728 |
latSec = -latSec;
|
|
729 |
}
|
|
730 |
|
|
731 |
int len = s.length();
|
|
732 |
if (index == 5 && len == 11) {
|
|
733 |
longDeg = Integer.parseInt(s.substring(index+1, index+4));
|
|
734 |
longMin = Integer.parseInt(s.substring(index+4, index+6));
|
|
735 |
longSec = 0;
|
|
736 |
} else if (index == 7 && len == 15) {
|
|
737 |
longDeg = Integer.parseInt(s.substring(index+1, index+4));
|
|
738 |
longMin = Integer.parseInt(s.substring(index+4, index+6));
|
|
739 |
longSec = Integer.parseInt(s.substring(index+6, index+8));
|
|
740 |
} else {
|
|
741 |
Main.warning("Wrong latitude&longitude data: " + s);
|
|
742 |
return;
|
|
743 |
}
|
|
744 |
if (s.charAt(index) == '-'){
|
|
745 |
longDeg = -longDeg;
|
|
746 |
longMin = -longMin;
|
|
747 |
longSec = -longSec;
|
|
748 |
}
|
|
749 |
} catch(Exception e) {
|
|
750 |
Main.warning("LatitudeAndLongitude() Parse error: " + s);
|
|
751 |
}
|
|
752 |
}
|
|
753 |
|
|
754 |
int getLatDeg() {
|
|
755 |
return latDeg;
|
|
756 |
}
|
|
757 |
|
|
758 |
int getLatMin() {
|
|
759 |
return latMin;
|
|
760 |
}
|
|
761 |
|
|
762 |
int getLatSec() {
|
|
763 |
return latSec;
|
|
764 |
}
|
|
765 |
|
|
766 |
int getLongDeg() {
|
|
767 |
return longDeg;
|
|
768 |
}
|
|
769 |
|
|
770 |
int getLongMin() {
|
|
771 |
return longMin;
|
|
772 |
}
|
|
773 |
|
|
774 |
int getLongSec() {
|
|
775 |
return longSec;
|
|
776 |
}
|
|
777 |
}
|
|
778 |
}
|