OpenSPCoop2Message_xml_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.ByteArrayInputStream;
  22. import java.io.FileInputStream;
  23. import java.io.InputStream;
  24. import java.io.InputStreamReader;
  25. import java.io.OutputStream;
  26. import java.util.ArrayList;
  27. import java.util.List;

  28. import org.openspcoop2.message.OpenSPCoop2MessageFactory;
  29. import org.openspcoop2.message.OpenSPCoop2RestXmlMessage;
  30. import org.openspcoop2.message.exception.MessageException;
  31. import org.openspcoop2.message.exception.MessageNotSupportedException;
  32. import org.openspcoop2.message.xml.MessageXMLUtils;
  33. import org.openspcoop2.message.xml.XPathExpressionEngine;
  34. import org.openspcoop2.utils.io.DumpByteArrayOutputStream;
  35. import org.openspcoop2.utils.transport.http.ContentTypeUtilities;
  36. import org.openspcoop2.utils.transport.http.HttpConstants;
  37. import org.openspcoop2.utils.xml.DynamicNamespaceContext;
  38. import org.openspcoop2.utils.xml.XPathReturnType;
  39. import org.w3c.dom.Element;
  40. import org.w3c.dom.Node;
  41. import org.xml.sax.InputSource;

  42. /**
  43.  * Implementazione dell'OpenSPCoop2Message utilizzabile per messaggi xml
  44.  *
  45.  * @author Andrea Poli (poli@link.it)
  46.  * @author $Author$
  47.  * @version $Rev$, $Date$
  48.  */
  49. public class OpenSPCoop2Message_xml_impl extends AbstractBaseOpenSPCoop2RestMessage<Element> implements OpenSPCoop2RestXmlMessage {

  50.     public OpenSPCoop2Message_xml_impl(OpenSPCoop2MessageFactory messageFactory) {
  51.         super(messageFactory);
  52.     }
  53.     public OpenSPCoop2Message_xml_impl(OpenSPCoop2MessageFactory messageFactory, InputStream is,String contentType) throws MessageException {
  54.         super(messageFactory, is, contentType);
  55.     }
  56.    
  57.     @Override
  58.     protected Element buildContent() throws MessageException{
  59.         try{
  60.             return buildContent(this._getInputStream());
  61.         }finally{
  62.             try{
  63.                 this._getInputStream().close();
  64.             }catch(Exception eClose){
  65.                 // close
  66.             }
  67.         }
  68.     }
  69.     @Override
  70.     protected Element buildContent(DumpByteArrayOutputStream contentBuffer) throws MessageException{
  71.         try{
  72.             if(contentBuffer.isSerializedOnFileSystem()) {
  73.                 try(InputStream is = new FileInputStream(contentBuffer.getSerializedFile())){
  74.                     return buildContent(is);
  75.                 }
  76.             }
  77.             else {
  78.                 try(InputStream is = new ByteArrayInputStream(contentBuffer.toByteArray())){
  79.                     return buildContent(is);
  80.                 }
  81.             }
  82.         }
  83.         catch(MessageException me) {
  84.             throw me;
  85.         }
  86.         catch(Exception e){
  87.             throw new MessageException(e.getMessage(),e);
  88.         }
  89.     }
  90.     protected Element buildContent(InputStream is) throws MessageException{
  91.         InputStreamReader isr = null;
  92.         InputSource isSax = null;
  93.         try{
  94.             isr = new InputStreamReader(is,this.contentTypeCharsetName);
  95.             isSax = new InputSource(isr);
  96.             isSax.setEncoding(this.contentTypeCharsetName);
  97.             return MessageXMLUtils.getInstance(this.messageFactory).newElement(isSax);
  98.         }catch(Exception e){
  99.             throw new MessageException(e.getMessage(),e);
  100.         }finally{
  101.             try{
  102.                 if(isr!=null){
  103.                     isr.close();
  104.                 }
  105.             }catch(Exception eClose){
  106.                 // close
  107.             }
  108.         }
  109.     }

  110.     @Override
  111.     protected String buildContentAsString() throws MessageException{
  112.         try{
  113.             return this.getAsString(this.content, false);
  114.         }catch(Exception e){
  115.             throw new MessageException(e.getMessage(),e);
  116.         }
  117.     }
  118.    
  119.     @Override
  120.     protected byte[] buildContentAsByteArray() throws MessageException{
  121.         try{
  122.             return this.getAsString(this.content, false).getBytes(this.contentTypeCharsetName);
  123.         }catch(Exception e){
  124.             throw new MessageException(e.getMessage(),e);
  125.         }
  126.     }
  127.    
  128.     @Override
  129.     protected void serializeContent(OutputStream os, boolean consume) throws MessageException {
  130.         try{
  131.             MessageXMLUtils.getInstance(this.messageFactory).writeTo(this.content, os, true, this.contentTypeCharsetName);
  132.             os.flush();
  133.         }catch(Exception e){
  134.             throw new MessageException(e.getMessage(),e);
  135.         }
  136.     }

  137.     @Override
  138.     public boolean isProblemDetailsForHttpApis_RFC7807() throws MessageException,MessageNotSupportedException {
  139.         try{
  140.             if(this.contentType==null) {
  141.                 return false;
  142.             }
  143.             String baseType = ContentTypeUtilities.readBaseTypeFromContentType(this.contentType);
  144.             return HttpConstants.CONTENT_TYPE_XML_PROBLEM_DETAILS_RFC_7807.equalsIgnoreCase(baseType);
  145.         }catch(Exception e){
  146.             throw new MessageException(e.getMessage(),e);
  147.         }
  148.     }

  149.    
  150.     @Override
  151.     public void addElement(String name, String value)  throws MessageException,MessageNotSupportedException{
  152.          _processElement(name, null, value, true, false, null);
  153.     }
  154.     @Override
  155.     public void addElement(String name, String namespace, String value)  throws MessageException,MessageNotSupportedException{
  156.         _processElement(name, namespace, value, true, false, null);
  157.     }
  158.    
  159.     @Override
  160.     public void addElementIn(String pattern, String name, String value)  throws MessageException,MessageNotSupportedException{
  161.         _processElement(name, null, value, true, false, pattern);
  162.     }
  163.     @Override
  164.     public void addElementIn(String pattern, String name, String namespace, String value)  throws MessageException,MessageNotSupportedException{
  165.         _processElement(name, namespace, value, true, false, pattern);
  166.     }
  167.    
  168.     @Override
  169.     public void removeElement(String name) throws MessageException,MessageNotSupportedException{
  170.          _processElement(name, null, null, false, true, null);
  171.     }
  172.     @Override
  173.     public void removeElement(String name, String namespace) throws MessageException,MessageNotSupportedException{
  174.          _processElement(name, namespace, null, false, true, null);
  175.     }
  176.    
  177.     @Override
  178.     public void removeElementIn(String pattern, String name) throws MessageException,MessageNotSupportedException{
  179.          _processElement(name, null, null, false, true, pattern);
  180.     }
  181.     @Override
  182.     public void removeElementIn(String pattern, String name, String namespace) throws MessageException,MessageNotSupportedException{
  183.          _processElement(name, namespace, null, false, true, pattern);
  184.     }
  185.    
  186.     public void _processElement(String name, String namespace, String value, boolean add, boolean remove, String pattern) throws MessageException {
  187.         try {
  188.             if(!this.hasContent()) {
  189.                 return;
  190.             }
  191.            
  192.             Element content = this.getContent();
  193.             Node element = null;
  194.             if(pattern!=null) {
  195.                 XPathExpressionEngine engine = new XPathExpressionEngine(this.messageFactory);
  196.                 DynamicNamespaceContext dnc = new DynamicNamespaceContext();
  197.                 dnc.findPrefixNamespace(content);
  198.                 element = (Node) engine.getMatchPattern(content, dnc, pattern, XPathReturnType.NODE);
  199.             }
  200.             else {
  201.                 element = content;
  202.             }
  203.                
  204.             if(remove) {
  205.                 List<Node> list = MessageXMLUtils.getInstance(this.messageFactory).getNotEmptyChildNodes(element, false);
  206.                 List<Node> removeNodes = new ArrayList<Node>();
  207.                 if(list!=null && !list.isEmpty()) {
  208.                     for (Node node : list) {
  209.                         if(namespace!=null) {
  210.                             if(namespace.equals(node.getNamespaceURI()) && name.equals(node.getLocalName())) {
  211.                                 removeNodes.add(node);
  212.                             }
  213.                         }
  214.                         else {
  215.                             if(node.getNamespaceURI()==null && name.equals(node.getLocalName())) {
  216.                                 removeNodes.add(node);
  217.                             }
  218.                         }
  219.                     }
  220.                 }
  221.                 while(!removeNodes.isEmpty()) {
  222.                     Node n = removeNodes.remove(0);
  223.                     element.removeChild(n);
  224.                 }
  225.                
  226.                 /*NodeList list = null;
  227.                 if(namespace!=null) {
  228.                     list = element.getElementsByTagNameNS(namespace, name);
  229.                 }
  230.                 else {
  231.                     list = element.getElementsByTagName(name);
  232.                 }
  233.                 if(list!=null && list.getLength()>0) {
  234.                     for (int i = 0; i < list.getLength(); i++) {
  235.                         Node n = list.item(i);
  236.                         element.removeChild(n);
  237.                     }
  238.                 }*/
  239.             }
  240.             else if(add) {
  241.                 Element eAdd = null;
  242.                 if(namespace!=null) {
  243.                     eAdd = element.getOwnerDocument().createElementNS(namespace, name);
  244.                 }
  245.                 else {
  246.                     eAdd = element.getOwnerDocument().createElement(name);
  247.                 }
  248.                 eAdd.setTextContent(value);
  249.                 element.appendChild(eAdd);
  250.             }
  251.            
  252.         }catch(Exception e) {
  253.             if(pattern!=null) {
  254.                 throw new MessageException("Operazione fallita (pattern: "+pattern+"): "+e.getMessage(),e);
  255.             }
  256.             else {
  257.                 throw new MessageException("Operazione fallita: "+e.getMessage(),e);
  258.             }
  259.         }
  260.     }
  261. }