| /* |
| * Copyright (c) 2001, 2013, 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. |
| */ |
| |
| 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)) { |
| 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; |
| } |
| } |
| } |