com.datatorrent.lib.appdata.schemas.SchemaUtils.java Source code

Java tutorial

Introduction

Here is the source code for com.datatorrent.lib.appdata.schemas.SchemaUtils.java

Source

/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 com.datatorrent.lib.appdata.schemas;

import java.io.IOException;
import java.io.InputStream;
import java.io.StringWriter;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.commons.io.IOUtils;

import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * This class holds utility methods for processing JSON.
 * @since 3.0.0
 */
public class SchemaUtils {
    public static final String FIELD_TAGS = "tags";

    /**
     * This constructor should not be used.
     */
    private SchemaUtils() {
        //Do nothing
    }

    /**
     * This is a utility method which loads the contents of a resource file into a string.
     * @param resource The resource file whose contents need to be loaded.
     * @return The contents of the specified resource file.
     */
    public static String jarResourceFileToString(String resource) {
        StringWriter stringWriter = new StringWriter();
        try {
            InputStream is = SchemaUtils.class.getClassLoader().getResourceAsStream(resource);
            Preconditions.checkArgument(is != null, resource + " could not be found in the resources.");

            IOUtils.copy(is, stringWriter);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }
        return stringWriter.toString();
    }

    /**
     * This is a utility method that loads the contents of the given input stream into a string.
     * @param inputStream The input stream to read from.
     * @return The contents of the given input stream as a String.
     */
    public static String inputStreamToString(InputStream inputStream) {
        StringWriter stringWriter = new StringWriter();

        try {
            IOUtils.copy(inputStream, stringWriter);
        } catch (IOException ex) {
            throw new RuntimeException(ex);
        }

        return stringWriter.toString();
    }

    /**
     * This is a utility method to check that the given JSONObject has the given keys.
     * @param jo The {@link JSONObject} to check.
     * @param fields The keys in the {@link JSONObject} to check.
     * @return True if the given {@link JSONObject} contains all the given keys. False otherwise.
     */
    public static boolean checkValidKeys(JSONObject jo, Fields fields) {
        @SuppressWarnings("unchecked")
        Set<String> fieldSet = fields.getFields();
        Set<String> jsonKeys = getSetOfJSONKeys(jo);

        return jsonKeys.containsAll(fieldSet);
    }

    /**
     * This is a utility method to check that the given JSONObject has the given keys.
     * It throws an {@link IllegalArgumentException} if it doesn't contain all the given keys.
     * @param jo The {@link JSONObject} to check.
     * @param fields The keys in the {@link JSONObject} to check.
     */
    public static void checkValidKeysEx(JSONObject jo, Fields fields) {
        @SuppressWarnings("unchecked")
        Set<String> fieldSet = fields.getFields();
        Set<String> jsonKeys = getSetOfJSONKeys(jo);

        if (!jsonKeys.containsAll(fieldSet)) {

            throw new IllegalArgumentException(
                    "The given set of keys " + fieldSet + " doesn't equal the set of keys in the json " + jsonKeys);
        }
    }

    /**
     * This is a utility method to check that the given JSONObject has the given keys.
     * @param jo The {@link JSONObject} to check.
     * @param fieldsCollection The keys in the {@link JSONObject} to check.
     * @return True if the given {@link JSONObject} contains all the given keys. False otherwise.
     */
    public static boolean checkValidKeys(JSONObject jo, Collection<Fields> fieldsCollection) {
        return checkValidKeysHelper(jo, fieldsCollection);
    }

    private static boolean checkValidKeysHelper(JSONObject jo, Collection<Fields> fieldsCollection) {
        for (Fields fields : fieldsCollection) {
            LOG.debug("Checking keys: {}", fields);
            if (checkValidKeys(jo, fields)) {
                return true;
            }
        }

        LOG.error("The first level of keys in the provided JSON {} do not match any of the " + "valid keysets {}",
                getSetOfJSONKeys(jo), fieldsCollection);
        return false;
    }

    public static boolean checkValidKeys(JSONObject jo, List<Fields> fieldsCollection) {
        return checkValidKeysHelper(jo, fieldsCollection);
    }

    /**
     * This is a utility method to check that the given JSONObject has the given keys.
     * It throws an {@link IllegalArgumentException} if it doesn't contain all the given keys.
     * @param jo The {@link JSONObject} to check.
     * @param fieldsCollection The keys in the {@link JSONObject} to check.
     * @return True if the given {@link JSONObject} contains all the given keys. False otherwise.
     */
    public static boolean checkValidKeysEx(JSONObject jo, Collection<Fields> fieldsCollection) {
        return checkValidKeysExHelper(jo, fieldsCollection);
    }

    public static boolean checkValidKeysExHelper(JSONObject jo, Collection<Fields> fieldsCollection) {
        for (Fields fields : fieldsCollection) {
            if (checkValidKeys(jo, fields)) {
                return true;
            }
        }

        Set<String> keys = getSetOfJSONKeys(jo);

        throw new IllegalArgumentException("The given json object has an invalid set of keys: " + keys
                + "\nOne of the following key combinations was expected:\n" + fieldsCollection);
    }

    public static boolean checkValidKeysEx(JSONObject jo, List<Fields> fieldsCollection) {
        return checkValidKeysExHelper(jo, fieldsCollection);
    }

    public static Set<String> getSetOfJSONKeys(JSONObject jo) {
        @SuppressWarnings("unchecked")
        Iterator<String> keyIterator = jo.keys();
        Set<String> keySet = Sets.newHashSet();

        while (keyIterator.hasNext()) {
            keySet.add(keyIterator.next());
        }

        return keySet;
    }

