1/*
2 * Copyright (c) 2000, 2013, 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
26import java.util.ArrayList;
27import java.util.List;
28
29/**
30 * Main class for the javazic time zone data compiler.
31 *
32 * @since 1.4
33 */
34public class Main {
35
36    private static boolean verbose = false;
37    static boolean outputDoc = false;
38
39    private List<String> ziFiles = new ArrayList<String>();
40    private static String zoneNamesFile = null;
41    private static String versionName = "unknown";
42    private static String outputDir = "zoneinfo";
43    private static String mapFile = null;
44
45    /**
46     * Parses the specified arguments and sets up the variables.
47     * @param argv the arguments
48     */
49    void processArgs(String[] argv) {
50        for (int i = 0; i < argv.length; i++) {
51            String arg = argv[i];
52            if (arg.startsWith("-h")) {
53                usage();
54                System.exit(0);
55            } else if (arg.equals("-d")) {
56                outputDir = argv[++i];
57            } else if (arg.equals("-v")) {
58                verbose = true;
59            } else if (arg.equals("-V")) {
60                versionName = argv[++i];
61            } else if (arg.equals("-doc")) {
62                outputDoc = true;
63            } else if (arg.equals("-map")) {
64                outputDoc = true;
65                mapFile = argv[++i];
66            } else if (arg.equals("-f")) {
67                zoneNamesFile = argv[++i];
68            } else if (arg.equals("-S")) {
69                try {
70                    Zoneinfo.setYear(Integer.parseInt(argv[++i]));
71                } catch (Exception e) {
72                    error("invalid year: " + argv[i]);
73                    usage();
74                    System.exit(1);
75                }
76            } else {
77                boolean isStartYear = arg.equals("-s");
78                if (isStartYear || arg.equals("-e")) {
79                    try {
80                        int year = Integer.parseInt(argv[++i]);
81                        if (isStartYear) {
82                            Zoneinfo.setStartYear(year);
83                        } else {
84                            Zoneinfo.setEndYear(year);
85                        }
86                    } catch (Exception e) {
87                        error("invalid year: " + argv[i]);
88                        usage();
89                        System.exit(1);
90                    }
91                } else {
92                    // the rest of args are zoneinfo source files
93                    while (i < argv.length) {
94                        ziFiles.add(argv[i++]);
95                    }
96                }
97            }
98        }
99    }
100
101    /**
102     * Parses zoneinfo source files
103     */
104    int compile() {
105        int nFiles = ziFiles.size();
106        int status = 0;
107        Mappings maps = new Mappings();
108        BackEnd backend = BackEnd.getBackEnd();
109
110        for (int i = 0; i < nFiles; i++) {
111            Zoneinfo frontend = Zoneinfo.parse(ziFiles.get(i));
112
113            for (String key : frontend.getZones().keySet()) {
114                info(key);
115
116                Timezone tz = frontend.phase2(key);
117                status |= backend.processZoneinfo(tz);
118            }
119
120            maps.add(frontend);
121        }
122
123        // special code for dealing with the conflicting name "MET"
124        Zone.addMET();
125
126        maps.resolve();
127
128        status |= backend.generateSrc(maps);
129
130        return status;
131    }
132
133    public static void main(String[] argv) {
134        Main zic = new Main();
135
136        /*
137         * Parse args
138         */
139        zic.processArgs(argv);
140
141        /*
142         * Read target zone names
143         */
144        if (zoneNamesFile != null) {
145            Zone.readZoneNames(zoneNamesFile);
146        }
147
148        zic.compile();
149    }
150
151    void usage() {
152        System.err.println("Usage: javazic [options] file...\n"+
153                           "         -f namefile  file containing zone names\n"+
154                           "                      to be generated (ie, generating subset)\n"+
155                           "         -d dir       output directory\n"+
156                           "         -v           verbose\n"+
157                           "         -V datavers  specifies the tzdata version string\n"+
158                           "                      (eg, \"tzdata2000g\")"+
159                           "         -S year      output only SimleTimeZone data of that year\n"+
160                           "         -s year      start year (default: 1900)\n"+
161                           "         -e year      end year (default: 2037)\n"+
162                           "         -doc         generates HTML documents\n"+
163                           "         -map mapfile generates HTML documents with map information\n"+
164                           "         file...      zoneinfo source file(s)");
165    }
166
167    /**
168     * @return the output directory path name
169     */
170    static String getOutputDir() {
171        return outputDir;
172    }
173
174    /**
175     * @return the map file's path and name
176     */
177    static String getMapFile() {
178        return mapFile;
179    }
180
181    /**
182     * Returns the time zone data version string specified by the -V
183     * option. If it is not specified, "unknown" is returned.
184     * @return the time zone data version string
185     */
186    static String getVersionName() {
187        return versionName;
188    }
189
190    /**
191     * Prints out the specified fatal error message and calls {@link
192     * java.lang.System#exit System.exit(1)}.
193     * @param msg the fatal error message
194     */
195    static void panic(String msg) {
196        printMessage("fatal error", msg);
197        System.exit(1);
198    }
199
200    /**
201     * Prints out the specified error message.
202     * @param msg the error message
203     */
204    static void error(String msg) {
205        printMessage("error", msg);
206    }
207
208    /**
209     * Prints out the specified warning message.
210     * @param msg the warning message
211     */
212    static void warning(String msg) {
213        printMessage("warning", msg);
214    }
215
216    /**
217     * Prints out the informative message.
218     * @param msg the informative message
219     */
220    static void info(String msg) {
221        if (verbose) {
222            printMessage(null, msg);
223        }
224    }
225
226    private static void printMessage(String type, String msg) {
227        if (type != null) {
228            type += ": ";
229        } else {
230            type = "";
231        }
232        System.err.println("javazic: " + type + msg);
233    }
234}
235