PatternExtractor.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.pdd.core.dynamic;
- import java.util.List;
- import org.apache.commons.lang.StringUtils;
- import org.openspcoop2.message.OpenSPCoop2Message;
- import org.openspcoop2.message.OpenSPCoop2MessageFactory;
- import org.openspcoop2.message.OpenSPCoop2RestJsonMessage;
- import org.openspcoop2.message.constants.MessageRole;
- import org.openspcoop2.message.constants.MessageType;
- import org.openspcoop2.message.xml.MessageXMLUtils;
- import org.openspcoop2.protocol.sdk.Context;
- import org.openspcoop2.utils.SemaphoreLock;
- import org.openspcoop2.utils.json.JsonPathNotFoundException;
- import org.openspcoop2.utils.json.JsonPathNotValidException;
- import org.openspcoop2.utils.transport.http.HttpConstants;
- import org.openspcoop2.utils.xml.AbstractXPathExpressionEngine;
- import org.openspcoop2.utils.xml.DynamicNamespaceContext;
- import org.openspcoop2.utils.xml.XPathNotFoundException;
- import org.openspcoop2.utils.xml.XPathNotValidException;
- import org.openspcoop2.utils.xml.XPathReturnType;
- import org.openspcoop2.utils.xml2json.JsonXmlPathExpressionEngine;
- import org.slf4j.Logger;
- import org.w3c.dom.Element;
- import org.w3c.dom.Node;
- import org.w3c.dom.NodeList;
- /**
- * GestorePathEstrazione
- *
- * @author Andrea Poli (apoli@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class PatternExtractor {
- public static PatternExtractor getJsonPatternExtractor(String json, Logger log, boolean bufferMessage_readOnly, Context context) throws DynamicException {
- try {
- OpenSPCoop2MessageFactory messageFactory = OpenSPCoop2MessageFactory.getDefaultMessageFactory();
- OpenSPCoop2Message jsonMessageVerifica = messageFactory.createMessage(MessageType.JSON, MessageRole.NONE,
- HttpConstants.CONTENT_TYPE_JSON, json.getBytes()).getMessage();
- MessageContent messageContent = new MessageContent(jsonMessageVerifica.castAsRestJson(), bufferMessage_readOnly, context);
- return new PatternExtractor(messageFactory, messageContent, log);
- }catch(Exception e) {
- throw new DynamicException(e.getMessage(),e);
- }
- }
- public static PatternExtractor getXmlPatternExtractor(Element element, Logger log, boolean bufferMessage_readOnly, Context context) throws DynamicException {
- try {
- OpenSPCoop2MessageFactory messageFactory = OpenSPCoop2MessageFactory.getDefaultMessageFactory();
- OpenSPCoop2Message jsonMessageVerifica = messageFactory.createMessage(MessageType.XML, MessageRole.NONE,
- HttpConstants.CONTENT_TYPE_XML, MessageXMLUtils.getInstance(messageFactory).toByteArray(element, true)).getMessage();
- MessageContent messageContent = new MessageContent(jsonMessageVerifica.castAsRestXml(), bufferMessage_readOnly, context);
- return new PatternExtractor(messageFactory, messageContent, log);
- }catch(Exception e) {
- throw new DynamicException(e.getMessage(),e);
- }
- }
-
- private Logger log;
-
- private OpenSPCoop2MessageFactory messageFactory;
- private Element element = null;
- private Boolean refresh = null;
- private DynamicNamespaceContext dnc;
-
- private String elementJson = null;
-
- private MessageContent messageContent = null;
- private boolean messageContent_initialized = false;
-
- public PatternExtractor(OpenSPCoop2MessageFactory messageFactory, MessageContent messageContent, Logger log) {
- this.messageFactory = messageFactory;
- this.messageContent = messageContent;
- this.log = log;
- }
-
- // I seguenti costruttori li lascio per backward compatibility se usati dentro delle trasformazioni
- @Deprecated
- public PatternExtractor(OpenSPCoop2MessageFactory messageFactory, Element element, Logger log) {
- try {
- PatternExtractor pe = getXmlPatternExtractor(element, log, false, null);
- this.messageFactory = pe.messageFactory;
- this.messageContent = pe.messageContent;
- this.log = pe.log;
- }catch(Exception e) {
- throw new RuntimeException(e.getMessage(),e);
- }
- }
- @Deprecated
- public PatternExtractor(String elementJson, Logger log) {
- try {
- PatternExtractor pe = getJsonPatternExtractor(elementJson, log, false, null);
- this.messageFactory = pe.messageFactory;
- this.messageContent = pe.messageContent;
- this.log = pe.log;
- }catch(Exception e) {
- throw new RuntimeException(e.getMessage(),e);
- }
- }
-
-
- private void init() throws DynamicException {
- if(!this.messageContent_initialized) {
- _init();
- }
- }
- private org.openspcoop2.utils.Semaphore semaphore = new org.openspcoop2.utils.Semaphore("PatternExtractor");
- private void _init() throws DynamicException {
- SemaphoreLock slock = this.semaphore.acquireThrowRuntime("init");
- try {
- if(!this.messageContent_initialized) {
- if(this.messageContent!=null) {
- try {
- //this.messageFactory = this.messageContent.getMessageFactory();
- if(this.messageContent.isJson()) {
- this.elementJson = this.messageContent.getElementJson();
- }
- else if(this.messageContent.isXml()) {
- this.element = this.messageContent.getElement();
- this.dnc = new DynamicNamespaceContext();
- this.dnc.findPrefixNamespace(this.element);
- }
- else if(this.messageContent.isRestMultipart()) {
- this.elementJson = this.messageContent.getElementJson();
- if(this.elementJson==null) {
- this.element = this.messageContent.getElement();
- if(this.element!=null) {
- this.dnc = new DynamicNamespaceContext();
- this.dnc.findPrefixNamespace(this.element);
- }
- else {
- throw new Exception("Invalid multipart content");
- }
- }
- }
- }catch(Exception e) {
- throw new DynamicException(e.getMessage(),e);
- }
- }
- this.messageContent_initialized = true;
- }
- }finally {
- this.semaphore.release(slock, "init");
- }
- }
-
-
- public void refreshContent() {
- if(this.element!=null && this.refresh==null) {
- this._refreshContent();
- }
- }
- private void _refreshContent() {
- SemaphoreLock slock = this.semaphore.acquireThrowRuntime("refreshContent");
- // effettuo il refresh, altrimenti le regole xpath applicate sulla richiesta, nel flusso di risposta (es. header http della risposta) non funzionano.
- try {
- this.refresh = true;
- if(this.element!=null) {
- MessageXMLUtils xmlUtils = MessageXMLUtils.getInstance(this.messageFactory);
- this.element = xmlUtils.newElement(xmlUtils.toByteArray(this.element));
- }
- }catch(Exception e){
- this.log.error("Refresh fallito: "+e.getMessage(),e);
- }finally {
- this.semaphore.release(slock, "refreshContent");
- }
- }
-
- public boolean match(String pattern) throws DynamicException {
- init();
-
- String v = read(pattern);
- return v!=null && !"".equals(v);
- }
-
- public String read(String pattern) throws DynamicException {
- init();
-
- String operazione = "Read (pattern: "+pattern+")";
-
- String valore = null;
- try {
- if(this.element!=null) {
- AbstractXPathExpressionEngine xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(this.messageFactory);
- valore = AbstractXPathExpressionEngine.extractAndConvertResultAsString(this.element, this.dnc, xPathEngine, pattern, this.log);
- }
- else {
- valore = JsonXmlPathExpressionEngine.extractAndConvertResultAsString(this.elementJson, pattern, this.log);
- }
- }
- catch(XPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(XPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(JsonPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(JsonPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(org.openspcoop2.utils.UtilsMultiException e) {
- int index = 0;
- boolean notFound = true;
- boolean notValid = true;
- for (Throwable t : e.getExceptions()) {
- if(t instanceof XPathNotFoundException || t instanceof JsonPathNotFoundException) {
- this.log.debug("["+index+"] "+operazione+" failed: "+t.getMessage(),t);
- }
- else {
- notFound = false;
- }
-
- if(!(t instanceof XPathNotValidException) && !(t instanceof JsonPathNotValidException)) {
- notValid = false;
- }
-
- index++;
- }
- if(!notFound) {
- if(notValid) {
- throw new DynamicException(e.getMessage(),e);
- }
- else {
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
- }
- catch(Exception e){
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- return valore;
- }
-
- public List<String> readList(String pattern) throws DynamicException {
- init();
-
- String operazione = "ReadList (pattern: "+pattern+")";
-
- List<String> valore = null;
- try {
- if(this.element!=null) {
- AbstractXPathExpressionEngine xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(this.messageFactory);
- xPathEngine.getMatchPattern(this.element, this.dnc, pattern, XPathReturnType.BOOLEAN);
- valore = AbstractXPathExpressionEngine.extractAndConvertResultAsList(this.element, this.dnc, xPathEngine, pattern, this.log);
- }
- else {
- valore = JsonXmlPathExpressionEngine.extractAndConvertResultAsList(this.elementJson, pattern, this.log);
- }
- }
- catch(XPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(XPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(JsonPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(JsonPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(org.openspcoop2.utils.UtilsMultiException e) {
- int index = 0;
- boolean notFound = true;
- boolean notValid = true;
- for (Throwable t : e.getExceptions()) {
- if(t instanceof XPathNotFoundException || t instanceof JsonPathNotFoundException) {
- this.log.debug("["+index+"] "+operazione+" failed: "+t.getMessage(),t);
- }
- else {
- notFound = false;
- }
-
- if(!(t instanceof XPathNotValidException) && !(t instanceof JsonPathNotValidException)) {
- notValid = false;
- }
-
- index++;
- }
- if(!notFound) {
- if(notValid) {
- throw new DynamicException(e.getMessage(),e);
- }
- else {
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
- }
- catch(Exception e){
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- return valore;
- }
-
- // Lascio per utilizzi in vecchie trasformazioni
- @Deprecated
- public void remove(String pattern) throws DynamicException {
- this._remove(pattern, null);
- }
- public void removeByXPath(String pattern) throws DynamicException {
- if(pattern==null || StringUtils.isEmpty(pattern)) {
- throw new DynamicException("XPath pattern undefined");
- }
- this._remove(pattern, null);
- }
- public void removeJsonElement(String name) throws DynamicException {
- if(name==null || StringUtils.isEmpty(name)) {
- throw new DynamicException("JsonElement name undefined");
- }
- this._remove(null, name);
- }
- public void removeByJsonPath(String pattern, String name) throws DynamicException {
- if(pattern==null || StringUtils.isEmpty(pattern)) {
- throw new DynamicException("JsonPath pattern undefined");
- }
- if(name==null || StringUtils.isEmpty(name)) {
- throw new DynamicException("JsonElement name undefined");
- }
- this._remove(pattern, name);
- }
- private void _remove(String pattern, String name) throws DynamicException {
- init();
-
- String opName = "";
- if(name!=null) {
- opName="name:"+name+"";
- }
- String opPattern = "";
- if(pattern!=null) {
- opPattern="pattern:"+pattern+"";
- if(name!=null) {
- opPattern+=" ";
- }
- }
- String operazione = "Remove ("+opPattern+""+opName+")";
-
- try {
- if(this.messageContent!=null) {
- this.messageContent.setUpdatable();
- }
-
- if(this.element!=null) {
- AbstractXPathExpressionEngine xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(this.messageFactory);
- Node n = (Node) xPathEngine.getMatchPattern(this.element, this.dnc, pattern, XPathReturnType.NODE);
- if(n.getParentNode()!=null) {
- n.getParentNode().removeChild(n);
- }
- else {
- this.element.removeChild(n);
- }
- }
- else {
- if(this.messageContent!=null && this.messageContent.isJson() && this.messageContent.getJsonMessage()!=null) {
- OpenSPCoop2RestJsonMessage json = this.messageContent.getJsonMessage();
- if(pattern!=null) {
- json.removeElement(pattern, name);
- }
- else {
- json.removeElement(name);
- }
- }
- else {
- // retrocompatibilita'
- String s = JsonXmlPathExpressionEngine.extractAndConvertResultAsString(this.elementJson, pattern, this.log);
- this.elementJson = this.elementJson.replace(s, "");
- }
- }
- }
- catch(XPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(XPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(JsonPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(JsonPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(org.openspcoop2.utils.UtilsMultiException e) {
- int index = 0;
- boolean notFound = true;
- boolean notValid = true;
- for (Throwable t : e.getExceptions()) {
- if(t instanceof XPathNotFoundException || t instanceof JsonPathNotFoundException) {
- this.log.debug("["+index+"] "+operazione+" failed: "+t.getMessage(),t);
- }
- else {
- notFound = false;
- }
-
- if(!(t instanceof XPathNotValidException) && !(t instanceof JsonPathNotValidException)) {
- notValid = false;
- }
-
- index++;
- }
- if(!notFound) {
- if(notValid) {
- throw new DynamicException(e.getMessage(),e);
- }
- else {
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
- }
- catch(Exception e){
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
-
- // Lascio per utilizzi in vecchie trasformazioni
- @Deprecated
- public void removeList(String pattern) throws DynamicException {
- this._removeList(pattern);
- }
- public void removeListByXPath(String pattern) throws DynamicException {
- if(pattern==null || StringUtils.isEmpty(pattern)) {
- throw new DynamicException("XPath pattern undefined");
- }
- this._remove(pattern, null);
- }
- private void _removeList(String pattern) throws DynamicException {
- init();
-
- String operazione = "RemoveList (pattern: "+pattern+")";
-
- try {
- this.messageContent.setUpdatable();
-
- if(this.element!=null) {
- AbstractXPathExpressionEngine xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(this.messageFactory);
- NodeList nList = (NodeList) xPathEngine.getMatchPattern(this.element, this.dnc, pattern, XPathReturnType.NODESET);
- if(nList!=null && nList.getLength()>0) {
- for (int i = 0; i < nList.getLength(); i++) {
- Node n = nList.item(i);
- if(n.getParentNode()!=null) {
- n.getParentNode().removeChild(n);
- }
- else {
- this.element.removeChild(n);
- }
- }
- }
- }
- else {
- // Soluzione deprecata: usare removeByJsonPath
- List<String> valori = JsonXmlPathExpressionEngine.extractAndConvertResultAsList(this.elementJson, pattern, this.log);
- if(valori!=null && !valori.isEmpty()) {
- for (String valore : valori) {
- this.elementJson = this.elementJson.replace(valore, "");
- }
- }
- }
- }
- catch(XPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(XPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(JsonPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(JsonPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(org.openspcoop2.utils.UtilsMultiException e) {
- int index = 0;
- boolean notFound = true;
- boolean notValid = true;
- for (Throwable t : e.getExceptions()) {
- if(t instanceof XPathNotFoundException || t instanceof JsonPathNotFoundException) {
- this.log.debug("["+index+"] "+operazione+" failed: "+t.getMessage(),t);
- }
- else {
- notFound = false;
- }
-
- if(!(t instanceof XPathNotValidException) && !(t instanceof JsonPathNotValidException)) {
- notValid = false;
- }
-
- index++;
- }
- if(!notFound) {
- if(notValid) {
- throw new DynamicException(e.getMessage(),e);
- }
- else {
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
- }
- catch(Exception e){
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
-
-
-
- public void replaceValueByXPath(String pattern, String newValue) throws DynamicException {
- if(pattern==null || StringUtils.isEmpty(pattern)) {
- throw new DynamicException("XPath pattern undefined");
- }
- if(newValue==null) {
- throw new DynamicException("New value undefined");
- }
- this._replaceValue(pattern, null, newValue);
- }
- public void replaceJsonElementValue(String name, Object newValue) throws DynamicException {
- if(name==null || StringUtils.isEmpty(name)) {
- throw new DynamicException("JsonElement name undefined");
- }
- if(newValue==null) {
- throw new DynamicException("New value undefined");
- }
- this._replaceValue(null, name, newValue);
- }
- public void replaceValueByJsonPath(String pattern, String name, Object newValue) throws DynamicException {
- if(pattern==null || StringUtils.isEmpty(pattern)) {
- throw new DynamicException("JsonPath pattern undefined");
- }
- if(name==null || StringUtils.isEmpty(name)) {
- throw new DynamicException("JsonElement name undefined");
- }
- if(newValue==null) {
- throw new DynamicException("New value undefined");
- }
- this._replaceValue(pattern, name, newValue);
- }
- private void _replaceValue(String pattern, String name, Object value) throws DynamicException {
- init();
-
- String opName = "";
- if(name!=null) {
- opName=" name:"+name+"";
- }
- String operazione = "Replace value (pattern: "+pattern+""+opName+")";
-
- try {
- if(this.messageContent!=null) {
- this.messageContent.setUpdatable();
- }
-
- if(this.element!=null) {
- AbstractXPathExpressionEngine xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(this.messageFactory);
- Node n = (Node) xPathEngine.getMatchPattern(this.element, this.dnc, pattern, XPathReturnType.NODE);
- n.setTextContent(value.toString());
- }
- else {
- if(this.messageContent!=null && this.messageContent.isJson() && this.messageContent.getJsonMessage()!=null) {
- OpenSPCoop2RestJsonMessage json = this.messageContent.getJsonMessage();
- if(pattern!=null) {
- json.replaceValue(pattern, name, value);
- }
- else {
- json.replaceValue(name, value);
- }
- }
- }
- }
- catch(XPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(XPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(Exception e){
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
-
-
- public void replaceValuesByXPath(String pattern, String newValue) throws DynamicException {
- if(pattern==null || StringUtils.isEmpty(pattern)) {
- throw new DynamicException("XPath pattern undefined");
- }
- if(newValue==null) {
- throw new DynamicException("New value undefined");
- }
- this._replaceValues(pattern, null, newValue);
- }
- private void _replaceValues(String pattern, String name, String value) throws DynamicException {
- init();
-
- String opName = "";
- if(name!=null) {
- opName=" name:"+name+"";
- }
- String operazione = "Replace values (pattern: "+pattern+""+opName+")";
-
- try {
- this.messageContent.setUpdatable();
-
- if(this.element!=null) {
- AbstractXPathExpressionEngine xPathEngine = new org.openspcoop2.message.xml.XPathExpressionEngine(this.messageFactory);
- NodeList nList = (NodeList) xPathEngine.getMatchPattern(this.element, this.dnc, pattern, XPathReturnType.NODESET);
- if(nList!=null && nList.getLength()>0) {
- for (int i = 0; i < nList.getLength(); i++) {
- Node n = nList.item(i);
- n.setTextContent(value);
- }
- }
- }
- else {
- throw new Exception("Unsupported in json structure");
- }
- }
- catch(XPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(XPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(JsonPathNotFoundException e){
- this.log.debug(operazione+" failed, results not found: "+e.getMessage(),e);
- }
- catch(JsonPathNotValidException e){
- throw new DynamicException(e.getMessage(),e);
- }
- catch(org.openspcoop2.utils.UtilsMultiException e) {
- int index = 0;
- boolean notFound = true;
- boolean notValid = true;
- for (Throwable t : e.getExceptions()) {
- if(t instanceof XPathNotFoundException || t instanceof JsonPathNotFoundException) {
- this.log.debug("["+index+"] "+operazione+" failed: "+t.getMessage(),t);
- }
- else {
- notFound = false;
- }
-
- if(!(t instanceof XPathNotValidException) && !(t instanceof JsonPathNotValidException)) {
- notValid = false;
- }
-
- index++;
- }
- if(!notFound) {
- if(notValid) {
- throw new DynamicException(e.getMessage(),e);
- }
- else {
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
- }
- catch(Exception e){
- throw new DynamicException(operazione+" failed: "+e.getMessage(),e);
- }
- }
- }