    public static Map<String, String> convertFieldToType(Map<String, Type> fieldToType) {
        Map<String, String> fieldToTypeString = Maps.newHashMap();

        for (Map.Entry<String, Type> entry : fieldToType.entrySet()) {
            String field = entry.getKey();
            String typeString = entry.getValue().name();

            fieldToTypeString.put(field, typeString);
        }

        return fieldToTypeString;
    }

    public static JSONArray findFirstKeyJSONArray(JSONObject jo, String key) {
        if (jo.has(key)) {
            try {
                JSONArray jsonArray = jo.getJSONArray(key);
                return jsonArray;
            } catch (JSONException ex) {
                throw new RuntimeException(ex);
            }
        }

        @SuppressWarnings("unchecked")
        Iterator<String> keyIterator = jo.keys();

        while (keyIterator.hasNext()) {
            String childKey = keyIterator.next();

            JSONArray childJa = null;

            try {
                childJa = jo.getJSONArray(childKey);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJa != null) {
                JSONArray result = findFirstKeyJSONArray(childJa, key);

                if (result != null) {
                    return result;
                }

                continue;
            }

            JSONObject childJo = null;

            try {
                childJo = jo.getJSONObject(childKey);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJo != null) {
                JSONArray result = findFirstKeyJSONArray(childJo, key);

                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

    public static JSONArray findFirstKeyJSONArray(JSONArray ja, String key) {
        for (int index = 0; index < ja.length(); index++) {
            JSONArray childJa = null;

            try {
                childJa = ja.getJSONArray(index);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJa != null) {
                JSONArray result = findFirstKeyJSONArray(childJa, key);

                if (result != null) {
                    return result;
                }

                continue;
            }

            JSONObject childJo = null;

            try {
                childJo = ja.getJSONObject(index);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJo != null) {
                JSONArray result = findFirstKeyJSONArray(childJo, key);

                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

    public static JSONObject findFirstKeyJSONObject(JSONObject jo, String key) {
        if (jo.has(key)) {
            try {
                JSONObject jsonObject = jo.getJSONObject(key);
                return jsonObject;
            } catch (JSONException ex) {
                throw new RuntimeException(ex);
            }
        }

        @SuppressWarnings("unchecked")
        Iterator<String> keyIterator = jo.keys();

        while (keyIterator.hasNext()) {
            String childKey = keyIterator.next();

            JSONArray childJa = null;

            try {
                childJa = jo.getJSONArray(childKey);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJa != null) {
                JSONObject result = findFirstKeyJSONObject(childJa, key);

                if (result != null) {
                    return result;
                }

                continue;
            }

            JSONObject childJo = null;

            try {
                childJo = jo.getJSONObject(childKey);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJo != null) {
                JSONObject result = findFirstKeyJSONObject(childJo, key);

                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

    public static JSONObject findFirstKeyJSONObject(JSONArray ja, String key) {
        for (int index = 0; index < ja.length(); index++) {
            JSONArray childJa = null;

            try {
                childJa = ja.getJSONArray(index);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJa != null) {
                JSONObject result = findFirstKeyJSONObject(childJa, key);

                if (result != null) {
                    return result;
                }

                continue;
            }

            JSONObject childJo = null;

            try {
                childJo = ja.getJSONObject(index);
            } catch (JSONException ex) {
                //Do nothing
            }

            if (childJo != null) {
                JSONObject result = findFirstKeyJSONObject(childJo, key);

                if (result != null) {
                    return result;
                }
            }
        }

        return null;
    }

    /**
     * Converts the given JSONObject into a {@link Map}.
     * @param jo The {@link JSONObject} to convert.
     * @return The converted {@link JSONObject}.
     */
    public static Map<String, String> extractMap(JSONObject jo) {
        Map<String, String> resultMap = Maps.newHashMap();
        @SuppressWarnings("unchecked")
        Iterator<String> keyIterator = jo.keys();

        while (keyIterator.hasNext()) {
            String key = keyIterator.next();
            String value;

            try {
                value = jo.getString(key);
            } catch (JSONException ex) {
                throw new RuntimeException(ex);
            }

            resultMap.put(key, value);
        }

        return resultMap;
    }

    /**
     * This is a utility method which creates a {@link JSONObject} out of the given map.
     * @param map The map to convert into a {@link JSONObject}.
     * @return The converted map.
     */
    public static JSONObject createJSONObject(Map<String, String> map) {
        JSONObject jo = new JSONObject();

        for (Map.Entry<String, String> entry : map.entrySet()) {
            String key = entry.getKey();
            String value = entry.getValue();

            try {
                jo.put(key, value);
            } catch (JSONException ex) {
                throw new RuntimeException(ex);
            }
        }

        return jo;
    }

    /**
     * This is a helper method which converts the given {@link JSONArray} to a {@link List} of Strings.
     *
     * @param jsonStringArray The {@link JSONArray} to convert.
     * @return The converted {@link List} of Strings.
     */
    public static List<String> getStringsFromJSONArray(JSONArray jsonStringArray) throws JSONException {
        List<String> stringArray = Lists.newArrayListWithCapacity(jsonStringArray.length());

        for (int stringIndex = 0; stringIndex < jsonStringArray.length(); stringIndex++) {
            stringArray.add(jsonStringArray.getString(stringIndex));
        }

        return stringArray;
    }

    /**
     * This is a helper method which retrieves the schema tags from the {@link JSONObject} if they are present.
     *
     * @param jo The {@link JSONObject} to retrieve schema tags from.
     * @return A list containing the retrieved schema tags. The list is empty if there are no schema tags present.
     */
    public static List<String> getTags(JSONObject jo) throws JSONException {
        if (jo.has(FIELD_TAGS)) {
            return getStringsFromJSONArray(jo.getJSONArray(FIELD_TAGS));
        } else {
            return Collections.emptyList();
        }
    }

    private static final Logger LOG = LoggerFactory.getLogger(SchemaUtils.class);
}