Java tutorial
/** * 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); }