/*
 * $Header: /home/cvspublic/jakarta-slide/src/share/org/apache/slide/common/ServiceAccessException.java,v 1.12 2004/07/28 09:38:15 ib Exp $
 * $Revision: 1.12 $
 * $Date: 2004/07/28 09:38:15 $
 *
 * ====================================================================
 *
 * Copyright 1999-2002 The Apache Software Foundation 
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

package org.apache.slide.common;

import java.io.PrintWriter;
import java.io.StringWriter;
import org.apache.slide.common.Domain;
import org.apache.slide.util.Messages;
import org.apache.slide.util.logger.Logger;

/**
 * Service access exception.
 *
 * @version $Revision: 1.12 $
 */
public class ServiceAccessException extends SlideException {

    private static final String CHANNEL = "org.apache.slide.common.ServiceAccessException";
    private static final int DEBUG = Logger.DEBUG;
    private static Logger LOGGER = Domain.getLogger();

    /* hold the cause exception, if supplied */
    private Throwable nestedException = null;

    // ----------------------------------------------------------- Constructors

    /**
     * Constructor.
     *
     * @param service Service from which the exception was thrown
     * @param cause Cause of the exception
     */
    public ServiceAccessException(Service service, String cause) {
        super(Messages.format
              (ServiceAccessException.class.getName(), service, computeCause(cause)), false);
        
        if (LOGGER.isEnabled(CHANNEL, DEBUG)) {
            StringWriter sw = new StringWriter();
            printStackTrace( new PrintWriter(sw, true) ); //autoFlush=true
            LOGGER.log( sw.toString(), CHANNEL, DEBUG );
        }
    }

    /**
     * Constructor.
     *
     * @param service Service from which the exception was thrown
     * @param e Exception which is the initial cause of the problem
     */
    public ServiceAccessException(Service service, Throwable e) {
        this(service, computeCause(e));
        nestedException = e;
    }

    /**
     * computeCause.
     *
     * @param delieveredCause the cause as a string, if null or empty e is used
     * @param e the exception stacktrace is shown, if cause is not supplied
     */
    private static String computeCause(String delieveredCause, Throwable e) {
        String result = delieveredCause;
        if (delieveredCause == null || delieveredCause.equals("")) {
            StringWriter sw = new StringWriter();
            e.printStackTrace(new PrintWriter(sw, true)); //autoFlush=true
            result = sw.toString();
        }
        return result;
    }

    /**
     * computeCause.
     *
     * @param delieveredCause the cause as a string, if null or empty the current stack is used
     */
    private static String computeCause(String delieveredCause) {
        if (delieveredCause == null || delieveredCause.equals("")) {
            return "cause is empty";
        } else {
            return delieveredCause;
        }
    }

    /**
     * computeCause.
     *
     * @param e if getMessage is empty the stack trace of e is used
     */
    private static String computeCause(Throwable e) {
        return computeCause(e.getMessage(), e);
    }

    /**
     * return the cause exception, if supplied, else null.
     */
    public Throwable getCauseException() {
        return nestedException;
    }

}
