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 static com.entwinemedia.fn.data.json.Jsons.arr;
import static com.entwinemedia.fn.data.json.Jsons.f;
import static com.entwinemedia.fn.data.json.Jsons.obj;
import static com.entwinemedia.fn.data.json.Jsons.v;
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 org.opencastproject.util.data.Option;
import com.entwinemedia.fn.data.json.Field;
import com.entwinemedia.fn.data.json.JObject;
import com.entwinemedia.fn.data.json.JValue;
import com.entwinemedia.fn.data.json.Jsons;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;
import java.util.ArrayList;
import java.util.Arrays;
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.Set;
/**
* 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() {
}
/**
* Turn a map into a {@link JObject} object
*
* @param map
* the source map
* @return a new {@link JObject} generated with the map values
*/
public static JObject mapToJSON(Map<String, String> map) {
if (map == null) {
throw new IllegalArgumentException("Map must not be null!");
}
List<Field> fields = new ArrayList<Field>();
for (Entry<String, String> item : map.entrySet()) {
fields.add(f(item.getKey(), v(item.getValue(), Jsons.BLANK)));
}
return obj(fields);
}
/**
* Turn a set into a {@link JObject} object
*
* @param set
* the source set
* @return a new {@link JObject} generated with the map values
*/
public static JValue setToJSON(Set<String> set) {
if (set == null) {
return arr();
}
List<JValue> arrEntries = new ArrayList<JValue>();
for (String item : set) {
arrEntries.add(v(item, Jsons.BLANK));
}
return arr(arrEntries);
}
/**
* 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 JValue filtersToJSON(ResourceListQuery query, ListProvidersService listProvidersService,
Organization org) throws ListProviderException {
List<Field> filtersJSON = new ArrayList<Field>();
List<Field> fields = null;
List<ResourceListFilter<?>> filters = query.getAvailableFilters();
for (ResourceListFilter<?> f : filters) {
fields = new ArrayList<Field>();
fields.add(f("type", v(f.getSourceType().toString().toLowerCase())));
fields.add(f("label", v(f.getLabel())));
Option<String> listProviderName = f.getValuesListName();
if (listProviderName.isSome()) {
Map<String, String> values = null;
boolean translatable = false;
if (org != null && !listProvidersService.hasProvider(listProviderName.get(), org.getId())
&& !listProvidersService.hasProvider(listProviderName.get())) {
values = new HashMap<String, String>();
} else {
values = listProvidersService.getList(listProviderName.get(), query, false);
if (Arrays.asList(userListsToReduce).contains(listProviderName.get())) {
// reduces the user list ('values' map) by the configured userFilterRegex
values.keySet().removeIf(u -> !u.matches(userFilterRegex));
}
translatable = listProvidersService.isTranslatable(listProviderName.get());
}
List<Field> valuesJSON = new ArrayList<Field>();
for (Entry<String, String> entry : values.entrySet()) {
valuesJSON.add(f(entry.getKey(), v(entry.getValue(), Jsons.BLANK)));
}
fields.add(f("options", obj(valuesJSON)));
fields.add(f("translatable", translatable));
}
filtersJSON.add(f(f.getName(), obj(fields)));
}
return obj(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 JValue filtersToJSONSeriesWriteAccess(ResourceListQuery query, ListProvidersService listProvidersService,
Map<String, String> series) throws ListProviderException {
List<Field> filtersJSON = new ArrayList<>();
for (ResourceListFilter<?> filter : query.getAvailableFilters()) {
List<Field> fields = new ArrayList<>();
fields.add(f("type", v(filter.getSourceType().toString().toLowerCase())));
fields.add(f("label", v(filter.getLabel())));
Option<String> listProviderName = filter.getValuesListName();
if (listProviderName.isSome()) {
boolean translatable = false;
List<Field> valuesJSON = new ArrayList<>();
if (listProvidersService.hasProvider(listProviderName.get())) {
if (listProviderName.get().equals("SERIES")) {
for (Entry<String, String> entry : series.entrySet()) {
valuesJSON.add(f(entry.getValue(), v(entry.getKey(), Jsons.BLANK)));
}
} else {
Map<String, String> values = listProvidersService.getList(listProviderName.get(), query, false);
for (Entry<String, String> entry : values.entrySet()) {
valuesJSON.add(f(entry.getKey(), v(entry.getValue(), Jsons.BLANK)));
}
}
translatable = listProvidersService.isTranslatable(listProviderName.get());
}
fields.add(f("options", obj(valuesJSON)));
fields.add(f("translatable", translatable));
}
filtersJSON.add(f(filter.getName(), obj(fields)));
}
return obj(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;
}
}