/*
 * 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 javax.xml.soap;

import javax.xml.namespace.QName;
import java.util.Iterator;

/**
 * A container for <code>DetailEntry</code> objects. <code>DetailEntry</code> objects give detailed
 * error information that is application-specific and related to the <code>SOAPBody</code> object
 * that contains it.
 * <p/>
 * A <code>Detail</code> object, which is part of a <code>SOAPFault</code> object, can be retrieved
 * using the method <code>SOAPFault.getDetail</code>. The <code>Detail</code> interface provides two
 * methods. One creates a new <code>DetailEntry</code> object and also automatically adds it to the
 * <code>Detail</code> object. The second method gets a list of the <code>DetailEntry</code> objects
 * contained in a <code>Detail</code> object.
 * <p/>
 * The following code fragment, in which <i>sf</i> is a <code>SOAPFault</code> object, gets its
 * <code>Detail</code> object (<i>d</i>), adds a new <code>DetailEntry</code> object to <i>d</i>,
 * and then gets a list of all the <code>DetailEntry</code> objects in <i>d</i>. The code also
 * creates a <code>Name</code> object to pass to the method <code>addDetailEntry</code>. The
 * variable <i>se</i>, used to create the <code>Name</code> object, is a <code>SOAPEnvelope</code>
 * object. <PRE> Detail d = sf.getDetail(); Name name = se.createName("GetLastTradePrice", "WOMBAT",
 * "http://www.wombat.org/trader"); d.addDetailEntry(name); Iterator it = d.getDetailEntries();
 * </PRE>
 */
public interface Detail extends SOAPFaultElement {

    /**
     * Creates a new <code>DetailEntry</code> object with the given name and adds it to this
     * <code>Detail</code> object.
     *
     * @param name a <code>Name</code> object identifying the new <code>DetailEntry</code> object
     * @return DetailEntry.
     * @throws SOAPException thrown when there is a problem in adding a DetailEntry object to this
     *                       Detail object.
     */
    public abstract DetailEntry addDetailEntry(Name name) throws SOAPException;

    /**
     * Gets a list of the detail entries in this <code>Detail</code> object.
     *
     * @return an <code>Iterator</code> object over the <code>DetailEntry</code> objects in this
     *         <code>Detail</code> object
     */
    public abstract Iterator getDetailEntries();

    public abstract DetailEntry addDetailEntry(QName qname)
            throws SOAPException;
}
