/* * Copyright 2017 StreamSets Inc. * * Licensed under 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.streamsets.pipeline.lib.util; import com.streamsets.pipeline.api.Field; import com.streamsets.pipeline.api.Record; import com.streamsets.pipeline.api.StageException; import com.streamsets.pipeline.api.ext.ContextExtensions; import com.streamsets.pipeline.api.ext.DataCollectorServices; import com.streamsets.pipeline.api.ext.json.JsonMapper; import com.streamsets.pipeline.api.impl.Utils; import java.io.IOException; import java.math.BigDecimal; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Date; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.UUID; public class JsonUtil { private JsonUtil() {} @SuppressWarnings("unchecked") public static Field jsonToField(Object json) throws IOException { Field field; if (json == null) { field = Field.create(Field.Type.STRING, null); } else if (json instanceof List) { List jsonList = (List) json; List<Field> list = new ArrayList<>(jsonList.size()); for (Object element : jsonList) { list.add(jsonToField(element)); } field = Field.create(list); } else if (json instanceof Map) { Map<String, Object> jsonMap = (Map<String, Object>) json; Map<String, Field> map = new LinkedHashMap<>(); for (Map.Entry<String, Object> entry : jsonMap.entrySet()) { map.put(entry.getKey(), jsonToField(entry.getValue())); } field = Field.create(map); } else if (json instanceof String) { field = Field.create((String) json); } else if (json instanceof Boolean) { field = Field.create((Boolean) json); } else if (json instanceof Character) { field = Field.create((Character) json); } else if (json instanceof Byte) { field = Field.create((Byte) json); } else if (json instanceof Short) { field = Field.create((Short) json); } else if (json instanceof Integer) { field = Field.create((Integer) json); } else if (json instanceof Long) { field = Field.create((Long) json); } else if (json instanceof Float) { field = Field.create((Float) json); } else if (json instanceof Double) { field = Field.create((Double) json); } else if (json instanceof byte[]) { field = Field.create((byte[]) json); } else if (json instanceof Date) { field = Field.createDatetime((Date) json); } else if (json instanceof BigDecimal) { field = Field.create((BigDecimal) json); } else if (json instanceof UUID) { field = Field.create(json.toString()); } else { throw new IOException(Utils.format("Not recognized type '{}', value '{}'", json.getClass(), json)); } return field; } public static Object fieldToJsonObject(Record record, Field field) throws StageException { Object obj; if (field.getValue() == null) { obj = null; } else if(field.getType()== Field.Type.BOOLEAN) { obj = field.getValueAsBoolean(); } else if(field.getType()== Field.Type.BYTE) { obj = field.getValueAsByte(); } else if(field.getType()== Field.Type.BYTE_ARRAY) { obj = field.getValueAsByteArray(); } else if(field.getType()== Field.Type.CHAR) { obj = field.getValueAsChar(); } else if(field.getType()== Field.Type.DATE) { obj = field.getValueAsDate(); } else if(field.getType()== Field.Type.TIME) { obj = field.getValueAsTime(); } else if(field.getType()== Field.Type.DATETIME) { obj = field.getValueAsDatetime(); } else if(field.getType()== Field.Type.DECIMAL) { obj = field.getValueAsDecimal(); } else if(field.getType()== Field.Type.DOUBLE) { obj = field.getValueAsDouble(); } else if(field.getType()== Field.Type.FLOAT) { obj = field.getValueAsFloat(); } else if(field.getType()== Field.Type.INTEGER) { obj = field.getValueAsInteger(); } else if(field.getType()== Field.Type.LONG) { obj = field.getValueAsLong(); } else if(field.getType()== Field.Type.SHORT) { obj = field.getValueAsShort(); } else if(field.getType()== Field.Type.STRING) { obj = field.getValueAsString(); } else if(field.getType()== Field.Type.LIST) { List<Field> list = field.getValueAsList(); List<Object> toReturn = new ArrayList<>(list.size()); for(Field f : list) { toReturn.add(fieldToJsonObject(record, f)); } obj = toReturn; } else if(field.getType()== Field.Type.MAP || field.getType() == Field.Type.LIST_MAP) { Map<String, Field> map = field.getValueAsMap(); Map<String, Object> toReturn = new LinkedHashMap<>(); for (Map.Entry<String, Field> entry :map.entrySet()) { toReturn.put(entry.getKey(), fieldToJsonObject(record, entry.getValue())); } obj = toReturn; } else { throw new StageException( CommonError.CMN_0100, field.getType(), field.getValue(), record.getHeader().getSourceId()); } return obj; } public static String jsonRecordToString(ContextExtensions ext, Record r) throws StageException { try { JsonMapper jsonMapper = DataCollectorServices.instance().get(JsonMapper.SERVICE_KEY); return jsonMapper.writeValueAsString(JsonUtil.fieldToJsonObject(r, r.get())); } catch (IOException e) { throw new StageException(CommonError.CMN_0101, r.getHeader().getSourceId(), e.toString(), e); } } public static byte[] jsonRecordToBytes(ContextExtensions ext, Record r, Field f) throws StageException { try { JsonMapper jsonMapper = DataCollectorServices.instance().get(JsonMapper.SERVICE_KEY); return jsonMapper.writeValueAsBytes(JsonUtil.fieldToJsonObject(r, f)); } catch (IOException e) { throw new StageException(CommonError.CMN_0101, r.getHeader().getSourceId(), e.toString(), e); } } public static Field bytesToField(ContextExtensions ext, byte[] bytes) throws StageException { try { JsonMapper jsonMapper = DataCollectorServices.instance().get(JsonMapper.SERVICE_KEY); return jsonToField(jsonMapper.readValue(bytes, Object.class)); } catch (Exception e) { throw new StageException(CommonError.CMN_0101, new String(bytes, StandardCharsets.UTF_8), e.toString(), e); } } }