/* * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. 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 org.wso2.carbon.mediator.datamapper.engine.output.writers; import com.fasterxml.jackson.core.JsonFactory; import com.fasterxml.jackson.core.JsonGenerator; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.mediator.datamapper.engine.core.exceptions.InvalidPayloadException; import org.wso2.carbon.mediator.datamapper.engine.core.exceptions.SchemaException; import org.wso2.carbon.mediator.datamapper.engine.core.exceptions.WriterException; import org.wso2.carbon.mediator.datamapper.engine.core.schemas.Schema; import org.wso2.carbon.mediator.datamapper.engine.core.schemas.SchemaElement; import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import static org.wso2.carbon.mediator.datamapper.engine.utils.DataMapperEngineConstants.*; /** * This class implements {@link Writer} interface and json writer for data mapper engine using * Jackson */ public class JSONWriter implements Writer { private static final Log log = LogFactory.getLog(JSONWriter.class); private Schema outputSchema; private JsonGenerator jsonGenerator; private StringWriter writer; private List<SchemaElement> schemaElementList; public JSONWriter(Schema outputSchema) throws SchemaException, WriterException { this.outputSchema = outputSchema; this.writer = new StringWriter(); this.schemaElementList = new ArrayList<>(); this.schemaElementList.add(new SchemaElement(outputSchema.getName())); try { JsonFactory jsonFactory = new JsonFactory(); this.jsonGenerator = jsonFactory.createGenerator(writer); writeStartAnonymousObject(); } catch (IOException e) { throw new WriterException("Error while creating json generator. " + e.getMessage()); } } @Override public void writeStartObject(String name) throws WriterException { try { String schemaName = name; if (name.endsWith(SCHEMA_ATTRIBUTE_PARENT_ELEMENT_POSTFIX)) { schemaName = name.substring(0, name.lastIndexOf(SCHEMA_ATTRIBUTE_PARENT_ELEMENT_POSTFIX)); } schemaElementList.add(new SchemaElement(schemaName)); String type = null; try { type = outputSchema.getElementTypeByName(schemaElementList); } catch (InvalidPayloadException | SchemaException e) { throw new WriterException(e.getMessage()); } if (OBJECT_ELEMENT_TYPE.equals(type)) { jsonGenerator.writeObjectFieldStart(name); } else if (STRING_ELEMENT_TYPE.equals(type)) { jsonGenerator.writeObjectFieldStart(name); } else { jsonGenerator.writeArrayFieldStart(name); //start an object only if it is an object array if (!outputSchema.isCurrentArrayIsPrimitive()) { jsonGenerator.writeStartObject(); } } } catch (IOException e) { throw new WriterException("Error while creating starting object. " + e.getMessage()); } } @Override public void writeField(String name, Object value) throws WriterException { try { if (value instanceof String) { jsonGenerator.writeStringField(name, (String) value); } else if (value instanceof Integer) { jsonGenerator.writeNumberField(name, (Integer) value); } else if (value instanceof Double) { jsonGenerator.writeNumberField(name, (Double) value); } else if (value instanceof Boolean) { jsonGenerator.writeBooleanField(name, (Boolean) value); } } catch (IOException e) { throw new WriterException("Error while creating writing field. " + e.getMessage()); } } @Override public void writeEndObject(String objectName) throws WriterException { try { if ((!ARRAY_ELEMENT_TYPE.equals(outputSchema.getElementTypeByName(schemaElementList)) && !schemaElementList .isEmpty()) && schemaElementList.get(schemaElementList.size() - 1).getElementName() .equals(objectName)) { schemaElementList.remove(schemaElementList.size() - 1); jsonGenerator.writeEndObject(); } else if (ARRAY_ELEMENT_TYPE.equals(outputSchema.getElementTypeByName(schemaElementList))) { if (!outputSchema.isCurrentArrayIsPrimitive()) { jsonGenerator.writeEndObject(); } } } catch (IOException | SchemaException | InvalidPayloadException e) { throw new WriterException("Error while creating ending object. " + e.getMessage()); } } @Override public String terminateMessageBuilding() throws WriterException { String inputJSVariable = null; try { writeEndObject(null); jsonGenerator.close(); inputJSVariable = writer.toString(); writer.close(); return inputJSVariable; } catch (IOException e) { throw new WriterException("Error while creating terminating message building. " + e.getMessage()); } } @Override public void writeStartArray() { } @Override public void writeEndArray() throws WriterException { try { schemaElementList.remove(schemaElementList.size() - 1); jsonGenerator.writeEndArray(); } catch (IOException e) { try { jsonGenerator.writeEndObject(); jsonGenerator.writeEndArray(); } catch (IOException e1) { throw new WriterException(e.getMessage()); } } } @Override public void writeStartAnonymousObject() throws WriterException { try { jsonGenerator.writeStartObject(); } catch (IOException e) { throw new WriterException("Error while creating anonymous object. " + e.getMessage()); } } @Override public void writePrimitive(Object value) throws WriterException { try { if (value instanceof String) { jsonGenerator.writeString((String) value); } else if (value instanceof Boolean) { jsonGenerator.writeBoolean((Boolean) value); } else if (value instanceof Long) { jsonGenerator.writeNumber((Long) value); } else if (value instanceof Double) { jsonGenerator.writeNumber((Double) value); } } catch (IOException e) { throw new WriterException("Error while writing primitive. " + e.getMessage()); } } }