1 /* Copyright 2002-2013 CS Systèmes d'Information
2 * Licensed to CS Systèmes d'Information (CS) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * CS licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17 package org.orekit.errors;
18
19 import java.text.MessageFormat;
20 import java.text.ParseException;
21 import java.util.Locale;
22
23 import org.apache.commons.math3.exception.util.ExceptionContext;
24 import org.apache.commons.math3.exception.util.ExceptionContextProvider;
25 import org.apache.commons.math3.exception.util.Localizable;
26
27 /** This class is the base class for all specific exceptions thrown by
28 * the orekit classes.
29
30 * <p>When the orekit classes throw exceptions that are specific to
31 * the package, these exceptions are always subclasses of
32 * OrekitException. When exceptions that are already covered by the
33 * standard java API should be thrown, like
34 * ArrayIndexOutOfBoundsException or InvalidParameterException, these
35 * standard exceptions are thrown rather than the commons-math specific
36 * ones.</p>
37 * <p>This class also provides utility methods to throw some standard
38 * java exceptions with localized messages.</p>
39 *
40 * @author Luc Maisonobe
41
42 */
43
44 public class OrekitException extends Exception {
45
46 /** Serializable UID. */
47 private static final long serialVersionUID = 3366757982695469677L;
48
49 /** Exception context (may be null). */
50 private final ExceptionContext context;
51
52 /** Format specifier (to be translated). */
53 private final Localizable specifier;
54
55 /** Parts to insert in the format (no translation). */
56 private final Object[] parts;
57
58 /** Simple constructor.
59 * Build an exception with a translated and formatted message
60 * @param specifier format specifier (to be translated)
61 * @param parts parts to insert in the format (no translation)
62 */
63 public OrekitException(final Localizable specifier, final Object ... parts) {
64 this.context = null;
65 this.specifier = specifier;
66 this.parts = (parts == null) ? new Object[0] : parts.clone();
67 }
68
69 /** Copy constructor.
70 * @param exception exception to copy from
71 * @since 5.1
72 */
73 public OrekitException(final OrekitException exception) {
74 super(exception);
75 this.context = exception.context;
76 this.specifier = exception.specifier;
77 this.parts = exception.parts.clone();
78 }
79
80 /** Simple constructor.
81 * Build an exception from a cause and with a specified message
82 * @param message descriptive message
83 * @param cause underlying cause
84 */
85 public OrekitException(final Localizable message, final Throwable cause) {
86 super(cause);
87 this.context = null;
88 this.specifier = message;
89 this.parts = new Object[0];
90 }
91
92 /** Simple constructor.
93 * Build an exception from a cause and with a translated and formatted message
94 * @param cause underlying cause
95 * @param specifier format specifier (to be translated)
96 * @param parts parts to insert in the format (no translation)
97 */
98 public OrekitException(final Throwable cause, final Localizable specifier,
99 final Object ... parts) {
100 super(cause);
101 this.context = null;
102 this.specifier = specifier;
103 this.parts = (parts == null) ? new Object[0] : parts.clone();
104 }
105
106 /** Simple constructor.
107 * Build an exception from an Apache Commons Math exception context context
108 * @param provider underlying exception context provider
109 * @since 6.0
110 */
111 public OrekitException(final ExceptionContextProvider provider) {
112 super(provider.getContext().getThrowable());
113 this.context = provider.getContext();
114 this.specifier = null;
115 this.parts = new Object[0];
116 }
117
118 /** Gets the message in a specified locale.
119 * @param locale Locale in which the message should be translated
120 * @return localized message
121 * @since 5.0
122 */
123 public String getMessage(final Locale locale) {
124 return (context != null) ?
125 context.getMessage(locale) :
126 buildMessage(locale, specifier, parts);
127 }
128
129 /** {@inheritDoc} */
130 @Override
131 public String getMessage() {
132 return getMessage(Locale.US);
133 }
134
135 /** {@inheritDoc} */
136 @Override
137 public String getLocalizedMessage() {
138 return getMessage(Locale.getDefault());
139 }
140
141 /** Get the localizable specifier of the error message.
142 * @return localizable specifier of the error message
143 * @since 5.1
144 */
145 public Localizable getSpecifier() {
146 return specifier;
147 }
148
149 /** Get the variable parts of the error message.
150 * @return a copy of the variable parts of the error message
151 * @since 5.1
152 */
153 public Object[] getParts() {
154 return parts.clone();
155 }
156
157 /**
158 * Builds a message string by from a pattern and its arguments.
159 * @param locale Locale in which the message should be translated
160 * @param specifier format specifier (to be translated)
161 * @param parts parts to insert in the format (no translation)
162 * @return a message string
163 */
164 private static String buildMessage(final Locale locale, final Localizable specifier,
165 final Object ... parts) {
166 return (specifier == null) ? "" : new MessageFormat(specifier.getLocalizedString(locale), locale).format(parts);
167 }
168
169 /** Create an {@link java.lang.IllegalArgumentException} with localized message.
170 * @param specifier format specifier (to be translated)
171 * @param parts parts to insert in the format (no translation)
172 * @return an {@link java.lang.IllegalArgumentException} with localized message
173 */
174 public static IllegalArgumentException createIllegalArgumentException(final Localizable specifier,
175 final Object ... parts) {
176 return new IllegalArgumentException() {
177
178 /** Serializable UID. */
179 private static final long serialVersionUID = 2601215225271704045L;
180
181 /** {@inheritDoc} */
182 @Override
183 public String getMessage() {
184 return buildMessage(Locale.US, specifier, parts);
185 }
186
187 /** {@inheritDoc} */
188 @Override
189 public String getLocalizedMessage() {
190 return buildMessage(Locale.getDefault(), specifier, parts);
191 }
192
193 };
194
195 }
196
197 /** Create an {@link java.lang.IllegalStateException} with localized message.
198 * @param specifier format specifier (to be translated)
199 * @param parts parts to insert in the format (no translation)
200 * @return an {@link java.lang.IllegalStateException} with localized message
201 */
202 public static IllegalStateException createIllegalStateException(final Localizable specifier,
203 final Object ... parts) {
204
205 return new IllegalStateException() {
206
207 /** Serializable UID. */
208 private static final long serialVersionUID = -5527779242879685212L;
209
210 /** {@inheritDoc} */
211 @Override
212 public String getMessage() {
213 return buildMessage(Locale.US, specifier, parts);
214 }
215
216 /** {@inheritDoc} */
217 @Override
218 public String getLocalizedMessage() {
219 return buildMessage(Locale.getDefault(), specifier, parts);
220 }
221
222 };
223
224 }
225
226 /** Create an {@link java.text.ParseException} with localized message.
227 * @param specifier format specifier (to be translated)
228 * @param parts parts to insert in the format (no translation)
229 * @return an {@link java.text.ParseException} with localized message
230 */
231 public static ParseException createParseException(final Localizable specifier,
232 final Object ... parts) {
233
234 return new ParseException("", 0) {
235
236 /** Serializable UID. */
237 private static final long serialVersionUID = 4771367217940584391L;
238
239 /** {@inheritDoc} */
240 @Override
241 public String getMessage() {
242 return buildMessage(Locale.US, specifier, parts);
243 }
244
245 /** {@inheritDoc} */
246 @Override
247 public String getLocalizedMessage() {
248 return buildMessage(Locale.getDefault(), specifier, parts);
249 }
250
251 };
252
253 }
254
255 /** Create an {@link java.lang.RuntimeException} for an internal error.
256 * @param cause underlying cause
257 * @return an {@link java.lang.RuntimeException} for an internal error
258 */
259 public static RuntimeException createInternalError(final Throwable cause) {
260
261 /** Format specifier (to be translated). */
262 final Localizable specifier = OrekitMessages.INTERNAL_ERROR;
263
264 /** Parts to insert in the format (no translation). */
265 final String parts = "orekit@c-s.fr";
266
267 return new RuntimeException() {
268
269 /** Serializable UID. */
270 private static final long serialVersionUID = -6493358459835909138L;
271
272 /** {@inheritDoc} */
273 @Override
274 public String getMessage() {
275 return buildMessage(Locale.US, specifier, parts);
276 }
277
278 /** {@inheritDoc} */
279 @Override
280 public String getLocalizedMessage() {
281 return buildMessage(Locale.getDefault(), specifier, parts);
282 }
283
284 };
285
286 }
287
288 }