1 /*
2 * #%L
3 * BatchedWriteException.java - mongodb-async-driver - Allanbank Consulting, Inc.
4 * %%
5 * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
6 * %%
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 * #L%
19 */
20 package com.allanbank.mongodb.error;
21
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.HashSet;
25 import java.util.IdentityHashMap;
26 import java.util.List;
27 import java.util.Map;
28 import java.util.Set;
29
30 import com.allanbank.mongodb.builder.BatchedWrite;
31 import com.allanbank.mongodb.builder.write.WriteOperation;
32
33 /**
34 * BatchedWriteException provides a single exception containing the aggregated
35 * errors across the batched writes.
36 *
37 * @copyright 2013, Allanbank Consulting, Inc., All Rights Reserved
38 */
39 public class BatchedWriteException extends ReplyException {
40
41 /** The serialization version for the class. */
42 private static final long serialVersionUID = -7797670480003384909L;
43
44 /**
45 * Constructs a single error message from the nested errors.
46 *
47 * @param errors
48 * The nested errors.
49 * @return An errors message composed of the nested errors.
50 */
51 private static String createErrorMessage(
52 final Map<WriteOperation, Throwable> errors) {
53 final StringBuilder builder = new StringBuilder();
54 if (errors.size() == 1) {
55 builder.append("Error sending a batched write: ");
56 builder.append(errors.values().iterator().next().getMessage());
57 }
58 else {
59 builder.append(errors.size());
60 builder.append(" errors sending a batched write. Unique error messages:\n\t");
61
62 final Set<String> unique = new HashSet<String>();
63 for (final Throwable error : errors.values()) {
64 final String message = error.getMessage();
65 if (unique.add(message)) {
66 builder.append(message);
67 builder.append("\n\t");
68 }
69 }
70 builder.setLength(builder.length() - 2);
71 }
72
73 return builder.toString();
74 }
75
76 /** The nested errors. */
77 private final Map<WriteOperation, Throwable> myErrors;
78
79 /** The number of touched documents when the error is triggered. */
80 private final long myN;
81
82 /** The writes that did not get run by the server. */
83 private final List<WriteOperation> mySkipped;
84
85 /** The write that caused the errors. */
86 private final BatchedWrite myWrite;
87
88 /**
89 * Creates a new BatchedWriteException.
90 *
91 * @param write
92 * The write that caused the errors.
93 * @param n
94 * The number of touched documents when the error is triggered.
95 * @param skipped
96 * The writes that did not get run by the server.
97 * @param errors
98 * The nested errors.
99 */
100 public BatchedWriteException(final BatchedWrite write, final long n,
101 final List<WriteOperation> skipped,
102 final Map<WriteOperation, Throwable> errors) {
103 super(null, createErrorMessage(errors));
104
105 myWrite = write;
106 myN = n;
107 mySkipped = Collections.unmodifiableList(new ArrayList<WriteOperation>(
108 skipped));
109 myErrors = Collections
110 .unmodifiableMap(new IdentityHashMap<WriteOperation, Throwable>(
111 errors));
112 }
113
114 /**
115 * Returns the nested errors.
116 *
117 * @return The nested errors.
118 */
119 public Map<WriteOperation, Throwable> getErrors() {
120 return myErrors;
121 }
122
123 /**
124 * Returns the number of touched documents when the error is triggered.
125 *
126 * @return The number of touched documents when the error is triggered.
127 */
128 public long getN() {
129 return myN;
130 }
131
132 /**
133 * Returns the writes that did not get run by the server.
134 *
135 * @return The writes that did not get run by the server.
136 */
137 public List<WriteOperation> getSkipped() {
138 return mySkipped;
139 }
140
141 /**
142 * Returns the write that caused the errors.
143 *
144 * @return The write that caused the errors.
145 */
146 public BatchedWrite getWrite() {
147 return myWrite;
148 }
149 }