JSONUtils.java
/*
* Licensed to The Apereo Foundation under one or more contributor license
* agreements. See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
*
* The Apereo Foundation licenses this file to you under the Educational
* Community 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://opensource.org/licenses/ecl2.txt
*
* 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 org.opencastproject.index.service.util;
import org.opencastproject.list.api.ListProviderException;
import org.opencastproject.list.api.ListProvidersService;
import org.opencastproject.list.api.ResourceListFilter;
import org.opencastproject.list.api.ResourceListQuery;
import org.opencastproject.security.api.Organization;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonNull;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Optional;
/**
* Utility class providing helpers for all operation related to JSON.
*/
public final class JSONUtils {
/** This regex is used to reduce the users in the filter selectbox.
* The filter is located in the top right corner in the admin ui. */
private static String userFilterRegex;
private static final String[] userListsToReduce = {"CONTRIBUTORS", "PUBLISHER",
"ORGANIZERS", "CONTRIBUTORS.USERNAMES", "EVENTS.PUBLISHER", "USERS.NAME"};
private JSONUtils() {
}
public static String safeString(Object input) {
return input != null ? input.toString() : "";
}
/**
* Turn a collection into a {@link JsonArray}
*
* @param collection
* the collection
* @return a new {@link JsonArray} generated with the colleciton values
*/
public static JsonArray collectionToJsonArray(Collection<?> collection) {
JsonArray jsonArray = new JsonArray();
if (collection != null) {
for (Object item : collection) {
jsonArray.add(convertToJsonElement(item));
}
}
return jsonArray;
}
public static <T> JsonArray arrayToJsonArray(T[] array) {
JsonArray jsonArray = new JsonArray();
if (array != null) {
for (T item : array) {
jsonArray.add(convertToJsonElement(item));
}
}
return jsonArray;
}
/**
* Turn a map into a {@link JsonObject} object
*
* @param map
* the source map
* @return a new {@link JsonObject} generated with the map values
*/
public static JsonObject mapToJsonObject(Map<?, ?> map) {
JsonObject jsonObject = new JsonObject();
if (map != null) {
for (Map.Entry<?, ?> entry : map.entrySet()) {
String key = String.valueOf(entry.getKey());
JsonElement value = convertToJsonElement(entry.getValue());
jsonObject.add(key, value);
}
}
return jsonObject;
}
private static JsonElement convertToJsonElement(Object item) {
if (item == null) return JsonNull.INSTANCE;
if (item instanceof JsonElement) return (JsonElement) item;
if (item instanceof Number) return new JsonPrimitive((Number) item);
if (item instanceof Boolean) return new JsonPrimitive((Boolean) item);
if (item instanceof Character) return new JsonPrimitive((Character) item);
if (item instanceof String) return new JsonPrimitive((String) item);
return new JsonPrimitive(item.toString());
}
/**
* Generate JSON presentation of the given filters
*
* @param query
* The {@link ResourceListQuery}
* @param listProvidersService
* The {@link ListProvidersService} to get the possible values
* @param org
* The {@link Organization}
* @return
* @throws ListProviderException
* if the possible values can not be retrieved correctly from the list provider.
*/
public static JsonObject filtersToJSON(ResourceListQuery query, ListProvidersService listProvidersService,
Organization org) throws ListProviderException {
JsonObject filtersJson = new JsonObject();
List<ResourceListFilter<?>> filters = query.getAvailableFilters();
for (ResourceListFilter<?> f : filters) {
JsonObject filterObject = new JsonObject();
filterObject.addProperty("type", f.getSourceType().toString().toLowerCase());
filterObject.addProperty("label", f.getLabel());
Optional<String> listProviderName = f.getValuesListName();
if (listProviderName.isPresent()) {
Map<String, String> values;
boolean translatable = false;
String providerName = listProviderName.get();
if (org != null
&& !listProvidersService.hasProvider(providerName, org.getId())
&& !listProvidersService.hasProvider(providerName)) {
values = new HashMap<>();
} else {
values = listProvidersService.getList(providerName, query, false);
if (Arrays.asList(userListsToReduce).contains(providerName)) {
// reduces the user list ('values' map) by the configured userFilterRegex
values.keySet().removeIf(u -> !u.matches(userFilterRegex));
}
translatable = listProvidersService.isTranslatable(providerName);
}
JsonObject optionsJson = new JsonObject();
for (Entry<String, String> entry : values.entrySet()) {
optionsJson.addProperty(entry.getKey(), entry.getValue() != null ? entry.getValue() : "");
}
filterObject.add("options", optionsJson);
filterObject.addProperty("translatable", translatable);
}
filtersJson.add(f.getName(), filterObject);
}
return filtersJson;
}
/**
* Generate JSON presentation of the given filters
*
* @param query
* The {@link ResourceListQuery}
* @param listProvidersService
* The {@link ListProvidersService} to get the possible values
* @param series
* The Series with write access
* @return
* @throws ListProviderException
* if the possible values can not be retrieved correctly from the list provider.
*/
public static JsonObject filtersToJSONSeriesWriteAccess(ResourceListQuery query,
ListProvidersService listProvidersService, Map<String, String> series) throws ListProviderException {
JsonObject filtersJson = new JsonObject();
for (ResourceListFilter<?> filter : query.getAvailableFilters()) {
JsonObject filterObject = new JsonObject();
filterObject.addProperty("type", filter.getSourceType().toString().toLowerCase());
filterObject.addProperty("label", filter.getLabel());
Optional<String> listProviderName = filter.getValuesListName();
if (listProviderName.isPresent()) {
String providerName = listProviderName.get();
JsonObject optionsJson = new JsonObject();
boolean translatable = false;
if (listProvidersService.hasProvider(providerName)) {
if (listProviderName.get().equals("SERIES")) {
for (Entry<String, String> entry : series.entrySet()) {
optionsJson.addProperty(entry.getValue(), entry.getKey() != null ? entry.getKey() : "");
}
} else {
Map<String, String> values = listProvidersService.getList(providerName, query, false);
for (Entry<String, String> entry : values.entrySet()) {
optionsJson.addProperty(entry.getKey(), entry.getValue() != null ? entry.getValue() : "");
}
}
translatable = listProvidersService.isTranslatable(providerName);
}
filterObject.add("options", optionsJson);
filterObject.addProperty("translatable", translatable);
}
filtersJson.add(filter.getName(), filterObject);
}
return filtersJson;
}
/**
* Returns a JSON object with key-value from given map
*
* @param map
* The source list for the JSON object
* @return a JSON object containing the all the key-value as parameter
* @throws JSONException
*/
public static JSONObject fromMap(Map<String, String> map) throws JSONException {
JSONObject json = new JSONObject();
if (map == null)
return json;
for (Entry<String, String> entry : map.entrySet()) {
json.put(entry.getKey(), entry.getValue());
}
return json;
}
/**
* Converts a JSON object to a map. All values are of type {@link String}
*
* @param json
* the JSON object to convert
* @return the map
*/
public static Map<String, String> toMap(JSONObject json) {
if (json == null)
return Collections.emptyMap();
HashMap<String, String> map = new HashMap<String, String>();
for (Iterator<String> iterator = json.keys(); iterator.hasNext();) {
String key = iterator.next();
map.put(key, json.optString(key));
}
return map;
}
public static void setUserRegex(String regex) {
userFilterRegex = regex;
}
}