JsonXmlPathExpressionEngine.java
- /*
- * GovWay - A customizable API Gateway
- * https://govway.org
- *
- * Copyright (c) 2005-2025 Link.it srl (https://link.it).
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 3, as published by
- * the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- package org.openspcoop2.utils.xml2json;
- import java.util.List;
- import org.codehaus.jettison.mapped.Configuration;
- import org.openspcoop2.utils.json.JsonPathNotValidException;
- import org.openspcoop2.utils.xml.AbstractXPathExpressionEngine;
- import org.openspcoop2.utils.xml.DynamicNamespaceContext;
- import org.openspcoop2.utils.xml.XPathExpressionEngine;
- import org.slf4j.Logger;
- import com.jayway.jsonpath.JsonPath;
- /**
- * PathExpressionEngine
- *
- * @author Poli Andrea (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class JsonXmlPathExpressionEngine {
- private static final String PREFIX = "xpath ";
- private static final String NAMESPACE_PREFIX = "namespace("; // namespace
- private static final String NAMESPACE_END = ")";
-
- public static void validate(String patternParam, Logger log) throws JsonPathNotValidException {
-
- boolean json2Xml = false;
- String pattern = patternParam;
- String tipo = "Mapped";
- if(patternParam!=null && patternParam.toLowerCase().startsWith(PREFIX.toLowerCase())) {
- // default
- json2Xml = true;
- pattern = patternParam.substring(PREFIX.length());
- tipo = "Mapped";
- }
- if(pattern==null || "".equals(pattern)) {
- throw new JsonPathNotValidException("Espressione da utilizzare non fornita");
- }
-
- if(!json2Xml) {
- try {
- JsonPath.compile(pattern);
- } catch(Exception e) {
- throw new JsonPathNotValidException("Validazione del jsonPath indicato ["+pattern+"] fallita: "+e.getMessage(),e);
- }
- }
-
- else {
- try {
- // Wrappo in un unico elemento radice, altrimenti la conversione xml non riesce
-
- pattern = pattern.trim();
-
- if(pattern.toLowerCase().startsWith(NAMESPACE_PREFIX)) {
- pattern = pattern.substring(NAMESPACE_PREFIX.length());
- if(!pattern.contains(NAMESPACE_END)) {
- throw new JsonPathNotValidException("Espressione '"+patternParam+"' in un formato non corretto; non è stata riscontrata la chiusura della definizione dei namespace");
- }
- int offSet = pattern.indexOf(NAMESPACE_END);
- String namespaces = pattern.substring(0, offSet);
- if(offSet<(pattern.length()-1)) {
- pattern = pattern.substring(offSet+1, pattern.length());
- pattern = pattern.trim();
- }
- else {
- pattern = null;
- }
-
- if(pattern==null || "".equals(pattern)) {
- throw new JsonPathNotValidException("Espressione '"+patternParam+"' da utilizzare non fornita dopo la dichiarazione dei namespace");
- }
- //System.out.println("NAMESPACE ["+namespaces+"]");
- //System.out.println("PATTERN ["+pattern+"]");
- if(namespaces!=null && !"".equals(namespaces)) {
-
- String [] tmp = namespaces.split(",");
- if(tmp!=null && tmp.length>0) {
- for (String namespaceDeclaration : tmp) {
- if(namespaceDeclaration!=null && !"".equals(namespaceDeclaration)) {
- if(!namespaceDeclaration.contains(":")) {
- throw new JsonPathNotValidException("Espressione '"+patternParam+"' da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: atteso ':' separator. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- else {
- int indexOfPrefix = namespaceDeclaration.indexOf(":");
- String prefix = namespaceDeclaration.substring(0, indexOfPrefix);
- String uri = null;
- if(indexOfPrefix<(namespaceDeclaration.length()-1)) {
- uri = namespaceDeclaration.substring(indexOfPrefix+1, namespaceDeclaration.length());
- }
- else {
- throw new JsonPathNotValidException("Espressione '"+patternParam+"' da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: attesa dichiarazione namespace. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- prefix = prefix.trim();
- uri = uri.trim();
- if(prefix==null || "".equals(prefix)) {
- throw new JsonPathNotValidException("Espressione '"+patternParam+"' da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: prefisso non presente. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- if(uri==null || "".equals(uri)) {
- throw new JsonPathNotValidException("Espressione '"+patternParam+"' da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: dichiarazione namespace non presente. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- //System.out.println("prefix ["+prefix+"] uri["+uri+"]");
- }
- }
- }
- }
- }
-
- }
-
- AbstractXPathExpressionEngine engine = new XPathExpressionEngine();
- engine.validate(pattern);
-
- }
- catch(JsonPathNotValidException e) {
- throw e;
- }
- catch(Exception e) {
- throw new JsonPathNotValidException("Trasformazione json2xml '"+tipo+"' fallita: "+e.getMessage(),e);
- }
- }
-
- }
-
-
- public static String extractAndConvertResultAsString(String elementJson, String pattern, Logger log) throws Exception {
- Object o = _extractAndConvertResultAsString(elementJson, pattern, log, false);
- if(o!=null) {
- return (String) o;
- }
- return null;
- }
- @SuppressWarnings("unchecked")
- public static List<String> extractAndConvertResultAsList(String elementJson, String pattern, Logger log) throws Exception {
- Object o = _extractAndConvertResultAsString(elementJson, pattern, log, true);
- if(o!=null) {
- return (List<String>) o;
- }
- return null;
- }
- private static Object _extractAndConvertResultAsString(String elementJson, String patternParam, Logger log, boolean returnAsList) throws Exception {
-
- IJson2Xml json2Xml = null;
- String pattern = patternParam;
- String tipo = "Mapped";
- if(patternParam!=null && patternParam.toLowerCase().startsWith(PREFIX.toLowerCase())) {
- // default
- json2Xml = Xml2JsonFactory.getJson2XmlMapped(new Configuration()); // gli altri tipi, jsonML e badgerFished richiedono una struttura json specifica.
- pattern = patternParam.substring(PREFIX.length());
- tipo = "Mapped";
- }
- if(pattern==null || "".equals(pattern)) {
- throw new Exception("Espressione da utilizzare non fornita");
- }
-
- if(json2Xml!=null) {
- String node = null;
- DynamicNamespaceContext dnc = new DynamicNamespaceContext();
- try {
- // Wrappo in un unico elemento radice, altrimenti la conversione xml non riesce
- String elementJsonWrapped = "{ \"json2xml\" : "+elementJson+" }";
- node = json2Xml.json2xml(elementJsonWrapped);
- if(node==null || "".equals(node)) {
- throw new Exception("xml element ottenuto è vuoto");
- }
- pattern = pattern.trim();
- String namespaces = null;
- StringBuilder sbNamespaceDeclarations = new StringBuilder("");
- if(pattern.toLowerCase().startsWith(NAMESPACE_PREFIX)) {
- pattern = pattern.substring(NAMESPACE_PREFIX.length());
- if(!pattern.contains(NAMESPACE_END)) {
- throw new Exception("Espressione in un formato non corretto; non è stata riscontrata la chiusura della definizione dei namespace");
- }
- int offSet = pattern.indexOf(NAMESPACE_END);
- namespaces = pattern.substring(0, offSet);
- if(offSet<(pattern.length()-1)) {
- pattern = pattern.substring(offSet+1, pattern.length());
- pattern = pattern.trim();
- }
- else {
- pattern = null;
- }
-
- if(pattern==null || "".equals(pattern)) {
- throw new Exception("Espressione da utilizzare non fornita dopo la dichiarazione dei namespace");
- }
- //System.out.println("NAMESPACE ["+namespaces+"]");
- //System.out.println("PATTERN ["+pattern+"]");
-
- String newNameXmlns = "___xmlns";
- boolean foundXmlns = false;
- boolean foundDeclXmlns = false;
- if(node.contains("<xmlns:")) {
- foundXmlns = true;
- node = node.replaceAll("<xmlns:", "<"+newNameXmlns+":");
- node = node.replaceAll("</xmlns:", "</"+newNameXmlns+":");
- }
-
- if(namespaces!=null && !"".equals(namespaces)) {
-
- String [] tmp = namespaces.split(",");
- if(tmp!=null && tmp.length>0) {
- for (String namespaceDeclaration : tmp) {
- if(namespaceDeclaration!=null && !"".equals(namespaceDeclaration)) {
- if(!namespaceDeclaration.contains(":")) {
- throw new Exception("Espressione da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: atteso ':' separator. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- else {
- int indexOfPrefix = namespaceDeclaration.indexOf(":");
- String prefix = namespaceDeclaration.substring(0, indexOfPrefix);
- String uri = null;
- if(indexOfPrefix<(namespaceDeclaration.length()-1)) {
- uri = namespaceDeclaration.substring(indexOfPrefix+1, namespaceDeclaration.length());
- }
- else {
- throw new Exception("Espressione da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: attesa dichiarazione namespace. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- prefix = prefix.trim();
- uri = uri.trim();
- if(prefix==null || "".equals(prefix)) {
- throw new Exception("Espressione da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: prefisso non presente. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- if(uri==null || "".equals(uri)) {
- throw new Exception("Espressione da utilizzare non corretta; dichiarazione dei namespace in un formato non corretto: dichiarazione namespace non presente. ("+namespaces+") ("+namespaceDeclaration+")");
- }
- //System.out.println("prefix ["+prefix+"] uri["+uri+"]");
- if(prefix.equals("xmlns")) {
- prefix = newNameXmlns;
- foundDeclXmlns = true;
- }
- dnc.addNamespace(prefix, uri);
- sbNamespaceDeclarations.append(" xmlns:").append(prefix).append("=\"").append(uri).append("\" ");
- }
- }
- }
- }
- }
-
- if(foundXmlns && !foundDeclXmlns) {
- String prefix = newNameXmlns;
- String uri = "http://govway.org/utils/json2xml/xmlns";
- dnc.addNamespace(prefix, uri);
- sbNamespaceDeclarations.append(" xmlns:").append(prefix).append("=\"").append(uri).append("\" ");
- }
-
- }
-
- if(sbNamespaceDeclarations!=null && sbNamespaceDeclarations.length()>0) {
- node = node.replaceFirst("<json2xml>", ("<json2xml"+sbNamespaceDeclarations+">"));
- }
-
- }catch(Exception e) {
- throw new Exception("Trasformazione json2xml '"+tipo+"' fallita: "+e.getMessage(),e);
- }
- try {
- // NOTA: e' importante invocarlo con il corretto metodo
- XPathExpressionEngine xPathEngine = new XPathExpressionEngine();
- if(returnAsList) {
- return AbstractXPathExpressionEngine.extractAndConvertResultAsList(node, dnc, xPathEngine, pattern, log);
- }
- else {
- return AbstractXPathExpressionEngine.extractAndConvertResultAsString(node, dnc, xPathEngine, pattern, log);
- }
- }catch(Exception e) {
- throw new Exception("Trasformazione json2xml '"+tipo+"' fallita: "+e.getMessage()+"\nXml: \n"+node,e);
- }
- }
-
- if(returnAsList) {
- return org.openspcoop2.utils.json.JsonPathExpressionEngine.extractAndConvertResultAsList(elementJson, pattern, log);
- }
- else {
- return org.openspcoop2.utils.json.JsonPathExpressionEngine.extractAndConvertResultAsString(elementJson, pattern, log);
- }
- }
- }