Package groovy.json

Source Code of groovy.json.JsonSlurper

/*
* Copyright 2003-2014 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;

import groovy.json.internal.JsonFastParser;
import groovy.json.internal.JsonParserCharArray;
import groovy.json.internal.JsonParserLax;
import groovy.json.internal.JsonParserUsingCharacterSource;
import org.codehaus.groovy.runtime.DefaultGroovyMethodsSupport;
import org.codehaus.groovy.runtime.ResourceGroovyMethods;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.net.URL;
import java.util.*;

/**
* This has the same interface as the original JsonSlurper written for version 1.8.0, but its
* implementation has completely changed. It is now up to 20x faster than before, and its speed
* competes and often substantially exceeds popular common JSON parsers circa Jan, 2014.
* <p />
* JSON slurper parses text or reader content into a data structure of lists and maps.
* <p>
* Example usage:
* <code><pre>
* def slurper = new JsonSlurper()
* def result = slurper.parseText('{"person":{"name":"Guillaume","age":33,"pets":["dog","cat"]}}')
*
* assert result.person.name == "Guillaume"
* assert result.person.age == 33
* assert result.person.pets.size() == 2
* assert result.person.pets[0] == "dog"
* assert result.person.pets[1] == "cat"
* </pre></code>
*
* JsonSlurper can use several types of JSON parsers. Please read the documentation for
* JsonParserType. There are relaxed mode parsers, large file parser, and index overlay parsers.
* Don't worry, it is all groovy. JsonSlurper will just work, but understanding the different parser
* types may allow you to drastically improve the performance of your JSON parsing.
* <p />
*
* Index overlay parsers (INDEX_OVERLAY and LAX) are the fastest JSON parsers.
* However they are not the default for a good reason.
* Index overlay parsers  has pointers (indexes really) to original char buffer.
* Care must be used if putting parsed maps into a long term cache as members of map
* maybe index overlay objects pointing to original buffer.
* You can mitigate these risks by using chop and lazy chop properties.
* <p />
* Chop eagerly dices up the buffer so each Value element points to a small copy of the original buffer.
* <p />
* Lazy Chop dices up the buffer when a list get or map get is called so if an GPath expression or
* such is applied.
* <p />
* You do not need chop or lazy chop if you are NOT putting the map into a long term cache.
* You do not need chop or lazy chop if you are doing object de-serialization.
* Recommendation is to use INDEX_OVERLAY for JSON buffers under 2MB.
* The maxSizeForInMemory is set to 2MB and any file over 2MB will use a parser designed for
* large files, which is slower than the INDEX_OVERLAY, LAX, and CHAR_BUFFER parsers, but
* faster than most commonly used JSON parsers on the JVM for most use cases circa January 2014.
* <p />
* To enable the INDEX_OVERLAY parser do this:
*
* <code><pre>
*             parser = new JsonSlurper().setType( JsonParserType.INDEX_OVERLAY );
* </pre></code>
*
* @see groovy.json.JsonParserType
*
* @author Guillaume Laforge
* @author Rick Hightower
* @since 1.8.0
*/
public class JsonSlurper {


    private int maxSizeForInMemory = 2000000;
    private boolean chop = false;
    private boolean lazyChop = true;
    private boolean checkDates = true;

    private JsonParserType type = JsonParserType.CHAR_BUFFER;

    /**
     * Max size before Slurper starts to use windowing buffer parser.
     * @return size of file/buffer
     * @since 2.3
     */
    public int getMaxSizeForInMemory() {
        return maxSizeForInMemory;
    }


    /**
     * Max size before Slurper starts to use windowing buffer parser.
     * @since 2.3
     * @return JsonSlurper
     */
    public JsonSlurper setMaxSizeForInMemory( int maxSizeForInMemory ) {
        this.maxSizeForInMemory = maxSizeForInMemory;
        return this;
    }

    /** Parser type.
     * @since 2.3
     * @see groovy.json.JsonParserType
     * @return  type
     */
    public JsonParserType getType() {
        return type;
    }


    /** Parser type.
     * @since 2.3
     * @see groovy.json.JsonParserType
     * @return  JsonSlurper
     */
    public JsonSlurper setType( JsonParserType type ) {
        this.type = type;
        return this;
    }

