Coverage Report - com.allanbank.mongodb.bson.json.Json
 
Classes in this File Line Coverage Branch Coverage Complexity
Json
82%
14/17
75%
3/4
2.8
 
 1  
 /*
 2  
  * #%L
 3  
  * Json.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.bson.json;
 22  
 
 23  
 import java.io.Reader;
 24  
 import java.io.StringReader;
 25  
 import java.io.StringWriter;
 26  
 import java.io.Writer;
 27  
 
 28  
 import com.allanbank.mongodb.bson.Document;
 29  
 import com.allanbank.mongodb.bson.DocumentAssignable;
 30  
 import com.allanbank.mongodb.bson.DocumentReference;
 31  
 import com.allanbank.mongodb.bson.Element;
 32  
 import com.allanbank.mongodb.bson.element.BinaryElement;
 33  
 import com.allanbank.mongodb.bson.element.BooleanElement;
 34  
 import com.allanbank.mongodb.bson.element.DoubleElement;
 35  
 import com.allanbank.mongodb.bson.element.IntegerElement;
 36  
 import com.allanbank.mongodb.bson.element.JsonSerializationVisitor;
 37  
 import com.allanbank.mongodb.bson.element.LongElement;
 38  
 import com.allanbank.mongodb.bson.element.MaxKeyElement;
 39  
 import com.allanbank.mongodb.bson.element.MinKeyElement;
 40  
 import com.allanbank.mongodb.bson.element.MongoTimestampElement;
 41  
 import com.allanbank.mongodb.bson.element.NullElement;
 42  
 import com.allanbank.mongodb.bson.element.ObjectIdElement;
 43  
 import com.allanbank.mongodb.bson.element.RegularExpressionElement;
 44  
 import com.allanbank.mongodb.bson.element.StringElement;
 45  
 import com.allanbank.mongodb.bson.element.SymbolElement;
 46  
 import com.allanbank.mongodb.bson.element.TimestampElement;
 47  
 import com.allanbank.mongodb.error.JsonException;
 48  
 import com.allanbank.mongodb.error.JsonParseException;
 49  
 
 50  
 /**
 51  
  * Json provides a simplified interface for parsing JSON documents into BSON
 52  
  * {@link Document}s and also serializing BSON {@link Document}s into JSON text.
 53  
  * <p>
 54  
  * Basic JSON types are parsed as follows:
 55  
  * <dl>
 56  
  * <dt>{@code true} or {@code false} token</dt>
 57  
  * <dd>Creates an {@link BooleanElement}. <br/>
 58  
  * <code>{ a : true }</code> or <code>{ a : false }</code></dd>
 59  
  * <dt>{@code null} token</dt>
 60  
  * <dd>Creates an {@link NullElement}. <br/>
 61  
  * <code>{ a : null }</code></dd>
 62  
  * <dt>Other Non-Quoted Strings</dt>
 63  
  * <dd>Creates a {@link SymbolElement}:<br/>
 64  
  * <code>{ a : b }</code></dd>
 65  
  * <dt>Quoted Strings (either single or double quotes)</dt>
 66  
  * <dd>Creates a {@link StringElement}:<br/>
 67  
  * <code>{ a : 'b' }</code> or <code>{ a : "b" }</code></dd>
 68  
  * <dt>Integers (Numbers without a {@code . } or exponent)</dt>
 69  
  * <dd>Creates an {@link IntegerElement} if within the range [
 70  
  * {@link Integer#MIN_VALUE}, {@link Integer#MAX_VALUE}], otherwise a
 71  
  * {@link LongElement}. Value is parsed by {@link Long#parseLong(String)}.<br/>
 72  
  * <code>{ a : 1234 }</code> or <code>{ a : 123456789012 }</code></dd>
 73  
  * <dt>Doubles (Numbers with a {@code . } or exponent)</dt>
 74  
  * <dd>Creates an {@link DoubleElement}. Value is parsed by
 75  
  * {@link Double#parseDouble(String)}.<br/>
 76  
  * <code>{ a : 1.2 }</code> or <code>{ a : 1e12 }</code></dd>
 77  
  * </p>
 78  
  * <p>
 79  
  * In addition to the basic JSON types the parser also supports the following
 80  
  * standard MongoDB/BSON extensions:
 81  
  * </p>
 82  
  * <dl>
 83  
  * <dt>BinData</dt>
 84  
  * <dd>Creates a {@link BinaryElement}. The first field is the sub-type,
 85  
  * normally zero. The second field is the base64 encoded binary value: <br/>
 86  
  * <code>{ a : BinData(0, "VVU=") }</code> or
 87  
  * <code>{ a : { $binary:"VVU=", $type:0 } }</code></dd>
 88  
  * <code>{ a : { $binary:"VVU=", $type: '0x00' } }</code></dd>
 89  
  * <code>{ a : { $binary:"VVU=", $type: '00' } }</code></dd>
 90  
  * <dt>HexData</dt>
 91  
  * <dd>Creates a {@link BinaryElement}. The first field is the sub-type,
 92  
  * normally zero. The second field is the hex encoded binary value: <br/>
 93  
  * <code>{ a : HexData(0, "cafe") }</code></dd>
 94  
  * <dt>ISODate</dt>
 95  
  * <dd>Creates a {@link TimestampElement}: <br/>
 96  
  * <code>{ a : ISODate("2012-07-14T01:00:00.000") }</code> or
 97  
  * <code>{ a : { $date : "2012-07-14T01:00:00.000" } }</code> or
 98  
  * <code>{ a : { $date : 1234567890 } }</code></dd>
 99  
  * <dt>MaxKey</dt>
 100  
  * <dd>Creates a {@link MaxKeyElement}: <br/>
 101  
  * <code>{ a : MaxKey }</code> or <code>{ a : MaxKey() }</code></dd>
 102  
  * <dt>MinKey</dt>
 103  
  * <dd>Creates a {@link MinKeyElement}: <br/>
 104  
  * <code>{ a : MinKey }</code> or <code>{ a : MinKey() }</code></dd>
 105  
  * <dt>NumberLong</dt>
 106  
  * <dd>Creates a {@link LongElement}: <br/>
 107  
  * <code>{ a : NumberLong("123456789") }</code></dd>
 108  
  * <dt>ObjectId</dt>
 109  
  * <dd>Creates an {@link ObjectIdElement}. The string is the hex encoding of the
 110  
  * 128 bit value: <br/>
 111  
  * <code>{ a : ObjectId("4e9d87aa5825b60b637815a6") }</code> or
 112  
  * <code>{ a : { $oid : "4e9d87aa5825b60b637815a6" } }</code></dd>
 113  
  * <dt>$regex</dt>
 114  
  * <dd>Creates an {@link RegularExpressionElement}: <br/>
 115  
  * <code>{ a : { $regex : 'cat' , $options : 'i' } }</code></dd>
 116  
  * <dt>Timestamp</dt>
 117  
  * <dd>Creates a {@link MongoTimestampElement}. The first value is the seconds
 118  
  * since the UNIX epoch. The second value is an ordinal: <br/>
 119  
  * <code>{ a : Timestamp(0,0) }</code> or
 120  
  * <code>{ a : { $timestamp : { t : 0, i : 0 } } }</code></dd>
 121  
  * </dl>
 122  
  * <p>
 123  
  * The following non-standard extensions are also provided. These extensions may
 124  
  * be deprecated in future releases if standard extensions are created:
 125  
  * </p>
 126  
  * <dl>
 127  
  * <dt>DBPointer</dt>
 128  
  * <dd>Creates a {@link com.allanbank.mongodb.bson.element.DBPointerElement
 129  
  * DBPointerElement}:<br/>
 130  
  * <code>{ a : DBPointer("db", 'collection', ObjectId("4e9d87aa5825b60b637815a6") ) }</code>
 131  
  * <br/>
 132  
  * <b>Note</b>: DBPointers are deprecated in favor of the
 133  
  * {@link DocumentReference DBRef} convention</dd>
 134  
  * </dl>
 135  
  * <p>
 136  
  * <b>Note</b>: Currently serialization/parsing round trip is not supported for
 137  
  * the following {@link Element} types:
 138  
  * <ul>
 139  
  * <li>{@link com.allanbank.mongodb.bson.element.JavaScriptElement
 140  
  * JavaScriptElement}</li>
 141  
  * <li>{@link com.allanbank.mongodb.bson.element.JavaScriptWithScopeElement
 142  
  * JavaScriptWithScopeElement}</li>
 143  
  * </ul>
 144  
  * </p>
 145  
  * 
 146  
  * @see <a
 147  
  *      href="http://docs.mongodb.org/manual/reference/mongodb-extended-json/">MongoDB
 148  
  *      Extended JSON</a>
 149  
  * @api.yes This class is part of the driver's API. Public and protected members
 150  
  *          will be deprecated for at least 1 non-bugfix release (version
 151  
  *          numbers are &lt;major&gt;.&lt;minor&gt;.&lt;bugfix&gt;) before being
 152  
  *          removed or modified.
 153  
  * @copyright 2012-2013, Allanbank Consulting, Inc., All Rights Reserved
 154  
  */
 155  
 public class Json {
 156  
 
 157  
     /**
 158  
      * Parses the document from the reader into a BSON {@link Document}.
 159  
      * <p>
 160  
      * See the class documentation for important limitations on round trip
 161  
      * serialization and parsing.
 162  
      * </p>
 163  
      * 
 164  
      * @param input
 165  
      *            The source of the document to read.
 166  
      * @return The {@link Document} representation of the JSON document.
 167  
      * @throws JsonParseException
 168  
      *             On a failure to parse the JSON document.
 169  
      */
 170  
     public static Document parse(final Reader input) throws JsonParseException {
 171  
         final JsonParser parser = new JsonParser();
 172  
 
 173  
         try {
 174  
             final Object result = parser.parse(input);
 175  81
             if (result instanceof Document) {
 176  80
                 return (Document) result;
 177  
             }
 178  
 
 179  1
             throw new JsonParseException(
 180  
                     "Unknown type returned from the parsed document: " + result);
 181  
         }
 182  11
         catch (final ParseException pe) {
 183  11
             if (pe.currentToken != null) {
 184  
                 throw new JsonParseException(pe.getMessage(), pe,
 185  
                         pe.currentToken.beginLine, pe.currentToken.beginColumn);
 186  
             }
 187  0
             throw new JsonParseException(pe);
 188  
         }
 189  1
         catch (final RuntimeException re) {
 190  1
             throw new JsonParseException(re);
 191  
         }
 192  
     }
 193  
 
 194  
     /**
 195  
      * Parses the document from the reader into a BSON {@link Document}.
 196  
      * <p>
 197  
      * This method is equivalent to: <blockquote>
 198  
      * 
 199  
      * <pre>
 200  
      * <code>
 201  
      * parse(new StringReader(input));
 202  
      * </code>
 203  
      * </pre>
 204  
      * 
 205  
      * </blockquote>
 206  
      * </p>
 207  
      * <p>
 208  
      * See the class documentation for important limitations on round trip
 209  
      * serialization and parsing.
 210  
      * </p>
 211  
      * 
 212  
      * @param input
 213  
      *            The source of the document to read.
 214  
      * @return The {@link Document} representation of the JSON document.
 215  
      * @throws JsonParseException
 216  
      *             On a failure to parse the JSON document.
 217  
      */
 218  
     public static Document parse(final String input) throws JsonParseException {
 219  90
         return parse(new StringReader(input));
 220  
     }
 221  
 
 222  
     /**
 223  
      * Serializes the {@link Document} to an equivalent JSON document.
 224  
      * <p>
 225  
      * See the class documentation for important limitations on round trip
 226  
      * serialization and parsing.
 227  
      * </p>
 228  
      * 
 229  
      * @param document
 230  
      *            The document to conver to a JSON document.
 231  
      * @return The JSON document text.
 232  
      * @throws JsonException
 233  
      *             On a failure to write the JSON document.
 234  
      */
 235  
     public static String serialize(final DocumentAssignable document)
 236  
             throws JsonException {
 237  1
         final StringWriter writer = new StringWriter();
 238  
 
 239  1
         serialize(document, writer);
 240  
 
 241  1
         return writer.toString();
 242  
     }
 243  
 
 244  
     /**
 245  
      * Serializes the {@link Document} to an equivalent JSON document.
 246  
      * <p>
 247  
      * See the class documentation for important limitations on round trip
 248  
      * serialization and parsing.
 249  
      * </p>
 250  
      * 
 251  
      * @param document
 252  
      *            The document to conver to a JSON document.
 253  
      * @param sink
 254  
      *            The sink for the JSON document text.
 255  
      * @throws JsonException
 256  
      *             On a failure to write the JSON document.
 257  
      */
 258  
     public static void serialize(final DocumentAssignable document,
 259  
             final Writer sink) throws JsonException {
 260  1
         final JsonSerializationVisitor visitor = new JsonSerializationVisitor(
 261  
                 sink, true);
 262  1
         document.asDocument().accept(visitor);
 263  1
     }
 264  
 
 265  
     /**
 266  
      * Creates a new Json onbject - hidden.
 267  
      */
 268  
     private Json() {
 269  0
         super();
 270  0
     }
 271  
 
 272  
 }