ca.nrc.cadc.xml.JsonInputter.java Source code

Java tutorial

Introduction

Here is the source code for ca.nrc.cadc.xml.JsonInputter.java

Source

/*
************************************************************************
*******************  CANADIAN ASTRONOMY DATA CENTRE  *******************
**************  CENTRE CANADIEN DE DONNES ASTRONOMIQUES  **************
*
*  (c) 2011.                            (c) 2011.
*  Government of Canada                 Gouvernement du Canada
*  National Research Council            Conseil national de recherches
*  Ottawa, Canada, K1A 0R6              Ottawa, Canada, K1A 0R6
*  All rights reserved                  Tous droits rservs
*
*  NRC disclaims any warranties,        Le CNRC dnie toute garantie
*  expressed, implied, or               nonce, implicite ou lgale,
*  statutory, of any kind with          de quelque nature que ce
*  respect to the software,             soit, concernant le logiciel,
*  including without limitation         y compris sans restriction
*  any warranty of merchantability      toute garantie de valeur
*  or fitness for a particular          marchande ou de pertinence
*  purpose. NRC shall not be            pour un usage particulier.
*  liable in any event for any          Le CNRC ne pourra en aucun cas
*  damages, whether direct or           tre tenu responsable de tout
*  indirect, special or general,        dommage, direct ou indirect,
*  consequential or incidental,         particulier ou gnral,
*  arising from the use of the          accessoire ou fortuit, rsultant
*  software.  Neither the name          de l'utilisation du logiciel. Ni
*  of the National Research             le nom du Conseil National de
*  Council of Canada nor the            Recherches du Canada ni les noms
*  names of its contributors may        de ses  participants ne peuvent
*  be used to endorse or promote        tre utiliss pour approuver ou
*  products derived from this           promouvoir les produits drivs
*  software without specific prior      de ce logiciel sans autorisation
*  written permission.                  pralable et particulire
*                                       par crit.
*
*  This file is part of the             Ce fichier fait partie du projet
*  OpenCADC project.                    OpenCADC.
*
*  OpenCADC is free software:           OpenCADC est un logiciel libre ;
*  you can redistribute it and/or       vous pouvez le redistribuer ou le
*  modify it under the terms of         modifier suivant les termes de
*  the GNU Affero General Public        la GNU Affero General Public
*  License as published by the          License? telle que publie
*  Free Software Foundation,            par la Free Software Foundation
*  either version 3 of the              : soit la version 3 de cette
*  License, or (at your option)         licence, soit ( votre gr)
*  any later version.                   toute version ultrieure.
*
*  OpenCADC is distributed in the       OpenCADC est distribu
*  hope that it will be useful,         dans lespoir quil vous
*  but WITHOUT ANY WARRANTY;            sera utile, mais SANS AUCUNE
*  without even the implied             GARANTIE : sans mme la garantie
*  warranty of MERCHANTABILITY          implicite de COMMERCIALISABILIT
*  or FITNESS FOR A PARTICULAR          ni dADQUATION  UN OBJECTIF
*  PURPOSE.  See the GNU Affero         PARTICULIER. Consultez la Licence
*  General Public License for           Gnrale Publique GNU Affero
*  more details.                        pour plus de dtails.
*
*  You should have received             Vous devriez avoir reu une
*  a copy of the GNU Affero             copie de la Licence Gnrale
*  General Public License along         Publique GNU Affero avec
*  with OpenCADC.  If not, see          OpenCADC ; si ce nest
*  <http://www.gnu.org/licenses/>.      pas le cas, consultez :
*                                       <http://www.gnu.org/licenses/>.
*
*  $Revision: 5 $
*
************************************************************************
*/

package ca.nrc.cadc.xml;

import org.jdom2.Attribute;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Namespace;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
 * JsonInputter
 */
public class JsonInputter {
    public JsonInputter() {
    }

    private final Map<String, String> listElementMap = new TreeMap<String, String>();

    public Map<String, String> getListElementMap() {
        return listElementMap;
    }