    /** Turns on buffer chopping for index overlay.
     * @since 2.3
     * @see groovy.json.JsonParserType
     * @return  chop on or off
     */
    public boolean isChop() {
        return chop;
    }

    /** Turns on buffer chopping for index overlay.
     * @since 2.3
     * @see groovy.json.JsonParserType
     * @return  JsonSlurper
     */
    public JsonSlurper setChop( boolean chop ) {
        this.chop = chop;
        return this;
    }


    /** Turns on buffer lazy chopping for index overlay.
     * @see groovy.json.JsonParserType
     * @return  on or off
     * @since 2.3
     */
    public boolean isLazyChop() {
        return lazyChop;
    }


    /** Turns on buffer lazy chopping for index overlay.
     * @see groovy.json.JsonParserType
     * @return  JsonSlurper
     * @since 2.3
     */
    public JsonSlurper setLazyChop( boolean lazyChop ) {
        this.lazyChop = lazyChop;
        return this;
    }

    /**
     * Determine if slurper will automatically parse strings it recognizes as dates. Index overlay only.
     * @return on or off
     * @since 2.3
     */
    public boolean isCheckDates() {
        return checkDates;
    }


    /**
     * Determine if slurper will automatically parse strings it recognizes as dates. Index overlay only.
     * @return on or off
     * @since 2.3
     */
    public JsonSlurper setCheckDates( boolean checkDates ) {
        this.checkDates = checkDates;
        return this;
    }

    /**
     * Parse a text representation of a JSON data structure
     *
     * @param text JSON text to parse
     * @return a data structure of lists and maps
     */
    public Object parseText(String text) {
        if (text == null || "".equals ( text )) {
            throw new IllegalArgumentException ( "Text must not be null"  );
        }
        return createParser().parse( text );
    }

    /**
     * Parse a JSON data structure from content from a reader
     *
     * @param reader reader over a JSON content
     * @return a data structure of lists and maps
     */
    public Object parse(Reader reader) {
        if (reader == null ) {
            throw new IllegalArgumentException ( "Reader must not be null"  );
        }

        Object content;
        JsonParser parser = createParser();
        content = parser.parse(reader);
        return content;
    }



    /**
     * Parse a JSON data structure from content from an inputStream
     *
     * @param inputStream stream over a JSON content
     * @return a data structure of lists and maps
     * @since 2.3
     */
    public Object parse(InputStream inputStream) {
        if (inputStream == null ) {
            throw new IllegalArgumentException ( "inputStream must not be null"  );
        }

        Object content;
        JsonParser parser = createParser();
        content = parser.parse( inputStream );
        return content;
    }

    /**
     * Parse a JSON data structure from content from an inputStream
     *
     * @param inputStream stream over a JSON content
     * @param charset charset
     * @return a data structure of lists and maps
     * @since 2.3
     */
    public Object parse(InputStream inputStream, String charset) {
        if (inputStream == null ) {
            throw new IllegalArgumentException ( "inputStream must not be null"  );
        }
        if ( charset == null ) {
            throw new IllegalArgumentException ( "charset must not be null"  );
        }

        Object content;
        content = createParser().parse(inputStream, charset);
        return content;
    }


    /**
     * Parse a JSON data structure from content from a byte array.
     *
     * @param bytes buffer of JSON content
     * @param charset charset
     * @return a data structure of lists and maps
     * @since 2.3
     */
    public Object parse(byte [] bytes, String charset) {
        if ( bytes == null ) {
            throw new IllegalArgumentException ( "bytes must not be null"  );
        }

        if ( charset == null ) {
            throw new IllegalArgumentException ( "charset must not be null"  );
        }


        Object content;
        content = createParser().parse(bytes, charset);
        return content;
    }


    /**
     * Parse a JSON data structure from content from a byte array.
     *
     * @param bytes buffer of JSON content
     * @return a data structure of lists and maps
     * @since 2.3
     */
    public Object parse(byte [] bytes) {
        if ( bytes == null ) {
            throw new IllegalArgumentException ( "bytes must not be null"  );
        }

        Object content;
        content = createParser().parse(bytes);
        return content;
    }

