| /* |
| * Copyright (c) 2013, 2021 Oracle and/or its affiliates. All rights reserved. |
| * |
| * This program and the accompanying materials are made available under the |
| * terms of the Eclipse Public License v. 2.0 which is available at |
| * http://www.eclipse.org/legal/epl-2.0, |
| * or the Eclipse Distribution License v. 1.0 which is available at |
| * http://www.eclipse.org/org/documents/edl-v10.php. |
| * |
| * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause |
| */ |
| |
| // Contributors: |
| // Denise Smith - 2.6 - initial implementation |
| package org.eclipse.persistence.oxm.record; |
| |
| import java.math.BigDecimal; |
| import java.math.BigInteger; |
| |
| import jakarta.json.Json; |
| import jakarta.json.JsonArrayBuilder; |
| import jakarta.json.JsonObjectBuilder; |
| import javax.xml.namespace.QName; |
| |
| import org.eclipse.persistence.internal.core.helper.CoreClassConstants; |
| import org.eclipse.persistence.internal.oxm.ConversionManager; |
| |
| public class JsonBuilderRecord extends JsonRecord<JsonBuilderRecord.Level> { |
| |
| private JsonObjectBuilder rootJsonObjectBuilder; |
| private JsonArrayBuilder rootJsonArrayBuilder; |
| |
| public JsonBuilderRecord(){ |
| super(); |
| isLastEventStart = false; |
| } |
| |
| public JsonBuilderRecord(JsonObjectBuilder jsonObjectBuilder){ |
| this(); |
| rootJsonObjectBuilder = jsonObjectBuilder; |
| } |
| |
| public JsonBuilderRecord(JsonArrayBuilder jsonArrayBuilder){ |
| this(); |
| rootJsonArrayBuilder = jsonArrayBuilder; |
| isRootArray = true; |
| } |
| |
| @Override |
| protected Level createNewLevel(boolean collection, Level parentLevel, boolean nestedArray){ |
| return new Level(collection, position, nestedArray); |
| } |
| |
| @Override |
| protected void startRootObject(){ |
| super.startRootObject(); |
| position.setJsonObjectBuilder(rootJsonObjectBuilder); |
| setComplex(position, true); |
| } |
| |
| @Override |
| protected void finishLevel(){ |
| if(!(position.isCollection && position.isEmptyCollection() && position.getKeyName() == null)){ |
| |
| Level parentLevel = (Level) position.parentLevel; |
| |
| if(parentLevel != null){ |
| if(parentLevel.isCollection){ |
| if(position.isCollection){ |
| parentLevel.getJsonArrayBuilder().add(position.getJsonArrayBuilder()); |
| }else{ |
| parentLevel.getJsonArrayBuilder().add(position.getJsonObjectBuilder()); |
| } |
| }else{ |
| if(position.isCollection){ |
| parentLevel.getJsonObjectBuilder().add(position.getKeyName(), position.getJsonArrayBuilder()); |
| }else{ |
| parentLevel.getJsonObjectBuilder().add(position.getKeyName(), position.getJsonObjectBuilder()); |
| } |
| } |
| } |
| } |
| super.finishLevel(); |
| } |
| |
| @Override |
| protected void startRootLevelCollection(){ |
| if(rootJsonArrayBuilder == null){ |
| rootJsonArrayBuilder = Json.createArrayBuilder(); |
| } |
| position.setJsonArrayBuilder(rootJsonArrayBuilder); |
| } |
| |
| @Override |
| public void endCollection() { |
| finishLevel(); |
| } |
| |
| @Override |
| protected void setComplex(Level level, boolean complex){ |
| boolean isAlreadyComplex = level.isComplex; |
| super.setComplex(level, complex); |
| if(complex && !isAlreadyComplex){ |
| if(level.jsonObjectBuilder == null){ |
| level.jsonObjectBuilder = Json.createObjectBuilder(); |
| } |
| } |
| } |
| |
| @Override |
| protected void writeEmptyCollection(Level level, String keyName){ |
| level.getJsonObjectBuilder().add(keyName, Json.createArrayBuilder()); |
| } |
| |
| @Override |
| protected void addValueToObject(Level level, String keyName, Object value, QName schemaType){ |
| JsonObjectBuilder jsonObjectBuilder = level.getJsonObjectBuilder(); |
| if(value == NULL){ |
| jsonObjectBuilder.addNull(keyName); |
| }else if(value instanceof Integer){ |
| jsonObjectBuilder.add(keyName, (Integer)value); |
| }else if(value instanceof BigDecimal){ |
| jsonObjectBuilder.add(keyName, (BigDecimal)value); |
| }else if(value instanceof BigInteger){ |
| jsonObjectBuilder.add(keyName, (BigInteger)value); |
| }else if(value instanceof Boolean){ |
| jsonObjectBuilder.add(keyName, (Boolean)value); |
| }else if(value instanceof Character){ |
| jsonObjectBuilder.add(keyName, (Character)value); |
| }else if(value instanceof Double){ |
| jsonObjectBuilder.add(keyName, (Double)value); |
| }else if(value instanceof Float){ |
| jsonObjectBuilder.add(keyName, (Float)value); |
| }else if(value instanceof Long){ |
| jsonObjectBuilder.add(keyName, (Long)value); |
| }else if(value instanceof String){ |
| jsonObjectBuilder.add(keyName, (String)value); |
| }else{ |
| ConversionManager conversionManager = getConversionManager(); |
| String convertedValue = conversionManager.convertObject(value, CoreClassConstants.STRING, schemaType); |
| Class<Object> theClass = conversionManager.javaType(schemaType); |
| if((schemaType == null || theClass == null) && (CoreClassConstants.NUMBER.isAssignableFrom(value.getClass()))){ |
| //if it's still a number and falls through the cracks we dont want "" around the value |
| BigDecimal convertedNumberValue = ((ConversionManager) session.getDatasourcePlatform().getConversionManager()).convertObject(value, CoreClassConstants.BIGDECIMAL, schemaType); |
| jsonObjectBuilder.add(keyName, convertedNumberValue); |
| }else{ |
| jsonObjectBuilder.add(keyName, convertedValue); |
| } |
| |
| } |
| } |
| |
| @Override |
| protected void addValueToArray(Level level, Object value, QName schemaType){ |
| JsonArrayBuilder jsonArrayBuilder = level.getJsonArrayBuilder(); |
| if(value == NULL){ |
| jsonArrayBuilder.addNull(); |
| }else if(value instanceof Integer){ |
| jsonArrayBuilder.add((Integer)value); |
| }else if(value instanceof BigDecimal){ |
| jsonArrayBuilder.add((BigDecimal)value); |
| }else if(value instanceof BigInteger){ |
| jsonArrayBuilder.add((BigInteger)value); |
| }else if(value instanceof Boolean){ |
| jsonArrayBuilder.add((Boolean)value); |
| }else if(value instanceof Character){ |
| jsonArrayBuilder.add((Character)value); |
| }else if(value instanceof Double){ |
| jsonArrayBuilder.add((Double)value); |
| }else if(value instanceof Float){ |
| jsonArrayBuilder.add((Float)value); |
| }else if(value instanceof Long){ |
| jsonArrayBuilder.add((Long)value); |
| }else if(value instanceof String){ |
| jsonArrayBuilder.add((String)value); |
| }else{ |
| ConversionManager conversionManager = getConversionManager(); |
| String convertedValue = conversionManager.convertObject(value, CoreClassConstants.STRING, schemaType); |
| Class<Object> theClass = conversionManager.javaType(schemaType); |
| if((schemaType == null || theClass == null) && (CoreClassConstants.NUMBER.isAssignableFrom(value.getClass()))){ |
| //if it's still a number and falls through the cracks we dont want "" around the value |
| BigDecimal convertedNumberValue = ((ConversionManager) session.getDatasourcePlatform().getConversionManager()).convertObject(value, CoreClassConstants.BIGDECIMAL, schemaType); |
| jsonArrayBuilder.add(convertedNumberValue); |
| }else{ |
| jsonArrayBuilder.add(convertedValue); |
| } |
| } |
| } |
| |
| |
| /** |
| * Instances of this class are used to maintain state about the current |
| * level of the JSON message being marshalled. |
| */ |
| protected static class Level extends JsonRecord.Level{ |
| |
| private JsonObjectBuilder jsonObjectBuilder; |
| private JsonArrayBuilder jsonArrayBuilder; |
| |
| public Level(boolean isCollection, Level position, boolean nestedArray) { |
| super(isCollection, position, nestedArray); |
| } |
| |
| @Override |
| public void setCollection(boolean isCollection) { |
| super.setCollection(isCollection); |
| if(isCollection && jsonArrayBuilder == null){ |
| jsonArrayBuilder = Json.createArrayBuilder(); |
| } |
| } |
| |
| public JsonObjectBuilder getJsonObjectBuilder() { |
| return jsonObjectBuilder; |
| } |
| |
| public void setJsonObjectBuilder(JsonObjectBuilder jsonObjectBuilder) { |
| this.jsonObjectBuilder = jsonObjectBuilder; |
| } |
| |
| public JsonArrayBuilder getJsonArrayBuilder() { |
| return jsonArrayBuilder; |
| } |
| |
| public void setJsonArrayBuilder(JsonArrayBuilder jsonArrayBuilder) { |
| this.jsonArrayBuilder = jsonArrayBuilder; |
| } |
| |
| } |
| |
| } |