    public Document input(final String json) throws JSONException {
        JSONObject rootJson = new JSONObject(json);
        List<String> keys = Arrays.asList(JSONObject.getNames(rootJson));
        List<Namespace> namespaces = new ArrayList<Namespace>();
        Namespace namespace = getNamespace(namespaces, rootJson, keys);

        String rootKey = null;
        List<Attribute> attributes = new ArrayList<Attribute>();
        for (String key : keys) {
            if (!key.startsWith("@xmlns")) {
                if (key.startsWith("@")) {
                    String value;
                    if (rootJson.isNull(key)) {
                        value = "";
                    } else {
                        value = getStringValue(rootJson.get(key));
                    }
                    attributes.add(new Attribute(key.substring(1), value));
                } else {
                    // DOM can only have one root element.
                    if (rootKey != null) {
                        throw new IllegalStateException("Found multiple root entries");
                    }
                    rootKey = key;
                }
            }
        }

        Element rootElement = new Element(rootKey, namespace);
        for (Attribute attribute : attributes) {
            rootElement.setAttribute(attribute);
        }

        Object value = rootJson.get(rootKey);
        processObject(rootKey, value, rootElement, namespace, namespaces);

        Document document = new Document();
        document.setRootElement(rootElement);
        return document;
    }

    private void processObject(String key, Object value, Element element, Namespace namespace,
            List<Namespace> namespaces) throws JSONException {
        if (value == null) {
            return;
        }

        if (listElementMap.containsKey(key)) {
            final Object childObject = ((JSONObject) value).get("$");
            //        ((JSONObject) value).get(listElementMap.get(key));

            if (childObject instanceof JSONArray) {
                processJSONArray(key, (JSONArray) childObject, element, namespace, namespaces);
            } else if (childObject instanceof JSONObject) {
                processJSONObject((JSONObject) childObject, element, namespaces);
            }
        } else if (value instanceof JSONObject) {
            processJSONObject((JSONObject) value, element, namespaces);
        } else {
            element.setText(getStringValue(value));
        }
    }

    private void processJSONObject(JSONObject jsonObject, Element element, List<Namespace> namespaces)
            throws JSONException {
        List<String> keys = Arrays.asList(JSONObject.getNames(jsonObject));
        Namespace namespace = getNamespace(namespaces, jsonObject, keys);
        if (namespace == null) {
            namespace = element.getNamespace();
        }

        for (String key : keys) {
            if (jsonObject.isNull(key)) {
                continue;
            }

            // attribute
            if (key.startsWith("@")) {
                Object value = jsonObject.get(key);
                element.setAttribute(new Attribute(key.substring(1), getStringValue(value)));
                continue;
            }

            // text content
            Object value = jsonObject.get(key);
            if (key.equals("$")) {
                element.setText(getStringValue(value));
                continue;
            }

            Element child = new Element(key, namespace);
            if (listElementMap.containsKey(key)) {
                final String childKey = listElementMap.get(key);
                final Object childObject = ((JSONObject) value).get("$");
                Element grandChild = new Element(childKey, namespace);

                if (childObject instanceof JSONArray) {
                    processJSONArray(key, (JSONArray) childObject, child, namespace, namespaces);
                } else if (childObject instanceof JSONObject) {
                    processJSONObject((JSONObject) childObject, grandChild, namespaces);
                    child.addContent(grandChild);
                }
            } else if (value instanceof JSONObject) {
                processJSONObject((JSONObject) value, child, namespaces);
            }

            element.addContent(child);
        }
    }

    private void processJSONArray(String key, JSONArray jsonArray, Element arrayElement, Namespace namespace,
            List<Namespace> namespaces) throws JSONException {
        String childTypeName = getListElementMap().get(key);

        for (int i = 0; i < jsonArray.length(); i++) {
            if (jsonArray.isNull(i)) {
                continue;
            }

            Element child;
            if (childTypeName == null) {
                child = arrayElement;
            } else {
                child = new Element(childTypeName, namespace);
                arrayElement.addContent(child);
            }

            Object value = jsonArray.get(i);
            processObject(childTypeName, value, child, namespace, namespaces);
        }
    }

    private Namespace getNamespace(List<Namespace> namespaces, JSONObject jsonObject, List<String> keys)
            throws JSONException {
        for (String key : keys) {
            if (key.equals("@xmlns")) {
                if (jsonObject.isNull(key)) {
                    break;
                }
                String uri = jsonObject.getString(key);
                Namespace namespace = Namespace.getNamespace(uri);
                if (!namespaces.contains(namespace)) {
                    namespaces.add(namespace);
                }
                return namespace;
            }
        }
        return null;
    }

    private String getStringValue(Object value) {
        if (value instanceof String) {
            return (String) value;
        } else if (value instanceof Integer || value instanceof Double || value instanceof Long) {
            return ((Number) value).toString();
        } else if (value instanceof Boolean) {
            return ((Boolean) value).toString();
        } else {
            String error = "Unknown value " + value.getClass().getSimpleName();
            throw new IllegalArgumentException(error);
        }
    }

}