/*
 * Copyright 2001-2004 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.ws.scout.registry;

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashSet;

import javax.xml.registry.BulkResponse;
import javax.xml.registry.JAXRException;

/**
 * Implements JAXR BulkResponse Interface.
 * For futher details, look into the JAXR API Javadoc.
 *
 * @author <a href="mailto:anil@apache.org">Anil Saldhana</a>
 * @author <a href="mailto:geirm@apache.org">Geir Magnusson Jr.</a>
 */
public class BulkResponseImpl extends JAXRResponseImpl implements BulkResponse
{
    private boolean partialResponse = false;

    private Collection<Exception> exceptions = new ArrayList<Exception>();
    private Collection<? extends Object> collection = new ArrayList<Object>();
    /**
     * Creates a new instance of BulkResponseImpl
     */
    public BulkResponseImpl()
    {
    }

    BulkResponseImpl(LinkedHashSet<? extends Object> collection)
    {
        this.collection = collection;
    }

    /**
     * Get Collection of RegistryObjects *
     */
    public Collection<? extends Object> getCollection() throws JAXRException
    {
        return this.collection;
    }

    /**
     * The javadoc is unclear.  it says for getExceptions() :
     *   "Get the Collection of RegistryException instances in case of partial
     *     commit. Caller thread will block here if result is not yet available.
     *     Return null if result is available and there is no RegistryException(s)."
     * Yet the return javadoc says :
     *   "Collection of RegistryException instances. The Collection may be empty but not null."
     *
     * So my interpretation is return null if result avail, and empty collection otherwise
     *
     * @return Collection Exceptions
     * @throws JAXRException
     */
    public Collection getExceptions() throws JAXRException
    {
        return (this.exceptions.size() == 0 ? null : exceptions);
    }

    public boolean isPartialResponse() throws JAXRException
    {
        if (exceptions.size() > 0) {
            this.partialResponse = true;
        }
        return this.partialResponse;
    }

    public void setPartialResponse(boolean b) throws JAXRException
    {
        this.partialResponse = b;
    }

    public void setCollection(Collection<? extends Object> coll) throws JAXRException
    {
        this.collection = coll;
    }

    /**
     * Setter for property exceptions.
     *
     * @param exceptions New value of property exceptions.
     */
    public void setExceptions(Collection<Exception> exceptions)
    {
        this.exceptions = exceptions;
    }

}
