1f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
3f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * This program and the accompanying materials are made available under
4f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * the terms of the Common Public License v1.0 which accompanies this distribution,
5f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * and is available at http://www.eclipse.org/legal/cpl-v10.html
6f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
7f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * $Id: ExceptionCommon.java,v 1.1.1.1.2.2 2004/07/10 03:34:52 vlad_r Exp $
8f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
9f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectpackage com.vladium.util.exception;
10f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
11f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.PrintStream;
12f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.io.PrintWriter;
13f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.text.MessageFormat;
14f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Collections;
15f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Enumeration;
16f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.HashMap;
17f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Locale;
18f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.Map;
19f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport java.util.ResourceBundle;
20f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
21f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectimport com.vladium.util.IJREVersion;
22f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
23f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// TODO: embed build # in error codes
24f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
25f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------
26f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project/**
27f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * TODO: javadoc
28f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
29f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * Based on code <a href="http://www.fawcette.com/javapro/2002_12/online/exception_vroubtsov_12_16_02/default_pf.asp">published</a>
30f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * by me in JavaPro, 2002.<P>
31f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
32f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * This non-instantiable class provides static support functions common to
33f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * {@link AbstractException} and {@link AbstractRuntimeException}.<P>
34f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project *
35f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project * @author Vlad Roubtsov, (C) 2002
36f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project */
37f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Projectabstract class ExceptionCommon implements IJREVersion
38f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project{
39f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // public: ................................................................
40f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
41f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
42f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * This method can be called by static initializers of {@link AbstractException}
43f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * and {@link AbstractRuntimeException} subclasses in order to add another
44f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * resource bundle to the set that is used to look up error codes. This makes
45f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * it possible to extend the set of exception error codes across independently
46f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * maintained and built projects.<P>
47f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
48f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * <BLOCKQUOTE>
49f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Note that this introduces a possibility of error code name clashes. This
50f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * is resolved in the following way:
51f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * <UL>
52f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *     <LI> when <CODE>getMessage(namespace, code)</CODE> is called, 'code'
53f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *     is attempted to be looked up in the resource bundle previously keyed
54f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *     under 'namespace';
55f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
56f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *     <LI> if no such bundle it found or if it does not contain a value for
57f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *     key 'code', the same step is repeated for the superclass of 'namespace';
58f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
59f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *     <LI> finally, if all of the above steps fail, the root resource bundle
60f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *     specified by {@link #ROOT_RESOURCE_BUNDLE_NAME} is searched.
61f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * </UL>
62f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
63f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * This strategy ensures that error codes follow inheritance and hiding rules
64f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * similar to Java static methods.<P>
65f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * </BLOCKQUOTE>
66f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
67f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * <B>IMPORTANT:</B> this method must be called from static class initializers
68f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * <I>only</I>.<P>
69f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
70f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * There is no visible state change if the indicated resource is not found
71f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * or if it has been added already under the same key.<P>
72f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
73f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param namespace the Class object acting as the namespace key for the
74f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * resource bundle identified by 'messageResourceBundleName'. <I>This should
75f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * be the calling class.</I> [the method is a no-op if this is null]
76f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
77f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param messageResourceBundleName name of a bundle (path relative to 'namespace'
78f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * package) to add to the set from which error code mappings are retrieved
79f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * [the method is a no-op if this is null or an empty string]
80f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
81f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return ResourceBundle that corresponds to 'namespace' key or null if
82f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * no such bundle could be loaded
83f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
84f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @throws Error if 'namespace' does not correspond to an exception class derived
85f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * from {@link AbstractException} or {@link AbstractRuntimeException}.
86f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
87f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @see #lookup
88f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
89f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    public static ResourceBundle addExceptionResource (final Class namespace,
90f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                                                       final String messageResourceBundleName)
91f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
92f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ((namespace != null) && (messageResourceBundleName != null)
93f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            && (messageResourceBundleName.length () > 0))
94f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
95f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // bail out if the some other exception hierarchy attempts
96f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // to use this functionality:
97f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (! ABSTRACT_EXCEPTION.isAssignableFrom (namespace)
98f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                && ! ABSTACT_RUNTIME_EXCEPTION.isAssignableFrom (namespace))
99f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
100f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                throw new Error ("addExceptionResource(): class [" + namespace +
101f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    "] is not a subclass of " + ABSTRACT_EXCEPTION.getName () +
102f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    " or " + ABSTACT_RUNTIME_EXCEPTION.getName ());
103f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
104f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
105f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // try to load resource bundle
106f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
107f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            ResourceBundle temprb = null;
108f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            String nameInNamespace = null;
109f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            try
110f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
111f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                nameInNamespace = getNameInNamespace (namespace, messageResourceBundleName);
112f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
113f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                //temprb = ResourceBundle.getBundle (nameInNamespace);
114f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
115f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                ClassLoader loader = namespace.getClassLoader ();
116f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (loader == null) loader = ClassLoader.getSystemClassLoader ();
117f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
118f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                temprb = ResourceBundle.getBundle (nameInNamespace, Locale.getDefault (), loader);
119f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
120f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            catch (Throwable ignore)
121f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
122f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project               // ignored intentionally: if the exception codes rb is absent,
123f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project               // we are still in a supported configuration
124f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project               temprb = null;
125f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
126f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
127f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (temprb != null)
128f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
129f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                synchronized (s_exceptionCodeMap)
130f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
131f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final ResourceBundle currentrb =
132f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        (ResourceBundle) s_exceptionCodeMap.get (namespace);
133f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (currentrb != null)
134f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        return currentrb;
135f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    else
136f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
137f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        s_exceptionCodeMap.put (namespace, temprb);
138f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        return temprb;
139f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
140f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
141f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
142f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
143f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
144f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return null;
145f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
146f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
147f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // protected: .............................................................
148f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
149f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // package: ...............................................................
150f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
151f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
152f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    static void printStackTrace (Throwable t, final PrintWriter out)
153f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
154f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (JRE_1_4_PLUS)
155f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
156f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (t instanceof IThrowableWrapper)
157f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
158f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final IThrowableWrapper tw = (IThrowableWrapper) t;
159f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
160f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                tw.__printStackTrace (out);
161f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
162f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else
163f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
164f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                t.printStackTrace (out);
165f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
166f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
167f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
168f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
169f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            for (boolean first = true; t != null; )
170f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
171f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (first)
172f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    first = false;
173f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                else
174f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
175f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    out.println ();
176f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    out.println (NESTED_THROWABLE_HEADER);
177f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
178f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
179f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (t instanceof IThrowableWrapper)
180f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
181f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final IThrowableWrapper tw = (IThrowableWrapper) t;
182f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
183f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    tw.__printStackTrace (out);
184f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    t = tw.getCause ();
185f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
186f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                else
187f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
188f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    t.printStackTrace (out);
189f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    break;
190f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
191f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
192f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
193f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
194f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
195f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
196f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    static void printStackTrace (Throwable t, final PrintStream out)
197f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
198f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (JRE_1_4_PLUS)
199f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
200f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (t instanceof IThrowableWrapper)
201f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
202f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final IThrowableWrapper tw = (IThrowableWrapper) t;
203f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
204f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                tw.__printStackTrace (out);
205f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
206f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            else
207f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
208f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                t.printStackTrace (out);
209f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
210f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
211f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
212f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
213f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            for (boolean first = true; t != null; )
214f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
215f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (first)
216f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    first = false;
217f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                else
218f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
219f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    out.println ();
220f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    out.println (NESTED_THROWABLE_HEADER);
221f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
222f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
223f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (t instanceof IThrowableWrapper)
224f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
225f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final IThrowableWrapper tw = (IThrowableWrapper) t;
226f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
227f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    tw.__printStackTrace (out);
228f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    t = tw.getCause ();
229f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
230f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                else
231f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
232f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    t.printStackTrace (out);
233f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    break;
234f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
235f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
236f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
237f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
238f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
239f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
240f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
241f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Provides support for lookup of exception error codes from {@link AbstractException}
242f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * and {@link AbstractRuntimeException} and their subclasses.
243f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
244f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param namespace the Class object acting as the key to the namespace from
245f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * which to retrieve the description for 'code' [can be null, in which case
246f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * only the root namespace is used for lookup]
247f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
248f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param code the message string value that was passed into exception
249f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * constructor [can be null, in which case null is returned].
250f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
251f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return looked-up error message or the error code if it could not be
252f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * looked up [null is returned on null 'code' input only].
253f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
254f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * This method does not throw.
255f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
256f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @see AbstractException#getMessage
257f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @see AbstractRuntimeException#getMessage
258f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
259f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    static String getMessage (final Class namespace, final String code)
260f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
261f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (code == null) return null;
262f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
263f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
264f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
265f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (code.length () > 0)
266f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
267f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // look the code up in the resource bundle:
268f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final String msg = lookup (namespace, code);
269f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (msg == null)
270f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
271f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    // if code lookup failed, return 'code' as is:
272f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    return code;
273f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
274f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                else
275f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
276f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    return EMBED_ERROR_CODE ? "[" + code + "] " + msg : msg;
277f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
278f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project           }
279f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project           else
280f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project           {
281f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project               return "";
282f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project           }
283f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
284f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (Throwable t)
285f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
286f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // this method must never fail: default to returning the input
287f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // verbatim on all unexpected problems
288f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return code;
289f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
290f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
291f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
292f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
293f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Provides support for lookup of exception error codes from {@link AbstractException}
294f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * and {@link AbstractRuntimeException} and their subclasses.
295f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
296f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param namespace the Class object acting as the key to the namespace from
297f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * which to retrieve the description for 'code' [can be null, in which case
298f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * only the root namespace is used for lookup]
299f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
300f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param code the message string value that was passed into exception
301f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * constructor [can be null, in which case null is returned].
302f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
303f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @param arguments java.text.MessageFormat-style parameters to be substituted
304f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * into the error message once it is looked up.
305f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
306f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return looked-up error message or the error code if it could not be
307f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * looked up [null is returned on null 'code' input only].
308f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
309f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * This method does not throw.
310f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
311f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @see AbstractException#getMessage
312f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @see AbstractRuntimeException#getMessage
313f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
314f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    static String getMessage (final Class namespace, final String code, final Object [] arguments)
315f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
316f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (code == null) return null;
317f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final String pattern = getMessage (namespace, code);
318f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
319f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // assertion: pattern != null
320f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
321f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if ((arguments == null) || (arguments.length == 0))
322f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
323f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return pattern;
324f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
325f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
326f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
327f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            try
328f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
329f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return MessageFormat.format (pattern, arguments);
330f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
331f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            catch (Throwable t)
332f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
333f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // this method cannot fail: default to returning the input
334f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // verbatim on all unexpected problems:
335f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
336f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                final StringBuffer msg = new StringBuffer (code + EOL);
337f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
338f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                for (int a = 0; a < arguments.length; a ++)
339f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
340f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    msg.append ("\t{" + a + "} = [");
341f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    final Object arg = arguments [a];
342f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    try
343f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
344f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        msg.append (arg.toString ());
345f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
346f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    catch (Throwable e) // guard against bad toString() overrides
347f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
348f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        if (arg != null)
349f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            msg.append (arg.getClass ().getName ());
350f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        else
351f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            msg.append ("null");
352f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
353f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    msg.append ("]");
354f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    msg.append (EOL);
355f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
356f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
357f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                return msg.toString ();
358f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
359f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
360f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
361f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
362f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // private: ...............................................................
363f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
364f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
365f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private ExceptionCommon () {} // prevent subclassing
366f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
367f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /**
368f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * Internal property lookup method. It implements the lookup scheme described
369f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * in {@link #addExceptionResource}.
370f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     *
371f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     * @return property value corresponding to 'propertyName' [null if lookup fails]
372f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project     */
373f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static String lookup (Class namespace, final String propertyName)
374f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
375f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (propertyName == null) return null;
376f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
377f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // note: the following does not guard against exceptions that do not subclass
378f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // our base classes [done elsewhere], however it will not crash either
379f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
380f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // check extension bundles:
381f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (namespace != null)
382f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
383f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            ResourceBundle rb;
384f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            while (namespace != ABSTRACT_EXCEPTION && namespace != ABSTACT_RUNTIME_EXCEPTION
385f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                   && namespace != THROWABLE && namespace != null)
386f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
387f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                synchronized (s_exceptionCodeMap)
388f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
389f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    rb = (ResourceBundle) s_exceptionCodeMap.get (namespace);
390f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (rb == null)
391f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
392f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        // check if there is a default bundle to be loaded for this namespace:
393f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        if ((rb = addExceptionResource (namespace, "exceptions")) == null)
394f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        {
395f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            // add an immutable empty bundle to avoid this check in the future:
396f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                            s_exceptionCodeMap.put (namespace, EMPTY_RESOURCE_BUNDLE);
397f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        }
398f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
399f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
400f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
401f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                if (rb != null)
402f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                {
403f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    String propertyValue = null;
404f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    try
405f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    {
406f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                        propertyValue = rb.getString (propertyName);
407f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    }
408f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    catch (Throwable ignore) {}
409f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                    if (propertyValue != null) return propertyValue;
410f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                }
411f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
412f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                // walk the inheritance chain for 'namespace':
413f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                namespace = namespace.getSuperclass ();
414f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
415f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
416f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
417f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // if everything fails, check the root bundle:
418f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (ROOT_RESOURCE_BUNDLE != null)
419f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
420f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            String propertyValue = null;
421f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            try
422f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            {
423f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project                propertyValue = ROOT_RESOURCE_BUNDLE.getString (propertyName);
424f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            }
425f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            catch (Throwable ignore) {}
426f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            if (propertyValue != null) return propertyValue;
427f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
428f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
429f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        return null;
430f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
431f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
432f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static String getNameInNamespace (final Class namespace, final String name)
433f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
434f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (namespace == null) return name;
435f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
436f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final String namespaceName = namespace.getName ();
437f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        final int lastDot = namespaceName.lastIndexOf ('.');
438f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
439f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        if (lastDot <= 0)
440f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return name;
441f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        else
442f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return namespaceName.substring (0, lastDot + 1)  + name;
443f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
444f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
445f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
446f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // changes this to 'false' to eliminate repetition of error codes in
447f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // the output of getMessage():
448f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final boolean EMBED_ERROR_CODE = true;
449f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
450f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // the name of the 'root' message resource bundle, derived as
451f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // [this package name + ".exceptions"]:
452f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final String ROOT_RESOURCE_BUNDLE_NAME;      // set in <clinit>
453f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
454f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // the root resource bundle; always checked if all other lookups fail:
455f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final ResourceBundle ROOT_RESOURCE_BUNDLE;   // set in <clinit>
456f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
457f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // static cache of all loaded resource bundles, populated via addExceptionResource():
458f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final Map /* Class -> ResourceBundle */ s_exceptionCodeMap = new HashMap ();
459f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
460f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // misc constants:
461f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
462f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final String NESTED_THROWABLE_HEADER = "[NESTED EXCEPTION]:";
463f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final Class THROWABLE                    = Throwable.class;
464f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final Class ABSTRACT_EXCEPTION           = AbstractException.class;
465f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final Class ABSTACT_RUNTIME_EXCEPTION    = AbstractRuntimeException.class;
466f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    /*private*/ static final Enumeration EMPTY_ENUMERATION  = Collections.enumeration (Collections.EMPTY_SET);
467f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final ResourceBundle EMPTY_RESOURCE_BUNDLE = new ResourceBundle ()
468f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
469f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public Object handleGetObject (final String key)
470f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
471f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return null;
472f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
473f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
474f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        public Enumeration getKeys ()
475f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
476f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            return EMPTY_ENUMERATION;
477f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
478f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    };
479f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
480f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    // end-of-line terminator for the current platform:
481f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    private static final String EOL = System.getProperty ("line.separator", "\n");
482f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
483f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
484f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    static
485f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    {
486f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // set the name of ROOT_RESOURCE_BUNDLE_NAME:
487f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        ROOT_RESOURCE_BUNDLE_NAME = getNameInNamespace (ExceptionCommon.class, "exceptions");
488f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
489f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        // set the root resource bundle:
490f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        ResourceBundle temprb = null;
491f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        try
492f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
493f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            temprb = ResourceBundle.getBundle (ROOT_RESOURCE_BUNDLE_NAME);
494f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
495f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        catch (Throwable ignore)
496f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        {
497f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project            // if the exception codes rb is absent, we are still in a supported configuration
498f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        }
499f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project        ROOT_RESOURCE_BUNDLE = temprb;
500f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project    }
501f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project
502f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project} // end of class
503f6fe897e173f4e4bda72a7dddb091b667066764aThe Android Open Source Project// ----------------------------------------------------------------------------
504