Coverage Report - com.allanbank.mongodb.client.callback.CursorCallback
 
Classes in this File Line Coverage Branch Coverage Complexity
CursorCallback
100%
23/23
100%
4/4
1.25
 
 1  
 /*
 2  
  * #%L
 3  
  * CursorCallback.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.concurrent.atomic.AtomicBoolean;
 24  
 
 25  
 import com.allanbank.mongodb.Callback;
 26  
 import com.allanbank.mongodb.MongoDbException;
 27  
 import com.allanbank.mongodb.MongoIterator;
 28  
 import com.allanbank.mongodb.bson.Document;
 29  
 import com.allanbank.mongodb.client.Client;
 30  
 import com.allanbank.mongodb.client.MongoIteratorImpl;
 31  
 import com.allanbank.mongodb.client.message.CursorableMessage;
 32  
 import com.allanbank.mongodb.client.message.Query;
 33  
 import com.allanbank.mongodb.client.message.Reply;
 34  
 
 35  
 /**
 36  
  * Callback to convert a {@link CursorableMessage} {@link Reply} into a
 37  
  * {@link MongoIteratorImpl}.
 38  
  * 
 39  
  * @api.no This class is <b>NOT</b> part of the drivers API. This class may be
 40  
  *         mutated in incompatible ways between any two releases of the driver.
 41  
  * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
 42  
  */
 43  16
 public final class CursorCallback extends
 44  
         AbstractReplyCallback<MongoIterator<Document>> implements AddressAware {
 45  
 
 46  
     /** The server the original request was sent to. */
 47  
     private volatile String myAddress;
 48  
 
 49  
     /** The original query. */
 50  
     private final Client myClient;
 51  
 
 52  
     /** If true then the callback should expect a command formated cursor reply. */
 53  
     private final boolean myCommand;
 54  
 
 55  
     /** The original message to start the cursor. */
 56  
     private final CursorableMessage myMessage;
 57  
 
 58  
     /** The reply to the query. */
 59  
     private volatile Reply myReply;
 60  
 
 61  
     /**
 62  
      * Initially set to false. Set to true for the first of address or reply
 63  
      * being set. The second fails and {@link #trigger() triggers} the callback.
 64  
      */
 65  
     private final AtomicBoolean mySetOther;
 66  
 
 67  
     /**
 68  
      * Create a new CursorCallback.
 69  
      * 
 70  
      * @param client
 71  
      *            The client interface to the server.
 72  
      * @param message
 73  
      *            The original query.
 74  
      * @param command
 75  
      *            If true then the callback should expect a command formated
 76  
      *            cursor reply.
 77  
      * @param results
 78  
      *            The callback to update once the first set of results are
 79  
      *            ready.
 80  
      */
 81  
     public CursorCallback(final Client client, final CursorableMessage message,
 82  
             final boolean command,
 83  
             final Callback<MongoIterator<Document>> results) {
 84  
 
 85  45
         super(results);
 86  
 
 87  45
         myClient = client;
 88  45
         myMessage = message;
 89  45
         myCommand = command;
 90  
 
 91  45
         mySetOther = new AtomicBoolean(false);
 92  45
     }
 93  
 
 94  
     /**
 95  
      * Returns the server the original request was sent to.
 96  
      * 
 97  
      * @return The server the original request was sent to.
 98  
      */
 99  
     public String getAddress() {
 100  4
         return myAddress;
 101  
     }
 102  
 
 103  
     /**
 104  
      * Sets the value of the server the original request was sent to.
 105  
      * 
 106  
      * @param address
 107  
      *            The new value for the server the original request was sent to.
 108  
      */
 109  
     @Override
 110  
     public void setAddress(final String address) {
 111  18
         myAddress = address;
 112  18
         trigger();
 113  18
     }
 114  
 
 115  
     /**
 116  
      * {@inheritDoc}
 117  
      * <p>
 118  
      * Overridden to add the {@link Query} to the exception.
 119  
      * </p>
 120  
      * 
 121  
      * @see AbstractReplyCallback#asError(Reply, int, int, String)
 122  
      */
 123  
     @Override
 124  
     protected MongoDbException asError(final Reply reply, final int okValue,
 125  
             final int errorNumber, final String errorMessage) {
 126  8
         return super.asError(reply, okValue, errorNumber, false, errorMessage,
 127  
                 myMessage);
 128  
     }
 129  
 
 130  
     /**
 131  
      * {@inheritDoc}
 132  
      * <p>
 133  
      * Overridden to construct a {@link MongoIteratorImpl} around the reply.
 134  
      * </p>
 135  
      * 
 136  
      * @see AbstractReplyCallback#convert(Reply)
 137  
      */
 138  
     @Override
 139  
     protected MongoIterator<Document> convert(final Reply reply)
 140  
             throws MongoDbException {
 141  17
         Reply result = reply;
 142  17
         if (isCommand()) {
 143  5
             result = CommandCursorTranslator.translate(reply);
 144  
         }
 145  17
         return new MongoIteratorImpl(myMessage, myClient, myAddress, result);
 146  
     }
 147  
 
 148  
     /**
 149  
      * {@inheritDoc}
 150  
      * <p>
 151  
      * Overridden to check if the server address has been set and if so then
 152  
      * pass the converted reply to the {@link #getForwardCallback() forward
 153  
      * callback}. Otherwise the call is dropped.
 154  
      * </p>
 155  
      */
 156  
     @Override
 157  
     protected void handle(final Reply reply) {
 158  16
         myReply = reply;
 159  16
         trigger();
 160  16
     }
 161  
 
 162  
     /**
 163  
      * Returns true if the callback should expect a command formated cursor
 164  
      * reply.
 165  
      * 
 166  
      * @return True if the callback should expect a command formated cursor
 167  
      *         reply.
 168  
      */
 169  
     protected boolean isCommand() {
 170  17
         return myCommand;
 171  
     }
 172  
 
 173  
     /**
 174  
      * Triggers the callback when the address and reply are set.
 175  
      */
 176  
     private void trigger() {
 177  34
         if (!mySetOther.compareAndSet(false, true)) {
 178  16
             super.handle(myReply);
 179  
         }
 180  34
     }
 181  
 }