Util.java revision 3170:dc017a37aac5
1/*
2 * Copyright (c) 2002, 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
26package com.sun.tools.javah;
27
28import java.io.PrintWriter;
29import java.text.MessageFormat;
30import java.util.Locale;
31import java.util.ResourceBundle;
32import java.util.MissingResourceException;
33import javax.tools.Diagnostic;
34import javax.tools.Diagnostic.Kind;
35import javax.tools.DiagnosticListener;
36import javax.tools.JavaFileObject;
37
38import com.sun.tools.javac.util.DefinedBy;
39import com.sun.tools.javac.util.DefinedBy.Api;
40
41/**
42 * Messages, verbose and error handling support.
43 *
44 * For errors, the failure modes are:
45 *      error -- User did something wrong
46 *      bug   -- Bug has occurred in javah
47 *      fatal -- We can't even find resources, so bail fast, don't localize
48 *
49 * <p><b>This is NOT part of any supported API.
50 * If you write code that depends on this, you do so at your own
51 * risk.  This code and its internal interfaces are subject to change
52 * or deletion without notice.</b></p>
53 */
54public class Util {
55    /** Exit is used to replace the use of System.exit in the original javah.
56     */
57    public static class Exit extends Error {
58        private static final long serialVersionUID = 430820978114067221L;
59        Exit(int exitValue) {
60            this(exitValue, null);
61        }
62
63        Exit(int exitValue, Throwable cause) {
64            super(cause);
65            this.exitValue = exitValue;
66            this.cause = cause;
67        }
68
69        Exit(Exit e) {
70            this(e.exitValue, e.cause);
71        }
72
73        public final int exitValue;
74        public final Throwable cause;
75    }
76
77    /*
78     * Help for verbosity.
79     */
80    public boolean verbose = false;
81
82    public PrintWriter log;
83    public DiagnosticListener<? super JavaFileObject> dl;
84
85    Util(PrintWriter log, DiagnosticListener<? super JavaFileObject> dl) {
86        this.log = log;
87        this.dl = dl;
88    }
89
90    public void log(String s) {
91        log.println(s);
92    }
93
94
95    /*
96     * Help for loading localized messages.
97     */
98    private ResourceBundle m;
99
100    private void initMessages() throws Exit {
101        try {
102            m = ResourceBundle.getBundle("com.sun.tools.javah.resources.l10n");
103        } catch (MissingResourceException mre) {
104            fatal("Error loading resources.  Please file a bug report.", mre);
105        }
106    }
107
108    private String getText(String key, Object... args) throws Exit {
109        if (m == null)
110            initMessages();
111        try {
112            return MessageFormat.format(m.getString(key), args);
113        } catch (MissingResourceException e) {
114            fatal("Key " + key + " not found in resources.", e);
115        }
116        return null; /* dead code */
117    }
118
119    /*
120     * Usage message.
121     */
122    public void usage() throws Exit {
123        log.println(getText("usage"));
124    }
125
126    public void version() throws Exit {
127        log.println(getText("javah.version",
128                                   System.getProperty("java.version"), null));
129    }
130
131    /*
132     * Failure modes.
133     */
134    public void bug(String key) throws Exit {
135        bug(key, null);
136    }
137
138    public void bug(String key, Exception e) throws Exit {
139        dl.report(createDiagnostic(Diagnostic.Kind.ERROR, key));
140        dl.report(createDiagnostic(Diagnostic.Kind.NOTE, "bug.report"));
141        throw new Exit(11, e);
142    }
143
144    public void error(String key, Object... args) throws Exit {
145        dl.report(createDiagnostic(Diagnostic.Kind.ERROR, key, args));
146        throw new Exit(15);
147    }
148
149    private void fatal(String msg, Exception e) throws Exit {
150        dl.report(createDiagnostic(Diagnostic.Kind.ERROR, "", msg));
151        throw new Exit(10, e);
152    }
153
154    private Diagnostic<JavaFileObject> createDiagnostic(
155            final Diagnostic.Kind kind, final String code, final Object... args) {
156        return new Diagnostic<JavaFileObject>() {
157            @DefinedBy(Api.COMPILER)
158            public String getCode() {
159                return code;
160            }
161            @DefinedBy(Api.COMPILER)
162            public long getColumnNumber() {
163                return Diagnostic.NOPOS;
164            }
165            @DefinedBy(Api.COMPILER)
166            public long getEndPosition() {
167                return Diagnostic.NOPOS;
168            }
169            @DefinedBy(Api.COMPILER)
170            public Kind getKind() {
171                return kind;
172            }
173            @DefinedBy(Api.COMPILER)
174            public long getLineNumber() {
175                return Diagnostic.NOPOS;
176            }
177            @DefinedBy(Api.COMPILER)
178            public String getMessage(Locale locale) {
179                if (code.length() == 0)
180                    return (String) args[0];
181                return getText(code, args); // FIXME locale
182            }
183            @DefinedBy(Api.COMPILER)
184            public long getPosition() {
185                return Diagnostic.NOPOS;
186            }
187            @DefinedBy(Api.COMPILER)
188            public JavaFileObject getSource() {
189                return null;
190            }
191            @DefinedBy(Api.COMPILER)
192            public long getStartPosition() {
193                return Diagnostic.NOPOS;
194            }
195        };
196    }
197}
198