/*
 * Copyright 1999,2004-2005 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.catalina.tribes;

import java.util.ArrayList;

/**
 * Channel Exception<br>
 * A channel exception is thrown when an internal error happens
 * somewhere in the channel. <br>
 * When a global error happens, the cause can be retrieved using <code>getCause()</code><br><br>
 * If an application is sending a message and some of the recipients fail to receive it,
 * the application can retrieve what recipients failed by using the <code>getFaultyMembers()</code>
 * method. This way, an application will always know if a message was delivered successfully or not.
 * @author Filip Hanik
 * @version $Revision: 304032 $, $Date: 2005-07-27 10:11:55 -0500 (Wed, 27 Jul 2005) $
 */

public class ChannelException extends Exception {
    /*
     * Holds a list of faulty members
     */
    private ArrayList faultyMembers=null;
    
    /**
     * Constructor, creates a ChannelException
     * @see java.lang.Exception#Exception()
     */
    public ChannelException() {
        super();
    }

    /**
     * Constructor, creates a ChannelException with an error message
     * @see java.lang.Exception#Exception(String)
     */
    public ChannelException(String message) {
        super(message);
    }

    /**
     * Constructor, creates a ChannelException with an error message and a cause
     * @param message String
     * @param cause Throwable
     * @see java.lang.Exception#Exception(String,Throwable)
     */
    public ChannelException(String message, Throwable cause) {
        super(message, cause);
    }

    /**
     * Constructor, creates a ChannelException with a cause
     * @param cause Throwable
     * @see java.lang.Exception#Exception(Throwable)
     */
    public ChannelException(Throwable cause) {
        super(cause);
    }
    
    /**
     * Returns the message for this exception
     * @return String
     * @see java.lang.Exception#getMessage()
     */
    public String getMessage() {
        StringBuffer buf = new StringBuffer(super.getMessage());
        if (faultyMembers==null || faultyMembers.size() == 0 ) {
            buf.append("; No faulty members identified.");
        } else {
            buf.append("; Faulty members:");
            for ( int i=0; i<faultyMembers.size(); i++ ) {
                FaultyMember mbr = (FaultyMember)faultyMembers.get(i);
                buf.append(mbr.getMember().getName());
                buf.append("; ");
            }
        }
        return buf.toString();
    }
    
    /**
     * Adds a faulty member, and the reason the member failed.
     * @param mbr Member
     * @param x Exception
     */
    public void addFaultyMember(Member mbr, Exception x ) {
        addFaultyMember(new FaultyMember(mbr,x));
    }
    
    /**
     * Adds a list of faulty members
     * @param mbrs FaultyMember[]
     */
    public void addFaultyMember(FaultyMember[] mbrs) {
        for (int i=0; mbrs!=null && i<mbrs.length; i++ ) {
            addFaultyMember(mbrs[i]);
        }
    }

    /**
     * Adds a faulty member
     * @param mbr FaultyMember
     */
    public void addFaultyMember(FaultyMember mbr) {
        if ( this.faultyMembers==null ) this.faultyMembers = new ArrayList();
        faultyMembers.add(mbr);
    }
    
    /**
     * Returns an array of members that failed and the reason they failed.
     * @return FaultyMember[]
     */
    public FaultyMember[] getFaultyMembers() {
        if ( this.faultyMembers==null ) return new FaultyMember[0];
        return (FaultyMember[])faultyMembers.toArray(new FaultyMember[faultyMembers.size()]);
    }
    
    /**
     * 
     * <p>Title: FaultyMember class</p> 
     * 
     * <p>Description: Represent a failure to a specific member when a message was sent
     * to more than one member</p> 
     * 
     * @author Filip Hanik
     * @version 1.0
     */
    public static class FaultyMember {
        protected Exception cause;
        protected Member member;
        public FaultyMember(Member mbr, Exception x) { 
            this.member = mbr;
            this.cause = x;
        }
        
        public Member getMember() {
            return member;
        }
        
        public Exception getCause() {
            return cause;
        }
        
        public String toString() {
            return "FaultyMember:"+member.toString();
        }
    }

}
