
/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements. See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership. The ASF licenses this file
 * to you 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.axis2.jaxws.sample.faults;

import org.test.faults.FaultyWebServiceFault;

/**
 * This class was generated by the JAXWS SI.
 * JAX-WS RI 2.0_01-b15-fcs
 * Generated source version: 2.0
 * 
 */
// annotation is commented as part of the test to make sure defaults are used
//@WebFault(faultBean="org.test.faults.FaultyWebServiceFault", name = "FaultyWebServiceFault", targetNamespace = "http://org/test/faults")
public class FaultyWebServiceFault_Exception
    extends Exception
{

    /**
     * Java type that goes as soapenv:Fault detail element.
     * 
     */
    private FaultyWebServiceFault faultInfo;
    
    /**
     * 
     * @param faultInfo
     * @param message
     */
    public FaultyWebServiceFault_Exception(String message, FaultyWebServiceFault faultInfo) {
        super(message);
        this.faultInfo = faultInfo;
    }

    /**
     * 
     * @param faultInfo
     * @param message
     * @param cause
     */
    public FaultyWebServiceFault_Exception(String message, FaultyWebServiceFault faultInfo, Throwable cause) {
        super(message, cause);
        this.faultInfo = faultInfo;
    }

    /**
     * 
     * @return
     *     returns fault bean: duke.org.FaultyWebServiceFault
     */
    public FaultyWebServiceFault getFaultInfo() {
        return faultInfo;
    }

}
