001/*
002 *  Licensed to the Apache Software Foundation (ASF) under one
003 *  or more contributor license agreements.  See the NOTICE file
004 *  distributed with this work for additional information
005 *  regarding copyright ownership.  The ASF licenses this file
006 *  to you under the Apache License, Version 2.0 (the
007 *  "License"); you may not use this file except in compliance
008 *  with the License.  You may obtain a copy of the License at
009 *
010 *    http://www.apache.org/licenses/LICENSE-2.0
011 *
012 *  Unless required by applicable law or agreed to in writing,
013 *  software distributed under the License is distributed on an
014 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 *  KIND, either express or implied.  See the License for the
016 *  specific language governing permissions and limitations
017 *  under the License.
018 *
019 */
020package org.apache.mina.core.write;
021
022import java.io.IOException;
023import java.util.ArrayList;
024import java.util.Collection;
025import java.util.Collections;
026import java.util.LinkedHashMap;
027import java.util.List;
028import java.util.Set;
029
030import org.apache.mina.util.MapBackedSet;
031
032/**
033 * An exception which is thrown when one or more write operations failed.
034 *
035 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
036 */
037public class WriteException extends IOException {
038    /** The mandatory serialVersionUUID */
039    private static final long serialVersionUID = -4174407422754524197L;
040
041    /** The list of WriteRequest stored in this exception */
042    private final List<WriteRequest> requests;
043
044    /**
045     * Creates a new exception.
046     * 
047     * @param request The associated {@link WriteRequest}
048     */
049    public WriteException(WriteRequest request) {
050        super();
051        this.requests = asRequestList(request);
052    }
053
054    /**
055     * Creates a new exception.
056     * 
057     * @param request The associated {@link WriteRequest}
058     * @param message The detail message
059     */
060    public WriteException(WriteRequest request, String message) {
061        super(message);
062        this.requests = asRequestList(request);
063    }
064
065    /**
066     * Creates a new exception.
067     * 
068     * @param request The associated {@link WriteRequest}
069     * @param message The detail message
070     * @param cause The Exception's cause
071     */
072    public WriteException(WriteRequest request, String message, Throwable cause) {
073        super(message);
074        initCause(cause);
075        this.requests = asRequestList(request);
076    }
077
078    /**
079     * Creates a new exception.
080     * 
081     * @param request The associated {@link WriteRequest}
082     * @param cause The Exception's cause
083     */
084    public WriteException(WriteRequest request, Throwable cause) {
085        initCause(cause);
086        this.requests = asRequestList(request);
087    }
088
089    /**
090     * Creates a new exception.
091     * 
092     * @param requests The collection of {@link WriteRequest}s
093     */
094    public WriteException(Collection<WriteRequest> requests) {
095        super();
096        this.requests = asRequestList(requests);
097    }
098
099    /**
100     * Creates a new exception.
101     * 
102     * @param requests The collection of {@link WriteRequest}s
103     * @param message The detail message
104     */
105    public WriteException(Collection<WriteRequest> requests, String message) {
106        super(message);
107        this.requests = asRequestList(requests);
108    }
109
110    /**
111     * Creates a new exception.
112     * 
113     * @param requests The collection of {@link WriteRequest}s
114     * @param message The detail message
115     * @param cause The Exception's cause
116     */
117    public WriteException(Collection<WriteRequest> requests, String message, Throwable cause) {
118        super(message);
119        initCause(cause);
120        this.requests = asRequestList(requests);
121    }
122
123    /**
124     * Creates a new exception.
125     * 
126     * @param requests The collection of {@link WriteRequest}s
127     * @param cause The Exception's cause
128     */
129    public WriteException(Collection<WriteRequest> requests, Throwable cause) {
130        initCause(cause);
131        this.requests = asRequestList(requests);
132    }
133
134    /**
135     * @return the list of the failed {@link WriteRequest}, in the order of occurrence.
136     */
137    public List<WriteRequest> getRequests() {
138        return requests;
139    }
140
141    /**
142     * @return the firstly failed {@link WriteRequest}. 
143     */
144    public WriteRequest getRequest() {
145        return requests.get(0);
146    }
147
148    private static List<WriteRequest> asRequestList(Collection<WriteRequest> requests) {
149        if (requests == null) {
150            throw new IllegalArgumentException("requests");
151        }
152        
153        if (requests.isEmpty()) {
154            throw new IllegalArgumentException("requests is empty.");
155        }
156
157        // Create a list of requests removing duplicates.
158        Set<WriteRequest> newRequests = new MapBackedSet<WriteRequest>(new LinkedHashMap<WriteRequest, Boolean>());
159        
160        for (WriteRequest r : requests) {
161            newRequests.add(r.getOriginalRequest());
162        }
163
164        return Collections.unmodifiableList(new ArrayList<WriteRequest>(newRequests));
165    }
166
167    private static List<WriteRequest> asRequestList(WriteRequest request) {
168        if (request == null) {
169            throw new IllegalArgumentException("request");
170        }
171
172        List<WriteRequest> requests = new ArrayList<WriteRequest>(1);
173        requests.add(request.getOriginalRequest());
174        
175        return Collections.unmodifiableList(requests);
176    }
177}