SPCoopSbustamento.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.protocol.spcoop.builder;

  21. import java.io.ByteArrayInputStream;
  22. import java.io.ByteArrayOutputStream;
  23. import java.io.InputStream;
  24. import java.io.SequenceInputStream;
  25. import java.util.ArrayList;
  26. import java.util.Collections;
  27. import java.util.List;

  28. import javax.xml.soap.AttachmentPart;
  29. import javax.xml.soap.MimeHeaders;
  30. import javax.xml.soap.SOAPBody;
  31. import javax.xml.soap.SOAPElement;
  32. import javax.xml.soap.SOAPHeader;
  33. import javax.xml.soap.SOAPHeaderElement;

  34. import org.openspcoop2.message.OpenSPCoop2Message;
  35. import org.openspcoop2.message.OpenSPCoop2SoapMessage;
  36. import org.openspcoop2.message.constants.MessageType;
  37. import org.openspcoop2.message.soap.DumpSoapMessageUtils;
  38. import org.openspcoop2.message.soap.SoapUtils;
  39. import org.openspcoop2.message.xml.MessageXMLUtils;
  40. import org.openspcoop2.protocol.sdk.IProtocolFactory;
  41. import org.openspcoop2.protocol.sdk.ProtocolException;
  42. import org.openspcoop2.protocol.sdk.builder.ProprietaManifestAttachments;
  43. import org.openspcoop2.protocol.sdk.state.IState;
  44. import org.openspcoop2.protocol.spcoop.SPCoopBustaRawContent;
  45. import org.openspcoop2.protocol.spcoop.config.SPCoopProperties;
  46. import org.openspcoop2.protocol.spcoop.constants.SPCoopCostanti;
  47. import org.openspcoop2.protocol.spcoop.validator.SPCoopValidazioneSintattica;
  48. import org.openspcoop2.utils.UtilsMultiException;
  49. import org.slf4j.Logger;
  50. import org.w3c.dom.Document;
  51. import org.w3c.dom.Element;
  52. import org.w3c.dom.NodeList;
  53. import org.w3c.dom.Text;

  54. /**
  55.  * Classe utilizzata per Sbustare un SOAPEnvelope dell'header eGov.
  56.  *
  57.  *
  58.  * @author Poli Andrea (apoli@link.it)
  59.  * @author $Author$
  60.  * @version $Rev$, $Date$
  61.  */

  62. public class SPCoopSbustamento {

  63.     private Logger log;
  64.     private IProtocolFactory<?> protocolFactory;
  65.     private SPCoopValidazioneSintattica validazioneSintattica = null;
  66.     private SPCoopProperties spcoopProperties = null;
  67.     private IState state;
  68.    
  69.     public SPCoopSbustamento(IProtocolFactory<?> protocolFactory,IState state) throws ProtocolException{
  70.         this.protocolFactory = protocolFactory;
  71.         this.log = protocolFactory.getLogger();
  72.         this.spcoopProperties = SPCoopProperties.getInstance(this.log);
  73.        
  74.         this.state = state;
  75.        
  76.         this.validazioneSintattica = (SPCoopValidazioneSintattica) this.protocolFactory.createValidazioneSintattica(this.state);
  77.        
  78.     }
  79.    
  80.     /**
  81.      * Effettua lo sbustamento eGov
  82.      *  
  83.      * @param msg Messaggio in cui deve essere estratto un header eGov.
  84.      *
  85.      */
  86.     public SOAPHeaderElement sbustamentoEGov(OpenSPCoop2Message msg,ProprietaManifestAttachments proprietaManifestAttachments) throws ProtocolException{    

  87.         SOAPHeader headerSOAP = null;
  88.         SOAPHeaderElement header = null;
  89.         try{

  90.             OpenSPCoop2SoapMessage soapMsg = msg.castAsSoap();
  91.            
  92.             // Estraggo header
  93.             this.validazioneSintattica.setMsg(soapMsg);
  94.             this.validazioneSintattica.setReadQualifiedAttribute(proprietaManifestAttachments.isReadQualifiedAttribute());
  95.             headerSOAP = soapMsg.getSOAPHeader();
  96.             SPCoopBustaRawContent bustaElement = this.validazioneSintattica.getHeaderEGov(msg.getFactory(), headerSOAP);
  97.             if(bustaElement == null){
  98.                 throw new Exception ("Header eGov non presente");
  99.             }
  100.             header = bustaElement.getElement();
  101.             if(header == null){
  102.                 throw new Exception ("Header eGov non presente");
  103.             }

  104.             soapMsg.removeHeaderElement(headerSOAP, header);
  105.            
  106.             // Remove Manifest
  107.             if(proprietaManifestAttachments.isGestioneManifest() && soapMsg.countAttachments()>0){
  108.                 this.remove_eGovManifest(msg,proprietaManifestAttachments);
  109.             }

  110.             return header;
  111.            
  112.         }catch(Exception e){    
  113.             this.log.error("SbustamentoEGov non riuscito: "+e.getMessage(),e);
  114.             throw new ProtocolException("SbustamentoEGov non riuscito: "+e.getMessage(),e);    
  115.         }
  116.         finally{
  117.             // *** GB ***
  118.             if(this.validazioneSintattica!=null){
  119.                 this.validazioneSintattica.setHeaderSOAP(null);
  120.             }
  121.             headerSOAP = null;
  122.             header = null;
  123.             // *** GB ***
  124.         }
  125.     }


  126.     public OpenSPCoop2Message remove_eGovManifest(OpenSPCoop2Message msgParam,ProprietaManifestAttachments proprietaManifestAttachments) throws ProtocolException{
  127.         try{
  128.             OpenSPCoop2SoapMessage msg = msgParam.castAsSoap();
  129.            
  130.             MessageXMLUtils xmlUtils = MessageXMLUtils.getInstance(msg.getFactory());
  131.            
  132.             SOAPBody body = msg.getSOAPBody();
  133.            
  134.             // dopo la modifica del commit '185e2d7ba1db561d769128aadbee493103963ac9' per la validazione dei contenuti si ottiene l'errore: class org.apache.xerces.dom.ElementNSImpl cannot be cast to class javax.xml.soap.SOAPElement
  135.             // uso metodo getFirstSOAPElement in cui รจ stato ripristinato il vecchio codice
  136.             /**Element e = msg.getFirstChildElement(body);*/
  137.             /**System.out.println("CLASSE ["+e.getClass().getName()+"] ["+msg.getAsString(e, false)+"]");*/
  138.             Element e = SoapUtils.getFirstSOAPElement(body);
  139.            
  140.             SOAPElement descrizione = (SOAPElement) e;
  141.             java.util.Iterator<?> it = descrizione.getChildElements();
  142.             String idMsg = null;
  143.             while(it.hasNext()){
  144.                 Object element = it.next();
  145.                 if(!(element instanceof SOAPElement)){
  146.                     continue;
  147.                 }
  148.                 SOAPElement descrizioneMessaggio = (SOAPElement) element;
  149.                
  150.                 // uguale a sopra il motivo
  151.                 /**SOAPElement riferimento = (SOAPElement)msg.getFirstChildElement(descrizioneMessaggio);*/
  152.                 SOAPElement riferimento = SoapUtils.getFirstSOAPElement(descrizioneMessaggio);
  153.                
  154.                 if(riferimento.getAttribute("role").equalsIgnoreCase(this.spcoopProperties.getRoleRichiestaManifest())){
  155.                     idMsg = riferimento.getAttribute("href");
  156.                     break;
  157.                 }else if(riferimento.getAttribute("role").equalsIgnoreCase(this.spcoopProperties.getRoleRispostaManifest())){
  158.                     idMsg = riferimento.getAttribute("href");
  159.                     break;
  160.                 }      
  161.             }
  162.             if(idMsg==null){
  163.                 throw new Exception("DescrizioneMessaggio con ruolo "+this.spcoopProperties.getRoleRichiestaManifest()
  164.                         +" o "+this.spcoopProperties.getRoleRispostaManifest()+" non trovato.");
  165.             }
  166.            
  167.             if(idMsg.startsWith("cid:"))
  168.                 idMsg = idMsg.substring("cid:".length());
  169.             MimeHeaders mhs = new MimeHeaders();
  170.             mhs.addHeader("Content-ID", idMsg);
  171.             AttachmentPart ap = (AttachmentPart) msg.getAttachments(mhs).next();
  172.             msg.removeAttachments(mhs);
  173.            

  174.             // Leggo body originale presente nell'attachment
  175.             java.io.InputStream inputDH = getInputStream(msg, ap);
  176.            
  177.             // Ripristino body Originale
  178.             msg.getSOAPBody().removeContents();
  179.            
  180.             // Check eventuale <?xml instruction
  181.             byte[]bytePotenzialiXML = new byte[5]; // <?xml
  182.             int readByte = inputDH.read(bytePotenzialiXML);
  183.             boolean xmlContentPresente = false;
  184.             if( (readByte==5) &&
  185.                 (((char)bytePotenzialiXML[0])=='<') &&
  186.                 (((char)bytePotenzialiXML[1])=='?') &&
  187.                 (((char)bytePotenzialiXML[2])=='x') &&
  188.                 (((char)bytePotenzialiXML[3])=='m') &&
  189.                 (((char)bytePotenzialiXML[4])=='l') ){
  190.                 readByte = inputDH.read();
  191.                 while( (((char)readByte)!='>') && (readByte!=-1)  ){
  192.                     readByte = inputDH.read();
  193.                 }
  194.                 if(((char)readByte)=='>'){
  195.                     xmlContentPresente = true;
  196.                 }
  197.             }
  198.            
  199.             // Se il body allegato e' vuoto mi fermo.
  200.             // Parsare uno stream vuoto da errore con AXIOM.
  201.             if(readByte == -1) return msg;
  202.            
  203.             // Costruzione isBody
  204.             InputStream isBody = null;
  205.             if(xmlContentPresente == false){
  206.                 //isBody = dh.getInputStream();
  207.                 isBody = getInputStream(msg, ap);
  208.             }else{
  209.                 isBody = inputDH;
  210.             }
  211.            
  212.             // Puo' darsi che siano piu' elementi nello stream senza un unico rootelement.
  213.             // Questo fa arrabbiare il parser.
  214.             // Aggiungo un WrapperElement per farmi costruire l'elemento e poi ne cerco i figli.
  215.            
  216.             List<InputStream> iss = new ArrayList<InputStream>();
  217.             iss.add(new ByteArrayInputStream("<OpenSPCoopWrapper>".getBytes()));
  218.             iss.add(isBody);
  219.             iss.add(new ByteArrayInputStream("</OpenSPCoopWrapper>".getBytes()));
  220.             InputStream is = new SequenceInputStream(Collections.enumeration(iss));
  221.                
  222.             Document doc = xmlUtils.newDocument(is);
  223.             NodeList nl = doc.getDocumentElement().getChildNodes();
  224.             for(int i = 0; i < nl.getLength(); i++) {
  225.                 org.w3c.dom.Node n = nl.item(i);
  226.                 if(n instanceof Element) {
  227.                     Element element = (Element) n;
  228.                     if(SPCoopCostanti.LOCAL_NAME_MANIFEST_EGOV_EMPTY_BODY.equals(element.getLocalName()) &&
  229.                             SPCoopCostanti.NAMESPACE_MANIFEST_EGOV_EMPTY_BODY.equals(element.getNamespaceURI())){
  230.                         // Body Empty
  231.                         //System.out.println("SBUSTAMENTO EMPTY PATCH");
  232.                         continue;
  233.                     }
  234.                     msg.getSOAPBody().addChildElement(SoapUtils.getSoapFactory(msg.getFactory(), MessageType.SOAP_11).createElement(element));
  235.                 }
  236.                 if(n instanceof Text) {
  237.                     msg.getSOAPBody().addTextNode(n.getTextContent());
  238.                 }

  239.             }
  240.            
  241.             return msg;
  242.            
  243.         } catch(Exception e) {
  244.             this.log.error("Rimozione Manifest degli Attachments non riuscita: "+e.getMessage(),e);
  245.             throw new ProtocolException("Rimozione Manifest degli Attachments non riuscita: "+e.getMessage(),e);        
  246.         }  
  247.     }
  248.    
  249.     private InputStream getInputStream(OpenSPCoop2SoapMessage msg, AttachmentPart ap) throws Exception {
  250.         java.io.InputStream inputDH = null;
  251.         try {
  252.             // Provo con codiceOriginale ma in jboss non funziona sempre
  253.             javax.activation.DataHandler dh = ap.getDataHandler();
  254.             inputDH = dh.getInputStream();
  255.         }catch(Exception e) {
  256.             try {
  257.                 inputDH = new ByteArrayInputStream(DumpSoapMessageUtils.dumpAttachmentAsByteArray(msg, ap));
  258.             }catch(Exception eInternal) {
  259.                 throw new UtilsMultiException(e, eInternal);
  260.             }
  261.         }
  262.         return inputDH;
  263.     }
  264.    
  265.     /**
  266.      * Metodo che si occupa di eliminare dal SOAPHeader, passato col parametro <var>header</var>
  267.      * l'header eGov.
  268.      *
  269.      * @param header bytes del SOAPHeader, contenente la busta eGov da estrarre.
  270.      * @return bytes del SOAPHeader, in cui e' stato estratto l'header eGov.
  271.      *
  272.      */
  273.     @Deprecated public byte[] removeSPCoop(byte [] header) throws ProtocolException{

  274.         ByteArrayOutputStream reqByteSbustata = null;
  275.         try{
  276.             String headerSTR = new String(header);

  277.             // Ricerco header EGov
  278.             int endIntestazione = 0;
  279.             int start = 0;
  280.             while(true){
  281.                 int indexOfEGov = headerSTR.indexOf(SPCoopCostanti.ACTOR_EGOV,start);
  282.                 if(indexOfEGov == -1)
  283.                     break;
  284.                 StringBuilder rovesciata = new StringBuilder();
  285.                 for(int i = indexOfEGov-1; i>0 ; i-- ){
  286.                     rovesciata.append(((char)header[i]));
  287.                     if( ((char)header[i]) == '<' ){
  288.                         start = i;
  289.                         break;
  290.                     }
  291.                 }
  292.                 StringBuilder rigaCompleta = new StringBuilder();
  293.                 rovesciata.reverse();
  294.                 rigaCompleta.append(rovesciata.toString());
  295.                 rigaCompleta.append(SPCoopCostanti.ACTOR_EGOV);
  296.                 for(int i = (indexOfEGov+SPCoopCostanti.ACTOR_EGOV.length()); i<header.length ; i++ ){
  297.                     rigaCompleta.append(((char)header[i]));
  298.                     if( ((char)header[i]) == '>' ){
  299.                         break;
  300.                     }
  301.                 }
  302.                 if(rigaCompleta.toString().indexOf("Intestazione") != -1){
  303.                     endIntestazione = start -1 + rigaCompleta.length();
  304.                     break;
  305.                 }else{
  306.                     start = start -1 + rigaCompleta.length();
  307.                 }
  308.             }


  309.             // Elimino Header
  310.             if(start == 0){
  311.                 return null;
  312.             }
  313.             int end =  headerSTR.indexOf("Intestazione>",endIntestazione) + "Intestazione>".length();
  314.             if(end == -1){
  315.                 return null;
  316.             }
  317.             if(end <= start){
  318.                 return null;
  319.             }
  320.             reqByteSbustata = new ByteArrayOutputStream();
  321.             for(int i=0; i<start ; i++)
  322.                 reqByteSbustata.write(header[i]);
  323.             boolean eraserSpaziDopoEGov = false;
  324.             for(int i=end; i<header.length ; i++){
  325.                 if( (eraserSpaziDopoEGov==false) && ((char)header[i]=='<' )  ){
  326.                     eraserSpaziDopoEGov=true;
  327.                     reqByteSbustata.write(header[i]);
  328.                 }else if (eraserSpaziDopoEGov)
  329.                     reqByteSbustata.write(header[i]);
  330.             }

  331.             byte[] bustaSenzaEGov = reqByteSbustata.toByteArray();
  332.             reqByteSbustata.close();
  333.             return bustaSenzaEGov;

  334.         } catch(Exception e) {
  335.             try{
  336.                 if(reqByteSbustata!=null)
  337.                     reqByteSbustata.close();
  338.             }catch(Exception eis){
  339.                 // close
  340.             }
  341.             this.log.error("RimozioneHeaderSPCoop non riuscita: "+e.getMessage(),e);
  342.             throw new ProtocolException("RimozioneHeaderSPCoop non riuscita: "+e.getMessage(),e);      
  343.         }  
  344.     }

  345.     public IProtocolFactory<?> getProtocolFactory() {
  346.         return this.protocolFactory;
  347.     }

  348.     public SOAPHeaderElement sbustamento(OpenSPCoop2Message msg,
  349.             ProprietaManifestAttachments proprietaManifestAttachments)
  350.             throws ProtocolException {
  351.         return this.sbustamentoEGov(msg, proprietaManifestAttachments);
  352.     }

  353. }