1 /* Copyright 2002-2016 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.util.Locale;
21
22 import org.hipparchus.exception.Localizable;
23 import org.hipparchus.exception.MathRuntimeException;
24
25 /** This class is the base class for all specific exceptions thrown by
26 * the Orekit classes.
27
28 * <p>When the Orekit classes throw exceptions that are specific to
29 * the package, these exceptions are always subclasses of
30 * OrekitException. When exceptions that are already covered by the
31 * standard java API should be thrown, like
32 * ArrayIndexOutOfBoundsException or InvalidParameterException, these
33 * standard exceptions are thrown rather than the Hipparchus specific
34 * ones.</p>
35 * <p>This class also provides utility methods to throw some standard
36 * java exceptions with localized messages.</p>
37 *
38 * @author Luc Maisonobe
39
40 */
41
42 public class OrekitException extends Exception implements LocalizedException {
43
44 /** Serializable UID. */
45 private static final long serialVersionUID = 20150611L;
46
47 /** Format specifier (to be translated). */
48 private final Localizable specifier;
49
50 /** Parts to insert in the format (no translation). */
51 private final Object[] parts;
52
53 /** Simple constructor.
54 * Build an exception with a translated and formatted message
55 * @param specifier format specifier (to be translated)
56 * @param parts parts to insert in the format (no translation)
57 */
58 public OrekitException(final Localizable specifier, final Object ... parts) {
59 this.specifier = specifier;
60 this.parts = (parts == null) ? new Object[0] : parts.clone();
61 }
62
63 /** Copy constructor.
64 * @param exception exception to copy from
65 * @since 5.1
66 */
67 public OrekitException(final OrekitException exception) {
68 super(exception);
69 this.specifier = exception.specifier;
70 this.parts = exception.parts.clone();
71 }
72
73 /** Simple constructor.
74 * Build an exception from a cause and with a specified message
75 * @param message descriptive message
76 * @param cause underlying cause
77 */
78 public OrekitException(final Localizable message, final Throwable cause) {
79 super(cause);
80 this.specifier = message;
81 this.parts = new Object[0];
82 }
83
84 /** Simple constructor.
85 * Build an exception from a cause and with a translated and formatted message
86 * @param cause underlying cause
87 * @param specifier format specifier (to be translated)
88 * @param parts parts to insert in the format (no translation)
89 */
90 public OrekitException(final Throwable cause, final Localizable specifier,
91 final Object ... parts) {
92 super(cause);
93 this.specifier = specifier;
94 this.parts = (parts == null) ? new Object[0] : parts.clone();
95 }
96
97 /** Simple constructor.
98 * Build an exception from an Hipparchus exception
99 * @param exception underlying Hipparchus exception
100 * @since 6.0
101 */
102 public OrekitException(final MathRuntimeException exception) {
103 super(exception);
104 this.specifier = exception.getSpecifier();
105 this.parts = exception.getParts();
106 }
107
108 /** {@inheritDoc} */
109 @Override
110 public String getMessage(final Locale locale) {
111 return buildMessage(locale, specifier, parts);
112 }
113
114 /** {@inheritDoc} */
115 @Override
116 public String getMessage() {
117 return getMessage(Locale.US);
118 }
119
120 /** {@inheritDoc} */
121 @Override
122 public String getLocalizedMessage() {
123 return getMessage(Locale.getDefault());
124 }
125
126 /** {@inheritDoc} */
127 @Override
128 public Localizable getSpecifier() {
129 return specifier;
130 }
131
132 /** {@inheritDoc} */
133 @Override
134 public Object[] getParts() {
135 return parts.clone();
136 }
137
138 /** Recover a OrekitException, possibly embedded in a {@link MathRuntimeException}.
139 * <p>
140 * If the {@code MathRuntimeException} does not embed a OrekitException, a
141 * new one will be created.
142 * </p>
143 * @param exception MathRuntimeException to analyze
144 * @return a (possibly embedded) OrekitException
145 */
146 public static OrekitException unwrap(final MathRuntimeException exception) {
147
148 for (Throwable t = exception; t != null; t = t.getCause()) {
149 if (t instanceof OrekitException) {
150 return (OrekitException) t;
151 }
152 }
153
154 return new OrekitException(exception);
155
156 }
157
158 /**
159 * Builds a message string by from a pattern and its arguments.
160 * @param locale Locale in which the message should be translated
161 * @param specifier format specifier (to be translated)
162 * @param parts parts to insert in the format (no translation)
163 * @return a message string
164 */
165 private static String buildMessage(final Locale locale, final Localizable specifier, final Object ... parts) {
166 return (specifier == null) ? "" : new MessageFormat(specifier.getLocalizedString(locale), locale).format(parts);
167 }
168
169 }