All Downloads are FREE. Search and download functionalities are using the official Maven repository.

groovy.json.JsonBuilder.groovy Maven / Gradle / Ivy

There is a newer version: 1.0.b11
Show newest version
/*
 * Copyright 2003-2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package groovy.json

/**
 * A builder for creating JSON payloads.
 * 

* This builder supports the usual builder syntax made of nested method calls and closures, * but also some specific aspects of JSON data structures, such as list of values, etc. * Please make sure to have a look at the various methods provided by this builder * to be able to learn about the various possibilities of usage. *

* Example: *


 *       def builder = new groovy.json.JsonBuilder()
 *       def root = builder.people {
 *           person {
 *               firstName 'Guillame'
 *               lastName 'Laforge'
 *               // Named arguments are valid values for objects too
 *               address(
 *                       city: 'Paris',
 *                       country: 'France',
 *                       zip: 12345,
 *               )
 *               married true
 *               // a list of values
 *               conferences 'JavaOne', 'Gr8conf'
 *           }
 *       }
 *
 *       // creates a data structure made of maps (Json object) and lists (Json array)
 *       assert root instanceof Map
 *
 *       assert builder.toString() == '{"people":{"person":{"firstName":"Guillame","lastName":"Laforge","address":{"city":"Paris","country":"France","zip":12345},"married":true,"conferences":["JavaOne","Gr8conf"]}}}'
 * 
* * @author Guillaume Laforge * @since 1.8.0 */ class JsonBuilder implements Writable { /** * Resulting data structure made of lists and maps, representing a JSON payload */ def content /** * Instanciates a JSON builder, possibly with some existing data structure. * * @param content a pre-existing data structure, default to null */ JsonBuilder(content = null) { this.content = content } /** * Named arguments can be passed to the JSON builder instance to create a root JSON object *

* Example: *


     * def json = new JsonBuilder()
     * json name: "Guillaume", age: 33
     *
     * assert json.toString() == '{"name":"Guillaume","age":33}'
     * 
* * @param m a map of key / value pairs * @return a map of key / value pairs */ def call(Map m) { this.content = m return content } /** * A list of elements as arguments to the JSON builder creates a root JSON array *

* Example: *


     * def json = new JsonBuilder()
     * def result = json([1, 2, 3])
     *
     * assert result instanceof List
     * assert json.toString() == "[1,2,3]"
     * 
* * @param l a list of values * @return a list of values */ def call(List l) { this.content = l return content } /** * Varargs elements as arguments to the JSON builder create a root JSON array *

* Example: *


     * def json = new JsonBuilder()
     * def result = json 1, 2, 3
     *
     * assert result instanceof List
     * assert json.toString() == "[1,2,3]"
     * 
* @param args an array of values * @return a list of values */ def call(Object... args) { this.content = args.toList() return this.content } /** * A closure passed to a JSON builder will create a root JSON object *

* Example: *


     * def json = new JsonBuilder()
     * def result = json {
     *      name "Guillaume"
     *      age 33
     * }
     *
     * assert result instanceof Map
     * assert json.toString() == '{"name":"Guillaume","age":33}'
     * 
* * @param c a closure whose method call statements represent key / values of a JSON object * @return a map of key / value pairs */ def call(Closure c) { this.content = JsonDelegate.cloneDelegateAndGetContent(c) return content } /** * A method call on the JSON builder instance will create a root object with only one key * whose name is the name of the method being called. * This method takes as arguments: *
    *
  • a closure
  • *
  • a map (ie. named arguments)
  • *
  • a map and a closure
  • *
  • or no argument at all
  • *
*

* Example with a classicala builder-style: *


     * def json = new JsonBuilder()
     * def result = json.person {
     *      name "Guillaume"
     *      age 33
     * }
     *
     * assert result instanceof Map
     * assert json.toString() == '{"person":{"name":"Guillaume","age":33}}'
     * 
* * Or alternatively with a method call taking named arguments: *

     * def json = new JsonBuilder()
     * json.person name: "Guillaume", age: 33
     *
     * assert json.toString() == '{"person":{"name":"Guillaume","age":33}}'
     * 
* * If you use named arguments and a closure as last argument, * the key/value pairs of the map (as named arguments) * and the key/value pairs represented in the closure * will be merged together — * the closure properties overriding the map key/values * in case the same key is used. *

     * def json = new JsonBuilder()
     * json.person(name: "Guillaume", age: 33) { town "Paris" }
     *
     * assert json.toString() == '{"person":{"name":"Guillaume","age":33,"town":"Paris"}}'
     * 
* * The empty args call will create a key whose value will be an empty JSON object: *

     * def json = new JsonBuilder()
     * json.person()
     *
     * assert json.toString() == '{"person":{}}'
     * 
* * @param name the single key * @param args the value associated with the key * @return a map with a single key */ def invokeMethod(String name, Object args) { if (args?.size() == 0) { this.content = [(name): [:]] return content } else if (args?.size() == 1) { if (args[0] instanceof Closure) { this.content = [(name): JsonDelegate.cloneDelegateAndGetContent(args[0])] return content } else if (args[0] instanceof Map) { this.content = [(name): args[0]] return content } } else if (args?.size() == 2 && args[0] instanceof Map && args[1] instanceof Closure) { this.content = [(name): [*:args[0], *:JsonDelegate.cloneDelegateAndGetContent(args[1])]] return content } throw new JsonException("Expected no arguments, a single map, a single closure, or a map and closure as arguments.") } /** * Serializes the internal data structure built with the builder to a conformant JSON payload string *

* Example: *


     * def json = new JsonBuilder()
     * json { temperature 37 }
     * 
     * assert json.toString() == '{"temperature":37}'
     * 
* * @return a JSON output */ String toString() { JsonOutput.toJson(content) } /** * Pretty-prints and formats the JSON payload. *

* This method calls the JsonLexer to parser the output of the builder, * so this may not be an optimal method to call, * and should be used mainly for debugging purpose * for a human-readable output of the JSON content. * * @return a pretty printed JSON output */ String toPrettyString() { JsonOutput.prettyPrint(toString()) } /** * The JSON builder implements the Writable interface, * so that you can have the builder serialize itself the JSON payload to a writer. *

* Example: *


     * def json = new JsonBuilder()
     * json { temperature 37 }
     *
     * def out = new StringWriter()
     * out << json
     *
     * assert out.toString() == '{"temperature":37}' 
     * 
* * @param out a writer on which to serialize the JSON payload * @return the writer */ Writer writeTo(Writer out) { out << toString() } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy