Coverage Report - com.allanbank.mongodb.bson.builder.impl.DocumentBuilderImpl
 
Classes in this File Line Coverage Branch Coverage Complexity
DocumentBuilderImpl
98%
80/81
100%
20/20
1.354
 
 1  
 /*
 2  
  * #%L
 3  
  * DocumentBuilderImpl.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.bson.builder.impl;
 21  
 
 22  
 import java.io.StringWriter;
 23  
 import java.util.Date;
 24  
 import java.util.Iterator;
 25  
 import java.util.UUID;
 26  
 import java.util.regex.Pattern;
 27  
 
 28  
 import com.allanbank.mongodb.bson.Document;
 29  
 import com.allanbank.mongodb.bson.DocumentAssignable;
 30  
 import com.allanbank.mongodb.bson.Element;
 31  
 import com.allanbank.mongodb.bson.ElementAssignable;
 32  
 import com.allanbank.mongodb.bson.builder.ArrayBuilder;
 33  
 import com.allanbank.mongodb.bson.builder.BuilderFactory;
 34  
 import com.allanbank.mongodb.bson.builder.DocumentBuilder;
 35  
 import com.allanbank.mongodb.bson.element.BinaryElement;
 36  
 import com.allanbank.mongodb.bson.element.BooleanElement;
 37  
 import com.allanbank.mongodb.bson.element.DocumentElement;
 38  
 import com.allanbank.mongodb.bson.element.DoubleElement;
 39  
 import com.allanbank.mongodb.bson.element.IntegerElement;
 40  
 import com.allanbank.mongodb.bson.element.JavaScriptElement;
 41  
 import com.allanbank.mongodb.bson.element.JavaScriptWithScopeElement;
 42  
 import com.allanbank.mongodb.bson.element.JsonSerializationVisitor;
 43  
 import com.allanbank.mongodb.bson.element.LongElement;
 44  
 import com.allanbank.mongodb.bson.element.MaxKeyElement;
 45  
 import com.allanbank.mongodb.bson.element.MinKeyElement;
 46  
 import com.allanbank.mongodb.bson.element.MongoTimestampElement;
 47  
 import com.allanbank.mongodb.bson.element.NullElement;
 48  
 import com.allanbank.mongodb.bson.element.ObjectId;
 49  
 import com.allanbank.mongodb.bson.element.ObjectIdElement;
 50  
 import com.allanbank.mongodb.bson.element.RegularExpressionElement;
 51  
 import com.allanbank.mongodb.bson.element.StringElement;
 52  
 import com.allanbank.mongodb.bson.element.SymbolElement;
 53  
 import com.allanbank.mongodb.bson.element.TimestampElement;
 54  
 import com.allanbank.mongodb.bson.element.UuidElement;
 55  
 import com.allanbank.mongodb.bson.impl.RootDocument;
 56  
 
 57  
 /**
 58  
  * A builder for BSON documents.
 59  
  * 
 60  
  * @api.no This class is <b>NOT</b> part of the drivers API. This class may be
 61  
  *         mutated in incompatible ways between any two releases of the driver.
 62  
  * @copyright 2011-2013, Allanbank Consulting, Inc., All Rights Reserved
 63  
  */
 64  0
 public class DocumentBuilderImpl extends AbstractBuilder implements
 65  
         DocumentBuilder {
 66  
 
 67  
     /** Tracks if an _id element is present. */
 68  
     private boolean myIdPresent;
 69  
 
 70  
     /**
 71  
      * Creates a new builder.
 72  
      */
 73  
     public DocumentBuilderImpl() {
 74  5279
         this((AbstractBuilder) null);
 75  5279
     }
 76  
 
 77  
     /**
 78  
      * Creates a new builder.
 79  
      * 
 80  
      * @param outerScope
 81  
      *            The outer document scope.
 82  
      */
 83  
     public DocumentBuilderImpl(final AbstractBuilder outerScope) {
 84  806474
         super(outerScope);
 85  806474
     }
 86  
 
 87  
     /**
 88  
      * Creates a new builder.
 89  
      * 
 90  
      * @param seedDocument
 91  
      *            The document to seed the builder with. The builder will
 92  
      *            contain the seed document elements plus any added/appended
 93  
      *            elements.
 94  
      */
 95  
     public DocumentBuilderImpl(final DocumentAssignable seedDocument) {
 96  100388
         this((AbstractBuilder) null);
 97  
 
 98  100388
         final Document document = seedDocument.asDocument();
 99  100388
         myElements.addAll(document.getElements());
 100  100388
     }
 101  
 
 102  
     /**
 103  
      * {@inheritDoc}
 104  
      */
 105  
     @Override
 106  
     public DocumentBuilder add(final ElementAssignable elementRef)
 107  
             throws IllegalArgumentException {
 108  1639418
         final Element element = elementRef.asElement();
 109  1639418
         myElements.add(element);
 110  1639418
         if ("_id".equals(element.getName())) {
 111  166
             myIdPresent = true;
 112  
         }
 113  1639418
         return this;
 114  
     }
 115  
 
 116  
     /**
 117  
      * {@inheritDoc}
 118  
      */
 119  
     @Override
 120  
     public DocumentBuilder add(final String name, final boolean value)
 121  
             throws IllegalArgumentException {
 122  201051
         return addBoolean(name, value);
 123  
     }
 124  
 
 125  
     /**
 126  
      * {@inheritDoc}
 127  
      */
 128  
     @Override
 129  
     public DocumentBuilder add(final String name, final byte subType,
 130  
             final byte[] data) throws IllegalArgumentException {
 131  3
         return addBinary(name, subType, data);
 132  
     }
 133  
 
 134  
     /**
 135  
      * {@inheritDoc}
 136  
      */
 137  
     @Override
 138  
     public DocumentBuilder add(final String name, final byte[] data)
 139  
             throws IllegalArgumentException {
 140  10
         if (data == null) {
 141  1
             return addNull(name);
 142  
         }
 143  9
         return addBinary(name, data);
 144  
     }
 145  
 
 146  
     /**
 147  
      * {@inheritDoc}
 148  
      */
 149  
     @Override
 150  
     public DocumentBuilder add(final String name, final Date timestamp)
 151  
             throws IllegalArgumentException {
 152  25
         if (timestamp == null) {
 153  1
             return addNull(name);
 154  
         }
 155  24
         return addTimestamp(name, timestamp.getTime());
 156  
     }
 157  
 
 158  
     /**
 159  
      * {@inheritDoc}
 160  
      */
 161  
     @Override
 162  
     public DocumentBuilder add(final String name,
 163  
             final DocumentAssignable document) throws IllegalArgumentException {
 164  1116357
         if (document == null) {
 165  1
             return addNull(name);
 166  
         }
 167  1116356
         return addDocument(name, document);
 168  
     }
 169  
 
 170  
     /**
 171  
      * {@inheritDoc}
 172  
      */
 173  
     @Override
 174  
     public DocumentBuilder add(final String name, final double value)
 175  
             throws IllegalArgumentException {
 176  38
         return addDouble(name, value);
 177  
     }
 178  
 
 179  
     /**
 180  
      * {@inheritDoc}
 181  
      */
 182  
     @Override
 183  
     public DocumentBuilder add(final String name, final int value)
 184  
             throws IllegalArgumentException {
 185  300686
         return addInteger(name, value);
 186  
     }
 187  
 
 188  
     /**
 189  
      * {@inheritDoc}
 190  
      */
 191  
     @Override
 192  
     public DocumentBuilder add(final String name, final long value)
 193  
             throws IllegalArgumentException {
 194  68
         return addLong(name, value);
 195  
     }
 196  
 
 197  
     /**
 198  
      * {@inheritDoc}
 199  
      */
 200  
     @Override
 201  
     public DocumentBuilder add(final String name, final Object value)
 202  
             throws IllegalArgumentException {
 203  25
         add(BuilderFactory.e(name, value));
 204  24
         return this;
 205  
     }
 206  
 
 207  
     /**
 208  
      * {@inheritDoc}
 209  
      */
 210  
     @Override
 211  
     public DocumentBuilder add(final String name, final ObjectId id)
 212  
             throws IllegalArgumentException {
 213  18
         if (id == null) {
 214  1
             return addNull(name);
 215  
         }
 216  17
         return addObjectId(name, id);
 217  
     }
 218  
 
 219  
     /**
 220  
      * {@inheritDoc}
 221  
      */
 222  
     @Override
 223  
     public DocumentBuilder add(final String name, final Pattern pattern)
 224  
             throws IllegalArgumentException {
 225  6
         if (pattern == null) {
 226  1
             return addNull(name);
 227  
         }
 228  5
         return addRegularExpression(name, pattern);
 229  
     }
 230  
 
 231  
     /**
 232  
      * {@inheritDoc}
 233  
      */
 234  
     @Override
 235  
     public DocumentBuilder add(final String name, final String value)
 236  
             throws IllegalArgumentException {
 237  1406
         if (value == null) {
 238  1
             return addNull(name);
 239  
         }
 240  1405
         return addString(name, value);
 241  
     }
 242  
 
 243  
     /**
 244  
      * {@inheritDoc}
 245  
      */
 246  
     @Override
 247  
     @Deprecated
 248  
     public DocumentBuilder add(final String name, final String databaseName,
 249  
             final String collectionName, final ObjectId id)
 250  
             throws IllegalArgumentException {
 251  3
         return addDBPointer(name, databaseName, collectionName, id);
 252  
     }
 253  
 
 254  
     /**
 255  
      * {@inheritDoc}
 256  
      */
 257  
     @Override
 258  
     public DocumentBuilder add(final String name, final UUID uuid)
 259  
             throws IllegalArgumentException {
 260  4
         if (uuid == null) {
 261  1
             return addNull(name);
 262  
         }
 263  3
         return addUuid(name, uuid);
 264  
     }
 265  
 
 266  
     /**
 267  
      * {@inheritDoc}
 268  
      */
 269  
     @Override
 270  
     public DocumentBuilder addBinary(final String name, final byte subType,
 271  
             final byte[] value) throws IllegalArgumentException {
 272  27
         return add(new BinaryElement(name, subType, value));
 273  
     }
 274  
 
 275  
     /**
 276  
      * {@inheritDoc}
 277  
      */
 278  
     @Override
 279  
     public DocumentBuilder addBinary(final String name, final byte[] value)
 280  
             throws IllegalArgumentException {
 281  16056
         return add(new BinaryElement(name, value));
 282  
     }
 283  
 
 284  
     /**
 285  
      * {@inheritDoc}
 286  
      */
 287  
     @Override
 288  
     public DocumentBuilder addBoolean(final String name, final boolean value)
 289  
             throws IllegalArgumentException {
 290  201219
         return add(new BooleanElement(name, value));
 291  
     }
 292  
 
 293  
     /**
 294  
      * {@inheritDoc}
 295  
      */
 296  
     @Override
 297  
     @Deprecated
 298  
     public DocumentBuilder addDBPointer(final String name,
 299  
             final String databaseName, final String collectionName,
 300  
             final ObjectId id) throws IllegalArgumentException {
 301  14
         return add(new com.allanbank.mongodb.bson.element.DBPointerElement(
 302  
                 name, databaseName, collectionName, id));
 303  
     }
 304  
 
 305  
     /**
 306  
      * {@inheritDoc}
 307  
      */
 308  
     @Override
 309  
     public DocumentBuilder addDocument(final String name,
 310  
             final DocumentAssignable value) throws IllegalArgumentException {
 311  1116513
         return add(new DocumentElement(name, value.asDocument()));
 312  
     }
 313  
 
 314  
     /**
 315  
      * {@inheritDoc}
 316  
      */
 317  
     @Override
 318  
     public DocumentBuilder addDouble(final String name, final double value)
 319  
             throws IllegalArgumentException {
 320  91
         return add(new DoubleElement(name, value));
 321  
     }
 322  
 
 323  
     /**
 324  
      * {@inheritDoc}
 325  
      */
 326  
     @Override
 327  
     public DocumentBuilder addInteger(final String name, final int value)
 328  
             throws IllegalArgumentException {
 329  301768
         return add(new IntegerElement(name, value));
 330  
     }
 331  
 
 332  
     /**
 333  
      * {@inheritDoc}
 334  
      */
 335  
     @Override
 336  
     public DocumentBuilder addJavaScript(final String name, final String code)
 337  
             throws IllegalArgumentException {
 338  79
         return add(new JavaScriptElement(name, code));
 339  
     }
 340  
 
 341  
     /**
 342  
      * {@inheritDoc}
 343  
      */
 344  
     @Override
 345  
     public DocumentBuilder addJavaScript(final String name, final String code,
 346  
             final DocumentAssignable scope) throws IllegalArgumentException {
 347  12
         return add(new JavaScriptWithScopeElement(name, code,
 348  
                 scope.asDocument()));
 349  
     }
 350  
 
 351  
     /**
 352  
      * {@inheritDoc}
 353  
      */
 354  
     @Override
 355  
     public DocumentBuilder addLegacyUuid(final String name, final UUID uuid)
 356  
             throws IllegalArgumentException {
 357  4
         return add(new UuidElement(name, UuidElement.LEGACY_UUID_SUBTTYPE, uuid));
 358  
     }
 359  
 
 360  
     /**
 361  
      * {@inheritDoc}
 362  
      */
 363  
     @Override
 364  
     public DocumentBuilder addLong(final String name, final long value)
 365  
             throws IllegalArgumentException {
 366  113
         return add(new LongElement(name, value));
 367  
     }
 368  
 
 369  
     /**
 370  
      * {@inheritDoc}
 371  
      */
 372  
     @Override
 373  
     public DocumentBuilder addMaxKey(final String name)
 374  
             throws IllegalArgumentException {
 375  20
         return add(new MaxKeyElement(name));
 376  
     }
 377  
 
 378  
     /**
 379  
      * {@inheritDoc}
 380  
      */
 381  
     @Override
 382  
     public DocumentBuilder addMinKey(final String name)
 383  
             throws IllegalArgumentException {
 384  18
         return add(new MinKeyElement(name));
 385  
     }
 386  
 
 387  
     /**
 388  
      * {@inheritDoc}
 389  
      */
 390  
     @Override
 391  
     public DocumentBuilder addMongoTimestamp(final String name, final long value)
 392  
             throws IllegalArgumentException {
 393  19
         return add(new MongoTimestampElement(name, value));
 394  
     }
 395  
 
 396  
     /**
 397  
      * {@inheritDoc}
 398  
      */
 399  
     @Override
 400  
     public DocumentBuilder addNull(final String name)
 401  
             throws IllegalArgumentException {
 402  30
         return add(new NullElement(name));
 403  
     }
 404  
 
 405  
     /**
 406  
      * {@inheritDoc}
 407  
      */
 408  
     @Override
 409  
     public DocumentBuilder addObjectId(final String name, final ObjectId id)
 410  
             throws IllegalArgumentException {
 411  47
         return add(new ObjectIdElement(name, id));
 412  
     }
 413  
 
 414  
     /**
 415  
      * {@inheritDoc}
 416  
      */
 417  
     @Override
 418  
     public DocumentBuilder addRegularExpression(final String name,
 419  
             final Pattern pattern) throws IllegalArgumentException {
 420  7
         return add(new RegularExpressionElement(name, pattern));
 421  
     }
 422  
 
 423  
     /**
 424  
      * {@inheritDoc}
 425  
      */
 426  
     @Override
 427  
     public DocumentBuilder addRegularExpression(final String name,
 428  
             final String pattern, final String options)
 429  
             throws IllegalArgumentException {
 430  16
         return add(new RegularExpressionElement(name, pattern, options));
 431  
     }
 432  
 
 433  
     /**
 434  
      * {@inheritDoc}
 435  
      */
 436  
     @Override
 437  
     public DocumentBuilder addString(final String name, final String value)
 438  
             throws IllegalArgumentException {
 439  2402
         return add(new StringElement(name, value));
 440  
     }
 441  
 
 442  
     /**
 443  
      * {@inheritDoc}
 444  
      */
 445  
     @Override
 446  
     public DocumentBuilder addSymbol(final String name, final String symbol)
 447  
             throws IllegalArgumentException {
 448  33
         return add(new SymbolElement(name, symbol));
 449  
     }
 450  
 
 451  
     /**
 452  
      * {@inheritDoc}
 453  
      */
 454  
     @Override
 455  
     public DocumentBuilder addTimestamp(final String name, final long timestamp)
 456  
             throws IllegalArgumentException {
 457  66
         return add(new TimestampElement(name, timestamp));
 458  
     }
 459  
 
 460  
     /**
 461  
      * {@inheritDoc}
 462  
      */
 463  
     @Override
 464  
     public DocumentBuilder addUuid(final String name, final UUID uuid)
 465  
             throws IllegalArgumentException {
 466  6
         return add(new UuidElement(name, UuidElement.UUID_SUBTTYPE, uuid));
 467  
     }
 468  
 
 469  
     /**
 470  
      * {@inheritDoc}
 471  
      * <p>
 472  
      * Returns the result of {@link #build()}.
 473  
      * </p>
 474  
      * 
 475  
      * @see #build()
 476  
      */
 477  
     @Override
 478  
     public Document asDocument() {
 479  100607
         return build();
 480  
     }
 481  
 
 482  
     /**
 483  
      * {@inheritDoc}
 484  
      */
 485  
     @Override
 486  
     public Document build() {
 487  208156
         return new RootDocument(subElements(), myIdPresent);
 488  
     }
 489  
 
 490  
     /**
 491  
      * {@inheritDoc}
 492  
      */
 493  
     @Override
 494  
     public DocumentBuilder push(final String name) {
 495  400
         return doPush(name);
 496  
     }
 497  
 
 498  
     /**
 499  
      * {@inheritDoc}
 500  
      */
 501  
     @Override
 502  
     public ArrayBuilder pushArray(final String name) {
 503  1592
         return doPushArray(name);
 504  
     }
 505  
 
 506  
     /**
 507  
      * {@inheritDoc}
 508  
      */
 509  
     @Override
 510  
     public DocumentBuilder remove(final String name) {
 511  456
         final Iterator<Element> iter = myElements.iterator();
 512  1532
         while (iter.hasNext()) {
 513  1076
             if (name.equals(iter.next().getName())) {
 514  88
                 iter.remove();
 515  
             }
 516  
         }
 517  456
         return this;
 518  
     }
 519  
 
 520  
     /**
 521  
      * {@inheritDoc}
 522  
      */
 523  
     @Override
 524  
     public DocumentBuilder reset() {
 525  1146
         super.reset();
 526  1146
         return this;
 527  
     }
 528  
 
 529  
     /**
 530  
      * {@inheritDoc}
 531  
      * <p>
 532  
      * Overridden to return the current state of the builder as a document.
 533  
      * </p>
 534  
      */
 535  
     @Override
 536  
     public String toString() {
 537  1
         final StringWriter writer = new StringWriter();
 538  1
         final JsonSerializationVisitor visitor = new JsonSerializationVisitor(
 539  
                 writer, false);
 540  
 
 541  1
         visitor.visit(myElements);
 542  
 
 543  1
         return writer.toString();
 544  
     }
 545  
 
 546  
     /**
 547  
      * {@inheritDoc}
 548  
      * <p>
 549  
      * Overridden to return an {@link DocumentElement}.
 550  
      * </p>
 551  
      */
 552  
     @Override
 553  
     protected Element build(final String name) {
 554  701085
         return new DocumentElement(name, subElements(), true);
 555  
     }
 556  
 }