/*
 * Copyright (C) 2008, Google Inc.
 * Copyright (C) 2008, Jonas Fonseca <fonseca@diku.dk>
 * Copyright (C) 2007, Robin Rosenberg <robin.rosenberg@dewire.com>
 * Copyright (C) 2006-2007, Shawn O. Pearce <spearce@spearce.org>
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.errors;

import java.io.IOException;
import java.text.MessageFormat;

import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.internal.JGitText;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectChecker;
import org.eclipse.jgit.lib.ObjectId;

/**
 * Exception thrown when an object cannot be read from Git.
 */
public class CorruptObjectException extends IOException {
	private static final long serialVersionUID = 1L;

	private ObjectChecker.ErrorType errorType;

	/**
	 * Report a specific error condition discovered in an object.
	 *
	 * @param type
	 *            type of error
	 * @param id
	 *            identity of the bad object
	 * @param why
	 *            description of the error.
	 * @since 4.2
	 */
	public CorruptObjectException(ObjectChecker.ErrorType type, AnyObjectId id,
			String why) {
		super(MessageFormat.format(JGitText.get().objectIsCorrupt3,
				type.getMessageId(), id.name(), why));
		this.errorType = type;
	}

	/**
	 * Construct a CorruptObjectException for reporting a problem specified
	 * object id
	 *
	 * @param id
	 *            a {@link org.eclipse.jgit.lib.AnyObjectId}
	 * @param why
	 *            error message
	 */
	public CorruptObjectException(AnyObjectId id, String why) {
		super(MessageFormat.format(JGitText.get().objectIsCorrupt, id.name(), why));
	}

	/**
	 * Construct a CorruptObjectException for reporting a problem specified
	 * object id
	 *
	 * @param id
	 *            a {@link org.eclipse.jgit.lib.ObjectId}
	 * @param why
	 *            error message
	 */
	public CorruptObjectException(ObjectId id, String why) {
		super(MessageFormat.format(JGitText.get().objectIsCorrupt, id.name(), why));
	}

	/**
	 * Construct a CorruptObjectException for reporting a problem not associated
	 * with a specific object id.
	 *
	 * @param why
	 *            error message
	 */
	public CorruptObjectException(String why) {
		super(why);
	}

	/**
	 * Construct a CorruptObjectException for reporting a problem not associated
	 * with a specific object id.
	 *
	 * @param why
	 *            message describing the corruption.
	 * @param cause
	 *            optional root cause exception
	 * @since 3.4
	 */
	public CorruptObjectException(String why, Throwable cause) {
		super(why);
		initCause(cause);
	}

	/**
	 * Specific error condition identified by
	 * {@link org.eclipse.jgit.lib.ObjectChecker}.
	 *
	 * @return error condition or null.
	 * @since 4.2
	 */
	@Nullable
	public ObjectChecker.ErrorType getErrorType() {
		return errorType;
	}
}
