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

org.jooq.impl.JSONReader Maven / Gradle / Ivy

There is a newer version: 0.2.5
Show newest version
/*
 * Copyright (c) 2009-2016, Data Geekery GmbH (http://www.datageekery.com)
 * All rights reserved.
 *
 * 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.
 *
 * Other licenses:
 * -----------------------------------------------------------------------------
 * Commercial licenses for this work are available. These replace the above
 * ASL 2.0 and offer limited warranties, support, maintenance, and commercial
 * database integrations.
 *
 * For more information, please visit: http://www.jooq.org/licenses
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package org.jooq.impl;

import java.io.BufferedReader;
import java.io.Closeable;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.jooq.tools.json.ContainerFactory;
import org.jooq.tools.json.JSONParser;
import org.jooq.tools.json.ParseException;

/**
 * A very simple JSON reader based on Simple JSON.
 *
 * @author Johannes Bühler
 */
@SuppressWarnings({ "unchecked" })
final class JSONReader implements Closeable {

    private final BufferedReader br;
    private final JSONParser     parser;
    private String[]             fieldNames;
    private Map fieldIndexes;
    private List       records;

    JSONReader(Reader reader) {
        this.br = new BufferedReader(reader);
        this.parser = new JSONParser();
    }

    final List readAll() throws IOException {
        if (records == null) {
            try {
                LinkedHashMap> jsonRoot = getJsonRoot();

                readFields(jsonRoot);
                readRecords(jsonRoot);
            }
            catch (ParseException ex) {
                throw new RuntimeException(ex);
            }
        }

        return records;
    }

    final String[] getFields() throws IOException {
        if (fieldNames == null)
            readAll();

        return fieldNames;
    }

    @Override
    public final void close() throws IOException {
        br.close();
    }

    private final void readRecords(LinkedHashMap> jsonRoot) {
        records = new ArrayList();

        for (Object record : jsonRoot.get("records")) {
            String[] v = new String[fieldNames.length];
            int i = 0;

            // [#5372] Serialisation mode ARRAY
            if (record instanceof LinkedList)
                for (Object value : (LinkedList) record)
                    v[i++] = value == null ? null : String.valueOf(value);

            // [#5372] Serialisation mode OBJECT
            else if (record instanceof LinkedHashMap)
                for (Entry entry : ((LinkedHashMap) record).entrySet())
                    v[fieldIndexes.get(entry.getKey())] = entry.getValue() == null ? null : String.valueOf(entry.getValue());

            else
                throw new IllegalArgumentException("Ill formed JSON : " + jsonRoot);

            records.add(v);
        }
    }

    private LinkedHashMap> getJsonRoot() throws IOException, ParseException {
        Object parse = parser.parse(br, new ContainerFactory() {
            @Override
            public LinkedHashMap createObjectContainer() {
                return new LinkedHashMap();
            }

            @Override
            public List createArrayContainer() {
                return new LinkedList();
            }
        });
        return (LinkedHashMap>) parse;
    }

    private final void readFields(LinkedHashMap> jsonRoot) {
        LinkedList> fieldEntries =
            (LinkedList>) jsonRoot.get("fields");

        fieldNames = new String[fieldEntries.size()];
        fieldIndexes = new HashMap();
        int i = 0;
        for (LinkedHashMap key : fieldEntries) {
            String name = key.get("name");

            fieldNames[i] = name;
            fieldIndexes.put(name, i);

            i++;
        }
    }
}