001: /*
002: * @(#)GenDoc.java 1.8 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package sun.tools.javazic;
029:
030: import java.io.IOException;
031: import java.io.File;
032: import java.io.FileReader;
033: import java.io.FileWriter;
034: import java.io.BufferedReader;
035: import java.io.BufferedWriter;
036: import java.util.ArrayList;
037: import java.util.Calendar;
038: import java.util.Date;
039: import java.util.HashMap;
040: import java.util.Iterator;
041: import java.util.LinkedList;
042: import java.util.Set;
043: import java.util.StringTokenizer;
044: import java.util.TreeMap;
045: import java.util.TreeSet;
046: import sun.util.calendar.CalendarDate;
047: import sun.util.calendar.Gregorian;
048: import sun.util.calendar.ZoneInfoFile;
049:
050: /**
051: * <code>GenDoc</code> is one of back-end classes of javazic, and generates
052: * index.html and other html files which prints the detailed time zone
053: * information for each zone.
054: */
055: class GenDoc extends BackEnd {
056:
057: private static final String docDir = "doc";
058:
059: private static final String header1 = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Frameset//EN\""
060: + "\"http://www.w3.org/TR/REC-html40/frameset.dtd\">\n"
061: + "<HTML>\n<HEAD>\n<!-- Generated by javazic on ";
062: private static final String header2 = "-->\n<TITLE>\n"
063: + "Java 2 Platform Standard Edition - TimeZone information based on ";
064: private static final String header3 = "-->\n<TITLE>\n"
065: + "Java 2 Platform Standard Edition TimeZone - ";
066: private static final String header4 = "</TITLE>\n" + "</HEAD>\n\n";
067:
068: private static final String body1 = "<BODY BGCOLOR=\"white\">\n";
069: private static final String body2 = "</BODY>\n";
070:
071: private static final String footer = "</HTML>\n";
072:
073: // list of time zone name and zonefile name/real time zone name
074: // e.g.
075: // key (String) : value (String)
076: // "America/Denver" : "America/Denver.html" (real time zone)
077: // "America/Shiprock" : "America/Denver" (alias)
078: TreeMap timezoneList = new TreeMap();
079:
080: // list of time zone's display name and time zone name
081: // e.g.
082: // key (String) : value (String)
083: // "Tokyo, Asia" : "Asia/Tokyo"
084: // "Marengo, Indiana, America" : "America/Indiana/Marengo"
085: // (aliases included)
086: TreeMap displayNameList = new TreeMap();
087:
088: // list of top level regions
089: // e.g.
090: // key (String) : value (String)
091: // "America" : "America.html"
092: // (including entries in America/Indiana/, America/Kentucky/, ...)
093: TreeMap regionList = new TreeMap();
094:
095: // mapping list from zone name to latitude & longitude
096: // This list is generated from zone.tab.
097: // e.g.
098: // key (String) : value (LatitudeAndLongitude object)
099: // "Asia/Tokyo" : latitude=35.3916, longitude=13.9444
100: // (aliases not included)
101: HashMap mapList = null;
102:
103: /**
104: * Generates HTML document for each zone.
105: * @param Timezone
106: * @return 0 if no errors, or 1 if error occurred.
107: */
108: int processZoneinfo(Timezone tz) {
109: try {
110: int size;
111: int index;
112: String outputDir = Main.getOutputDir();
113: String zonename = tz.getName();
114: String zonefile = ZoneInfoFile.getFileName(zonename)
115: + ".html";
116: ArrayList stz = tz.getLastRules();
117:
118: timezoneList.put(zonename, zonefile);
119: displayNameList.put(transform(zonename), zonename);
120:
121: /* If outputDir doesn't end with file-separator, adds it. */
122: if (!outputDir.endsWith(File.separator)) {
123: outputDir += File.separatorChar;
124: }
125: outputDir += docDir + File.separatorChar;
126:
127: index = zonename.indexOf('/');
128: if (index != -1) {
129: regionList.put(zonename.substring(0, index), zonename
130: .substring(0, index)
131: + ".html");
132: }
133:
134: /* If zonefile includes file-separator, it's treated as part of
135: * pathname. And make directory if necessary.
136: */
137: index = zonefile.lastIndexOf('/');
138: if (index != -1) {
139: zonefile.replace('/', File.separatorChar);
140: outputDir += zonefile.substring(0, index + 1);
141: }
142: File outD = new File(outputDir);
143: outD.mkdirs();
144:
145: /* If mapfile is available, add a link to the appropriate map */
146: if ((mapList == null) && (Main.getMapFile() != null)) {
147: FileReader fr = new FileReader(Main.getMapFile());
148: BufferedReader in = new BufferedReader(fr);
149: mapList = new HashMap();
150: String line;
151: while ((line = in.readLine()) != null) {
152: // skip blank and comment lines
153: if (line.length() == 0 || line.charAt(0) == '#') {
154: continue;
155: }
156: StringTokenizer tokens = new StringTokenizer(line);
157: String token = tokens.nextToken(); /* We don't use the first token. */
158: token = tokens.nextToken();
159: LatitudeAndLongitude location = new LatitudeAndLongitude(
160: token);
161: token = tokens.nextToken();
162: mapList.put(token, location);
163: }
164: in.close();
165: }
166:
167: /* Open zoneinfo file to write. */
168: FileWriter fw = new FileWriter(outputDir
169: + zonefile.substring(index + 1));
170: BufferedWriter out = new BufferedWriter(fw);
171:
172: out.write(header1 + new Date() + header3 + zonename
173: + header4);
174: out.write(body1 + "<FONT size=\"+2\"><B>" + zonename
175: + "</B></FONT>");
176: LatitudeAndLongitude location = (LatitudeAndLongitude) mapList
177: .get(zonename);
178: if (location != null) {
179: float lat = location.getLatitude();
180: float lon = location.getLongitude();
181: out
182: .write(" "
183: + "<A HREF=\"http://mapweb.parc.xerox.com/map/color=1/border=1/ht=30/lat="
184: + lat + "/lon=" + lon + "/mark=" + lat
185: + "%2C" + lon + "/\">[map]</A>");
186: }
187: out.write("\n<P>\n");
188:
189: ArrayList zone = tz.getZones();
190: ArrayList rule = tz.getRules();
191: if (rule != null && zone != null) {
192: out
193: .write("<TABLE BORDER=\"0\" WIDTH=\"100%\" CELLPADDING=\"1\" CELLSPACING=\"0\">\n"
194: + "<TR>\n"
195: + "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\"><BR>"
196: + "<A HREF=\"#Rule\">Rule</A><BR></TD>\n"
197: + "<TD BGCOLOR=\"#EEEEFF\" WIDTH=\"50%\" ALIGN=\"CENTER\">"
198: + "<A HREF=\"#Zone\"><BR>Zone<BR></A></TD>\n"
199: + "</TR>\n</TABLE>\n");
200: }
201:
202: /* Output Rule records. */
203: if (rule != null) {
204: size = rule.size();
205: out
206: .write("<P>\n<A NAME=\"Rule\">"
207: + "<FONT SIZE=\"+1\"><B>Rules</B></FONT></A>\n"
208: + "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n"
209: + "<TR BGCOLOR=\"#CCCCFF\">\n"
210: + "<TD>NAME</TD><TD>FROM</TD><TD>TO</TD><TD>TYPE</TD>"
211: + "<TD>IN</TD><TD>ON</TD><TD>AT</TD><TD>SAVE</TD>"
212: + "<TD>LETTER/S</TD><TD>NOTES</TD>\n</TR>\n");
213: for (int i = 0; i < size; i++) {
214: out.write("<TR BGCOLOR=\"#FFFFFF\">\n");
215: StringTokenizer st = new StringTokenizer(
216: ((RuleRec) rule.get(i)).getLine());
217: String s;
218: if (st.hasMoreTokens()) { /* RULE - truncated */
219: st.nextToken();
220: }
221: if (st.hasMoreTokens()) { /* NAME */
222: out.write("<TD>" + st.nextToken() + "</TD>");
223: }
224: if (st.hasMoreTokens()) { /* FROM */
225: out.write("<TD>" + st.nextToken() + "</TD>");
226: }
227: if (st.hasMoreTokens()) { /* TO */
228: s = st.nextToken();
229: if (s.equals("max")) {
230: out.write("<TD><FONT COLOR=\"red\">" + s
231: + "</FONT></TD>");
232: } else {
233: out.write("<TD>" + s + "</TD>");
234: }
235: }
236: if (st.hasMoreTokens()) { /* TYPE */
237: out.write("<TD>" + st.nextToken() + "</TD>");
238: }
239: if (st.hasMoreTokens()) { /* IN */
240: out.write("<TD>" + st.nextToken() + "</TD>");
241: }
242: if (st.hasMoreTokens()) { /* ON */
243: out.write("<TD>" + st.nextToken() + "</TD>");
244: }
245: if (st.hasMoreTokens()) { /* AT */
246: out.write("<TD>" + st.nextToken() + "</TD>");
247: }
248: if (st.hasMoreTokens()) { /* SAVE */
249: out.write("<TD>" + st.nextToken() + "</TD>");
250: }
251: if (st.hasMoreTokens()) { /* LETTER/S */
252: out.write("<TD>" + st.nextToken() + "</TD>");
253: }
254: if (st.hasMoreTokens()) { /* NOTES */
255: s = st.nextToken();
256: while (st.hasMoreTokens()) {
257: s += " " + st.nextToken();
258: }
259: index = s.indexOf('#');
260: out.write("<TD>" + s.substring(index + 1)
261: + "</TD>\n");
262: } else {
263: out.write("<TD> </TD>\n");
264: }
265: out.write("</TR>\n");
266: }
267: out.write("</TABLE>\n<P> <P>\n");
268: }
269:
270: /* Output Zone records. */
271: if (zone != null) {
272: size = zone.size();
273: out
274: .write("<P>\n<A NAME=\"Zone\">"
275: + "<FONT SIZE=\"+1\"><B>Zones</B></FONT></A>\n"
276: + "<TABLE BORDER=\"1\" WIDTH=\"100%\" CELLPADDING=\"3\" CELLSPACING=\"0\">\n"
277: + "<TR BGCOLOR=\"#CCCCFF\">\n<TD>GMTOFF</TD>"
278: + "<TD>RULES</TD><TD>FORMAT</TD><TD>UNTIL</TD>"
279: + "<TD>NOTES</TD>\n</TR>\n");
280: for (int i = 0; i < size; i++) {
281: out.write("<TR>\n");
282: StringTokenizer st = new StringTokenizer(
283: ((ZoneRec) zone.get(i)).getLine());
284: String s = st.nextToken();
285: if (s.equals("Zone")) { /* NAME */
286: s = st.nextToken();
287: s = st.nextToken();
288: }
289: out.write("<TD>" + s + "</TD>"); /* GMTOFFSET */
290: if (st.hasMoreTokens()) { /* RULES */
291: out.write("<TD>" + st.nextToken() + "</TD>");
292: }
293: if (st.hasMoreTokens()) { /* FORMAT */
294: s = st.nextToken();
295: index = s.indexOf('#');
296: if (index != -1) {
297: if (index != 0) {
298: out.write("<TD>"
299: + s.substring(0, index - 1)
300: + "</TD>"); /* FORMAT */
301: s = s.substring(index + 1);
302: } else {
303: out.write("<TD> </TD>"); /* FORMAT */
304: }
305: while (st.hasMoreTokens()) {
306: s += " " + st.nextToken();
307: }
308: out.write("<TD> </TD>"); /* UNTIL */
309: out.write("<TD>" + s + "</TD>\n</TR>\n"); /* NOTES */
310: continue;
311: } else {
312: out.write("<TD>" + s + "</TD>"); /* FORMAT */
313: }
314: }
315:
316: if (st.hasMoreTokens()) { /* UNTIL */
317: s = st.nextToken();
318: while (st.hasMoreTokens()) {
319: s += " " + st.nextToken();
320: }
321: index = s.indexOf('#');
322: if (index != -1) {
323: if (index != 0) {
324: out.write("<TD>"
325: + s.substring(0, index - 1)
326: + "</TD>"); /* UNTIL */
327: } else {
328: out.write("<TD> </TD>"); /* UNTIL */
329: }
330: out.write("<TD>" + s.substring(index + 1)
331: + "</TD>\n"); /* NOTES */
332: } else {
333: out.write("<TD>" + s + "</TD>"); /* UNTIL */
334: out.write("<TD> </TD>\n"); /* NOTES */
335: }
336: } else {
337: out.write("<TD> </TD>"); /* UNTIL */
338: out.write("<TD> </TD>\n"); /* NOTES */
339: }
340: out.write("</TR>\n");
341: }
342: out.write("</TABLE>\n");
343: }
344: out.write(body2 + footer);
345:
346: out.close();
347: fw.close();
348: } catch (IOException e) {
349: Main.panic("IO error: " + e.getMessage());
350: return 1;
351: }
352:
353: return 0;
354: }
355:
356: /**
357: * Generates index.html and other top-level frame files.
358: * @param Mappings
359: * @return 0 if no errors, or 1 if error occurred.
360: */
361: int generateSrc(Mappings map) {
362: try {
363: int len;
364: Object o[];
365: String outputDir = Main.getOutputDir();
366: FileWriter fw1, fw2;
367: BufferedWriter out1, out2;
368:
369: /* Whether rawOffsetIndex list exists or not. */
370: LinkedList roi = map.getRawOffsetsIndex();
371: if (roi == null) {
372: Main.panic("Data not exist. (rawOffsetsIndex)");
373: return 1;
374: }
375: int roi_size = roi.size();
376: LinkedList roit = map.getRawOffsetsIndexTable();
377: if (roit == null || roit.size() != roi_size) {
378: Main
379: .panic("Data not exist. (rawOffsetsIndexTable) Otherwise, Invalid size");
380: return 1;
381: }
382:
383: /* Whether alias list exists or not. */
384: TreeMap a = map.getAliases();
385: if (a == null) {
386: Main.panic("Data not exist. (aliases)");
387: return 1;
388: }
389:
390: timezoneList.putAll(a);
391:
392: /* If outputDir doesn't end with file-separator, adds it. */
393: if (!outputDir.endsWith(File.separator)) {
394: outputDir += File.separatorChar;
395: }
396: outputDir += docDir + File.separatorChar;
397:
398: File outD = new File(outputDir);
399: outD.mkdirs();
400:
401: /* Creates index.html */
402: fw1 = new FileWriter(outputDir + "index.html", false);
403: out1 = new BufferedWriter(fw1);
404:
405: out1
406: .write(header1
407: + new Date()
408: + header2
409: + Main.getVersionName()
410: + header4
411: + "<FRAMESET cols=\"20%,80%\">\n"
412: + "<FRAMESET rows=\"30%,70%\">\n"
413: + "<FRAME src=\"overview-frame.html\" name=\"TimeZoneListFrame\">\n"
414: + "<FRAME src=\"allTimeZone-frame1.html\" name=\"allTimeZoneFrame\">\n"
415: + "</FRAMESET>"
416: + "<FRAME src=\"overview-summary.html\" name=\"rightFrame\">\n"
417: + "</FRAMESET>\n"
418: + "<NOFRAMES>\n"
419: + "<H2>\nFrame Alert\n</H2>\n\n"
420: + "<P>\n\n"
421: + "This document is designed to be viewed using the frames feature. If you see this\n"
422: + "message, you are using a non-frame-capable web client.\n"
423: + "<BR>\n"
424: + "Link to<A HREF=\"overview-summary.html\">Non-frame version.</A>\n"
425: + "</NOFRAMES>\n" + footer);
426:
427: out1.close();
428: fw1.close();
429:
430: /* Creates overview-frame.html */
431: fw1 = new FileWriter(outputDir + "overview-frame.html",
432: false);
433: out1 = new BufferedWriter(fw1);
434:
435: out1
436: .write(header1
437: + new Date()
438: + header2
439: + Main.getVersionName()
440: + header4
441: + 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> 2 Platform<br>Std. 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: o = regionList.keySet().toArray();
454: len = regionList.size();
455: Object tzo[] = timezoneList.keySet().toArray();
456: int tzlen = timezoneList.size();
457: for (int i = 0; i < len; i++) {
458: Object regionKey = o[i];
459: out1.write(" <A HREF=\""
460: + regionList.get(regionKey)
461: + "\" TARGET=\"allTimeZoneFrame\">" + regionKey
462: + "</A><BR>\n");
463:
464: fw2 = new FileWriter(outputDir
465: + regionList.get(regionKey), false);
466: out2 = new BufferedWriter(fw2);
467:
468: out2.write(header1 + new Date() + header3 + regionKey
469: + header4 + body1 + "<FONT size=\"+1\"><B>"
470: + regionKey
471: + "</B></FONT>\n<BR>\n<TABLE>\n<TR>\n<TD>");
472:
473: boolean found = false;
474: for (int j = 0; j < tzlen; j++) {
475: String timezoneKey = (String) tzo[j];
476: int regionIndex = timezoneKey.indexOf('/');
477: if (regionIndex == -1
478: || !regionKey.equals(timezoneKey.substring(
479: 0, regionIndex))) {
480: if (found) {
481: break;
482: } else {
483: continue;
484: }
485: }
486:
487: found = true;
488: if (a.containsKey(timezoneKey)) {
489: Object realName = a.get(timezoneKey);
490: while (a.containsKey(realName)) {
491: realName = a.get(realName);
492: }
493: out2.write(timezoneKey + " (alias for "
494: + "<A HREF=\""
495: + timezoneList.get(realName)
496: + "\" TARGET=\"rightFrame\">"
497: + realName + "</A>)");
498: } else {
499: out2.write("<A HREF=\""
500: + timezoneList.get(timezoneKey)
501: + "\" TARGET=\"rightFrame\">"
502: + timezoneKey + "</A>");
503: }
504: out2.write("<BR>\n");
505: }
506: out2.write("</TD>\n</TR>\n</TABLE>\n" + body2 + footer);
507:
508: out2.close();
509: fw2.close();
510: }
511: out1
512: .write("</FONT></TD>\n</TR></TABLE>\n" + body2
513: + footer);
514:
515: out1.close();
516: fw1.close();
517:
518: /* Creates allTimeZone-frame1.html (Sorted by GMT offsets) */
519: fw1 = new FileWriter(outputDir + "allTimeZone-frame1.html",
520: false);
521: out1 = new BufferedWriter(fw1);
522:
523: out1
524: .write(header1
525: + new Date()
526: + header2
527: + Main.getVersionName()
528: + header4
529: + body1
530: + "<FONT size=\"+1\"><B>Sorted by GMT offsets</B></FONT>\n"
531: + "<BR>\n\n"
532: + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n"
533: + "<TR>\n<TD NOWRAP>\n");
534: for (int i = 0; i < roi_size; i++) {
535: TreeSet perRO = (TreeSet) roit.get(i);
536: Iterator keys = perRO.iterator();
537: while (keys.hasNext()) {
538: Object timezoneKey = keys.next();
539: out1.write("<TR>\n<TD><FONT SIZE=\"-1\">("
540: + Time.toGMTFormat(roi.get(i).toString())
541: + ")</FONT></TD>\n<TD>");
542:
543: if (a.containsKey(timezoneKey)) {
544: Object realName = a.get(timezoneKey);
545: while (a.containsKey(realName)) {
546: realName = a.get(realName);
547: }
548: out1.write(timezoneKey + " (alias for "
549: + "<A HREF=\""
550: + timezoneList.get(realName)
551: + "\" TARGET=\"rightFrame\">"
552: + realName + "</A>)");
553: } else {
554: out1.write("<A HREF=\""
555: + timezoneList.get(timezoneKey)
556: + "\" TARGET=\"rightFrame\">"
557: + timezoneKey + "</A>");
558: }
559: out1.write("</TD>\n</TR>\n");
560: }
561: }
562: out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2
563: + footer);
564:
565: out1.close();
566: fw1.close();
567:
568: /* Creates allTimeZone-frame2.html (Sorted by zone names) */
569: fw1 = new FileWriter(outputDir + "allTimeZone-frame2.html",
570: false);
571: out1 = new BufferedWriter(fw1);
572:
573: out1
574: .write(header1
575: + new Date()
576: + header2
577: + Main.getVersionName()
578: + header4
579: + body1
580: + "<FONT size=\"+1\"><B>Sorted by zone names</B></FONT>\n"
581: + "<BR>\n\n"
582: + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n"
583: + "<TR>\n<TD NOWRAP>\n");
584: o = timezoneList.keySet().toArray();
585: len = timezoneList.size();
586: for (int i = 0; i < len; i++) {
587: Object timezoneKey = o[i];
588: if (a.containsKey(timezoneKey)) {
589: Object realName = a.get(timezoneKey);
590: while (a.containsKey(realName)) {
591: realName = a.get(realName);
592: }
593: out1.write(timezoneKey + " (alias for "
594: + "<A HREF=\"" + timezoneList.get(realName)
595: + "\" TARGET=\"rightFrame\">" + realName
596: + "</A>)");
597: } else {
598: out1.write("<A HREF=\""
599: + timezoneList.get(timezoneKey)
600: + "\" TARGET=\"rightFrame\">" + timezoneKey
601: + "</A>");
602: }
603: out1.write("<BR> \n");
604: }
605: out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2
606: + footer);
607:
608: out1.close();
609: fw1.close();
610:
611: /* Creates allTimeZone-frame3.html (Sorted by city names) */
612: fw1 = new FileWriter(outputDir + "allTimeZone-frame3.html",
613: false);
614: out1 = new BufferedWriter(fw1);
615:
616: out1
617: .write(header1
618: + new Date()
619: + header2
620: + Main.getVersionName()
621: + header4
622: + body1
623: + "<FONT size=\"+1\"><B>Sorted by city names</B></FONT>\n"
624: + "<BR>\n\n"
625: + "<TABLE BORDER=\"0\" WIDTH=\"100%\">\n"
626: + "<TR>\n<TD NOWRAP>\n");
627:
628: Set aliasSet = a.keySet();
629: len = aliasSet.size();
630: Object aliasNames[] = aliasSet.toArray();
631: for (int i = 0; i < len; i++) {
632: displayNameList.put(transform((String) aliasNames[i]),
633: aliasNames[i]);
634: }
635:
636: o = displayNameList.keySet().toArray();
637: len = displayNameList.size();
638: for (int i = 0; i < len; i++) {
639: Object displayName = o[i];
640: Object timezoneKey = displayNameList.get(o[i]);
641: if (a.containsKey(timezoneKey)) {
642: Object realName = a.get(timezoneKey);
643: while (a.containsKey(realName)) {
644: realName = a.get(realName);
645: }
646: out1.write(displayName + " (alias for "
647: + "<A HREF=\"" + timezoneList.get(realName)
648: + "\" TARGET=\"rightFrame\">" + realName
649: + "</A>)");
650: } else {
651: out1.write("<A HREF=\""
652: + timezoneList.get(timezoneKey)
653: + "\" TARGET=\"rightFrame\">" + displayName
654: + "</A>");
655: }
656: out1.write("<BR> \n");
657: }
658:
659: out1.write("</FONT></TD>\n</TR>\n</TABLE>\n" + body2
660: + footer);
661:
662: out1.close();
663: fw1.close();
664:
665: /* Creates overview-summary.html */
666: fw1 = new FileWriter(outputDir + "overview-summary.html",
667: false);
668: out1 = new BufferedWriter(fw1);
669:
670: out1
671: .write(header1
672: + new Date()
673: + header2
674: + Main.getVersionName()
675: + header4
676: + body1
677: + "This is the list of time zones generated from <B>"
678: + Main.getVersionName()
679: + "</B> for Java 2 Platform, "
680: + "Standard Edition. The source code can be obtained "
681: + "from ftp site <a href=\"ftp://elsie.nci.nih.gov/pub/\">"
682: + "ftp://elsie.nci.nih.gov/pub/</a>. A total of <B>"
683: + len
684: + "</B> time zones and aliases are supported "
685: + "in this edition.\n<BR>\n"
686: + "(This site keeps only the latest release.)\nFor the "
687: + "format of rules and zones, refer to the zic "
688: + "(zoneinfo compiler) man page on "
689: + "<a href=\"http://docs.sun.com/ab2/coll.40.6/REFMAN1M/@Ab2PageView/266070?DwebQuery=zic&oqt=zic&Ab2Lang=C&Ab2Enc=iso-8859-1\">Solaris</a> "
690: + "or Linux.\n<p>\nNote that this time zone data is not "
691: + "a public interface of the Java run-time. No "
692: + "applications should rely on the time zone data on "
693: + "this web page. Time zone names and time zone data "
694: + "may change without any prior notice.\n"
695: + body2 + footer);
696:
697: out1.close();
698: fw1.close();
699: } catch (IOException e) {
700: Main.panic("IO error: " + e.getMessage());
701: return 1;
702: }
703:
704: return 0;
705: }
706:
707: String transform(String s) {
708: int index = s.lastIndexOf("/");
709:
710: /* If the string doesn't include any delimiter, return */
711: if (index == -1) {
712: return s;
713: }
714:
715: int lastIndex = index;
716: String str = s.substring(index + 1);
717: do {
718: index = s.substring(0, lastIndex).lastIndexOf('/');
719: str += ", " + s.substring(index + 1, lastIndex);
720: lastIndex = index;
721: } while (index > -1);
722:
723: return str;
724: }
725: }
726:
727: class LatitudeAndLongitude {
728: private float latitude;
729: private float longitude;
730:
731: LatitudeAndLongitude(String s) {
732: try {
733: if (!s.startsWith("+") && !s.startsWith("-")) {
734: Main.warning("Wrong latitude&longitude data: " + s);
735: return;
736: }
737:
738: int index;
739: if (((index = s.lastIndexOf("+")) <= 0)
740: && ((index = s.lastIndexOf("-")) <= 0)) {
741: Main.warning("Wrong latitude&longitude data: " + s);
742: return;
743: }
744:
745: latitude = ((s.startsWith("+")) ? 1 : -1)
746: * Float.parseFloat(s.substring(1, index));
747: if (index > 5) {
748: latitude /= 10000;
749: } else {
750: latitude /= 100;
751: }
752:
753: longitude = ((s.charAt(index) == '+') ? 1 : -1)
754: * Float.parseFloat(s.substring(index + 1));
755: if ((s.length() - index) > 6) {
756: longitude /= 10000;
757: } else {
758: longitude /= 100;
759: }
760: } catch (Exception e) {
761: Main.warning("LatitudeAndLongitude() Parse error: " + s);
762: }
763: }
764:
765: float getLatitude() {
766: return latitude;
767: }
768:
769: float getLongitude() {
770: return longitude;
771: }
772: }
|