/*
* Copyright 2014 Red Hat, Inc. and/or its affiliates.
*
* Licensed 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 org.dashbuilder.dataset.json;
import org.dashbuilder.dataprovider.DataSetProviderRegistry;
import org.dashbuilder.dataprovider.DataSetProviderType;
import org.dashbuilder.dataset.ColumnType;
import org.dashbuilder.dataset.def.*;
import org.dashbuilder.dataset.filter.DataSetFilter;
import org.dashbuilder.json.Json;
import org.dashbuilder.json.JsonArray;
import org.dashbuilder.json.JsonException;
import org.dashbuilder.json.JsonObject;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
/**
* DataSetDef from/to JSON utilities
*/
public class DataSetDefJSONMarshaller {
public static final String UUID = "uuid";
public static final String NAME = "name";
public static final String PROVIDER = "provider";
public static final String ISPUBLIC = "isPublic";
public static final String PUSH_ENABLED = "pushEnabled";
public static final String PUSH_MAXSIZE = "pushMaxSize";
public static final String COLUMNS = "columns";
public static final String COLUMN_ID = "id";
public static final String COLUMN_TYPE = "type";
public static final String COLUMN_PATTERN = "pattern";
public static final String FILTERS = "filters";
public static final String ALL_COLUMNS = "allColumns";
public static final String CACHE_ENABLED = "cacheEnabled";
public static final String CACHE_MAXROWS = "cacheMaxRows";
public static final String REFRESH_TIME = "refreshTime";
public static final String REFRESH_ALWAYS = "refreshAlways";
public static final List<String> ROOT_KEYS = Arrays.asList(
UUID,
NAME,
PROVIDER,
ISPUBLIC,
PUSH_ENABLED,
PUSH_MAXSIZE,
COLUMNS,
FILTERS,
ALL_COLUMNS,
CACHE_ENABLED,
CACHE_MAXROWS,
REFRESH_TIME,
REFRESH_ALWAYS
);
protected DataSetProviderRegistry dataSetProviderRegistry;
protected DataSetLookupJSONMarshaller dataSetLookupJSONMarshaller;
public DataSetDefJSONMarshaller(DataSetProviderRegistry dataSetProviderRegistry) {
this(dataSetProviderRegistry, DataSetLookupJSONMarshaller.get());
}
public DataSetDefJSONMarshaller(DataSetProviderRegistry dataSetProviderRegistry, DataSetLookupJSONMarshaller dataSetLookupJSONMarshaller) {
this.dataSetProviderRegistry = dataSetProviderRegistry;
this.dataSetLookupJSONMarshaller = dataSetLookupJSONMarshaller;
}
public DataSetDef fromJson(String jsonString) throws Exception {
JsonObject json = Json.parse(jsonString);
DataSetProviderType type = readProviderType(json);
DataSetDef dataSetDef = type.createDataSetDef();
dataSetDef.setProvider(type);
readGeneralSettings(dataSetDef, json);
DataSetDefJSONMarshallerExt marshaller = type.getJsonMarshaller();
if (marshaller != null) {
marshaller.fromJson(dataSetDef, json);
}
else {
for (String key : json.keys()) {
if (!ROOT_KEYS.contains(key)) {
String value = json.getString(key);
dataSetDef.setProperty(key, value);
}
}
}
return dataSetDef;
}
public DataSetProviderType readProviderType(JsonObject json) throws Exception {
String provider = json.getString(PROVIDER);
if (isBlank(provider)) {
throw new IllegalArgumentException("Missing 'provider' property");
}
DataSetProviderType type = dataSetProviderRegistry.getProviderTypeByName(provider);
if (type == null) {
throw new IllegalArgumentException("Provider not supported: " + provider);
}
return type;
}
public DataSetDef readGeneralSettings(DataSetDef def, JsonObject json) throws Exception {
String uuid = json.getString(UUID);
String name = json.getString(NAME);
String isPublic = json.getString(ISPUBLIC);
String pushEnabled = json.getString(PUSH_ENABLED);
String pushMaxSize = json.getString(PUSH_MAXSIZE);
String cacheEnabled = json.getString(CACHE_ENABLED);
String cacheMaxRows = json.getString(CACHE_MAXROWS);
String refreshTime = json.getString(REFRESH_TIME);
String refreshAlways = json.getString(REFRESH_ALWAYS);
String allColumns = json.getString(ALL_COLUMNS);
if (!isBlank(uuid)) {
def.setUUID(uuid);
}
if (!isBlank(name)) {
def.setName(name);
}
if (!isBlank(isPublic)) {
def.setPublic(Boolean.parseBoolean(isPublic));
}
if (!isBlank(pushEnabled)) {
def.setPushEnabled(Boolean.parseBoolean(pushEnabled));
}
if (!isBlank(pushMaxSize)) {
def.setPushMaxSize(Integer.parseInt(pushMaxSize));
}
if (!isBlank(cacheEnabled)) {
def.setCacheEnabled(Boolean.parseBoolean(cacheEnabled));
}
if (!isBlank(cacheMaxRows)) {
def.setCacheMaxRows(Integer.parseInt(cacheMaxRows));
}
if (!isBlank(refreshTime)) {
def.setRefreshTime(refreshTime);
}
if (!isBlank(refreshAlways)) {
def.setRefreshAlways(Boolean.parseBoolean(refreshAlways));
}
if (!isBlank(allColumns)) {
def.setAllColumnsEnabled(Boolean.parseBoolean(allColumns));
}
if (json.has(COLUMNS)) {
JsonArray array = json.getArray(COLUMNS);
for (int i=0; i<array.length(); i++) {
JsonObject column = array.getObject(i);
String columnId = column.getString(COLUMN_ID);
String columnType = column.getString(COLUMN_TYPE);
String columnPattern = column.getString(COLUMN_PATTERN);
if (isBlank(columnId)) {
throw new IllegalArgumentException("Column id. attribute is mandatory.");
}
if (isBlank(columnType)) {
throw new IllegalArgumentException("Missing column 'type' attribute: " + columnId);
}
ColumnType type = ColumnType.TEXT;
if (columnType.equalsIgnoreCase("label")) {
type = ColumnType.LABEL;
}
else if (columnType.equalsIgnoreCase("date")) {
type = ColumnType.DATE;
}
else if (columnType.equalsIgnoreCase("number")) {
type = ColumnType.NUMBER;
}
def.addColumn(columnId, type);
if (!isBlank(columnPattern)) {
def.setPattern(columnId, columnPattern);
}
}
}
if (json.has(FILTERS)) {
JsonArray array = json.getArray(FILTERS);
DataSetFilter dataSetFilter = dataSetLookupJSONMarshaller.parseFilterOperation(array);
def.setDataSetFilter(dataSetFilter);
}
return def;
}
public String toJsonString(final DataSetDef dataSetDef) throws JsonException {
return toJsonObject( dataSetDef ).toString();
}
public JsonObject toJsonObject(final DataSetDef dataSetDef) throws JsonException {
JsonObject json = Json.createObject();
// UUID.
json.put(UUID, dataSetDef.getUUID());
// Name.
json.put(NAME, dataSetDef.getName());
// Provider.
json.put(PROVIDER, dataSetDef.getProvider().getName());
// Public.
json.put(ISPUBLIC, dataSetDef.isPublic());
// Backend cache.
json.put(CACHE_ENABLED, dataSetDef.isCacheEnabled());
json.put(CACHE_MAXROWS, dataSetDef.getCacheMaxRows());
// Client cache.
json.put(PUSH_ENABLED, dataSetDef.isPushEnabled());
json.put(PUSH_MAXSIZE, dataSetDef.getPushMaxSize());
// Refresh.
json.put(REFRESH_ALWAYS, dataSetDef.isRefreshAlways());
json.put(REFRESH_TIME, dataSetDef.getRefreshTime());
// Specific provider.
DataSetProviderType type = dataSetDef.getProvider();
DataSetDefJSONMarshallerExt marshaller = type.getJsonMarshaller();
if (marshaller != null) {
marshaller.toJson(dataSetDef, json);
}
// Data columns.
final Collection<DataColumnDef> columns = dataSetDef.getColumns();
if (columns != null)
{
final JsonArray columnsArray = toJsonObject(columns, dataSetDef);
if (columnsArray != null)
{
json.put(COLUMNS, columnsArray);
}
}
// Initial filter
final DataSetFilter filter = dataSetDef.getDataSetFilter();
if (filter != null) {
try {
final JsonArray filters = dataSetLookupJSONMarshaller.formatColumnFilters(filter.getColumnFilterList());
if (filters != null) {
json.put(FILTERS, filters);
}
} catch (Exception e) {
throw new JsonException(e);
}
}
// Extra properties (only when no marshaller is provided)
if (marshaller == null) {
for (String key : dataSetDef.getPropertyNames()) {
if (!ROOT_KEYS.contains(key)) {
String value = dataSetDef.getProperty(key);
json.put(key, value);
}
}
}
return json;
}
protected JsonArray toJsonObject(final Collection<DataColumnDef> columnList,
final DataSetDef dataSetDef) throws JsonException {
JsonArray result = null;
if (columnList != null && !columnList.isEmpty()) {
result = Json.createArray();
int idx = 0;
for (final DataColumnDef column : columnList) {
final String id = column.getId();
final ColumnType type = column.getColumnType();
final JsonObject columnObject = Json.createObject();
columnObject.put(COLUMN_ID, id);
columnObject.put(COLUMN_TYPE, type.name().toLowerCase());
String pattern = dataSetDef.getPattern(id);
if (pattern != null && pattern.trim().length() > 0) {
columnObject.put(COLUMN_PATTERN, pattern);
}
result.set(idx++, columnObject);
}
}
return result;
}
public static boolean isBlank(String str) {
int strLen;
if (str == null || (strLen = str.length()) == 0) {
return true;
}
for (int i = 0; i < strLen; i++) {
if (!Character.isSpace(str.charAt(i))) {
return false;
}
}
return true;
}
}