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