View Javadoc
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 }