    /**
     * Parse a JSON data structure from content from a char array.
     *
     * @param chars buffer of JSON content
     * @return a data structure of lists and maps
     * @since 2.3
     */
    public Object parse(char [] chars) {
        if ( chars == null ) {
            throw new IllegalArgumentException ( "chars must not be null"  );
        }

        Object content;
        content = createParser().parse(chars);
        return content;
    }


    private JsonParser createParser() {
        switch (type) {

            case LAX:
                return new JsonParserLax(false, chop, lazyChop, checkDates);

            case CHAR_BUFFER:
                return new JsonParserCharArray();

            case CHARACTER_SOURCE:
                return new JsonParserUsingCharacterSource();


            case INDEX_OVERLAY:
                return new JsonFastParser(false, chop, lazyChop, checkDates);

            default:
                return new JsonParserCharArray();
        }
    }

    /**
     * Parse a JSON data structure from content within a given File.
     *
     * @param file File containing JSON content
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(File file) {
        return parseFile(file, null);
    }

    /**
     * Parse a JSON data structure from content within a given File.
     *
     * @param file File containing JSON content
     * @param charset the charset for this File
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(File file, String charset) {
        return parseFile(file, charset);
    }

    private Object parseFile(File file, String charset) {

        if (file.length() < maxSizeForInMemory)  {
            return createParser().parse(file, charset);
        } else {
            return new JsonParserUsingCharacterSource().parse ( file, charset );
        }
    }

    /**
     * Parse a JSON data structure from content at a given URL.
     *
     * @param url URL containing JSON content
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(URL url) {
        return parseURL(url, null);
    }

    /**
     * Parse a JSON data structure from content at a given URL.
     *
     * @param url URL containing JSON content
     * @param params connection parameters
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(URL url, Map params) {
        return parseURL(url, params);
    }

    /**
     * Parse a JSON data structure from content at a given URL. Convenience variant when using Groovy named parameters for the connection params.
     *
     * @param params connection parameters
     * @param url URL containing JSON content
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(Map params, URL url) {
        return parseURL(url, params);
    }

    private Object parseURL(URL url, Map params) {
        Reader reader = null;
        try {
            if (params == null || params.isEmpty()) {
                reader = ResourceGroovyMethods.newReader(url);
            } else {
                reader = ResourceGroovyMethods.newReader(url, params);
            }
            return createParser ().parse ( reader );
        } catch(IOException ioe) {
            throw new JsonException("Unable to process url: " + url.toString(), ioe);
        } finally {
            if (reader != null) {
                DefaultGroovyMethodsSupport.closeWithWarning(reader);
            }
        }
    }

    /**
     * Parse a JSON data structure from content at a given URL.
     *
     * @param url URL containing JSON content
     * @param charset the charset for this File
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(URL url, String charset) {
        return parseURL(url, null, charset);
    }

    /**
     * Parse a JSON data structure from content at a given URL.
     *
     * @param url URL containing JSON content
     * @param params connection parameters
     * @param charset the charset for this File
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(URL url, Map params, String charset) {
        return parseURL(url, params, charset);
    }

    /**
     * Parse a JSON data structure from content at a given URL. Convenience variant when using Groovy named parameters for the connection params.
     *
     * @param params connection parameters
     * @param url URL containing JSON content
     * @param charset the charset for this File
     * @return a data structure of lists and maps
     * @since 2.2.0
     */
    public Object parse(Map params, URL url, String charset) {
        return parseURL(url, params, charset);
    }

    private Object parseURL(URL url, Map params, String charset) {
        Reader reader = null;
        try {
            if (params == null || params.isEmpty()) {
                reader = ResourceGroovyMethods.newReader(url, charset);
            } else {
                reader = ResourceGroovyMethods.newReader(url, params, charset);
            }
            return parse(reader);
        } catch(IOException ioe) {
            throw new JsonException("Unable to process url: " + url.toString(), ioe);
        } finally {
            if (reader != null) {
                DefaultGroovyMethodsSupport.closeWithWarning(reader);
            }
        }
    }
}
TOP

Related Classes of groovy.json.JsonSlurper

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.