OpenSPCoop2Message_json_impl.java

  1. /*
  2.  * GovWay - A customizable API Gateway
  3.  * https://govway.org
  4.  *
  5.  * Copyright (c) 2005-2025 Link.it srl (https://link.it).
  6.  *
  7.  * This program is free software: you can redistribute it and/or modify
  8.  * it under the terms of the GNU General Public License version 3, as published by
  9.  * the Free Software Foundation.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18.  *
  19.  */

  20. package org.openspcoop2.message.rest;

  21. import java.io.ByteArrayOutputStream;
  22. import java.io.InputStream;
  23. import java.io.OutputStream;
  24. import java.io.OutputStreamWriter;
  25. import java.io.Writer;

  26. import org.openspcoop2.message.OpenSPCoop2MessageFactory;
  27. import org.openspcoop2.message.OpenSPCoop2RestJsonMessage;
  28. import org.openspcoop2.message.exception.MessageException;
  29. import org.openspcoop2.message.exception.MessageNotSupportedException;
  30. import org.openspcoop2.utils.CopyStream;
  31. import org.openspcoop2.utils.io.DumpByteArrayOutputStream;
  32. import org.openspcoop2.utils.json.JSONUtils;
  33. import org.openspcoop2.utils.json.JsonPathExpressionEngine;
  34. import org.openspcoop2.utils.json.JsonPathReturnType;
  35. import org.openspcoop2.utils.transport.http.ContentTypeUtilities;
  36. import org.openspcoop2.utils.transport.http.HttpConstants;

  37. import com.fasterxml.jackson.databind.JsonNode;

  38. import net.minidev.json.JSONObject;
  39. import net.minidev.json.JSONStyle;

  40. /**
  41.  * Implementazione dell'OpenSPCoop2Message utilizzabile per messaggi json
  42.  *
  43.  * @author Andrea Poli (poli@link.it)
  44.  * @author $Author$
  45.  * @version $Rev$, $Date$
  46.  */
  47. public class OpenSPCoop2Message_json_impl extends AbstractBaseOpenSPCoop2RestMessage<String> implements OpenSPCoop2RestJsonMessage {

  48.     public OpenSPCoop2Message_json_impl(OpenSPCoop2MessageFactory messageFactory) {
  49.         super(messageFactory);
  50.         this.supportReadOnly = false; // il contenuto e' gia una stringa.
  51.     }
  52.     public OpenSPCoop2Message_json_impl(OpenSPCoop2MessageFactory messageFactory, InputStream is,String contentType) throws MessageException {
  53.         super(messageFactory, is, contentType);
  54.         this.supportReadOnly = false; // il contenuto e' gia una stringa.
  55.     }
  56.    
  57.     @Override
  58.     protected String buildContent() throws MessageException{
  59.         try{
  60.             //return org.openspcoop2.utils.Utilities.getAsString(this.countingInputStream, this.contentTypeCharsetName);
  61.             ByteArrayOutputStream bout = new ByteArrayOutputStream();
  62.             CopyStream.copy(this._getInputStream(), bout);
  63.             bout.flush();
  64.             bout.close();
  65.             return bout.toString(this.contentTypeCharsetName);
  66.         }catch(Exception e){
  67.             throw new MessageException(e.getMessage(),e);
  68.         }finally {
  69.             try {
  70.                 this._getInputStream().close();
  71.             }catch(Exception eClose) {
  72.                 // close
  73.             }
  74.         }
  75.     }
  76.     @Override
  77.     protected String buildContent(DumpByteArrayOutputStream contentBuffer) throws MessageException{
  78.         try{
  79.             return contentBuffer.toString(this.contentTypeCharsetName);
  80.         }catch(Exception e){
  81.             throw new MessageException(e.getMessage(),e);
  82.         }
  83.     }
  84.    
  85.     @Override
  86.     protected String buildContentAsString() throws MessageException{
  87.         return this.content;
  88.     }
  89.     @Override
  90.     protected byte[] buildContentAsByteArray() throws MessageException{
  91.         try{
  92.             return this.content.getBytes(this.contentTypeCharsetName);
  93.         }catch(Exception e){
  94.             throw new MessageException(e.getMessage(),e);
  95.         }
  96.     }

  97.     @Override
  98.     protected void serializeContent(OutputStream os, boolean consume) throws MessageException {
  99.         Writer w = null;
  100.         try{
  101.             w = new OutputStreamWriter(os,this.contentTypeCharsetName);
  102.             w.write(this.content);
  103.             w.flush();
  104.         }catch(Exception e){
  105.             throw new MessageException(e.getMessage(),e);
  106.         }finally{
  107.             try{
  108.                 if(w!=null){
  109.                     w.close();
  110.                 }
  111.             }catch(Exception eClose){
  112.                 // close
  113.             }
  114.         }
  115.     }
  116.    
  117.     @Override
  118.     public boolean isProblemDetailsForHttpApis_RFC7807() throws MessageException,MessageNotSupportedException {
  119.         try{
  120.             if(this.contentType==null) {
  121.                 return false;
  122.             }
  123.             String baseType = ContentTypeUtilities.readBaseTypeFromContentType(this.contentType);
  124.             return HttpConstants.CONTENT_TYPE_JSON_PROBLEM_DETAILS_RFC_7807.equalsIgnoreCase(baseType);
  125.         }catch(Exception e){
  126.             throw new MessageException(e.getMessage(),e);
  127.         }
  128.     }

  129.     @Override
  130.     public void prettyFormatContent() throws MessageException,MessageNotSupportedException{
  131.         try {
  132.             if(this.hasContent()) {
  133.                 String content = this.getContent();
  134.                 JSONUtils jsonUtils = JSONUtils.getInstance(true);
  135.                 JsonNode node = jsonUtils.getAsNode(content);
  136.                 this.updateContent(jsonUtils.toString(node));
  137.             }
  138.         }catch(Exception e) {
  139.             throw new MessageException(e.getMessage(),e);
  140.         }
  141.     }
  142.    
  143.     @Override
  144.     public void addSimpleElement(String name, Object value) throws MessageException,MessageNotSupportedException{
  145.         this._processJsonField(true, null, name, value, true, false, false);
  146.     }
  147.     @Override
  148.     public void addSimpleElement(String jsonPath, String name, Object value) throws MessageException,MessageNotSupportedException{
  149.         this._processJsonField(false, jsonPath, name, value, true, false, false);
  150.     }
  151.     @Override
  152.     public void addObjectElement(String name, Object value) throws MessageException,MessageNotSupportedException{
  153.         this._processJsonField(true, null, name, toJSONObject(value), true, false, false);
  154.     }
  155.     @Override
  156.     public void addObjectElement(String jsonPath, String name, Object value) throws MessageException,MessageNotSupportedException{
  157.         this._processJsonField(false, jsonPath, name, toJSONObject(value), true, false, false);
  158.     }
  159.     private net.minidev.json.JSONObject toJSONObject(Object valueParam) throws MessageException {
  160.         net.minidev.json.JSONObject value = null;
  161.         if(valueParam instanceof net.minidev.json.JSONObject) {
  162.             value = (net.minidev.json.JSONObject) valueParam;
  163.         }
  164.         else if(valueParam instanceof String) {
  165.             try {
  166.                 value = JsonPathExpressionEngine.getJSONObject((String)valueParam);
  167.             }catch(Exception e) {
  168.                 throw new MessageException(e.getMessage(),e);
  169.             }
  170.         }
  171.         else if(valueParam instanceof JsonNode) {
  172.             try {
  173.                 value = JsonPathExpressionEngine.getJSONObject((JsonNode)valueParam);
  174.             }catch(Exception e) {
  175.                 throw new MessageException(e.getMessage(),e);
  176.             }
  177.         }
  178.         else if(valueParam instanceof InputStream) {
  179.             try {
  180.                 value = JsonPathExpressionEngine.getJSONObject((InputStream)valueParam);
  181.             }catch(Exception e) {
  182.                 throw new MessageException(e.getMessage(),e);
  183.             }
  184.         }
  185.         else {
  186.             throw new MessageException("Unsupported type '"+valueParam.getClass().getName()+"'");
  187.         }
  188.         return value;
  189.     }
  190.    
  191.     @Override
  192.     public void addArrayElement(String name, Object value) throws MessageException,MessageNotSupportedException{
  193.         this._processJsonField(true, null, name, toJSONArray(value), true, false, false);
  194.     }
  195.     @Override
  196.     public void addArrayElement(String jsonPath, String name, Object value) throws MessageException,MessageNotSupportedException{
  197.         this._processJsonField(false, jsonPath, name, toJSONArray(value), true, false, false);
  198.     }
  199.     private net.minidev.json.JSONArray toJSONArray(Object valueParam) throws MessageException {
  200.         net.minidev.json.JSONArray value = null;
  201.         if(valueParam instanceof net.minidev.json.JSONArray) {
  202.             value = (net.minidev.json.JSONArray) valueParam;
  203.         }
  204.         else if(valueParam instanceof String) {
  205.             try {
  206.                 value = JsonPathExpressionEngine.getJSONArray((String)valueParam);
  207.             }catch(Exception e) {
  208.                 throw new MessageException(e.getMessage(),e);
  209.             }
  210.         }
  211.         else if(valueParam instanceof JsonNode) {
  212.             try {
  213.                 value = JsonPathExpressionEngine.getJSONArray((JsonNode)valueParam);
  214.             }catch(Exception e) {
  215.                 throw new MessageException(e.getMessage(),e);
  216.             }
  217.         }
  218.         else if(valueParam instanceof InputStream) {
  219.             try {
  220.                 value = JsonPathExpressionEngine.getJSONArray((InputStream)valueParam);
  221.             }catch(Exception e) {
  222.                 throw new MessageException(e.getMessage(),e);
  223.             }
  224.         }
  225.         else {
  226.             throw new MessageException("Unsupported type '"+valueParam.getClass().getName()+"'");
  227.         }
  228.         return value;
  229.     }

  230.     @Override
  231.     public void removeElement(String name) throws MessageException,MessageNotSupportedException{
  232.         this._processJsonField(true, null, name, null, false, true, false);
  233.     }
  234.     @Override
  235.     public void removeElement(String jsonPath, String name) throws MessageException,MessageNotSupportedException{
  236.         this._processJsonField(false, jsonPath, name, null, false, true, false);
  237.     }
  238.    
  239.     @Override
  240.     public void replaceValue(String name, Object value) throws MessageException,MessageNotSupportedException{
  241.         this._processJsonField(true, null, name, value, false, false, true);
  242.     }
  243.     @Override
  244.     public void replaceValue(String jsonPath, String name, Object value) throws MessageException,MessageNotSupportedException{
  245.         this._processJsonField(false, jsonPath, name, value, false, false, true);
  246.     }
  247.    
  248.     private void _processJsonField(boolean rootElement, String jsonPath, String name, Object value, boolean add, boolean remove, boolean replaceValue) throws MessageException {
  249.         try {
  250.             if(!this.hasContent()) {
  251.                 return;
  252.             }
  253.             JsonPathExpressionEngine engine = new JsonPathExpressionEngine();
  254.             JSONObject rootObject = JsonPathExpressionEngine.getJSONObject(this.getContent());
  255.             Object o = rootObject;
  256.             if(!rootElement) {
  257.                 if(jsonPath==null) {
  258.                     throw new Exception("JsonPath undefined");
  259.                 }
  260.                 o = engine.getMatchPattern(rootObject, jsonPath, JsonPathReturnType.JSON_PATH_OBJECT);
  261.             }
  262.             if(o instanceof net.minidev.json.JSONObject) {
  263.                 net.minidev.json.JSONObject oNode = (net.minidev.json.JSONObject) o;
  264.                 if(add) {
  265.                     oNode.appendField(name, value);
  266.                 }
  267.                 else if(replaceValue) {
  268.                     oNode.remove(name);
  269.                     oNode.appendField(name, value);
  270.                 }
  271.                 else {
  272.                     oNode.remove(name);
  273.                 }
  274.             }
  275.             else if(o instanceof net.minidev.json.JSONArray){
  276.                 net.minidev.json.JSONArray arrayNode = (net.minidev.json.JSONArray) o;
  277.                 if(arrayNode.size()>0) {
  278.                     for (int i = 0; i < arrayNode.size(); i++) {
  279.                         Object oNodeArray = arrayNode.get(i);
  280.                         if(oNodeArray instanceof net.minidev.json.JSONObject) {
  281.                             net.minidev.json.JSONObject oNode = (net.minidev.json.JSONObject) oNodeArray;
  282.                             if(add) {
  283.                                 oNode.appendField(name, value);
  284.                             }
  285.                             else if(replaceValue) {
  286.                                 oNode.remove(name);
  287.                                 oNode.appendField(name, value);
  288.                             }
  289.                             else {
  290.                                 oNode.remove(name);
  291.                             }
  292.                         }
  293.                         else {
  294.                             throw new Exception("Tipo dell'oggetto individuato tramite jsonPath (posizione array '"+i+"') non consente l'operazione richiesta: "+oNodeArray.getClass().getName());
  295.                         }
  296.                     }
  297.                 }
  298.             }
  299.             else {
  300.                 throw new Exception("Tipo dell'oggetto individuato tramite jsonPath non consente l'operazione richiesta: "+o.getClass().getName());
  301.             }
  302.             this.updateContent(rootObject.toJSONString(JSONStyle.NO_COMPRESS));
  303.         }catch(Exception e) {
  304.             throw new MessageException("Operazione fallita (pattern: "+jsonPath+"): "+e.getMessage(),e);
  305.         }
  306.     }
  307. }