183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/*
2a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Copyright (C) 2007 The Android Open Source Project
383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *
4a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Licensed under the Apache License, Version 2.0 (the "License");
5a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * you may not use this file except in compliance with the License.
6a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * You may obtain a copy of the License at
783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com *
8a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com *      http://www.apache.org/licenses/LICENSE-2.0
9a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com *
10a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * Unless required by applicable law or agreed to in writing, software
11a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * distributed under the License is distributed on an "AS IS" BASIS,
12a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * See the License for the specific language governing permissions and
14a7139f6586c9bb8452e4c648ce582f8fbc626740JesusFreke@JesusFreke.com * limitations under the License.
1583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */
1683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
17128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com/*
18128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * As per the Apache license requirements, this file has been modified
19128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * from its original state.
20128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com *
21128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * Such modifications are Copyright (C) 2010 Ben Gruver, and are released
22128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com * under the original license
23128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com */
24128e8279c3cf44cc1d1c8f263035ba8e4044d5c6JesusFreke@JesusFreke.com
2583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compackage org.jf.dexlib.Util;
2683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
2783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport java.io.PrintStream;
2883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.comimport java.io.PrintWriter;
2983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
3083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com/**
3183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com * Exception which carries around structured context.
3283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com */
3383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.compublic class ExceptionWithContext
3483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        extends RuntimeException {
3583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /** non-null; human-oriented context of the exception */
3683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    private StringBuffer context;
3783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
3883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
3983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Augments the given exception with the given context, and return the
4083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * result. The result is either the given exception if it was an
4183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * {@link ExceptionWithContext}, or a newly-constructed exception if it
4283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * was not.
4383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
4483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param ex non-null; the exception to augment
4583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param str non-null; context to add
4683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; an appropriate instance
4783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
4883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public static ExceptionWithContext withContext(Throwable ex, String str) {
4983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        ExceptionWithContext ewc;
5083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
5183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (ex instanceof ExceptionWithContext) {
5283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            ewc = (ExceptionWithContext) ex;
5383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
5483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            ewc = new ExceptionWithContext(ex);
5583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
5683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
5783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        ewc.addContext(str);
5883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return ewc;
5983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
6083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
6183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
6283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Constructs an instance.
6383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
6483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param message human-oriented message
6583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
6683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public ExceptionWithContext(String message) {
6783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        this(message, null);
6883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
6983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
7083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
7183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Constructs an instance.
7283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
7383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param cause null-ok; exception that caused this one
7483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
7583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public ExceptionWithContext(Throwable cause) {
7683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        this(null, cause);
7783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
7883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
7983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
8083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Constructs an instance.
8183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
8283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param message human-oriented message
8383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param cause null-ok; exception that caused this one
8483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
8583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public ExceptionWithContext(String message, Throwable cause) {
8683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        super((message != null) ? message :
8783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com              (cause != null) ? cause.getMessage() : null,
8883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com              cause);
8983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
9083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (cause instanceof ExceptionWithContext) {
9183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            String ctx = ((ExceptionWithContext) cause).context.toString();
9283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            context = new StringBuffer(ctx.length() + 200);
9383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            context.append(ctx);
9483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        } else {
9583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            context = new StringBuffer(200);
9683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
9783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
9883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
9983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /** {@inheritDoc} */
10083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    @Override
10183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public void printStackTrace(PrintStream out) {
10283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        super.printStackTrace(out);
10383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        out.println(context);
10483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
10583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
10683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /** {@inheritDoc} */
10783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    @Override
10883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public void printStackTrace(PrintWriter out) {
10983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        super.printStackTrace(out);
11083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        out.println(context);
11183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
11283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
11383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
11483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Adds a line of context to this instance.
11583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
11683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param str non-null; new context
11783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
11883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public void addContext(String str) {
11983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (str == null) {
12083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            throw new NullPointerException("str == null");
12183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
12283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
12383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        context.append(str);
12483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        if (!str.endsWith("\n")) {
12583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com            context.append('\n');
12683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        }
12783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
12883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
12983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
13083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Gets the context.
13183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
13283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @return non-null; the context
13383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
13483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public String getContext() {
13583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        return context.toString();
13683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
13783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
13883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
13983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Prints the message and context.
14083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
14183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param out non-null; where to print to
14283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
14383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public void printContext(PrintStream out) {
14483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        out.println(getMessage());
14583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        out.print(context);
14683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
14783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com
14883b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    /**
14983b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * Prints the message and context.
15083b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     *
15183b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     * @param out non-null; where to print to
15283b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com     */
15383b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    public void printContext(PrintWriter out) {
15483b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        out.println(getMessage());
15583b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com        out.print(context);
15683b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com    }
15783b80f81d311b233188c281059aad4a9f5e8b4e6JesusFreke@JesusFreke.com}