JsonPathExpressionEngine.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.utils.json;

  21. import java.io.InputStream;
  22. import java.io.UnsupportedEncodingException;
  23. import java.util.ArrayList;
  24. import java.util.List;
  25. import java.util.Map;

  26. import org.openspcoop2.utils.UtilsException;
  27. import org.slf4j.Logger;

  28. import com.fasterxml.jackson.databind.JsonNode;
  29. import com.fasterxml.jackson.databind.node.TextNode;
  30. import com.jayway.jsonpath.JsonPath;
  31. import com.jayway.jsonpath.spi.cache.CacheProvider;
  32. import com.jayway.jsonpath.spi.cache.NOOPCache;

  33. import net.minidev.json.JSONArray;
  34. import net.minidev.json.JSONObject;
  35. import net.minidev.json.parser.JSONParser;
  36. import net.minidev.json.parser.ParseException;

  37. /**
  38.  * PathExpressionEngine
  39.  *
  40.  * @author Poli Andrea (apoli@link.it)
  41.  * @author $Author$
  42.  * @version $Rev$, $Date$
  43.  */
  44. public class JsonPathExpressionEngine {

  45.     public static void disableCacheJsonPathEngine() {
  46.         CacheProvider.setCache(new NOOPCache());
  47.     }
  48.    
  49.     public static String getAsString(JsonNode element) {
  50.         try{
  51.             return getJsonUtils().toString(element);
  52.         }catch(Exception e){
  53.             return null;
  54.         }
  55.     }

  56.     private static JSONUtils jsonUtils;
  57.     public static synchronized void initJsonUtils() throws UtilsException {
  58.         if(jsonUtils == null) {
  59.             jsonUtils = JSONUtils.getInstance();
  60.         }
  61.     }
  62.     public static JSONUtils getJsonUtils() throws UtilsException {
  63.         if(jsonUtils == null) {
  64.             initJsonUtils();
  65.         }
  66.         return jsonUtils;
  67.     }
  68.    
  69.    
  70.     public static JSONObject getJSONObject(InputStream is) throws JsonPathException {
  71.         if(is == null)
  72.             throw new JsonPathException("Document (InputStream) is null");

  73.         try {
  74.             return getJSONParser().parse(is, JSONObject.class);
  75.         } catch (UnsupportedEncodingException e) {
  76.             throw new JsonPathException(e.getMessage(), e);
  77.         } catch (ParseException e) {
  78.             throw new JsonPathException(e.getMessage(), e);
  79.         }
  80.     }
  81.     public static JSONArray getJSONArray(InputStream is) throws JsonPathException {
  82.         if(is == null)
  83.             throw new JsonPathException("Document (InputStream) is null");

  84.         try {
  85.             return getJSONParser().parse(is, JSONArray.class);
  86.         } catch (UnsupportedEncodingException e) {
  87.             throw new JsonPathException(e.getMessage(), e);
  88.         } catch (ParseException e) {
  89.             throw new JsonPathException(e.getMessage(), e);
  90.         }
  91.     }

  92.     public static JSONObject getJSONObject(String contenuto) throws JsonPathException {
  93.         if(contenuto == null)
  94.             throw new JsonPathException("Document (String) is null");

  95.         try {
  96.             return getJSONParser().parse(contenuto, JSONObject.class);
  97.         } catch (ParseException e) {
  98.             throw new JsonPathException(e.getMessage(), e);
  99.         }
  100.     }
  101.     public static JSONArray getJSONArray(String contenuto) throws JsonPathException {
  102.         if(contenuto == null)
  103.             throw new JsonPathException("Document (String) is null");

  104.         try {
  105.             return getJSONParser().parse(contenuto, JSONArray.class);
  106.         } catch (ParseException e) {
  107.             throw new JsonPathException(e.getMessage(), e);
  108.         }
  109.     }

  110.     public static JSONObject getJSONObject(JsonNode document) throws JsonPathException {
  111.         if(document == null)
  112.             throw new JsonPathException("Document (JsonNode) is null");

  113.         try {
  114.             return getJSONParser().parse(getAsString(document), JSONObject.class);
  115.         } catch (ParseException e) {
  116.             throw new JsonPathException(e.getMessage(), e);
  117.         }
  118.     }
  119.     public static JSONArray getJSONArray(JsonNode document) throws JsonPathException {
  120.         if(document == null)
  121.             throw new JsonPathException("Document (JsonNode) is null");

  122.         try {
  123.             return getJSONParser().parse(getAsString(document), JSONArray.class);
  124.         } catch (ParseException e) {
  125.             throw new JsonPathException(e.getMessage(), e);
  126.         }
  127.     }


  128.     // Bug: JSONParser is not thread safe!
  129. //  private static JSONParser jsonParser;
  130. //  public static synchronized void initJSONParser() {
  131. //      if(jsonParser == null) {
  132. //          jsonParser = new JSONParser(JSONParser.MODE_PERMISSIVE);
  133. //      }
  134. //  }
  135.     public static JSONParser getJSONParser() {
  136. //      if(jsonParser == null) {
  137. //          initJSONParser();
  138. //      }
  139. //      return jsonParser;
  140.         return new JSONParser(JSONParser.MODE_PERMISSIVE);
  141.     }

  142.     /* ---------- METODI RITORNANO STRINGHE -------------- */
  143.    
  144.     public List<String> getStringMatchPattern(JSONObject input, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  145.         if(input == null)
  146.             throw new JsonPathException("Document (JSONObject) is null");

  147.         if(pattern == null)
  148.             throw new JsonPathException("Pattern is null");

  149.         this.validate(pattern);
  150.        
  151.         try {
  152.             List<String> l = new ArrayList<>();
  153.             Object o = JsonPath.read(input, pattern);
  154.             _parseStringMatchPatternResult(o, l);
  155.             if(l==null || l.size()<=0) {
  156.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  157.             }
  158.             return l;
  159.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  160.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  161.         } catch(Exception e) {
  162.             throw new JsonPathException(e.getMessage(), e);
  163.         }
  164.     }

  165.     public List<String> getStringMatchPattern(JsonNode document, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  166.        
  167.         if(document == null)
  168.                 throw new JsonPathException("Document (JsonNode) is null");

  169.         if(pattern == null)
  170.             throw new JsonPathException("Pattern is null");

  171.         this.validate(pattern);
  172.        
  173.         try {
  174.             List<String> l = new ArrayList<>();
  175.             Object o = JsonPath.read(getAsString(document), pattern);
  176.             _parseStringMatchPatternResult(o, l);
  177.             if(l==null || l.size()<=0) {
  178.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  179.             }
  180.             return l;
  181.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  182.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  183.         } catch(Exception e) {
  184.             throw new JsonPathException(e.getMessage(), e);
  185.         }
  186.     }
  187.    
  188.     public List<String> getStringMatchPattern(InputStream is, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  189.         if(is == null)
  190.             throw new JsonPathException("Document (InputStream) is null");

  191.         if(pattern == null)
  192.             throw new JsonPathException("Pattern is null");

  193.         this.validate(pattern);
  194.        
  195.         try {
  196.             List<String> l = new ArrayList<>();
  197.             Object o = JsonPath.read(is, pattern);
  198.             _parseStringMatchPatternResult(o, l);
  199.             if(l==null || l.size()<=0) {
  200.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  201.             }
  202.             return l;
  203.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  204.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  205.         } catch(Exception e) {
  206.             throw new JsonPathException(e.getMessage(), e);
  207.         }
  208.     }
  209.    
  210.     public List<String> getStringMatchPattern(String contenuto, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  211.         if(contenuto == null)
  212.             throw new JsonPathException("Document (String) is null");

  213.         if(pattern == null)
  214.             throw new JsonPathException("Pattern is null");

  215.         this.validate(pattern);
  216.        
  217.         try {
  218.             List<String> l = new ArrayList<>();
  219.             Object o = JsonPath.read(contenuto, pattern);
  220.             _parseStringMatchPatternResult(o, l);
  221.             if(l==null || l.size()<=0) {
  222.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  223.             }
  224.             return l;
  225.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  226.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  227.         } catch(Exception e) {
  228.             throw new JsonPathException(e.getMessage(), e);
  229.         }
  230.     }
  231.     private void _parseStringMatchPatternResult(Object o, List<String> l) throws Exception {
  232.         if(o!=null) {
  233.             if(o instanceof Map<?, ?>) {
  234.                 // Lasciare questo if per formattare correttamente i nomi degli elementi tramite le utility (vedi test org.openspcoop2.pdd.core.trasformazioni.Test)
  235.                 throw new Exception("Unexpected type '"+o.getClass().getName()+"' (is instanceof Map)");
  236.             }
  237.             else if(o instanceof List) {
  238.                 List<?> lO = (List<?>) o;
  239.                 if(!lO.isEmpty()) {
  240.                     int position = 0;
  241.                     for (Object object : lO) {
  242.                         if(object!=null) {
  243.                             if(object instanceof String) {
  244.                                 l.add((String)object);
  245.                             }
  246.                             else if(object instanceof Number) {
  247.                                 l.add(object.toString());
  248.                             }
  249.                             else if(object instanceof Boolean) {
  250.                                 l.add(object.toString());
  251.                             }
  252.                             else{
  253.                                 throw new Exception("Unexpected type '"+object.getClass().getName()+"' at position "+position);
  254.                             }
  255.                         }
  256.                         position++;
  257.                     }
  258.                 }
  259.             }
  260.             else if(o instanceof String) {
  261.                 l.add((String)o);
  262.             }
  263.             else if(o instanceof Number) {
  264.                 l.add(o.toString());
  265.             }
  266.             else if(o instanceof Boolean) {
  267.                 l.add(o.toString());
  268.             }
  269.             else {
  270.                 throw new Exception("Unexpected type '"+o.getClass().getName()+"'");
  271.             }
  272.         }
  273.     }
  274.    
  275.    
  276.     /* ---------- METODI RITORNANO NUMBER -------------- */

  277.     public List<Number> getNumberMatchPattern(JSONObject input, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  278.         if(input == null)
  279.             throw new JsonPathException("Document (JSONObject) is null");

  280.         if(pattern == null)
  281.             throw new JsonPathException("Pattern is null");

  282.         this.validate(pattern);
  283.        
  284.         try {
  285.             List<Number> l = new ArrayList<Number>();
  286.             Object o = JsonPath.read(input, pattern);
  287.             _parseNumberMatchPatternResult(o, l);
  288.             if(l==null || l.size()<=0) {
  289.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  290.             }
  291.             return l;
  292.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  293.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  294.         } catch(Exception e) {
  295.             throw new JsonPathException(e.getMessage(), e);
  296.         }
  297.     }

  298.     public List<Number> getNumberMatchPattern(JsonNode document, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  299.         if(document == null)
  300.             throw new JsonPathException("Document (JsonNode) is null");

  301.         if(pattern == null)
  302.             throw new JsonPathException("Pattern is null");

  303.         this.validate(pattern);
  304.        
  305.         try {
  306.             List<Number> l = new ArrayList<Number>();
  307.             Object o = JsonPath.read(getAsString(document), pattern);
  308.             _parseNumberMatchPatternResult(o, l);
  309.             if(l==null || l.size()<=0) {
  310.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  311.             }
  312.             return l;
  313.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  314.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  315.         } catch(Exception e) {
  316.             throw new JsonPathException(e.getMessage(), e);
  317.         }
  318.     }
  319.    
  320.     public List<Number> getNumberMatchPattern(InputStream is, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  321.         if(is == null)
  322.             throw new JsonPathException("Document (InputStream) is null");

  323.         if(pattern == null)
  324.             throw new JsonPathException("Pattern is null");

  325.         this.validate(pattern);
  326.        
  327.         try {
  328.             List<Number> l = new ArrayList<Number>();
  329.             Object o = JsonPath.read(is, pattern);
  330.             _parseNumberMatchPatternResult(o, l);
  331.             if(l==null || l.size()<=0) {
  332.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  333.             }
  334.             return l;
  335.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  336.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  337.         } catch(Exception e) {
  338.             throw new JsonPathException(e.getMessage(), e);
  339.         }
  340.     }
  341.    
  342.     public List<Number> getNumberMatchPattern(String contenuto, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  343.         if(contenuto == null)
  344.             throw new JsonPathException("Document (String) is null");

  345.         if(pattern == null)
  346.             throw new JsonPathException("Pattern is null");

  347.         this.validate(pattern);
  348.        
  349.         try {
  350.             List<Number> l = new ArrayList<Number>();
  351.             Object o = JsonPath.read(contenuto, pattern);
  352.             _parseNumberMatchPatternResult(o, l);
  353.             if(l==null || l.size()<=0) {
  354.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  355.             }
  356.             return l;
  357.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  358.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  359.         }catch(Exception e) {
  360.             throw new JsonPathException(e.getMessage(), e);
  361.         }
  362.     }
  363.    
  364.     private void _parseNumberMatchPatternResult(Object o, List<Number> l) throws Exception {
  365.         if(o!=null) {
  366.             if(o instanceof List) {
  367.                 List<?> lO = (List<?>) o;
  368.                 if(!lO.isEmpty()) {
  369.                     int position = 0;
  370.                     for (Object object : lO) {
  371.                         if(object!=null) {
  372.                             if(object instanceof Number) {
  373.                                 l.add((Number)object);
  374.                             }
  375.                             else{
  376.                                 throw new Exception("Unexpected type '"+object.getClass().getName()+"' at position "+position);
  377.                             }
  378.                         }
  379.                         position++;
  380.                     }
  381.                 }
  382.             }
  383.             else if(o instanceof Number) {
  384.                 l.add((Number)o);
  385.             }
  386.             else {
  387.                 throw new Exception("Unexpected type '"+o.getClass().getName()+"'");
  388.             }
  389.         }
  390.     }
  391.    

  392.     /* ---------- METODI RITORNANO BOOLEAN -------------- */

  393.     public List<Boolean> getBooleanMatchPattern(JSONObject input, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  394.         if(input == null)
  395.             throw new JsonPathException("Document (JSONObject) is null");

  396.         if(pattern == null)
  397.             throw new JsonPathException("Pattern is null");

  398.         this.validate(pattern);
  399.        
  400.         try {
  401.             List<Boolean> l = new ArrayList<Boolean>();
  402.             Object o = JsonPath.read(input, pattern);
  403.             _parseBooleanMatchPatternResult(o, l);
  404.             if(l==null || l.size()<=0) {
  405.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  406.             }
  407.             return l;
  408.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  409.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  410.         }catch(Exception e) {
  411.             throw new JsonPathException(e.getMessage(), e);
  412.         }
  413.        
  414.     }

  415.     public List<Boolean> getBooleanMatchPattern(JsonNode document, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  416.         if(document == null)
  417.             throw new JsonPathException("Document (JsonNode) is null");

  418.         if(pattern == null)
  419.             throw new JsonPathException("Pattern is null");

  420.         this.validate(pattern);
  421.        
  422.         try {
  423.             List<Boolean> l = new ArrayList<Boolean>();
  424.             Object o = JsonPath.read(getAsString(document), pattern);
  425.             _parseBooleanMatchPatternResult(o, l);
  426.             if(l==null || l.size()<=0) {
  427.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  428.             }
  429.             return l;
  430.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  431.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  432.         }catch(Exception e) {
  433.             throw new JsonPathException(e.getMessage(), e);
  434.         }
  435.     }
  436.    
  437.     public List<Boolean> getBooleanMatchPattern(InputStream is, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  438.         if(is == null)
  439.             throw new JsonPathException("Document (InputStream) is null");

  440.         if(pattern == null)
  441.             throw new JsonPathException("Pattern is null");

  442.         this.validate(pattern);
  443.        
  444.         try {
  445.             List<Boolean> l = new ArrayList<Boolean>();
  446.             Object o = JsonPath.read(is, pattern);
  447.             _parseBooleanMatchPatternResult(o, l);
  448.             if(l==null || l.size()<=0) {
  449.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  450.             }
  451.             return l;
  452.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  453.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  454.         } catch(Exception e) {
  455.             throw new JsonPathException(e.getMessage(), e);
  456.         }
  457.     }
  458.    
  459.     public List<Boolean> getBooleanMatchPattern(String contenuto, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  460.         if(contenuto == null)
  461.             throw new JsonPathException("Document (String) is null");

  462.         if(pattern == null)
  463.             throw new JsonPathException("Pattern is null");

  464.         this.validate(pattern);
  465.        
  466.         try {
  467.             List<Boolean> l = new ArrayList<Boolean>();
  468.             Object o = JsonPath.read(contenuto, pattern);
  469.             _parseBooleanMatchPatternResult(o, l);
  470.             if(l==null || l.size()<=0) {
  471.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  472.             }
  473.             return l;
  474.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  475.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  476.         }catch(Exception e) {
  477.             throw new JsonPathException(e.getMessage(), e);
  478.         }
  479.     }
  480.    
  481.     private void _parseBooleanMatchPatternResult(Object o, List<Boolean> l) throws Exception {
  482.         if(o!=null) {
  483.             if(o instanceof List) {
  484.                 List<?> lO = (List<?>) o;
  485.                 if(!lO.isEmpty()) {
  486.                     int position = 0;
  487.                     for (Object object : lO) {
  488.                         if(object!=null) {
  489.                             if(object instanceof Boolean) {
  490.                                 l.add((Boolean)object);
  491.                             }
  492.                             else{
  493.                                 throw new Exception("Unexpected type '"+object.getClass().getName()+"' at position "+position);
  494.                             }
  495.                         }
  496.                         position++;
  497.                     }
  498.                 }
  499.             }
  500.             else if(o instanceof Boolean) {
  501.                 l.add((Boolean)o);
  502.             }
  503.             else {
  504.                 throw new Exception("Unexpected type '"+o.getClass().getName()+"'");
  505.             }
  506.         }
  507.     }
  508.    

  509.     /* ---------- METODI RITORNANO JSON NODE -------------- */

  510.     public JsonNode getJsonNodeMatchPattern(JSONObject input, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  511.         if(input == null)
  512.             throw new JsonPathException("Document (JSONObject) is null");

  513.         if(pattern == null)
  514.             throw new JsonPathException("Pattern is null");

  515.         this.validate(pattern);
  516.        
  517.         try {
  518.             Object object = JsonPath.read(input, pattern);
  519.             if(object==null) {
  520.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  521.             }
  522.             return this.convertToJsonNode(object);
  523.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  524.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  525.         }catch(Exception e) {
  526.             throw new JsonPathException(e.getMessage(), e);
  527.         }
  528.     }

  529.     public JsonNode getJsonNodeMatchPattern(JsonNode document, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  530.         if(document == null)
  531.             throw new JsonPathException("Document (JsonNode) is null");

  532.         if(pattern == null)
  533.             throw new JsonPathException("Pattern is null");
  534.        
  535.         this.validate(pattern);
  536.        
  537.         try {
  538.             String inputString = getAsString(document);
  539.             Object object = JsonPath.read(inputString, pattern);
  540.             if(object==null) {
  541.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  542.             }
  543.             return this.convertToJsonNode(object);
  544.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  545.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  546.         }catch(Exception e) {
  547.             throw new JsonPathException(e.getMessage(), e);
  548.         }
  549.     }
  550.    
  551.     public JsonNode getJsonNodeMatchPattern(InputStream is, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  552.         if(is == null)
  553.             throw new JsonPathException("Document (InputStream) is null");

  554.         if(pattern == null)
  555.             throw new JsonPathException("Pattern is null");
  556.        
  557.         this.validate(pattern);
  558.        
  559.         try {
  560.             Object object = JsonPath.read(is, pattern);
  561.             if(object==null) {
  562.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  563.             }
  564.             return this.convertToJsonNode(object);
  565.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  566.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  567.         }catch(Exception e) {
  568.             throw new JsonPathException(e.getMessage(), e);
  569.         }
  570.     }
  571.    
  572.     public JsonNode getJsonNodeMatchPattern(String contenuto, String pattern) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  573.         if(contenuto == null)
  574.             throw new JsonPathException("Document (String) is null");

  575.         if(pattern == null)
  576.             throw new JsonPathException("Pattern is null");

  577.         this.validate(pattern);
  578.        
  579.         try {
  580.             Object object = JsonPath.read(contenuto, pattern);
  581.             if(object==null) {
  582.                 throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  583.             }
  584.             return this.convertToJsonNode(object);
  585.         }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  586.             throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  587.         }catch(Exception e) {
  588.             throw new JsonPathException(e.getMessage(), e);
  589.         }

  590.     }
  591.     private JsonNode convertToJsonNode(Object object) throws UtilsException {
  592.         if(object instanceof String) {
  593.             return getJsonUtils().getAsNode("\""+((String) object)+"\"");
  594.         }
  595.         else  if(object instanceof JSONArray) {
  596.             JSONArray jsonObject = (JSONArray) object;
  597.             return getJsonUtils().getAsNode(jsonObject.toString());
  598.         }
  599.         else if(object instanceof JSONObject) {
  600.             JSONObject jsonObject = (JSONObject) object;
  601.             return getJsonUtils().getAsNode(jsonObject.toString());
  602.         }
  603.         else if(object instanceof Map<?, ?>) {
  604.             Map<?, ?> map = (Map<?, ?>) object;
  605.             return getJsonUtils().getAsNode(map);
  606.         }
  607.         else {
  608.             return getJsonUtils().getAsNode(object.toString());
  609.         }
  610.     }
  611.    

  612.     /* ---------- METODI RITORNANO OGGETTI -------------- */

  613.     public Object getMatchPattern(JSONObject input, String pattern, JsonPathReturnType returnType) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  614.         if(input == null)
  615.             throw new JsonPathException("Document (JSONObject)is null");

  616.         if(pattern == null)
  617.             throw new JsonPathException("Pattern is null");

  618.         this.validate(pattern);
  619.        
  620.         if(returnType == null)
  621.             throw new JsonPathException("JsonPathReturnType is null");

  622.         Object risposta = null;
  623.         switch(returnType) {
  624.         case STRING:
  625.             risposta = getStringMatchPattern(input, pattern);
  626.             break;
  627.         case NUMBER:
  628.             risposta = getNumberMatchPattern(input, pattern);
  629.             break;
  630.         case BOOLEAN:
  631.             risposta = getBooleanMatchPattern(input, pattern);
  632.             break;
  633.         case NODE:
  634.             risposta = getJsonNodeMatchPattern(input, pattern);
  635.             break;
  636.         default:
  637.             try {
  638.                 risposta = JsonPath.read(input, pattern);
  639.             }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  640.                 throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  641.             }
  642.             break;
  643.         }
  644.         if(risposta==null) {
  645.             throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  646.         }
  647.         return risposta;
  648.     }
  649.    

  650.     public Object getMatchPattern(JsonNode input, String pattern, JsonPathReturnType returnType) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  651.         if(input == null)
  652.             throw new JsonPathException("Document (JsonNode)is null");

  653.         if(pattern == null)
  654.             throw new JsonPathException("Pattern is null");

  655.         this.validate(pattern);
  656.        
  657.         if(returnType == null)
  658.             throw new JsonPathException("JsonPathReturnType is null");

  659.         Object risposta = null;
  660.         String inputString = getAsString(input);
  661.         switch(returnType) {
  662.         case STRING:
  663.             risposta = getStringMatchPattern(inputString, pattern);
  664.             break;
  665.         case NUMBER:
  666.             risposta = getNumberMatchPattern(inputString, pattern);
  667.             break;
  668.         case BOOLEAN:
  669.             risposta = getBooleanMatchPattern(inputString, pattern);
  670.             break;
  671.         case NODE:
  672.             risposta = getJsonNodeMatchPattern(inputString, pattern);
  673.             break;
  674.         default:
  675.             try {
  676.                 risposta = JsonPath.read(input, pattern);
  677.             }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  678.                 throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  679.             }
  680.             break;
  681.         }
  682.         if(risposta==null) {
  683.             throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  684.         }
  685.         return risposta;
  686.     }
  687.    
  688.     public Object getMatchPattern(InputStream input, String pattern, JsonPathReturnType returnType)throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  689.         if(input == null)
  690.             throw new JsonPathException("Document (InputStream) is null");

  691.         if(pattern == null)
  692.             throw new JsonPathException("Pattern is null");

  693.         this.validate(pattern);
  694.        
  695.         if(returnType == null)
  696.             throw new JsonPathException("JsonPathReturnType is null");

  697.         Object risposta = null;
  698.         switch(returnType) {
  699.         case STRING:
  700.             risposta = getStringMatchPattern(input, pattern);
  701.             break;
  702.         case NUMBER:
  703.             risposta = getNumberMatchPattern(input, pattern);
  704.             break;
  705.         case BOOLEAN:
  706.             risposta = getBooleanMatchPattern(input, pattern);
  707.             break;
  708.         case NODE:
  709.             risposta = getJsonNodeMatchPattern(input, pattern);
  710.             break;
  711.         default:
  712.             try {
  713.                 risposta = JsonPath.read(input, pattern);
  714.             }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  715.                 throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  716.             }catch(Exception e) {
  717.                 throw new JsonPathException(e.getMessage(), e);
  718.             }
  719.             break;
  720.         }
  721.         if(risposta==null) {
  722.             throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  723.         }
  724.         return risposta;
  725.     }
  726.    
  727.     public Object getMatchPattern(String input, String pattern, JsonPathReturnType returnType) throws JsonPathException, JsonPathNotFoundException, JsonPathNotValidException {
  728.         if(input == null)
  729.             throw new JsonPathException("Document (String) is null");
  730.        
  731.         if(pattern == null)
  732.             throw new JsonPathException("Pattern is null");

  733.         this.validate(pattern);
  734.        
  735.         if(returnType == null)
  736.             throw new JsonPathException("JsonPathReturnType is null");

  737.         Object risposta = null;
  738.         switch(returnType) {
  739.         case STRING:
  740.             risposta = getStringMatchPattern(input, pattern);
  741.             break;
  742.         case NUMBER:
  743.             risposta = getNumberMatchPattern(input, pattern);
  744.             break;
  745.         case BOOLEAN:
  746.             risposta = getBooleanMatchPattern(input, pattern);
  747.             break;
  748.         case NODE:
  749.             risposta = getJsonNodeMatchPattern(input, pattern);
  750.             break;
  751.         default:
  752.             try {
  753.                 risposta = JsonPath.read(input, pattern);
  754.             }catch(com.jayway.jsonpath.PathNotFoundException notFound) {
  755.                 throw new JsonPathNotFoundException(notFound.getMessage(),notFound);
  756.             }
  757.             break;
  758.         }
  759.         if(risposta==null) {
  760.             throw new com.jayway.jsonpath.PathNotFoundException("Nessun match trovato per l'espressione jsonPath ["+pattern+"]");
  761.         }
  762.         return risposta;
  763.     }
  764.    
  765.    
  766.     /* ---------- VALIDATORE -------------- */
  767.    
  768.     public void validate(String path) throws JsonPathNotValidException{
  769.         try {
  770.             JsonPath.compile(path);
  771.         } catch(Exception e) {
  772.             throw new JsonPathNotValidException("Validazione del jsonPath indicato ["+path+"] fallita: "+e.getMessage(),e);
  773.         }
  774.     }

  775.    
  776.     public static String extractAndConvertResultAsString(String elementJson, String pattern, Logger log) throws Exception {
  777.         List<String> l = _extractAndConvertResultAsString(elementJson, pattern, log, false);
  778.         if(l!=null && !l.isEmpty()) {
  779.             return l.get(0);
  780.         }
  781.         else {
  782.             return null;
  783.         }
  784.     }
  785.     public static List<String> extractAndConvertResultAsList(String elementJson, String pattern, Logger log) throws Exception {
  786.         return  _extractAndConvertResultAsString(elementJson, pattern, log, true);
  787.     }
  788.     private static List<String> _extractAndConvertResultAsString(String elementJson, String pattern, Logger log, boolean returnAsList) throws Exception {
  789.        
  790.         List<String> lReturn = new ArrayList<>();
  791.        
  792.         JsonPathExpressionEngine engine = new JsonPathExpressionEngine();
  793.        
  794.         Exception exceptionNodeSet = null;
  795.         try{
  796.             List<?> l = engine.getStringMatchPattern(elementJson, pattern);
  797.             if(l!=null && l.size()>0) {
  798.                 if(returnAsList) {
  799.                     for (Object s : l) {
  800.                         if(s instanceof String) {
  801.                             lReturn.add((String)s);
  802.                         }
  803.                         else if(s instanceof Map<?, ?>) {
  804.                             try {
  805.                                 Map<?,?> map = (Map<?,?>) s;
  806.                                 if(!map.isEmpty()) {
  807.                                     StringBuilder sb = new StringBuilder("{");
  808.                                     for (Object keyO : map.keySet()) {
  809.                                         if(sb.length()>1) {
  810.                                             sb.append(",");
  811.                                         }
  812.                                         //System.out.println("KEY '"+keyO+"' ("+keyO.getClass().getName()+")");
  813.                                         String key = (String) keyO;
  814.                                         sb.append("\"").append(key).append("\": ");
  815.                                         Object valueO = map.get(keyO);
  816.                                         if(valueO instanceof Boolean ||
  817.                                                 valueO instanceof Short ||
  818.                                                 valueO instanceof Integer ||
  819.                                                 valueO instanceof Long ||
  820.                                                 valueO instanceof Double ||
  821.                                                 valueO instanceof Float) {
  822.                                             sb.append(valueO);
  823.                                         }
  824.                                         else {
  825.                                             sb.append("\"").append(valueO).append("\"");
  826.                                         }
  827.                                     }
  828.                                     sb.append("}");
  829.                                     lReturn.add(sb.toString());
  830.                                 }
  831.                             }catch(Throwable t) {
  832.                                 lReturn.add(s.toString());
  833.                             }
  834.                         }
  835.                         else {
  836.                             lReturn.add(s.toString());
  837.                         }
  838.                     }
  839.                 }
  840.                 else {
  841.                     StringBuilder sbReturn = new StringBuilder();
  842. //                  if(l instanceof net.minidev.json.JSONArray) {
  843. //                      sbReturn.append("[");
  844. //                  }
  845.                    
  846.                     boolean first = true;
  847.                     for (Object s : l) {
  848.                         if(!first) {
  849.                             sbReturn.append(",");  
  850.                         }
  851.                         if(s instanceof String) {
  852.                             sbReturn.append((String)s);
  853.                         }
  854.                         else if(s instanceof Map<?, ?>) {
  855.                             try {
  856.                                 Map<?,?> map = (Map<?,?>) s;
  857.                                 if(!map.isEmpty()) {
  858.                                     StringBuilder sb = new StringBuilder("{");
  859.                                     for (Object keyO : map.keySet()) {
  860.                                         if(sb.length()>1) {
  861.                                             sb.append(",");
  862.                                         }
  863.                                         //System.out.println("KEY '"+keyO+"' ("+keyO.getClass().getName()+")");
  864.                                         String key = (String) keyO;
  865.                                         sb.append("\"").append(key).append("\": ");
  866.                                         Object valueO = map.get(keyO);
  867.                                         if(valueO instanceof Boolean ||
  868.                                                 valueO instanceof Short ||
  869.                                                 valueO instanceof Integer ||
  870.                                                 valueO instanceof Long ||
  871.                                                 valueO instanceof Double ||
  872.                                                 valueO instanceof Float) {
  873.                                             sb.append(valueO);
  874.                                         }
  875.                                         else {
  876.                                             sb.append("\"").append(valueO).append("\"");
  877.                                         }
  878.                                     }
  879.                                     sb.append("}");
  880.                                     sbReturn.append(sb.toString());
  881.                                 }
  882.                             }catch(Throwable t) {
  883.                                 sbReturn.append(s.toString());
  884.                             }
  885.                         }
  886.                         else {
  887.                             sbReturn.append(s.toString());
  888.                         }
  889.                         first=false;
  890.                     }
  891.                    
  892. //                  if(l instanceof net.minidev.json.JSONArray) {
  893. //                      sbReturn.append("]");
  894. //                  }
  895.                     lReturn.add(sbReturn.toString());
  896.                 }
  897.             }
  898.                        
  899.         }catch(Exception e){
  900.             exceptionNodeSet = e;
  901.         }
  902.            
  903.         if(lReturn.isEmpty()){
  904.            
  905.             JsonNode obj = engine.getJsonNodeMatchPattern(elementJson, pattern);
  906.             String risultato = null;
  907.             if(obj!=null) {
  908.                 if(obj instanceof TextNode) {
  909.                     TextNode text = (TextNode) obj;
  910.                     risultato = text.asText();
  911.                 }
  912.                 else {
  913.                     risultato = obj.toString();
  914.                 }
  915.             }
  916.             if(risultato!=null && risultato.startsWith("[") && risultato.endsWith("]")) {
  917.                 risultato = risultato.substring(1, risultato.length()-1);
  918.             }
  919.             if(risultato!=null && !"".equals(risultato)) {
  920.                 lReturn.add(risultato);
  921.             }
  922.            
  923.             if(exceptionNodeSet!=null){
  924.                 log.debug("Non sono stati trovati risultati tramite l'invocazione del metodo getStringMatchPattern("+pattern
  925.                         +") invocato in seguito all'errore dell'invocazione getJsonNodeMatchPattern("+
  926.                         pattern+",NODESET): "+exceptionNodeSet.getMessage(),exceptionNodeSet);
  927.                 // lancio questo errore.
  928.                 // Questo errore puo' avvenire perche' ho provato a fare xpath con nodeset
  929.                 //throw exceptionNodeSet;
  930.             }
  931.            
  932.         }
  933.        
  934.         return lReturn;
  935.     }
  936. }