Coverage Report - com.allanbank.mongodb.bson.json.JsonParser
 
Classes in this File Line Coverage Branch Coverage Complexity
JsonParser$1
N/A
N/A
6.438
JsonParser$JJCalls
100%
1/1
N/A
6.438
JsonParser$LookaheadSuccess
100%
1/1
N/A
6.438
 
 1  
 /* Generated By:JavaCC: Do not edit this line. JsonParser.java */
 2  
 /*
 3  
  * #%L
 4  
  * JsonParser.jj - mongodb-async-driver - Allanbank Consulting, Inc.
 5  
  * %%
 6  
  * Copyright (C) 2011 - 2014 Allanbank Consulting, Inc.
 7  
  * %%
 8  
  * Licensed under the Apache License, Version 2.0 (the "License");
 9  
  * you may not use this file except in compliance with the License.
 10  
  * You may obtain a copy of the License at
 11  
  * 
 12  
  *      http://www.apache.org/licenses/LICENSE-2.0
 13  
  * 
 14  
  * Unless required by applicable law or agreed to in writing, software
 15  
  * distributed under the License is distributed on an "AS IS" BASIS,
 16  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 17  
  * See the License for the specific language governing permissions and
 18  
  * limitations under the License.
 19  
  * #L%
 20  
  */
 21  
 package com.allanbank.mongodb.bson.json;
 22  
 
 23  
 import java.io.Reader;
 24  
 import java.io.StringReader;
 25  
 import java.text.SimpleDateFormat;
 26  
 import java.util.Arrays;
 27  
 import java.util.Date;
 28  
 import java.util.List;
 29  
 import java.util.TimeZone;
 30  
 import java.util.concurrent.TimeUnit;
 31  
 
 32  
 import com.allanbank.mongodb.bson.Document;
 33  
 import com.allanbank.mongodb.bson.Element;
 34  
 import com.allanbank.mongodb.bson.builder.ArrayBuilder;
 35  
 import com.allanbank.mongodb.bson.builder.BuilderFactory;
 36  
 import com.allanbank.mongodb.bson.builder.DocumentBuilder;
 37  
 import com.allanbank.mongodb.bson.element.ObjectId;
 38  
 import com.allanbank.mongodb.error.JsonParseException;
 39  
 import com.allanbank.mongodb.bson.io.EndianUtils;
 40  
 import com.allanbank.mongodb.util.IOUtils;
 41  
 
 42  
 /**
 43  
  * Parser for JSON documents.  This parser does not handle functions or complex expressions.
 44  
  * <p>
 45  
  * The intent of this parser is not to create a full capability JSON parser but 
 46  
  * instead to provide a simplified parser that accepts most valid documents.  
 47  
  * This parsers may also accept invalid documents/programs.
 48  
  * </p>
 49  
  * <p>
 50  
  * This class is not currently part of the drivers API.  We intend to eventually provide some 
 51  
  * basic JSON-->Document functionality but are looking for feedback from the community
 52  
  * on that interface. 
 53  
  * </p>
 54  
  * <p>
 55  
  * Users should not utilize this class directly.  Instead they should use the 
 56  
  * {@link Json} static class.
 57  
  * </p>
 58  
  *
 59  
  * @see <a href="http://www.ietf.org/rfc/rfc4627.txt">RFC 4627</a>
 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 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
 63  
  */
 64  
 @SuppressWarnings({ "unused", "javadoc", "deprecated" })
 65  
 /* package */ class JsonParser implements JsonParserConstants {
 66  
     /** The default time zone. */
 67  
     public static final TimeZone UTC = TimeZone.getTimeZone("UTC");
 68  
 
 69  
     /** The time formats accepted/parsed. */
 70  
     private static final String[] DATE_FORMATS = new String[] {
 71  
             "yyyy-MM-dd'T'HH:mm:ss.SSSZ", "yyyy-MM-dd'T'HH:mm:ssZ",
 72  
             "yyyy-MM-dd'T'HH:mmZ", "yyyy-MM-dd'T'HH:mm:ss.SSS",
 73  
             "yyyy-MM-dd'T'HH:mm:ss", "yyyy-MM-dd'T'HH:mm",
 74  
             "yyyy-MM-dd HH:mm:ss.SSSZ", "yyyy-MM-dd HH:mm:ssZ",
 75  
             "yyyy-MM-dd HH:mmZ", "yyyy-MM-dd HH:mm:ss.SSS",
 76  
             "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd HH:mm", "yyyy-MM-dd", };
 77  
 
 78  
     /**
 79  
      * Create a new JsonParser.
 80  
      */
 81  
     public JsonParser() {
 82  
         this(new StringReader(""));
 83  
     }
 84  
 
 85  
     /**
 86  
      * Parses the current source of data.
 87  
      * 
 88  
      * @param text
 89  
      *            The text JSON to parse.
 90  
      * @return The Document or list of documents parsed.
 91  
      * @throws ParseException
 92  
      *             On a failure to parse the JSON document.
 93  
      */
 94  
     public Object parse(final String text) throws ParseException {
 95  
         ReInit(new StringReader(text));
 96  
         return parse();
 97  
     }
 98  
 
 99  
     /**
 100  
      * Parses the current source of data.
 101  
      * 
 102  
      * @param reader
 103  
      *            The text JSON to parse.
 104  
      * @return The Document or list of documents parsed.
 105  
      * @throws ParseException
 106  
      *             On a failure to parse the JSON document.
 107  
      */
 108  
     public Object parse(final Reader reader) throws ParseException {
 109  
         ReInit(reader);
 110  
         return parse();
 111  
     }
 112  
 
 113  
     /**
 114  
      * Converts the Base64 string to a binary array.
 115  
      * 
 116  
      * @param base64Token
 117  
      *            The Base64 encoded bytes.
 118  
      * @return The decoded bytes.
 119  
      * @throws JsonParseException
 120  
      *             On a failure to decodee the binary.
 121  
      */
 122  
     private byte[] toBinaryFromBase64(final Token base64Token)
 123  
             throws JsonParseException {
 124  
         final String base64 = trimQuotes(base64Token.image);
 125  
         try {
 126  
             return IOUtils.base64ToBytes(base64);
 127  
         }
 128  
         catch (final IllegalArgumentException iae) {
 129  
             throw new JsonParseException(iae.getMessage() + " (line "
 130  
                     + base64Token.beginLine + ", column "
 131  
                     + base64Token.beginColumn + ")", iae,
 132  
                     base64Token.beginLine, base64Token.beginColumn);
 133  
         }
 134  
     }
 135  
 
 136  
     /**
 137  
      * Converts the HEX string to a binary array.
 138  
      * 
 139  
      * @param hexToken
 140  
      *            The HEX encoded bytes.
 141  
      * @return The decoded bytes.
 142  
      * @throws JsonParseException
 143  
      *             On a failure to decodee the binary.
 144  
      */
 145  
     private byte[] toBinaryFromHex(final Token hexToken)
 146  
             throws JsonParseException {
 147  
         final String hex = trimQuotes(hexToken.image);
 148  
         try {
 149  
             return IOUtils.hexToBytes(hex);
 150  
         }
 151  
         catch (final IllegalArgumentException iae) {
 152  
             throw new JsonParseException(iae.getMessage() + " (line "
 153  
                     + hexToken.beginLine + ", column " + hexToken.beginColumn
 154  
                     + ")", iae, hexToken.beginLine, hexToken.beginColumn);
 155  
         }
 156  
     }
 157  
 
 158  
     /**
 159  
      * Parses the ISO date string into a long field.
 160  
      * 
 161  
      * @param timestampToken
 162  
      *            The timestamp string.
 163  
      * @return The Date for the time string.
 164  
      * @throws JsonParseException
 165  
      *             On a failure to parse the date string.
 166  
      */
 167  
     private Date toDate(final Token timestampToken) throws JsonParseException {
 168  
 
 169  
         Exception last = null;
 170  
         final String timestamp = trimQuotes(timestampToken.image);
 171  
         for (final String format : DATE_FORMATS) {
 172  
             final SimpleDateFormat f = new SimpleDateFormat(format);
 173  
             f.setTimeZone(UTC);
 174  
             try {
 175  
                 return f.parse(timestamp);
 176  
             }
 177  
             catch (final java.text.ParseException pe) {
 178  
                 // Ignore. Try the next.
 179  
                 last = pe;
 180  
             }
 181  
         }
 182  
 
 183  
         throw new JsonParseException("Could not parse the time string '"
 184  
                 + timestamp + "' @ line " + timestampToken.beginLine
 185  
                 + ", column " + timestampToken.beginColumn + ".", last,
 186  
                 timestampToken.beginLine, timestampToken.beginColumn);
 187  
     }
 188  
 
 189  
     /**
 190  
      * Parses the ISO date string into a long field.
 191  
      * 
 192  
      * @param timestampToken
 193  
      *            The timestamp string.
 194  
      * @return The Date for the time string.
 195  
      * @throws JsonParseException
 196  
      *             On a failure to parse the date string.
 197  
      */
 198  
     private Date toDateFromEpoch(final Token timestampToken)
 199  
             throws JsonParseException {
 200  
 
 201  
         try {
 202  
             return new Date(Long.parseLong(timestampToken.image));
 203  
         }
 204  
         catch (NumberFormatException nfe) {
 205  
             throw new JsonParseException("Could not parse the time milliseconds '"
 206  
                     + timestampToken.image + "' @ line " + timestampToken.beginLine
 207  
                     + ", column " + timestampToken.beginColumn + ".", nfe,
 208  
                     timestampToken.beginLine, timestampToken.beginColumn);
 209  
         }
 210  
     }
 211  
 
 212  
     /**
 213  
      * Converts the HEX string to an integer.
 214  
      * 
 215  
      * @param hexToken
 216  
      *            The HEX encoded bytes.
 217  
      * @return The decoded integer.
 218  
      * @throws JsonParseException
 219  
      *             On a failure to decodee the integer.
 220  
      */
 221  
     private int toIntFromHex(final Token hexToken) throws JsonParseException {
 222  
         String hex = trimQuotes(hexToken.image);
 223  
         if (hex.startsWith("0x") || hex.startsWith("0X")) {
 224  
             hex = hex.substring(2);
 225  
         }
 226  
 
 227  
         try {
 228  
             return Integer.parseInt(hex, 16);
 229  
         }
 230  
         catch (final NumberFormatException nfe) {
 231  
             throw new JsonParseException(nfe.getMessage() + " (line "
 232  
                     + hexToken.beginLine + ", column " + hexToken.beginColumn
 233  
                     + ")", nfe, hexToken.beginLine, hexToken.beginColumn);
 234  
         }
 235  
     }
 236  
 
 237  
     /**
 238  
      * Converts the timestamp and increment into a MongoTimestamp Long value..
 239  
      * 
 240  
      * @param timestampToken
 241  
      *            The Mongo timestamp value (seconds since UNIX Epoch).
 242  
      * @param incrementToken
 243  
      *            The increment for the Mongo Timestamp.
 244  
      * @return The MongoTimestamp long value.
 245  
      * @throws JsonParseException
 246  
      *             On a failure to decode the timestamp integers.
 247  
      */
 248  
     private long toMongoTimestamp(final Token timestampToken,
 249  
             final Token incrementToken) throws JsonParseException {
 250  
         long value = 0;
 251  
 
 252  
         final String timestamp = trimQuotes(timestampToken.image);
 253  
         final String increment = trimQuotes(incrementToken.image);
 254  
         try {
 255  
             final long timePortion = Long.parseLong(timestamp) & 0xFFFFFFFFL;
 256  
 
 257  
             // Time is specified in milliseconds but only store seconds
 258  
             // so we truncate the time to milliseconds.
 259  
             value = TimeUnit.MILLISECONDS.toSeconds(timePortion);
 260  
             value <<= Integer.SIZE;
 261  
             value += (Long.parseLong(increment) & 0xFFFFFFFFL);
 262  
         }
 263  
         catch (final NumberFormatException nfe) {
 264  
             throw new JsonParseException(nfe.getMessage() + " (line "
 265  
                     + timestampToken.beginLine + ", column "
 266  
                     + timestampToken.beginColumn + ")", nfe,
 267  
                     timestampToken.beginLine, timestampToken.beginColumn);
 268  
         }
 269  
         return value;
 270  
     }
 271  
 
 272  
     /**
 273  
      * Tries to create a Mongo Timestamp from the four tokens in a document that
 274  
      * looks like:
 275  
      * <code>{ $timestamp : { &lt;token1&gt; : &lt;token2&gt; , &lt;token3&gt; : &lt;token4&gt; } }</code>
 276  
      * The second and fourth tokens should be integers. The first and third
 277  
      * should be either 't' or 'i'.
 278  
      * 
 279  
      * @param t1
 280  
      *            The first token in the document.
 281  
      * @param t2
 282  
      *            The second token in the document, should be an integer.
 283  
      * @param t3
 284  
      *            The third token in the document.
 285  
      * @param t4
 286  
      *            The fourth token in the document, should be an integer.
 287  
      */
 288  
     private long toMongoTimestamp(Token t1, Token t2, Token t3, Token t4) {
 289  
         try {
 290  
             long t2Int = Long.parseLong(trimQuotes(t2.image));
 291  
             long t4Int = Long.parseLong(trimQuotes(t4.image));
 292  
 
 293  
             String t1Str = trimQuotes(t1.image);
 294  
             String t3Str = trimQuotes(t3.image);
 295  
 
 296  
             long value = 0;
 297  
             if ("t".equals(t1Str) && "i".equals(t3Str)) {
 298  
                 // Time is specified in milliseconds but only store seconds
 299  
                 // so we truncate the time to milliseconds.
 300  
                 value = TimeUnit.MILLISECONDS.toSeconds(t2Int);
 301  
                 value <<= Integer.SIZE;
 302  
                 value += (t4Int & 0xFFFFFFFFL);
 303  
             }
 304  
             else if ("t".equals(t3Str) && "i".equals(t1Str)) {
 305  
                 value = TimeUnit.MILLISECONDS.toSeconds(t4Int);
 306  
                 value <<= Integer.SIZE;
 307  
                 value += (t2Int & 0xFFFFFFFFL);
 308  
             }
 309  
             else {
 310  
                 throw new JsonParseException(
 311  
                         "Invalid MongoDB Timestamp document at line "
 312  
                                 + t1.beginLine + ", column " + t1.beginColumn
 313  
                                 + ":", t1.beginLine, t1.beginColumn);
 314  
             }
 315  
             return value;
 316  
         }
 317  
         catch (NumberFormatException nfe) {
 318  
             throw new JsonParseException(nfe.getMessage() + " (line "
 319  
                     + t1.beginLine + ", column " + t1.beginColumn + ")", nfe,
 320  
                     t1.beginLine, t1.beginColumn);
 321  
         }
 322  
     }
 323  
 
 324  
     /**
 325  
      * Creates a ObjectId from the hex binary representation.
 326  
      * 
 327  
      * @param hexBytesToken
 328  
      *            The hex bytes for the ObjectId.
 329  
      * @return The ObjectId.
 330  
      * @throws JsonParseException
 331  
      *             On a failure to decode the hex binary into an ObjectId.
 332  
      */
 333  
     private ObjectId toObjectId(final Token hexBytesToken)
 334  
             throws JsonParseException {
 335  
         int timestamp = 0;
 336  
         long machineId = 0;
 337  
 
 338  
         final String hexBytes = trimQuotes(hexBytesToken.image);
 339  
         try {
 340  
             return new ObjectId(hexBytes);
 341  
         }
 342  
         catch (final IllegalArgumentException iae) {
 343  
             throw new JsonParseException(iae.getMessage() + " (line "
 344  
                     + hexBytesToken.beginLine + ", column "
 345  
                     + hexBytesToken.beginColumn + ")", iae,
 346  
                     hexBytesToken.beginLine, hexBytesToken.beginColumn);
 347  
         }
 348  
     }
 349  
 
 350  
     /**
 351  
      * Trims the quotes from the string.
 352  
      * 
 353  
      * @param string
 354  
      *            The string to trim the quotes from.
 355  
      * @return The string without the quotes.
 356  
      */
 357  
     private String trimQuotes(final String string) {
 358  
         if (!string.isEmpty()) {
 359  
             final int length = string.length();
 360  
             final char first = string.charAt(0);
 361  
             final char last = string.charAt(length - 1);
 362  
             if ((first == last) && ((first == '"') || (first == '\u005c''))) {
 363  
                 return string.substring(1, length - 1);
 364  
             }
 365  
         }
 366  
 
 367  
         return string;
 368  
     }
 369  
 
 370  
   final protected Object parse() throws ParseException {
 371  
     Object result = null;
 372  
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 373  
     case TOKEN_OPEN_BRACE:
 374  
       result = document(null);
 375  
       break;
 376  
     case TOKEN_OPEN_BRACKET:
 377  
       result = array(null);
 378  
       break;
 379  
     default:
 380  
       jj_la1[0] = jj_gen;
 381  
       jj_consume_token(-1);
 382  
       throw new ParseException();
 383  
     }
 384  
         {if (true) return result;}
 385  
     throw new Error("Missing return statement in function");
 386  
   }
 387  
 
 388  
   final private Document document(DocumentBuilder builder) throws ParseException {
 389  
     DocumentBuilder b = builder;
 390  
     if( b == null ) {
 391  
         b = BuilderFactory.start();
 392  
     }
 393  
     jj_consume_token(TOKEN_OPEN_BRACE);
 394  
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 395  
     case STRING_LITERAL:
 396  
     case HEX_DIGIT:
 397  
     case IDENTIFIER_NAME:
 398  
       members(b);
 399  
       break;
 400  
     default:
 401  
       jj_la1[1] = jj_gen;
 402  
       ;
 403  
     }
 404  
     jj_consume_token(TOKEN_CLOSE_BRACE);
 405  
         {if (true) return b.build();}
 406  
     throw new Error("Missing return statement in function");
 407  
   }
 408  
 
 409  
   final private List<Element> array(ArrayBuilder builder) throws ParseException {
 410  
     ArrayBuilder b = builder;
 411  
     if( b == null ) {
 412  
         b = BuilderFactory.startArray();
 413  
     }
 414  
     jj_consume_token(TOKEN_OPEN_BRACKET);
 415  
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 416  
     case TOKEN_TRUE:
 417  
     case TOKEN_FALSE:
 418  
     case TOKEN_NULL:
 419  
     case TOKEN_OPEN_BRACE:
 420  
     case TOKEN_OPEN_BRACKET:
 421  
     case DOUBLE:
 422  
     case INTEGER:
 423  
     case STRING_LITERAL:
 424  
     case HEX_DIGIT:
 425  
     case TOKEN_BINDATA:
 426  
     case TOKEN_HEXDATA:
 427  
     case TOKEN_ISODATE:
 428  
     case TOKEN_NUMBERLONG:
 429  
     case TOKEN_OBJECTID:
 430  
     case TOKEN_TIMESTAMP:
 431  
     case TOKEN_MAXKEY:
 432  
     case TOKEN_MINKEY:
 433  
     case TOKEN_DB_POINTER:
 434  
     case IDENTIFIER_NAME:
 435  
       elements(b);
 436  
       break;
 437  
     default:
 438  
       jj_la1[2] = jj_gen;
 439  
       ;
 440  
     }
 441  
     jj_consume_token(TOKEN_CLOSE_BRACKET);
 442  
         {if (true) return Arrays.asList(b.build());}
 443  
     throw new Error("Missing return statement in function");
 444  
   }
 445  
 
 446  
   final private void members(DocumentBuilder builder) throws ParseException {
 447  
     pair(builder);
 448  
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 449  
     case TOKEN_COMMA:
 450  
       jj_consume_token(TOKEN_COMMA);
 451  
       members(builder);
 452  
       break;
 453  
     default:
 454  
       jj_la1[3] = jj_gen;
 455  
       ;
 456  
     }
 457  
   }
 458  
 
 459  
   final private void pair(DocumentBuilder builder) throws ParseException {
 460  
     Token nameToken = null;
 461  
     String name = null;
 462  
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 463  
     case IDENTIFIER_NAME:
 464  
       nameToken = jj_consume_token(IDENTIFIER_NAME);
 465  
                                           name = nameToken.image;
 466  
       break;
 467  
     case STRING_LITERAL:
 468  
       nameToken = jj_consume_token(STRING_LITERAL);
 469  
                                          name = trimQuotes( nameToken.image );
 470  
       break;
 471  
     case HEX_DIGIT:
 472  
       nameToken = jj_consume_token(HEX_DIGIT);
 473  
                                     name = nameToken.image;
 474  
       break;
 475  
     default:
 476  
       jj_la1[4] = jj_gen;
 477  
       jj_consume_token(-1);
 478  
       throw new ParseException();
 479  
     }
 480  
     jj_consume_token(TOKEN_COLON);
 481  
     documentValue(name, builder);
 482  
   }
 483  
 
 484  
   final private void elements(ArrayBuilder builder) throws ParseException {
 485  
     arrayValue(builder);
 486  
     switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 487  
     case TOKEN_COMMA:
 488  
       jj_consume_token(TOKEN_COMMA);
 489  
       elements(builder);
 490  
       break;
 491  
     default:
 492  
       jj_la1[5] = jj_gen;
 493  
       ;
 494  
     }
 495  
   }
 496  
 
 497  
   final private void arrayValue(ArrayBuilder builder) throws ParseException {
 498  
     Token t1 = null;
 499  
     Token t2 = null;
 500  
     Token t3 = null;
 501  
     Token t4 = null;
 502  
     if (jj_2_1(2)) {
 503  
       jj_consume_token(TOKEN_OPEN_BRACE);
 504  
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 505  
       case TOKEN_BINARY:
 506  
         jj_consume_token(TOKEN_BINARY);
 507  
         jj_consume_token(TOKEN_COLON);
 508  
         t2 = jj_consume_token(STRING_LITERAL);
 509  
         jj_consume_token(TOKEN_COMMA);
 510  
         jj_consume_token(TOKEN_TYPE);
 511  
         jj_consume_token(TOKEN_COLON);
 512  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 513  
         case INTEGER:
 514  
           t1 = jj_consume_token(INTEGER);
 515  
           break;
 516  
         case STRING_LITERAL:
 517  
           t3 = jj_consume_token(STRING_LITERAL);
 518  
           break;
 519  
         default:
 520  
           jj_la1[6] = jj_gen;
 521  
           jj_consume_token(-1);
 522  
           throw new ParseException();
 523  
         }
 524  
               if( t1 != null ) {
 525  
                   builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
 526  
               } else {
 527  
                   builder.addBinary( (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
 528  
               }
 529  
         break;
 530  
       case TOKEN_TYPE:
 531  
         jj_consume_token(TOKEN_TYPE);
 532  
         jj_consume_token(TOKEN_COLON);
 533  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 534  
         case INTEGER:
 535  
           t1 = jj_consume_token(INTEGER);
 536  
           break;
 537  
         case STRING_LITERAL:
 538  
           t3 = jj_consume_token(STRING_LITERAL);
 539  
           break;
 540  
         default:
 541  
           jj_la1[7] = jj_gen;
 542  
           jj_consume_token(-1);
 543  
           throw new ParseException();
 544  
         }
 545  
         jj_consume_token(TOKEN_COMMA);
 546  
         jj_consume_token(TOKEN_BINARY);
 547  
         jj_consume_token(TOKEN_COLON);
 548  
         t2 = jj_consume_token(STRING_LITERAL);
 549  
               if( t1 != null ) {
 550  
                   builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
 551  
               } else {
 552  
                   builder.addBinary( (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
 553  
               }
 554  
         break;
 555  
       case TOKEN_DATE:
 556  
         jj_consume_token(TOKEN_DATE);
 557  
         jj_consume_token(TOKEN_COLON);
 558  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 559  
         case INTEGER:
 560  
           t1 = jj_consume_token(INTEGER);
 561  
           break;
 562  
         case STRING_LITERAL:
 563  
           t2 = jj_consume_token(STRING_LITERAL);
 564  
           break;
 565  
         default:
 566  
           jj_la1[8] = jj_gen;
 567  
           jj_consume_token(-1);
 568  
           throw new ParseException();
 569  
         }
 570  
               if ( t1 != null ) {
 571  
                   builder.add( toDateFromEpoch(t1) );
 572  
               } else {
 573  
                   builder.add( toDate(t2) );
 574  
               }
 575  
         break;
 576  
       case TOKEN_TS:
 577  
         jj_consume_token(TOKEN_TS);
 578  
         jj_consume_token(TOKEN_COLON);
 579  
         jj_consume_token(TOKEN_OPEN_BRACE);
 580  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 581  
         case IDENTIFIER_NAME:
 582  
           t1 = jj_consume_token(IDENTIFIER_NAME);
 583  
           break;
 584  
         case STRING_LITERAL:
 585  
           t1 = jj_consume_token(STRING_LITERAL);
 586  
           break;
 587  
         default:
 588  
           jj_la1[9] = jj_gen;
 589  
           jj_consume_token(-1);
 590  
           throw new ParseException();
 591  
         }
 592  
         jj_consume_token(TOKEN_COLON);
 593  
         t2 = jj_consume_token(INTEGER);
 594  
         jj_consume_token(TOKEN_COMMA);
 595  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 596  
         case IDENTIFIER_NAME:
 597  
           t3 = jj_consume_token(IDENTIFIER_NAME);
 598  
           break;
 599  
         case STRING_LITERAL:
 600  
           t3 = jj_consume_token(STRING_LITERAL);
 601  
           break;
 602  
         default:
 603  
           jj_la1[10] = jj_gen;
 604  
           jj_consume_token(-1);
 605  
           throw new ParseException();
 606  
         }
 607  
         jj_consume_token(TOKEN_COLON);
 608  
         t4 = jj_consume_token(INTEGER);
 609  
         jj_consume_token(TOKEN_CLOSE_BRACE);
 610  
               builder.addMongoTimestamp( toMongoTimestamp(t1, t2, t3, t4) );
 611  
         break;
 612  
       case TOKEN_REGEX:
 613  
         jj_consume_token(TOKEN_REGEX);
 614  
         jj_consume_token(TOKEN_COLON);
 615  
         t1 = jj_consume_token(STRING_LITERAL);
 616  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 617  
         case TOKEN_COMMA:
 618  
           jj_consume_token(TOKEN_COMMA);
 619  
           jj_consume_token(TOKEN_OPTIONS);
 620  
           jj_consume_token(TOKEN_COLON);
 621  
           t2 = jj_consume_token(STRING_LITERAL);
 622  
           break;
 623  
         default:
 624  
           jj_la1[11] = jj_gen;
 625  
           ;
 626  
         }
 627  
               if ( t2 != null ) {
 628  
                   builder.addRegularExpression( trimQuotes(t1.image), trimQuotes(t2.image) );
 629  
               } else {
 630  
                   builder.addRegularExpression( trimQuotes(t1.image), "" );
 631  
               }
 632  
         break;
 633  
       case TOKEN_OPTIONS:
 634  
         jj_consume_token(TOKEN_OPTIONS);
 635  
         jj_consume_token(TOKEN_COLON);
 636  
         t2 = jj_consume_token(STRING_LITERAL);
 637  
         jj_consume_token(TOKEN_COMMA);
 638  
         jj_consume_token(TOKEN_REGEX);
 639  
         jj_consume_token(TOKEN_COLON);
 640  
         t1 = jj_consume_token(STRING_LITERAL);
 641  
               builder.addRegularExpression( trimQuotes(t1.image), trimQuotes(t2.image) );
 642  
         break;
 643  
       case TOKEN_OID:
 644  
         jj_consume_token(TOKEN_OID);
 645  
         jj_consume_token(TOKEN_COLON);
 646  
         t1 = jj_consume_token(STRING_LITERAL);
 647  
               builder.addObjectId( toObjectId(t1) );
 648  
         break;
 649  
       case TOKEN_MAX:
 650  
         jj_consume_token(TOKEN_MAX);
 651  
         jj_consume_token(TOKEN_COLON);
 652  
         jj_consume_token(INTEGER);
 653  
              builder.addMaxKey();
 654  
         break;
 655  
       case TOKEN_MIN:
 656  
         jj_consume_token(TOKEN_MIN);
 657  
         jj_consume_token(TOKEN_COLON);
 658  
         jj_consume_token(INTEGER);
 659  
              builder.addMinKey();
 660  
         break;
 661  
       default:
 662  
         jj_la1[12] = jj_gen;
 663  
         jj_consume_token(-1);
 664  
         throw new ParseException();
 665  
       }
 666  
       jj_consume_token(TOKEN_CLOSE_BRACE);
 667  
     } else {
 668  
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 669  
       case TOKEN_OPEN_BRACE:
 670  
         document(builder.push());
 671  
         break;
 672  
       case TOKEN_OPEN_BRACKET:
 673  
         array(builder.pushArray());
 674  
         break;
 675  
       case HEX_DIGIT:
 676  
         t1 = jj_consume_token(HEX_DIGIT);
 677  
                              builder.addSymbol(t1.image);
 678  
         break;
 679  
       case IDENTIFIER_NAME:
 680  
         t1 = jj_consume_token(IDENTIFIER_NAME);
 681  
                                    builder.addSymbol(t1.image);
 682  
         break;
 683  
       case STRING_LITERAL:
 684  
         t1 = jj_consume_token(STRING_LITERAL);
 685  
                                   builder.addString(trimQuotes(t1.image));
 686  
         break;
 687  
       case DOUBLE:
 688  
         t1 = jj_consume_token(DOUBLE);
 689  
                           builder.addDouble(Double.parseDouble(t1.image));
 690  
         break;
 691  
       case INTEGER:
 692  
         t1 = jj_consume_token(INTEGER);
 693  
              // Experimentally determine the size of the integer.
 694  
              long value = Long.parseLong(t1.image);
 695  
              if( (Integer.MIN_VALUE <= value) && (value <= Integer.MAX_VALUE) ) {
 696  
                 builder.addInteger((int) value);
 697  
              } else {
 698  
                 builder.addLong(value);
 699  
              }
 700  
         break;
 701  
       case TOKEN_TRUE:
 702  
         jj_consume_token(TOKEN_TRUE);
 703  
                          builder.addBoolean(true);
 704  
         break;
 705  
       case TOKEN_FALSE:
 706  
         jj_consume_token(TOKEN_FALSE);
 707  
                           builder.addBoolean(false);
 708  
         break;
 709  
       case TOKEN_NULL:
 710  
         jj_consume_token(TOKEN_NULL);
 711  
                          builder.addNull();
 712  
         break;
 713  
       case TOKEN_BINDATA:
 714  
         jj_consume_token(TOKEN_BINDATA);
 715  
         jj_consume_token(69);
 716  
         t1 = jj_consume_token(INTEGER);
 717  
         jj_consume_token(TOKEN_COMMA);
 718  
         t2 = jj_consume_token(STRING_LITERAL);
 719  
         jj_consume_token(70);
 720  
              builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
 721  
         break;
 722  
       case TOKEN_HEXDATA:
 723  
         jj_consume_token(TOKEN_HEXDATA);
 724  
         jj_consume_token(69);
 725  
         t1 = jj_consume_token(INTEGER);
 726  
         jj_consume_token(TOKEN_COMMA);
 727  
         t2 = jj_consume_token(STRING_LITERAL);
 728  
         jj_consume_token(70);
 729  
              builder.addBinary( (byte) Integer.parseInt(t1.image), toBinaryFromHex(t2) );
 730  
         break;
 731  
       case TOKEN_ISODATE:
 732  
         jj_consume_token(TOKEN_ISODATE);
 733  
         jj_consume_token(69);
 734  
         t1 = jj_consume_token(STRING_LITERAL);
 735  
         jj_consume_token(70);
 736  
              builder.add( toDate(t1) );
 737  
         break;
 738  
       case TOKEN_NUMBERLONG:
 739  
         jj_consume_token(TOKEN_NUMBERLONG);
 740  
         jj_consume_token(69);
 741  
         t1 = jj_consume_token(STRING_LITERAL);
 742  
         jj_consume_token(70);
 743  
              builder.addLong(Long.parseLong(trimQuotes(t1.image)));
 744  
         break;
 745  
       case TOKEN_OBJECTID:
 746  
         jj_consume_token(TOKEN_OBJECTID);
 747  
         jj_consume_token(69);
 748  
         t1 = jj_consume_token(STRING_LITERAL);
 749  
         jj_consume_token(70);
 750  
              builder.addObjectId( toObjectId(t1) );
 751  
         break;
 752  
       case TOKEN_TIMESTAMP:
 753  
         jj_consume_token(TOKEN_TIMESTAMP);
 754  
         jj_consume_token(69);
 755  
         t1 = jj_consume_token(INTEGER);
 756  
         jj_consume_token(TOKEN_COMMA);
 757  
         t2 = jj_consume_token(INTEGER);
 758  
         jj_consume_token(70);
 759  
              builder.addMongoTimestamp( toMongoTimestamp(t1, t2) );
 760  
         break;
 761  
       case TOKEN_MAXKEY:
 762  
         jj_consume_token(TOKEN_MAXKEY);
 763  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 764  
         case 69:
 765  
           jj_consume_token(69);
 766  
           jj_consume_token(70);
 767  
           break;
 768  
         default:
 769  
           jj_la1[13] = jj_gen;
 770  
           ;
 771  
         }
 772  
              builder.addMaxKey();
 773  
         break;
 774  
       case TOKEN_MINKEY:
 775  
         jj_consume_token(TOKEN_MINKEY);
 776  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 777  
         case 69:
 778  
           jj_consume_token(69);
 779  
           jj_consume_token(70);
 780  
           break;
 781  
         default:
 782  
           jj_la1[14] = jj_gen;
 783  
           ;
 784  
         }
 785  
              builder.addMinKey();
 786  
         break;
 787  
       case TOKEN_DB_POINTER:
 788  
         jj_consume_token(TOKEN_DB_POINTER);
 789  
         jj_consume_token(69);
 790  
         t1 = jj_consume_token(STRING_LITERAL);
 791  
         jj_consume_token(TOKEN_COMMA);
 792  
         t2 = jj_consume_token(STRING_LITERAL);
 793  
         jj_consume_token(TOKEN_COMMA);
 794  
         jj_consume_token(TOKEN_OBJECTID);
 795  
         jj_consume_token(69);
 796  
         t3 = jj_consume_token(STRING_LITERAL);
 797  
         jj_consume_token(70);
 798  
         jj_consume_token(70);
 799  
              builder.addDBPointer(trimQuotes(t1.image), trimQuotes(t2.image), toObjectId(t3));
 800  
         break;
 801  
       default:
 802  
         jj_la1[15] = jj_gen;
 803  
         jj_consume_token(-1);
 804  
         throw new ParseException();
 805  
       }
 806  
     }
 807  
   }
 808  
 
 809  
   final private void documentValue(String name, DocumentBuilder builder) throws ParseException {
 810  
     Token t1 = null;
 811  
     Token t2 = null;
 812  
     Token t3 = null;
 813  
     Token t4 = null;
 814  
     if (jj_2_2(2)) {
 815  
       jj_consume_token(TOKEN_OPEN_BRACE);
 816  
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 817  
       case TOKEN_BINARY:
 818  
         jj_consume_token(TOKEN_BINARY);
 819  
         jj_consume_token(TOKEN_COLON);
 820  
         t2 = jj_consume_token(STRING_LITERAL);
 821  
         jj_consume_token(TOKEN_COMMA);
 822  
         jj_consume_token(TOKEN_TYPE);
 823  
         jj_consume_token(TOKEN_COLON);
 824  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 825  
         case INTEGER:
 826  
           t1 = jj_consume_token(INTEGER);
 827  
           break;
 828  
         case STRING_LITERAL:
 829  
           t3 = jj_consume_token(STRING_LITERAL);
 830  
           break;
 831  
         default:
 832  
           jj_la1[16] = jj_gen;
 833  
           jj_consume_token(-1);
 834  
           throw new ParseException();
 835  
         }
 836  
               if( t1 != null ) {
 837  
                   builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
 838  
               } else {
 839  
                   builder.addBinary( name, (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
 840  
               }
 841  
         break;
 842  
       case TOKEN_TYPE:
 843  
         jj_consume_token(TOKEN_TYPE);
 844  
         jj_consume_token(TOKEN_COLON);
 845  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 846  
         case INTEGER:
 847  
           t1 = jj_consume_token(INTEGER);
 848  
           break;
 849  
         case STRING_LITERAL:
 850  
           t3 = jj_consume_token(STRING_LITERAL);
 851  
           break;
 852  
         default:
 853  
           jj_la1[17] = jj_gen;
 854  
           jj_consume_token(-1);
 855  
           throw new ParseException();
 856  
         }
 857  
         jj_consume_token(TOKEN_COMMA);
 858  
         jj_consume_token(TOKEN_BINARY);
 859  
         jj_consume_token(TOKEN_COLON);
 860  
         t2 = jj_consume_token(STRING_LITERAL);
 861  
               if( t1 != null ) {
 862  
                   builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
 863  
               } else {
 864  
                   builder.addBinary( name, (byte) toIntFromHex(t3), toBinaryFromBase64(t2) );
 865  
               }
 866  
         break;
 867  
       case TOKEN_DATE:
 868  
         jj_consume_token(TOKEN_DATE);
 869  
         jj_consume_token(TOKEN_COLON);
 870  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 871  
         case INTEGER:
 872  
           t1 = jj_consume_token(INTEGER);
 873  
           break;
 874  
         case STRING_LITERAL:
 875  
           t2 = jj_consume_token(STRING_LITERAL);
 876  
           break;
 877  
         default:
 878  
           jj_la1[18] = jj_gen;
 879  
           jj_consume_token(-1);
 880  
           throw new ParseException();
 881  
         }
 882  
               if ( t1 != null ) {
 883  
                   builder.add( name, toDateFromEpoch(t1) );
 884  
               } else {
 885  
                   builder.add( name, toDate(t2) );
 886  
               }
 887  
         break;
 888  
       case TOKEN_TS:
 889  
         jj_consume_token(TOKEN_TS);
 890  
         jj_consume_token(TOKEN_COLON);
 891  
         jj_consume_token(TOKEN_OPEN_BRACE);
 892  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 893  
         case IDENTIFIER_NAME:
 894  
           t1 = jj_consume_token(IDENTIFIER_NAME);
 895  
           break;
 896  
         case STRING_LITERAL:
 897  
           t1 = jj_consume_token(STRING_LITERAL);
 898  
           break;
 899  
         default:
 900  
           jj_la1[19] = jj_gen;
 901  
           jj_consume_token(-1);
 902  
           throw new ParseException();
 903  
         }
 904  
         jj_consume_token(TOKEN_COLON);
 905  
         t2 = jj_consume_token(INTEGER);
 906  
         jj_consume_token(TOKEN_COMMA);
 907  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 908  
         case IDENTIFIER_NAME:
 909  
           t3 = jj_consume_token(IDENTIFIER_NAME);
 910  
           break;
 911  
         case STRING_LITERAL:
 912  
           t3 = jj_consume_token(STRING_LITERAL);
 913  
           break;
 914  
         default:
 915  
           jj_la1[20] = jj_gen;
 916  
           jj_consume_token(-1);
 917  
           throw new ParseException();
 918  
         }
 919  
         jj_consume_token(TOKEN_COLON);
 920  
         t4 = jj_consume_token(INTEGER);
 921  
         jj_consume_token(TOKEN_CLOSE_BRACE);
 922  
               builder.addMongoTimestamp( name, toMongoTimestamp(t1, t2, t3, t4) );
 923  
         break;
 924  
       case TOKEN_REGEX:
 925  
         jj_consume_token(TOKEN_REGEX);
 926  
         jj_consume_token(TOKEN_COLON);
 927  
         t1 = jj_consume_token(STRING_LITERAL);
 928  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 929  
         case TOKEN_COMMA:
 930  
           jj_consume_token(TOKEN_COMMA);
 931  
           jj_consume_token(TOKEN_OPTIONS);
 932  
           jj_consume_token(TOKEN_COLON);
 933  
           t2 = jj_consume_token(STRING_LITERAL);
 934  
           break;
 935  
         default:
 936  
           jj_la1[21] = jj_gen;
 937  
           ;
 938  
         }
 939  
               if ( t2 != null ) {
 940  
                   builder.addRegularExpression( name, trimQuotes(t1.image), trimQuotes(t2.image) );
 941  
               } else {
 942  
                   builder.addRegularExpression( name, trimQuotes(t1.image), "" );
 943  
               }
 944  
         break;
 945  
       case TOKEN_OPTIONS:
 946  
         jj_consume_token(TOKEN_OPTIONS);
 947  
         jj_consume_token(TOKEN_COLON);
 948  
         t2 = jj_consume_token(STRING_LITERAL);
 949  
         jj_consume_token(TOKEN_COMMA);
 950  
         jj_consume_token(TOKEN_REGEX);
 951  
         jj_consume_token(TOKEN_COLON);
 952  
         t1 = jj_consume_token(STRING_LITERAL);
 953  
               builder.addRegularExpression( name, trimQuotes(t1.image), trimQuotes(t2.image) );
 954  
         break;
 955  
       case TOKEN_OID:
 956  
         jj_consume_token(TOKEN_OID);
 957  
         jj_consume_token(TOKEN_COLON);
 958  
         t1 = jj_consume_token(STRING_LITERAL);
 959  
               builder.addObjectId( name, toObjectId(t1) );
 960  
         break;
 961  
       case TOKEN_MAX:
 962  
         jj_consume_token(TOKEN_MAX);
 963  
         jj_consume_token(TOKEN_COLON);
 964  
         jj_consume_token(INTEGER);
 965  
              builder.addMaxKey(name);
 966  
         break;
 967  
       case TOKEN_MIN:
 968  
         jj_consume_token(TOKEN_MIN);
 969  
         jj_consume_token(TOKEN_COLON);
 970  
         jj_consume_token(INTEGER);
 971  
              builder.addMinKey(name);
 972  
         break;
 973  
       default:
 974  
         jj_la1[22] = jj_gen;
 975  
         jj_consume_token(-1);
 976  
         throw new ParseException();
 977  
       }
 978  
       jj_consume_token(TOKEN_CLOSE_BRACE);
 979  
     } else {
 980  
       switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 981  
       case TOKEN_OPEN_BRACE:
 982  
         document(builder.push(name));
 983  
         break;
 984  
       case TOKEN_OPEN_BRACKET:
 985  
         array(builder.pushArray(name));
 986  
         break;
 987  
       case HEX_DIGIT:
 988  
         t1 = jj_consume_token(HEX_DIGIT);
 989  
                              builder.addSymbol(name, t1.image);
 990  
         break;
 991  
       case IDENTIFIER_NAME:
 992  
         t1 = jj_consume_token(IDENTIFIER_NAME);
 993  
                                    builder.addSymbol(name, t1.image);
 994  
         break;
 995  
       case STRING_LITERAL:
 996  
         t1 = jj_consume_token(STRING_LITERAL);
 997  
                                   builder.addString(name, trimQuotes(t1.image));
 998  
         break;
 999  
       case DOUBLE:
 1000  
         t1 = jj_consume_token(DOUBLE);
 1001  
                           builder.addDouble(name, Double.parseDouble(t1.image));
 1002  
         break;
 1003  
       case INTEGER:
 1004  
         t1 = jj_consume_token(INTEGER);
 1005  
              // Experimentally determine the size of the integer.
 1006  
              long value = Long.parseLong(t1.image);
 1007  
              if( (Integer.MIN_VALUE <= value) && (value <= Integer.MAX_VALUE) ) {
 1008  
                 builder.addInteger(name, (int) value);
 1009  
              } else {
 1010  
                 builder.addLong(name, value);
 1011  
              }
 1012  
         break;
 1013  
       case TOKEN_TRUE:
 1014  
         jj_consume_token(TOKEN_TRUE);
 1015  
                          builder.addBoolean(name, true);
 1016  
         break;
 1017  
       case TOKEN_FALSE:
 1018  
         jj_consume_token(TOKEN_FALSE);
 1019  
                           builder.addBoolean(name, false);
 1020  
         break;
 1021  
       case TOKEN_NULL:
 1022  
         jj_consume_token(TOKEN_NULL);
 1023  
                          builder.addNull(name);
 1024  
         break;
 1025  
       case TOKEN_BINDATA:
 1026  
         jj_consume_token(TOKEN_BINDATA);
 1027  
         jj_consume_token(69);
 1028  
         t1 = jj_consume_token(INTEGER);
 1029  
         jj_consume_token(TOKEN_COMMA);
 1030  
         t2 = jj_consume_token(STRING_LITERAL);
 1031  
         jj_consume_token(70);
 1032  
              builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromBase64(t2) );
 1033  
         break;
 1034  
       case TOKEN_HEXDATA:
 1035  
         jj_consume_token(TOKEN_HEXDATA);
 1036  
         jj_consume_token(69);
 1037  
         t1 = jj_consume_token(INTEGER);
 1038  
         jj_consume_token(TOKEN_COMMA);
 1039  
         t2 = jj_consume_token(STRING_LITERAL);
 1040  
         jj_consume_token(70);
 1041  
              builder.addBinary( name, (byte) Integer.parseInt(t1.image), toBinaryFromHex(t2) );
 1042  
         break;
 1043  
       case TOKEN_ISODATE:
 1044  
         jj_consume_token(TOKEN_ISODATE);
 1045  
         jj_consume_token(69);
 1046  
         t1 = jj_consume_token(STRING_LITERAL);
 1047  
         jj_consume_token(70);
 1048  
              builder.add( name, toDate(t1) );
 1049  
         break;
 1050  
       case TOKEN_NUMBERLONG:
 1051  
         jj_consume_token(TOKEN_NUMBERLONG);
 1052  
         jj_consume_token(69);
 1053  
         t1 = jj_consume_token(STRING_LITERAL);
 1054  
         jj_consume_token(70);
 1055  
              builder.addLong(name, Long.parseLong(trimQuotes(t1.image)));
 1056  
         break;
 1057  
       case TOKEN_OBJECTID:
 1058  
         jj_consume_token(TOKEN_OBJECTID);
 1059  
         jj_consume_token(69);
 1060  
         t1 = jj_consume_token(STRING_LITERAL);
 1061  
         jj_consume_token(70);
 1062  
              builder.addObjectId( name, toObjectId(t1) );
 1063  
         break;
 1064  
       case TOKEN_TIMESTAMP:
 1065  
         jj_consume_token(TOKEN_TIMESTAMP);
 1066  
         jj_consume_token(69);
 1067  
         t1 = jj_consume_token(INTEGER);
 1068  
         jj_consume_token(TOKEN_COMMA);
 1069  
         t2 = jj_consume_token(INTEGER);
 1070  
         jj_consume_token(70);
 1071  
              builder.addMongoTimestamp( name, toMongoTimestamp(t1, t2) );
 1072  
         break;
 1073  
       case TOKEN_MAXKEY:
 1074  
         jj_consume_token(TOKEN_MAXKEY);
 1075  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 1076  
         case 69:
 1077  
           jj_consume_token(69);
 1078  
           jj_consume_token(70);
 1079  
           break;
 1080  
         default:
 1081  
           jj_la1[23] = jj_gen;
 1082  
           ;
 1083  
         }
 1084  
              builder.addMaxKey(name);
 1085  
         break;
 1086  
       case TOKEN_MINKEY:
 1087  
         jj_consume_token(TOKEN_MINKEY);
 1088  
         switch ((jj_ntk==-1)?jj_ntk():jj_ntk) {
 1089  
         case 69:
 1090  
           jj_consume_token(69);
 1091  
           jj_consume_token(70);
 1092  
           break;
 1093  
         default:
 1094  
           jj_la1[24] = jj_gen;
 1095  
           ;
 1096  
         }
 1097  
              builder.addMinKey(name);
 1098  
         break;
 1099  
       case TOKEN_DB_POINTER:
 1100  
         jj_consume_token(TOKEN_DB_POINTER);
 1101  
         jj_consume_token(69);
 1102  
         t1 = jj_consume_token(STRING_LITERAL);
 1103  
         jj_consume_token(TOKEN_COMMA);
 1104  
         t2 = jj_consume_token(STRING_LITERAL);
 1105  
         jj_consume_token(TOKEN_COMMA);
 1106  
         jj_consume_token(TOKEN_OBJECTID);
 1107  
         jj_consume_token(69);
 1108  
         t3 = jj_consume_token(STRING_LITERAL);
 1109  
         jj_consume_token(70);
 1110  
         jj_consume_token(70);
 1111  
              builder.addDBPointer(name, trimQuotes(t1.image), trimQuotes(t2.image), toObjectId(t3));
 1112  
         break;
 1113  
       default:
 1114  
         jj_la1[25] = jj_gen;
 1115  
         jj_consume_token(-1);
 1116  
         throw new ParseException();
 1117  
       }
 1118  
     }
 1119  
   }
 1120  
 
 1121  
   private boolean jj_2_1(int xla) {
 1122  
     jj_la = xla; jj_lastpos = jj_scanpos = token;
 1123  
     try { return !jj_3_1(); }
 1124  
     catch(LookaheadSuccess ls) { return true; }
 1125  
     finally { jj_save(0, xla); }
 1126  
   }
 1127  
 
 1128  
   private boolean jj_2_2(int xla) {
 1129  
     jj_la = xla; jj_lastpos = jj_scanpos = token;
 1130  
     try { return !jj_3_2(); }
 1131  
     catch(LookaheadSuccess ls) { return true; }
 1132  
     finally { jj_save(1, xla); }
 1133  
   }
 1134  
 
 1135  
   private boolean jj_3R_5() {
 1136  
     if (jj_scan_token(TOKEN_REGEX)) return true;
 1137  
     return false;
 1138  
   }
 1139  
 
 1140  
   private boolean jj_3R_16() {
 1141  
     if (jj_scan_token(TOKEN_OID)) return true;
 1142  
     return false;
 1143  
   }
 1144  
 
 1145  
   private boolean jj_3_2() {
 1146  
     if (jj_scan_token(TOKEN_OPEN_BRACE)) return true;
 1147  
     Token xsp;
 1148  
     xsp = jj_scanpos;
 1149  
     if (jj_3R_10()) {
 1150  
     jj_scanpos = xsp;
 1151  
     if (jj_3R_11()) {
 1152  
     jj_scanpos = xsp;
 1153  
     if (jj_3R_12()) {
 1154  
     jj_scanpos = xsp;
 1155  
     if (jj_3R_13()) {
 1156  
     jj_scanpos = xsp;
 1157  
     if (jj_3R_14()) {
 1158  
     jj_scanpos = xsp;
 1159  
     if (jj_3R_15()) {
 1160  
     jj_scanpos = xsp;
 1161  
     if (jj_3R_16()) {
 1162  
     jj_scanpos = xsp;
 1163  
     if (jj_3R_17()) {
 1164  
     jj_scanpos = xsp;
 1165  
     if (jj_3R_18()) return true;
 1166  
     }
 1167  
     }
 1168  
     }
 1169  
     }
 1170  
     }
 1171  
     }
 1172  
     }
 1173  
     }
 1174  
     return false;
 1175  
   }
 1176  
 
 1177  
   private boolean jj_3R_15() {
 1178  
     if (jj_scan_token(TOKEN_OPTIONS)) return true;
 1179  
     return false;
 1180  
   }
 1181  
 
 1182  
   private boolean jj_3R_4() {
 1183  
     if (jj_scan_token(TOKEN_TS)) return true;
 1184  
     return false;
 1185  
   }
 1186  
 
 1187  
   private boolean jj_3R_14() {
 1188  
     if (jj_scan_token(TOKEN_REGEX)) return true;
 1189  
     return false;
 1190  
   }
 1191  
 
 1192  
   private boolean jj_3R_3() {
 1193  
     if (jj_scan_token(TOKEN_DATE)) return true;
 1194  
     return false;
 1195  
   }
 1196  
 
 1197  
   private boolean jj_3R_13() {
 1198  
     if (jj_scan_token(TOKEN_TS)) return true;
 1199  
     return false;
 1200  
   }
 1201  
 
 1202  
   private boolean jj_3R_2() {
 1203  
     if (jj_scan_token(TOKEN_TYPE)) return true;
 1204  
     return false;
 1205  
   }
 1206  
 
 1207  
   private boolean jj_3R_9() {
 1208  
     if (jj_scan_token(TOKEN_MIN)) return true;
 1209  
     return false;
 1210  
   }
 1211  
 
 1212  
   private boolean jj_3R_12() {
 1213  
     if (jj_scan_token(TOKEN_DATE)) return true;
 1214  
     return false;
 1215  
   }
 1216  
 
 1217  
   private boolean jj_3R_1() {
 1218  
     if (jj_scan_token(TOKEN_BINARY)) return true;
 1219  
     return false;
 1220  
   }
 1221  
 
 1222  
   private boolean jj_3R_8() {
 1223  
     if (jj_scan_token(TOKEN_MAX)) return true;
 1224  
     return false;
 1225  
   }
 1226  
 
 1227  
   private boolean jj_3R_7() {
 1228  
     if (jj_scan_token(TOKEN_OID)) return true;
 1229  
     return false;
 1230  
   }
 1231  
 
 1232  
   private boolean jj_3R_11() {
 1233  
     if (jj_scan_token(TOKEN_TYPE)) return true;
 1234  
     return false;
 1235  
   }
 1236  
 
 1237  
   private boolean jj_3_1() {
 1238  
     if (jj_scan_token(TOKEN_OPEN_BRACE)) return true;
 1239  
     Token xsp;
 1240  
     xsp = jj_scanpos;
 1241  
     if (jj_3R_1()) {
 1242  
     jj_scanpos = xsp;
 1243  
     if (jj_3R_2()) {
 1244  
     jj_scanpos = xsp;
 1245  
     if (jj_3R_3()) {
 1246  
     jj_scanpos = xsp;
 1247  
     if (jj_3R_4()) {
 1248  
     jj_scanpos = xsp;
 1249  
     if (jj_3R_5()) {
 1250  
     jj_scanpos = xsp;
 1251  
     if (jj_3R_6()) {
 1252  
     jj_scanpos = xsp;
 1253  
     if (jj_3R_7()) {
 1254  
     jj_scanpos = xsp;
 1255  
     if (jj_3R_8()) {
 1256  
     jj_scanpos = xsp;
 1257  
     if (jj_3R_9()) return true;
 1258  
     }
 1259  
     }
 1260  
     }
 1261  
     }
 1262  
     }
 1263  
     }
 1264  
     }
 1265  
     }
 1266  
     return false;
 1267  
   }
 1268  
 
 1269  
   private boolean jj_3R_6() {
 1270  
     if (jj_scan_token(TOKEN_OPTIONS)) return true;
 1271  
     return false;
 1272  
   }
 1273  
 
 1274  
   private boolean jj_3R_18() {
 1275  
     if (jj_scan_token(TOKEN_MIN)) return true;
 1276  
     return false;
 1277  
   }
 1278  
 
 1279  
   private boolean jj_3R_10() {
 1280  
     if (jj_scan_token(TOKEN_BINARY)) return true;
 1281  
     return false;
 1282  
   }
 1283  
 
 1284  
   private boolean jj_3R_17() {
 1285  
     if (jj_scan_token(TOKEN_MAX)) return true;
 1286  
     return false;
 1287  
   }
 1288  
 
 1289  
   /** Generated Token Manager. */
 1290  
   public JsonParserTokenManager token_source;
 1291  
   JavaCharStream jj_input_stream;
 1292  
   /** Current token. */
 1293  
   public Token token;
 1294  
   /** Next token. */
 1295  
   public Token jj_nt;
 1296  
   private int jj_ntk;
 1297  
   private Token jj_scanpos, jj_lastpos;
 1298  
   private int jj_la;
 1299  
   private int jj_gen;
 1300  
   final private int[] jj_la1 = new int[26];
 1301  
   static private int[] jj_la1_0;
 1302  
   static private int[] jj_la1_1;
 1303  
   static private int[] jj_la1_2;
 1304  
   static {
 1305  
       jj_la1_init_0();
 1306  
       jj_la1_init_1();
 1307  
       jj_la1_init_2();
 1308  
    }
 1309  
    private static void jj_la1_init_0() {
 1310  
       jj_la1_0 = new int[] {0x2800,0x10000000,0x10302f00,0x8000,0x10000000,0x8000,0x10200000,0x10200000,0x10200000,0x10000000,0x10000000,0x8000,0x0,0x0,0x0,0x10302f00,0x10200000,0x10200000,0x10200000,0x10000000,0x10000000,0x8000,0x0,0x0,0x0,0x10302f00,};
 1311  
    }
 1312  
    private static void jj_la1_init_1() {
 1313  
       jj_la1_1 = new int[] {0x0,0x2000040,0x200ffc0,0x0,0x2000040,0x0,0x0,0x0,0x0,0x2000000,0x2000000,0x0,0x1ff0000,0x0,0x0,0x200ffc0,0x0,0x0,0x0,0x2000000,0x2000000,0x0,0x1ff0000,0x0,0x0,0x200ffc0,};
 1314  
    }
 1315  
    private static void jj_la1_init_2() {
 1316  
       jj_la1_2 = new int[] {0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x20,0x20,0x0,};
 1317  
    }
 1318  
   final private JJCalls[] jj_2_rtns = new JJCalls[2];
 1319  
   private boolean jj_rescan = false;
 1320  
   private int jj_gc = 0;
 1321  
 
 1322  
   /** Constructor with InputStream. */
 1323  
   public JsonParser(java.io.InputStream stream) {
 1324  
      this(stream, null);
 1325  
   }
 1326  
   /** Constructor with InputStream and supplied encoding */
 1327  
   public JsonParser(java.io.InputStream stream, String encoding) {
 1328  
     try { jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
 1329  
     token_source = new JsonParserTokenManager(jj_input_stream);
 1330  
     token = new Token();
 1331  
     jj_ntk = -1;
 1332  
     jj_gen = 0;
 1333  
     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
 1334  
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
 1335  
   }
 1336  
 
 1337  
   /** Reinitialise. */
 1338  
   public void ReInit(java.io.InputStream stream) {
 1339  
      ReInit(stream, null);
 1340  
   }
 1341  
   /** Reinitialise. */
 1342  
   public void ReInit(java.io.InputStream stream, String encoding) {
 1343  
     try { jj_input_stream.ReInit(stream, encoding, 1, 1); } catch(java.io.UnsupportedEncodingException e) { throw new RuntimeException(e); }
 1344  
     token_source.ReInit(jj_input_stream);
 1345  
     token = new Token();
 1346  
     jj_ntk = -1;
 1347  
     jj_gen = 0;
 1348  
     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
 1349  
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
 1350  
   }
 1351  
 
 1352  
   /** Constructor. */
 1353  
   public JsonParser(java.io.Reader stream) {
 1354  
     jj_input_stream = new JavaCharStream(stream, 1, 1);
 1355  
     token_source = new JsonParserTokenManager(jj_input_stream);
 1356  
     token = new Token();
 1357  
     jj_ntk = -1;
 1358  
     jj_gen = 0;
 1359  
     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
 1360  
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
 1361  
   }
 1362  
 
 1363  
   /** Reinitialise. */
 1364  
   public void ReInit(java.io.Reader stream) {
 1365  
     jj_input_stream.ReInit(stream, 1, 1);
 1366  
     token_source.ReInit(jj_input_stream);
 1367  
     token = new Token();
 1368  
     jj_ntk = -1;
 1369  
     jj_gen = 0;
 1370  
     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
 1371  
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
 1372  
   }
 1373  
 
 1374  
   /** Constructor with generated Token Manager. */
 1375  
   public JsonParser(JsonParserTokenManager tm) {
 1376  
     token_source = tm;
 1377  
     token = new Token();
 1378  
     jj_ntk = -1;
 1379  
     jj_gen = 0;
 1380  
     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
 1381  
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
 1382  
   }
 1383  
 
 1384  
   /** Reinitialise. */
 1385  
   public void ReInit(JsonParserTokenManager tm) {
 1386  
     token_source = tm;
 1387  
     token = new Token();
 1388  
     jj_ntk = -1;
 1389  
     jj_gen = 0;
 1390  
     for (int i = 0; i < 26; i++) jj_la1[i] = -1;
 1391  
     for (int i = 0; i < jj_2_rtns.length; i++) jj_2_rtns[i] = new JJCalls();
 1392  
   }
 1393  
 
 1394  
   private Token jj_consume_token(int kind) throws ParseException {
 1395  
     Token oldToken;
 1396  
     if ((oldToken = token).next != null) token = token.next;
 1397  
     else token = token.next = token_source.getNextToken();
 1398  
     jj_ntk = -1;
 1399  
     if (token.kind == kind) {
 1400  
       jj_gen++;
 1401  
       if (++jj_gc > 100) {
 1402  
         jj_gc = 0;
 1403  
         for (int i = 0; i < jj_2_rtns.length; i++) {
 1404  
           JJCalls c = jj_2_rtns[i];
 1405  
           while (c != null) {
 1406  
             if (c.gen < jj_gen) c.first = null;
 1407  
             c = c.next;
 1408  
           }
 1409  
         }
 1410  
       }
 1411  
       return token;
 1412  
     }
 1413  
     token = oldToken;
 1414  
     jj_kind = kind;
 1415  
     throw generateParseException();
 1416  
   }
 1417  
 
 1418  288
   static private final class LookaheadSuccess extends java.lang.Error { }
 1419  
   final private LookaheadSuccess jj_ls = new LookaheadSuccess();
 1420  
   private boolean jj_scan_token(int kind) {
 1421  
     if (jj_scanpos == jj_lastpos) {
 1422  
       jj_la--;
 1423  
       if (jj_scanpos.next == null) {
 1424  
         jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken();
 1425  
       } else {
 1426  
         jj_lastpos = jj_scanpos = jj_scanpos.next;
 1427  
       }
 1428  
     } else {
 1429  
       jj_scanpos = jj_scanpos.next;
 1430  
     }
 1431  
     if (jj_rescan) {
 1432  
       int i = 0; Token tok = token;
 1433  
       while (tok != null && tok != jj_scanpos) { i++; tok = tok.next; }
 1434  
       if (tok != null) jj_add_error_token(kind, i);
 1435  
     }
 1436  
     if (jj_scanpos.kind != kind) return true;
 1437  
     if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls;
 1438  
     return false;
 1439  
   }
 1440  
 
 1441  
 
 1442  
 /** Get the next Token. */
 1443  
   final public Token getNextToken() {
 1444  
     if (token.next != null) token = token.next;
 1445  
     else token = token.next = token_source.getNextToken();
 1446  
     jj_ntk = -1;
 1447  
     jj_gen++;
 1448  
     return token;
 1449  
   }
 1450  
 
 1451  
 /** Get the specific Token. */
 1452  
   final public Token getToken(int index) {
 1453  
     Token t = token;
 1454  
     for (int i = 0; i < index; i++) {
 1455  
       if (t.next != null) t = t.next;
 1456  
       else t = t.next = token_source.getNextToken();
 1457  
     }
 1458  
     return t;
 1459  
   }
 1460  
 
 1461  
   private int jj_ntk() {
 1462  
     if ((jj_nt=token.next) == null)
 1463  
       return (jj_ntk = (token.next=token_source.getNextToken()).kind);
 1464  
     else
 1465  
       return (jj_ntk = jj_nt.kind);
 1466  
   }
 1467  
 
 1468  
   private java.util.List<int[]> jj_expentries = new java.util.ArrayList<int[]>();
 1469  
   private int[] jj_expentry;
 1470  
   private int jj_kind = -1;
 1471  
   private int[] jj_lasttokens = new int[100];
 1472  
   private int jj_endpos;
 1473  
 
 1474  
   private void jj_add_error_token(int kind, int pos) {
 1475  
     if (pos >= 100) return;
 1476  
     if (pos == jj_endpos + 1) {
 1477  
       jj_lasttokens[jj_endpos++] = kind;
 1478  
     } else if (jj_endpos != 0) {
 1479  
       jj_expentry = new int[jj_endpos];
 1480  
       for (int i = 0; i < jj_endpos; i++) {
 1481  
         jj_expentry[i] = jj_lasttokens[i];
 1482  
       }
 1483  
       jj_entries_loop: for (java.util.Iterator<?> it = jj_expentries.iterator(); it.hasNext();) {
 1484  
         int[] oldentry = (int[])(it.next());
 1485  
         if (oldentry.length == jj_expentry.length) {
 1486  
           for (int i = 0; i < jj_expentry.length; i++) {
 1487  
             if (oldentry[i] != jj_expentry[i]) {
 1488  
               continue jj_entries_loop;
 1489  
             }
 1490  
           }
 1491  
           jj_expentries.add(jj_expentry);
 1492  
           break jj_entries_loop;
 1493  
         }
 1494  
       }
 1495  
       if (pos != 0) jj_lasttokens[(jj_endpos = pos) - 1] = kind;
 1496  
     }
 1497  
   }
 1498  
 
 1499  
   /** Generate ParseException. */
 1500  
   public ParseException generateParseException() {
 1501  
     jj_expentries.clear();
 1502  
     boolean[] la1tokens = new boolean[71];
 1503  
     if (jj_kind >= 0) {
 1504  
       la1tokens[jj_kind] = true;
 1505  
       jj_kind = -1;
 1506  
     }
 1507  
     for (int i = 0; i < 26; i++) {
 1508  
       if (jj_la1[i] == jj_gen) {
 1509  
         for (int j = 0; j < 32; j++) {
 1510  
           if ((jj_la1_0[i] & (1<<j)) != 0) {
 1511  
             la1tokens[j] = true;
 1512  
           }
 1513  
           if ((jj_la1_1[i] & (1<<j)) != 0) {
 1514  
             la1tokens[32+j] = true;
 1515  
           }
 1516  
           if ((jj_la1_2[i] & (1<<j)) != 0) {
 1517  
             la1tokens[64+j] = true;
 1518  
           }
 1519  
         }
 1520  
       }
 1521  
     }
 1522  
     for (int i = 0; i < 71; i++) {
 1523  
       if (la1tokens[i]) {
 1524  
         jj_expentry = new int[1];
 1525  
         jj_expentry[0] = i;
 1526  
         jj_expentries.add(jj_expentry);
 1527  
       }
 1528  
     }
 1529  
     jj_endpos = 0;
 1530  
     jj_rescan_token();
 1531  
     jj_add_error_token(0, 0);
 1532  
     int[][] exptokseq = new int[jj_expentries.size()][];
 1533  
     for (int i = 0; i < jj_expentries.size(); i++) {
 1534  
       exptokseq[i] = jj_expentries.get(i);
 1535  
     }
 1536  
     return new ParseException(token, exptokseq, tokenImage);
 1537  
   }
 1538  
 
 1539  
   /** Enable tracing. */
 1540  
   final public void enable_tracing() {
 1541  
   }
 1542  
 
 1543  
   /** Disable tracing. */
 1544  
   final public void disable_tracing() {
 1545  
   }
 1546  
 
 1547  
   private void jj_rescan_token() {
 1548  
     jj_rescan = true;
 1549  
     for (int i = 0; i < 2; i++) {
 1550  
     try {
 1551  
       JJCalls p = jj_2_rtns[i];
 1552  
       do {
 1553  
         if (p.gen > jj_gen) {
 1554  
           jj_la = p.arg; jj_lastpos = jj_scanpos = p.first;
 1555  
           switch (i) {
 1556  
             case 0: jj_3_1(); break;
 1557  
             case 1: jj_3_2(); break;
 1558  
           }
 1559  
         }
 1560  
         p = p.next;
 1561  
       } while (p != null);
 1562  
       } catch(LookaheadSuccess ls) { }
 1563  
     }
 1564  
     jj_rescan = false;
 1565  
   }
 1566  
 
 1567  
   private void jj_save(int index, int xla) {
 1568  
     JJCalls p = jj_2_rtns[index];
 1569  
     while (p.gen > jj_gen) {
 1570  
       if (p.next == null) { p = p.next = new JJCalls(); break; }
 1571  
       p = p.next;
 1572  
     }
 1573  
     p.gen = jj_gen + xla - jj_la; p.first = token; p.arg = xla;
 1574  
   }
 1575  
 
 1576  584
   static final class JJCalls {
 1577  
     int gen;
 1578  
     Token first;
 1579  
     int arg;
 1580  
     JJCalls next;
 1581  
   }
 1582  
 
 1583  
 }