001: /*
002: * Copyright 2000-2004 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package sun.tools.javazic;
027:
028: import java.io.BufferedReader;
029: import java.io.FileReader;
030: import java.io.FileNotFoundException;
031: import java.io.IOException;
032: import java.util.ArrayList;
033: import java.util.HashMap;
034: import java.util.HashSet;
035: import java.util.List;
036: import java.util.Map;
037: import java.util.Set;
038: import java.util.StringTokenizer;
039:
040: /**
041: * ZoneRec hold information of time zone corresponding to each text
042: * line of the "Zone" part.
043: *
044: * @since 1.4
045: */
046: class ZoneRec {
047: private int gmtOffset;
048: private String ruleName;
049: private int directSave;
050: private Rule ruleRef;
051: private String format;
052: private boolean hasUntil;
053: private int untilYear;
054: private Month untilMonth;
055: private RuleDay untilDay;
056: private Time untilTime;
057: private long untilInMillis;
058: private String line;
059:
060: /**
061: * @return the "UNTIL" value in milliseconds
062: */
063: Time getUntilTime() {
064: return untilTime;
065: }
066:
067: /**
068: * @return the GMT offset value in milliseconds
069: */
070: int getGmtOffset() {
071: return gmtOffset;
072: }
073:
074: /**
075: * @return the rule name to which this zone record refers
076: */
077: String getRuleName() {
078: return ruleName;
079: }
080:
081: /**
082: * @return the amount of saving time directly defined in the
083: * "RULES/SAVE" field.
084: */
085: int getDirectSave() {
086: return directSave;
087: }
088:
089: /**
090: * @return true if this zone record has a reference to a rule
091: */
092: boolean hasRuleReference() {
093: return ruleRef != null;
094: }
095:
096: /**
097: * Returns the "FORMAT" field string of this zone record. This
098: * @return the "FORMAT" field
099: */
100: String getFormat() {
101: return format;
102: }
103:
104: /**
105: * @return the year in the "UNTIL" field
106: */
107: int getUntilYear() {
108: return untilYear;
109: }
110:
111: /**
112: * Returns the "UNTIL" field value in milliseconds from Janurary
113: * 1, 1970 0:00 GMT.
114: * @param currentSave the amount of daylight saving in
115: * milliseconds that is used to adjust wall-clock time.
116: * @return the milliseconds value of the "UNTIL" field
117: */
118: long getUntilTime(int currentSave) {
119: if (untilTime.isWall()) {
120: return untilInMillis - currentSave;
121: }
122: return untilInMillis;
123: }
124:
125: /**
126: * Returns the "UNTIL" time in milliseconds without adjusting GMT
127: * offsets or daylight saving.
128: * @return local "UNTIL" time in milliseconds
129: */
130: long getLocalUntilTime() {
131: return Time.getLocalTime(untilYear, untilMonth, untilDay,
132: untilTime.getTime());
133: }
134:
135: /**
136: * Returns the "UNTIL" time in milliseconds with adjusting GMT offsets and daylight saving.
137: * @return the "UNTIL" time after the adjustment
138: */
139: long getLocalUntilTime(int save, int gmtOffset) {
140: return Time.getLocalTime(untilYear, untilMonth, untilDay, save,
141: gmtOffset, untilTime);
142: }
143:
144: /**
145: * @return the text line of this zone record
146: */
147: String getLine() {
148: return line;
149: }
150:
151: /**
152: * Sets the specified text line to this zone record
153: */
154: void setLine(String line) {
155: this .line = line;
156: }
157:
158: /**
159: * @return true if this zone record has the "UNTIL" field
160: */
161: boolean hasUntil() {
162: return this .hasUntil;
163: }
164:
165: /**
166: * Adjusts the "UNTIL" time to GMT offset if this zone record has
167: * it. <code>untilTime</code> is not adjusted to daylight saving
168: * in this method.
169: */
170: void adjustTime() {
171: if (!hasUntil()) {
172: return;
173: }
174: if (untilTime.isSTD() || untilTime.isWall()) {
175: // adjust to gmt offset only here. adjust to real
176: // wall-clock time when tracking rules
177: untilInMillis -= gmtOffset;
178: }
179: }
180:
181: /**
182: * @return the reference to the Rule object
183: */
184: Rule getRuleRef() {
185: return ruleRef;
186: }
187:
188: /**
189: * Resolves the reference to a Rule and adjusts its "UNTIL" time
190: * to GMT offset.
191: */
192: void resolve(Zoneinfo zi) {
193: if (ruleName != null && (!"-".equals(ruleName))) {
194: ruleRef = zi.getRule(ruleName);
195: }
196: adjustTime();
197: }
198:
199: /**
200: * Parses a Zone text line that is described by a StringTokenizer.
201: * @param tokens represents tokens of a Zone text line
202: * @return the zone record produced by parsing the text
203: */
204: static ZoneRec parse(StringTokenizer tokens) {
205: ZoneRec rec = new ZoneRec();
206: try {
207: rec.gmtOffset = (int) Time.parse(tokens.nextToken())
208: .getTime();
209: String token = tokens.nextToken();
210: char c = token.charAt(0);
211: if (c >= '0' && c <= '9') {
212: rec.directSave = (int) Time.parse(token).getTime();
213: } else {
214: rec.ruleName = token;
215: }
216: rec.format = tokens.nextToken();
217: if (tokens.hasMoreTokens()) {
218: rec.hasUntil = true;
219: rec.untilYear = Integer.parseInt(tokens.nextToken());
220: if (tokens.hasMoreTokens()) {
221: rec.untilMonth = Month.parse(tokens.nextToken());
222: } else {
223: rec.untilMonth = Month.JANUARY;
224: }
225: if (tokens.hasMoreTokens()) {
226: rec.untilDay = RuleDay.parse(tokens.nextToken());
227: } else {
228: rec.untilDay = new RuleDay(1);
229: }
230: if (tokens.hasMoreTokens()) {
231: rec.untilTime = Time.parse(tokens.nextToken());
232: } else {
233: rec.untilTime = Time.parse("0:00");
234: }
235: rec.untilInMillis = rec.getLocalUntilTime();
236: }
237: } catch (Exception e) {
238: // TODO: error reporting
239: e.printStackTrace();
240: }
241: return rec;
242: }
243:
244: private static void panic(String msg) {
245: Main.panic(msg);
246: }
247: }
|