Java tutorial
/* * EasyCukes is just a framework aiming at making Cucumber even easier than what it already is. * Copyright (C) 2014 Worldline or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 3.0 of the License. * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.worldline.easycukes.commons.helpers; import lombok.NonNull; import lombok.experimental.UtilityClass; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.parser.JSONParser; import org.json.simple.parser.ParseException; import java.util.Iterator; import java.util.ListIterator; import java.util.Map.Entry; /** * This {@link JSONHelper} class provides various methods allowing to manipulate * JSON data. It uses internally {@link JSONObject} from <i>org.json.simple</i>. * * @author aneveux * @version 1.0 */ @Slf4j @UtilityClass public class JSONHelper { /** * {@link JSONParser} to be used in order to extract JSON data from the * {@link String} objects to be submitted. */ final static JSONParser parser = new JSONParser(); /** * Returns <b>true</b> if JSON object o1 is equals to JSON object o2. * * @param o1 a {@link JSONObject} containing some JSON data * @param o2 another {@link JSONObject} containing some JSON data * @return true if the json objects are equals */ public static boolean equals(@NonNull JSONObject o1, @NonNull JSONObject o2) { if (o1 == o2) return true; if (o1.size() != o2.size()) return false; try { final Iterator<Entry<String, Object>> i = o1.entrySet().iterator(); while (i.hasNext()) { final Entry<String, Object> e = i.next(); final String key = e.getKey(); final Object value1 = e.getValue(); final Object value2 = o2.get(key); if (value1 == null) { if (!(o2.get(key) == null && o2.containsKey(key))) return false; } else if (value1 instanceof JSONObject) { if (!(value2 instanceof JSONObject)) return false; if (!equals((JSONObject) value1, (JSONObject) value2)) return false; } else if (value1 instanceof JSONArray) { if (!(value2 instanceof JSONArray)) return false; if (!equals((JSONArray) value1, (JSONArray) value2)) return false; } else if (!value1.equals(value2)) return false; } } catch (final Exception unused) { unused.printStackTrace(); return false; } return true; } /** * Returns <b>true</b> if JSON array a1 is equals to JSON array a2. * * @param a1 a {@link JSONArray} containing some JSON data * @param a2 another {@link JSONArray} containing some JSON data * @return true if the json arrays are equals */ public static boolean equals(@NonNull JSONArray a1, @NonNull JSONArray a2) { if (a1 == a2) return true; if (a1.size() != a2.size()) return false; final ListIterator i1 = a1.listIterator(); ListIterator i2; boolean found = false; while (i1.hasNext()) { final Object o1 = i1.next(); found = false; i2 = a2.listIterator(); if (o1 instanceof JSONObject) while (i2.hasNext()) { final Object o2 = i2.next(); if (!(o2 instanceof JSONObject)) return false; if (equals((JSONObject) o1, (JSONObject) o2)) found = true; } else if (o1 instanceof JSONArray) while (i2.hasNext()) { final Object o2 = i2.next(); if (!(o2 instanceof JSONArray)) return false; if (equals((JSONArray) o1, (JSONArray) o2)) found = true; } else while (i2.hasNext()) { final Object o2 = i2.next(); if (o1.equals(o2)) found = true; } if (!found) return false; } return true; } /** * Returns <b>true</b> if JSON format of s1 is equals to JSON format of s2, * ignoring the case. * * @param s1 a {@link String} containing some JSON data * @param s2 another {@link String} containing some JSON data * @return true if both {@link String} objects are containing the same JSON * data (ignoring the case) */ public static boolean equals(@NonNull final String s1, @NonNull final String s2) { try { final JSONObject json1 = (JSONObject) parser.parse(s1); final JSONObject json2 = (JSONObject) parser.parse(s2); return equals(json1, json2); } catch (final ParseException e) { log.error(e.getMessage(), e); return false; } } /** * Returns a proper representation in JSON of a {@link String} object * already containing JSON (it basically deals with indentation) * * @param s a {@link String} containing JSON to be cleaned * @return a clean JSON representation of the JSON data contained in the * provided {@link String} * @throws ParseException if the provided {@link String} does not actually contain a * valid JSON data */ public static String toProperJSON(@NonNull final String s) throws ParseException { final Object obj = parser.parse(s); if (obj instanceof JSONObject) return ((JSONObject) obj).toJSONString(); if (obj instanceof JSONArray) return ((JSONArray) obj).toJSONString(); return s; } /** * Converts given {@link String} s to {@link JSONObject} format and returns * it * * @param s a {@link String} containing some JSON data * @return a {@link JSONObject} corresponding to the JSON data contained in * the provided {@link String} * @throws ParseException if the provided {@link String} does not actually contain some * valid JSON */ public static JSONObject toJSONObject(@NonNull final String s) throws ParseException { try { return (JSONObject) parser.parse(s); } catch (final ParseException e) { log.error(e.getMessage(), e); throw e; } } /** * Returns the value of a given property from a particular * {@link JSONObject} * * @param s the JSON String to be used for extracting values * @param property the property you'd like to get from the specified * {@link JSONObject} * @return the value of the specified property if it's found, or null if it * cannot be found * @throws ParseException */ public static String getPropertyValue(@NonNull final String s, @NonNull final String property) throws ParseException { try { final Object obj = parser.parse(s); if (obj != null) if (obj instanceof JSONObject) return JSONHelper.getValue((JSONObject) obj, property); else if (obj instanceof JSONArray) return JSONHelper.getValue((JSONArray) obj, property); } catch (final ParseException e) { log.error(e.getMessage(), e); throw e; } return null; } /** * Returns the value of a given property from a particular * {@link JSONObject} * * @param jsonObject the {@link JSONObject} to be used for extracting values * @param property the property you'd like to get from the specified * {@link JSONObject} * @return the value of the specified property if it's found, or null if it * cannot be found */ public static String getValue(@NonNull final JSONObject jsonObject, @NonNull final String property) { if (jsonObject != null) if (jsonObject.get(property) != null) return jsonObject.get(property).toString(); final int index = property.indexOf("."); if (index > 0) { final Object object = getProperty(jsonObject, property.substring(0, index)); if (object != null) { if (object instanceof JSONObject) return getValue((JSONObject) object, property.substring(index + 1)); if (object instanceof JSONArray) { final JSONArray jsonArray = (JSONArray) object; if (jsonArray.size() > 0) return getValue((JSONObject) jsonArray.get(0), property.substring(index + 1)); } } } return null; } /** * Returns the value of a given property from a particular * {@link JSONObject} * * @param jsonArray the {@link JSONArray} to be used for extracting values * @param property the property you'd like to get from the specified * {@link JSONObject} * @return the value of the specified property if it's found, or null if it * cannot be found */ public static String getValue(@NonNull final JSONArray jsonArray, @NonNull final String property) { if (jsonArray == null) return null; final int index = property.indexOf("."); if (index > 0) { final Object object = getProperty(jsonArray, property.substring(0, index)); if (object != null) { if (object instanceof JSONObject) return getValue((JSONObject) object, property.substring(index + 1)); if (object instanceof JSONArray) return getValue((JSONArray) object, property.substring(index + 1)); } } else return getProperty(jsonArray, property).toString(); return null; } /** * Returns a particular property from a JSONObject * * @param jsonObject JSONObject you want to parse * @param simpleProp property you're searching for * @return An Object matching the required property */ private static Object getProperty(@NonNull JSONObject jsonObject, @NonNull String simpleProp) { final int idx1 = simpleProp.indexOf("["); if (idx1 > 0) { final JSONArray jsonArray = (JSONArray) jsonObject.get(simpleProp.substring(0, idx1)); return getProperty(jsonArray, simpleProp.substring(idx1)); } else return jsonObject.get(simpleProp); } /** * Returns a particular property from a JSONArray * * @param jsonArray JSONArray you want to parse * @param simpleProp property you're searching for * @return An Object matching the required property */ private static Object getProperty(@NonNull JSONArray jsonArray, @NonNull String simpleProp) { if (simpleProp.startsWith("[")) { final int idx2 = simpleProp.indexOf("]"); if (idx2 > 0) { final String exp = simpleProp.substring(1, idx2); if (exp.contains("=")) { final String[] expParams = exp.split("="); for (final Iterator<JSONObject> iterator = jsonArray.iterator(); iterator.hasNext();) { final JSONObject jsonObject = iterator.next(); if (getValue(jsonObject, expParams[0]).equals(expParams[1])) return jsonObject; } } else if (StringUtils.isNumeric(exp) && jsonArray.size() > Integer.parseInt(exp)) return jsonArray.get(Integer.parseInt(exp)); } } return null; } /** * Returns a {@link JSONArray} format from a given String containing some * JSON data * * @param s a {@link String} containing some JSON data * @return a {@link JSONArray} representation of the provided {@link String} * @throws ParseException if the provided {@link String} does not actually contain some * valid JSON */ public static JSONArray toJSONArray(@NonNull final String s) throws ParseException { try { return (JSONArray) parser.parse(s); } catch (final ParseException e) { log.error(e.getMessage(), e); throw e; } } /** * Returns a proper representation in JSON of a {@link String} object * already containing JSON (it basically deals with indentation) * * @param s a {@link String} containing JSON to be cleaned * @return a clean JSON representation of the JSON data contained in the * provided {@link String} * @throws ParseException if the provided {@link String} does not actually contain a * valid JSON data */ public static Object parseJSON(@NonNull final String s) throws ParseException { return parser.parse(s); } }