1 /*
2 * #%L
3 * ReplyArrayCallback.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
21 package com.allanbank.mongodb.client.callback;
22
23 import java.util.Collections;
24 import java.util.List;
25
26 import com.allanbank.mongodb.Callback;
27 import com.allanbank.mongodb.MongoDbException;
28 import com.allanbank.mongodb.MongoIterator;
29 import com.allanbank.mongodb.bson.Document;
30 import com.allanbank.mongodb.bson.Element;
31 import com.allanbank.mongodb.bson.element.ArrayElement;
32 import com.allanbank.mongodb.client.SimpleMongoIteratorImpl;
33 import com.allanbank.mongodb.client.message.Reply;
34 import com.allanbank.mongodb.error.ReplyException;
35
36 /**
37 * Callback to expect and extract a single document from the reply and then
38 * extract its contained array.
39 *
40 * @api.no This class is <b>NOT</b> part of the drivers API. This class may be
41 * mutated in incompatible ways between any two releases of the driver.
42 * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
43 */
44 public class ReplyArrayCallback extends
45 AbstractReplyCallback<MongoIterator<Element>> {
46
47 /** The default name for the values array. */
48 public static final String DEFAULT_NAME = "values";
49
50 /** The name of the array element in the reply document. */
51 private final String myName;
52
53 /**
54 * Create a new ReplyDocumentCallback.
55 *
56 * @param results
57 * The callback to notify of the reply document.
58 */
59 public ReplyArrayCallback(final Callback<MongoIterator<Element>> results) {
60 this(DEFAULT_NAME, results);
61 }
62
63 /**
64 * Create a new ReplyDocumentCallback.
65 *
66 * @param name
67 * The name of the array element in the reply document.
68 * @param results
69 * The callback to notify of the reply document.
70 */
71 public ReplyArrayCallback(final String name,
72 final Callback<MongoIterator<Element>> results) {
73 super(results);
74
75 myName = name;
76 }
77
78 /**
79 * {@inheritDoc}
80 * <p>
81 * Creates an exception if the {@link Reply} has less than or more than a
82 * single reply document.
83 * </p>
84 *
85 * @param reply
86 * The raw reply.
87 * @return The exception created.
88 */
89 @Override
90 protected MongoDbException asError(final Reply reply) {
91 MongoDbException error = super.asError(reply);
92 if (error == null) {
93 final List<Document> results = reply.getResults();
94 if (results.size() != 1) {
95 error = new ReplyException(reply,
96 "Should only be a single document in the reply.");
97 }
98 else if (reply.getResults().get(0).find(ArrayElement.class, myName)
99 .isEmpty()) {
100 error = new ReplyException(reply, "No '" + myName
101 + "' array in the reply.");
102 }
103 }
104 return error;
105 }
106
107 /**
108 * {@inheritDoc}
109 * <p>
110 * Overridden to return the reply document.
111 * </p>
112 *
113 * @see AbstractReplyCallback#convert(Reply)
114 */
115 @Override
116 protected MongoIterator<Element> convert(final Reply reply)
117 throws MongoDbException {
118 final List<Document> results = reply.getResults();
119 if (results.size() == 1) {
120 List<Element> entries = Collections.emptyList();
121 final Document document = results.get(0);
122 final ArrayElement array = document.findFirst(ArrayElement.class,
123 myName);
124 if (array != null) {
125 entries = array.getEntries();
126 }
127
128 return new SimpleMongoIteratorImpl<Element>(entries);
129 }
130
131 return null;
132 }
133 }