SDIValidatoreServizioRiceviNotifica.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.sdi.validator;

  21. import java.io.ByteArrayInputStream;
  22. import java.util.Iterator;
  23. import java.util.List;

  24. import javax.xml.namespace.QName;
  25. import javax.xml.soap.AttachmentPart;
  26. import javax.xml.soap.SOAPElement;

  27. import org.openspcoop2.message.OpenSPCoop2Message;
  28. import org.openspcoop2.message.OpenSPCoop2MessageFactory;
  29. import org.openspcoop2.message.soap.SoapUtils;
  30. import org.openspcoop2.message.soap.mtom.MTOMUtilities;
  31. import org.openspcoop2.protocol.sdi.config.SDIProperties;
  32. import org.openspcoop2.protocol.sdi.constants.SDICostanti;
  33. import org.openspcoop2.protocol.sdi.constants.SDICostantiServizioRiceviNotifica;
  34. import org.openspcoop2.protocol.sdi.utils.SDICompatibilitaNamespaceErrati;
  35. import org.openspcoop2.protocol.sdk.Busta;
  36. import org.openspcoop2.protocol.sdk.Eccezione;
  37. import org.openspcoop2.protocol.sdk.IProtocolFactory;
  38. import org.openspcoop2.protocol.sdk.constants.CodiceErroreCooperazione;
  39. import org.openspcoop2.utils.Utilities;
  40. import org.openspcoop2.utils.io.Base64Utilities;
  41. import org.openspcoop2.utils.xml.AbstractValidatoreXSD;
  42. import org.w3c.dom.Element;

  43. import it.gov.fatturapa.sdi.messaggi.v1_0.NotificaEsitoCommittenteType;
  44. import it.gov.fatturapa.sdi.messaggi.v1_0.ScartoEsitoCommittenteType;
  45. import it.gov.fatturapa.sdi.messaggi.v1_0.constants.TipiMessaggi;
  46. import it.gov.fatturapa.sdi.ws.ricezione.v1_0.types.constants.EsitoNotificaType;
  47. import it.gov.fatturapa.sdi.ws.ricezione.v1_0.types.utils.ProjectInfo;

  48. /**
  49.  * SDIValidatoreServizioRiceviNotifica
  50.  *
  51.  * @author Andrea Poli (apoli@link.it)
  52.  * @author $Author$
  53.  * @version $Rev$, $Date$
  54.  */
  55. public class SDIValidatoreServizioRiceviNotifica {

  56.     private SDIValidazioneSintattica sdiValidazioneSintattica;
  57.     private SDIValidazioneSemantica sdiValidazioneSemantica;
  58.     private OpenSPCoop2Message msg;
  59.     private OpenSPCoop2MessageFactory messageFactory;
  60.     private boolean isRichiesta;
  61.     private SOAPElement sdiMessage;
  62.     private String namespace;
  63.     private Busta busta;
  64.        
  65.    
  66.     public SDIValidatoreServizioRiceviNotifica(SDIValidazioneSintattica sdiValidazioneSintattica,
  67.             OpenSPCoop2Message msg,boolean isRichiesta,
  68.             SOAPElement sdiMessage,Busta busta){
  69.         this.sdiValidazioneSintattica = sdiValidazioneSintattica;
  70.         this.msg = msg;
  71.         this.messageFactory = this.msg!=null ? this.msg.getFactory() : OpenSPCoop2MessageFactory.getDefaultMessageFactory();
  72.         this.isRichiesta = isRichiesta;
  73.         this.sdiMessage = sdiMessage;
  74.         this.namespace = ProjectInfo.getInstance().getProjectNamespace();
  75.         this.busta = busta;
  76.     }
  77.     public SDIValidatoreServizioRiceviNotifica(SDIValidazioneSemantica sdiValidazioneSemantica,
  78.             OpenSPCoop2Message msg,boolean isRichiesta,
  79.             SOAPElement sdiMessage,Busta busta){
  80.         this.sdiValidazioneSemantica = sdiValidazioneSemantica;
  81.         this.msg = msg;
  82.         this.messageFactory = this.msg!=null ? this.msg.getFactory() : OpenSPCoop2MessageFactory.getDefaultMessageFactory();
  83.         this.isRichiesta = isRichiesta;
  84.         this.sdiMessage = sdiMessage;
  85.         this.namespace = SDICostantiServizioRiceviNotifica.SDI_SERVIZIO_RICEVI_NOTIFICA_NAMESPACE;
  86.         this.busta = busta;
  87.     }
  88.    
  89.     private boolean checkServiceNamespace() throws Exception{
  90.         if(this.namespace.equals(this.sdiMessage.getNamespaceURI())==false){
  91.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  92.                     "Namespace ["+this.sdiMessage.getNamespaceURI()+"] differente da quello atteso ["+this.namespace+"]"));
  93.             return false;  
  94.         }
  95.         return true;
  96.     }
  97.    
  98.    
  99.    
  100.     /* ***** validaNotificaEsito ***** */
  101.        
  102.     public void validaNotificaEsito() throws Exception{
  103.        
  104.         if(checkServiceNamespace()==false){
  105.             return;
  106.         }
  107.        
  108.         if(this.sdiValidazioneSintattica!=null){
  109.             if(this.isRichiesta){
  110.                 this._validazioneSintattica_NotificaEsito_richiesta();
  111.             }
  112.             else{
  113.                 this._validazioneSintattica_NotificaEsito_risposta();
  114.             }
  115.         }
  116.         else{
  117.             if(this.isRichiesta){
  118.                 this._validazioneSemantica_NotificaEsito_richiesta();
  119.             }
  120.             else{
  121.                 this._validazioneSemantica_NotificaEsito_risposta();
  122.             }
  123.         }
  124.        
  125.     }
  126.     private void _validazioneSintattica_NotificaEsito_richiesta() throws Exception{
  127.        
  128.         if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ROOT_ELEMENT.equals(this.sdiMessage.getLocalName())==false){
  129.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  130.                     "LocalName ["+this.sdiMessage.getLocalName()+"] differente da quello atteso ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ROOT_ELEMENT+"]"));
  131.             return;
  132.         }
  133.        
  134.         List<SOAPElement> elementChilds = SoapUtils.getNotEmptyChildSOAPElement(this.sdiMessage);
  135.         if(elementChilds==null || elementChilds.size()<=0){
  136.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  137.                     "RootElement [{"+this.namespace+"}"+this.sdiMessage.getLocalName()+"] non contiene elementi"));
  138.             return;
  139.         }
  140.        
  141.         String identificativoSdI = null;
  142.         String nomeFile = null;
  143.         Boolean fileRead = null;
  144.         for (int i = 0; i < elementChilds.size(); i++) {
  145.             SOAPElement child = elementChilds.get(i);
  146.    
  147.             if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_IDENTIFICATIVO_SDI.equals(child.getLocalName())){
  148.                 if(identificativoSdI!=null){
  149.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  150.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.IDENTIFICATIVO_MESSAGGIO_PRESENTE_PIU_VOLTE));
  151.                     return;
  152.                 }
  153.                 if(child.getTextContent()==null){
  154.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  155.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.IDENTIFICATIVO_MESSAGGIO_NON_VALORIZZATO));
  156.                     return;
  157.                 }
  158.                 identificativoSdI = child.getTextContent();
  159.             }
  160.             else if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_NOME_FILE.equals(child.getLocalName())){
  161.                 if(nomeFile!=null){
  162.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  163.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  164.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_NOME_FILE+"] presente piu' volte"));
  165.                     return;
  166.                 }
  167.                 if(child.getTextContent()==null){
  168.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  169.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  170.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_NOME_FILE+"] non valorizzato"));
  171.                     return;
  172.                 }
  173.                 nomeFile = child.getTextContent();
  174.             }
  175.             else if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE.equals(child.getLocalName())){
  176.                 if(fileRead!=null){
  177.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  178.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  179.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] presente piu' volte"));
  180.                     return;
  181.                 }
  182.                 // Il contenuto viene gestito nella validazione semantica (poiche' deve essere applicata la sicurezza per la firma)
  183.                 fileRead = true;
  184.             }
  185.             else{
  186.                 this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  187.                         "Element ["+child.getLocalName()+"] sconosciuto"));
  188.                 return;
  189.             }
  190.            
  191.             if(child.getNamespaceURI()!=null){
  192.                 this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  193.                         "Element ["+child.getLocalName()+"] appartiene al namespace ("+child.getNamespaceURI()+"). Era atteso un elemento senza namespace"));
  194.                 return;
  195.             }
  196.         }
  197.         if(identificativoSdI==null){
  198.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  199.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.IDENTIFICATIVO_MESSAGGIO_NON_PRESENTE));
  200.             return;
  201.         }
  202.         if(nomeFile==null){
  203.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  204.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  205.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_NOME_FILE+"] non presente"));
  206.             return;
  207.         }
  208.         if(fileRead==null){
  209.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  210.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  211.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] non presente"));
  212.             return;
  213.         }
  214.        
  215.         // nomeFile
  216.         try{
  217.             SDIValidatoreNomeFile.validaNomeFileMessaggi(nomeFile, TipiMessaggi.EC);
  218.         }catch(Exception e){
  219.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  220.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  221.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_NOME_FILE+"] non valido: "+e.getMessage(),e,
  222.                             !this.sdiValidazioneSintattica.sdiProperties.isEnableValidazioneNomeFile()));
  223.             if(this.sdiValidazioneSintattica.sdiProperties.isEnableValidazioneNomeFile()){
  224.                 return;
  225.             }
  226.         }
  227.        
  228.         // setto i valori sdi nella busta
  229.         this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_IDENTIFICATIVO_SDI, identificativoSdI);
  230.         this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_NOME_FILE, nomeFile);
  231.        
  232.        
  233.     }
  234.    
  235.     private void _validazioneSemantica_NotificaEsito_richiesta() throws Exception{
  236.        
  237.         // NOTA: Il contenuto viene gestito nella validazione semantica (poiche' deve essere applicata la sicurezza per la firma)
  238.        
  239.         /* **** ESITO COMMITTENTE **** */
  240.        
  241.         byte[] esito = null;
  242.         try{
  243.             // la validazione sintattica garantisce la presenza
  244.             QName qnameEsito = new QName(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE);
  245.             Iterator<?> nodeEsitoIt = this.sdiMessage.getChildElements(qnameEsito);
  246.             SOAPElement nodeEsito = (SOAPElement) nodeEsitoIt.next();
  247.            
  248.             Element xomReference = MTOMUtilities.getIfExistsXomReference(this.messageFactory, nodeEsito);
  249.             if(xomReference!=null){
  250.                 try{
  251.                     String cid = MTOMUtilities.getCidXomReference(xomReference);
  252.                     if(cid==null){
  253.                         throw new Exception("XomReference without cid reference");
  254.                     }
  255.                     AttachmentPart ap = MTOMUtilities.getAttachmentPart(this.msg, cid);
  256.                     esito = Utilities.getAsByteArray(ap.getDataHandler().getInputStream());
  257.                     if(esito==null || esito.length<=0){
  258.                         throw new Exception("Contenuto non presente");
  259.                     }
  260.                 }catch(Exception e){
  261.                     this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  262.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  263.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] non valorizzato correttamente: "+e.getMessage(),e));
  264.                     return;
  265.                 }
  266.             }else{
  267.                 if(nodeEsito.getTextContent()==null){
  268.                     this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  269.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  270.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] non valorizzato"));
  271.                     return;
  272.                 }
  273.                 String base64Metadati = nodeEsito.getTextContent();
  274.                 if(base64Metadati==null || "".equals(base64Metadati)){
  275.                     throw new Exception("Codifica Base64 non presente");
  276.                 }
  277.                 try{
  278.                     esito = Base64Utilities.decode(base64Metadati);
  279.                 }catch(Exception e){
  280.                     // un errore non dovrebbe mai capitare, la validazione sintattica garantisce la presenza
  281.                     this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  282.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  283.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] decodifica base64 non riuscita: "+e.getMessage(),e));
  284.                     return;
  285.                 }
  286.             }
  287.            
  288.            
  289.         }catch(Exception e){
  290.             // un errore non dovrebbe mai capitare, la validazione sintattica garantisce la presenza
  291.             this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  292.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  293.                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] non accessibile: "+e.getMessage(),e));
  294.             return;
  295.         }
  296.         this._validazioneEsito(esito,this.sdiValidazioneSemantica.sdiProperties,this.sdiValidazioneSemantica.erroriValidazione,
  297.                 this.sdiValidazioneSemantica.validazioneUtils,this.sdiValidazioneSemantica.getProtocolFactory());
  298.        
  299.     }
  300.    
  301.     private void _validazioneEsito(byte[] esitoDoc, SDIProperties sdiProperties,
  302.             List<Eccezione> eccezioniValidazione, SDIValidazioneUtils validazioneUtils, IProtocolFactory<?> protocolFactory) throws Exception{
  303.    
  304.         boolean forceEccezioneLivelloInfo = false;
  305.         if(sdiProperties.isEnableAccessoMessaggi() == false) {
  306.             return;
  307.         }
  308.         else if(sdiProperties.isEnableAccessoMessaggiWarningMode()) {
  309.             forceEccezioneLivelloInfo = true;
  310.         }
  311.        
  312.         byte[] esito = esitoDoc;
  313.         if(sdiProperties.isEnableValidazioneMessaggiCompatibilitaNamespaceSenzaGov()){
  314.             esito = SDICompatibilitaNamespaceErrati.convertiXmlNamespaceSenzaGov(protocolFactory.getLogger(), esito);
  315.         }
  316.        
  317.         // validazione XSD file
  318.         if(sdiProperties.isEnableValidazioneXsdMessaggi()){
  319.             try{
  320.                 AbstractValidatoreXSD validatore =
  321.                         it.gov.fatturapa.sdi.messaggi.v1_0.utils.XSDValidatorWithSignature.getOpenSPCoop2MessageXSDValidator(protocolFactory.getLogger());
  322.                 validatore.valida(new ByteArrayInputStream(esito));
  323.             }catch(Exception e){
  324.                 eccezioniValidazione.add(
  325.                         validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  326.                                 "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] contiene un file Notifica di Esito Committente non valido rispetto allo schema XSD: "+
  327.                                         e.getMessage(),e,forceEccezioneLivelloInfo));
  328.                 return; // esco anche in caso di forceEccezioneLivelloInfo poiche' i messaggi non sono ben formati e non ha senso andare avanti
  329.             }
  330.         }
  331.        
  332.         // Lettura
  333.         NotificaEsitoCommittenteType esitoObject = null;
  334.         try{
  335.             it.gov.fatturapa.sdi.messaggi.v1_0.utils.serializer.JaxbDeserializer deserializer =
  336.                     new it.gov.fatturapa.sdi.messaggi.v1_0.utils.serializer.JaxbDeserializer();
  337.             esitoObject = deserializer.readNotificaEsitoCommittenteType(esito);
  338.         }catch(Exception e){
  339.             eccezioniValidazione.add(
  340.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  341.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RICHIESTA_ELEMENT_FILE+"] contiene un file Notifica di Esito Committente non valido: "+
  342.                                     e.getMessage(),e, forceEccezioneLivelloInfo));
  343.             return; // esco anche in caso di forceEccezioneLivelloInfo poiche' i messaggi non sono ben formati e non ha senso andare avanti
  344.         }
  345.        
  346.         // Esito.IdentificativoSdI
  347.         if(esitoObject.getIdentificativoSdI()!=null){
  348.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_IDENTIFICATIVO_SDI, esitoObject.getIdentificativoSdI().toString());
  349.         }
  350.        
  351.         // Esito.RiferimentoFattura
  352.         if(esitoObject.getRiferimentoFattura()!=null){
  353.             if(esitoObject.getRiferimentoFattura().getAnnoFattura()!=null){
  354.                 this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_RIFERIMENTO_FATTURA_ANNO, esitoObject.getRiferimentoFattura().getAnnoFattura().toString());
  355.             }
  356.             if(esitoObject.getRiferimentoFattura().getNumeroFattura()!=null){
  357.                 this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_RIFERIMENTO_FATTURA_NUMERO, esitoObject.getRiferimentoFattura().getNumeroFattura());
  358.             }
  359.             if(esitoObject.getRiferimentoFattura().getPosizioneFattura()!=null){
  360.                 this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_RIFERIMENTO_FATTURA_POSIZIONE, esitoObject.getRiferimentoFattura().getPosizioneFattura().toString());
  361.             }
  362.         }
  363.        
  364.         // Esito.Esito
  365.         if(esitoObject.getEsito()!=null){
  366.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_ESITO, esitoObject.getEsito().name());
  367.         }
  368.                
  369.         // Esito.Descrizione
  370.         if(esitoObject.getDescrizione()!=null){
  371.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_DESCRIZIONE, esitoObject.getDescrizione());
  372.         }
  373.        
  374.         // Esito.MessageId
  375.         if(esitoObject.getMessageIdCommittente()!=null){
  376.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_MESSAGE_ID_COMMITTENTE, esitoObject.getMessageIdCommittente());
  377.         }
  378.        
  379.     }
  380.    
  381.    
  382.    
  383.    
  384.     private void _validazioneSintattica_NotificaEsito_risposta() throws Exception{
  385.        
  386.         if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ROOT_ELEMENT.equals(this.sdiMessage.getLocalName())==false){
  387.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  388.                     "LocalName ["+this.sdiMessage.getLocalName()+"] differente da quello atteso ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ROOT_ELEMENT+"]"));
  389.             return;
  390.         }
  391.        
  392.         List<SOAPElement> elementChilds = SoapUtils.getNotEmptyChildSOAPElement(this.sdiMessage);
  393.         if(elementChilds==null || elementChilds.size()<=0){
  394.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  395.                     "RootElement [{"+this.namespace+"}"+this.sdiMessage.getLocalName()+"] non contiene elementi"));
  396.             return;
  397.         }
  398.        
  399.         String esito = null;
  400.         Boolean scartoElementRead = null;
  401.         String nomeFileScartoEsito = null;
  402.         Boolean scartoEsitoRead = null;
  403.         for (int i = 0; i < elementChilds.size(); i++) {
  404.             SOAPElement child = elementChilds.get(i);
  405.    
  406.             if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_ESITO.equals(child.getLocalName())){
  407.                 if(esito!=null){
  408.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  409.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  410.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_ESITO+"] presente piu' volte"));
  411.                     return;
  412.                 }
  413.                 if(child.getTextContent()==null){
  414.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  415.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  416.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_ESITO+"] non valorizzato"));
  417.                     return;
  418.                 }
  419.                 esito = child.getTextContent();
  420.             }
  421.             else if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO.equals(child.getLocalName())){
  422.                 if(scartoElementRead!=null){
  423.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  424.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  425.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO+"] presente piu' volte"));
  426.                     return;
  427.                 }
  428.                 scartoElementRead = true;
  429.                
  430.                 List<SOAPElement> elementScartoChilds = SoapUtils.getNotEmptyChildSOAPElement(child);
  431.                 if(elementScartoChilds==null || elementScartoChilds.size()<=0){
  432.                     this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  433.                             validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  434.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO+"] non contiene elementi"));
  435.                     return;
  436.                 }
  437.                 for (int j = 0; j < elementScartoChilds.size(); j++) {
  438.                     SOAPElement scartoChild = elementScartoChilds.get(j);
  439.                
  440.                     if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_NOME_FILE.equals(scartoChild.getLocalName())){
  441.                         if(nomeFileScartoEsito!=null){
  442.                             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  443.                                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  444.                                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_NOME_FILE+"] presente piu' volte"));
  445.                             return;
  446.                         }
  447.                         if(scartoChild.getTextContent()==null){
  448.                             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  449.                                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  450.                                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_NOME_FILE+"] non valorizzato"));
  451.                             return;
  452.                         }
  453.                         nomeFileScartoEsito = scartoChild.getTextContent();
  454.                     }
  455.                     else if(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_FILE.equals(scartoChild.getLocalName())){
  456.                         if(scartoEsitoRead!=null){
  457.                             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  458.                                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  459.                                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_FILE+"] presente piu' volte"));
  460.                             return;
  461.                         }
  462.                         // Il contenuto viene gestito nella validazione semantica (poiche' deve essere applicata la sicurezza per la firma)
  463.                         scartoEsitoRead = true;
  464.                     }
  465.                 }
  466.                
  467.             }
  468.             else{
  469.                 this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  470.                         validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  471.                         "Element ["+child.getLocalName()+"] sconosciuto"));
  472.                 return;
  473.             }
  474.            
  475.             if(child.getNamespaceURI()!=null){
  476.                 this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  477.                         validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  478.                         "Element ["+child.getLocalName()+"] appartiene al namespace ("+child.getNamespaceURI()+"). Era atteso un elemento senza namespace"));
  479.                 return;
  480.             }
  481.         }
  482.        
  483.         // esito
  484.         if(esito==null){
  485.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  486.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  487.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_ESITO+"] non presente"));
  488.             return;
  489.         }
  490.         try{
  491.             if(!EsitoNotificaType.ES00.name().equals(esito) &&
  492.                     !EsitoNotificaType.ES01.name().equals(esito) &&
  493.                     !EsitoNotificaType.ES02.name().equals(esito) ){
  494.                 throw new Exception("Valore ["+esito+"] differente dai valori attesi: ["+EsitoNotificaType.ES00.name()+","+EsitoNotificaType.ES01.name()+","+EsitoNotificaType.ES02.name()+"]");
  495.             }
  496.         }catch(Exception e){
  497.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  498.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  499.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_ESITO+"] non valido: "+e.getMessage(),e));
  500.             return;
  501.         }
  502.        
  503.         // scartoEsito (presente solo se ES00 = NOTIFICA NON ACCETTATA)
  504.         if(EsitoNotificaType.ES00.name().equals(esito)){
  505.             if(scartoEsitoRead==null){
  506.                 this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  507.                         validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  508.                                 "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO+"] non presente (richiesto dallo stato "+EsitoNotificaType.ES00.name()+")"));
  509.                 return;
  510.             }
  511.            
  512.             // nomeFile
  513.             try{
  514.                 SDIValidatoreNomeFile.validaNomeFileMessaggi(nomeFileScartoEsito, TipiMessaggi.SE);
  515.             }catch(Exception e){
  516.                 this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  517.                         validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  518.                                 "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_NOME_FILE+"] non valido: "+e.getMessage(),e,
  519.                                 !this.sdiValidazioneSintattica.sdiProperties.isEnableValidazioneNomeFile()));
  520.                 if(this.sdiValidazioneSintattica.sdiProperties.isEnableValidazioneNomeFile()){
  521.                     return;
  522.                 }
  523.             }
  524.            
  525.         }
  526.        
  527.         // ES02 = SERVIZIO NON DISPONIBILE
  528.         else if(EsitoNotificaType.ES02.name().equals(esito)){
  529.             this.sdiValidazioneSintattica.erroriValidazione.add(this.sdiValidazioneSintattica.
  530.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  531.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO+"] indica un ES02 - Sistema non Disponibile del SdI"));
  532.             return;
  533.         }
  534.                
  535.         // setto i valori sdi nella busta
  536.         this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_ESITO_NOTIFICA, esito);
  537.        
  538.        
  539.     }
  540.    
  541.     private void _validazioneSemantica_NotificaEsito_risposta() throws Exception{
  542.        
  543.         // NOTA: Il contenuto viene gestito nella validazione semantica (poiche' deve essere applicata la sicurezza per la firma)
  544.        
  545.         /* **** SCARTO ESITO COMMITTENTE **** */
  546.        
  547.         byte[] scartoEsito = null;
  548.         try{
  549.             // la validazione sintattica garantisce la presenza se richiesta
  550.             QName qnameEsito = new QName(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO);
  551.             Iterator<?> nodeEsitoIt = this.sdiMessage.getChildElements(qnameEsito);
  552.             SOAPElement nodeEsito = null;
  553.             if(nodeEsitoIt!=null){
  554.                 Object o = null;
  555.                 try{
  556.                     o = nodeEsitoIt.next();
  557.                 }catch(Exception e){
  558.                     // ignore
  559.                 }
  560.                 if(o!=null){
  561.                     nodeEsito = (SOAPElement) o;
  562.                 }
  563.             }
  564.            
  565.             if(nodeEsito!=null){

  566.                 QName qnameEsitoFile = new QName(SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_FILE);
  567.                 Iterator<?> nodeEsitoFileIt = nodeEsito.getChildElements(qnameEsitoFile);
  568.                 SOAPElement nodeEsitoFile = null;
  569.                 if(nodeEsitoFileIt!=null){
  570.                     Object o = null;
  571.                     try{
  572.                         o = nodeEsitoFileIt.next();
  573.                     }catch(Exception e){
  574.                         // ignore
  575.                     }
  576.                     if(o!=null){
  577.                         nodeEsitoFile = (SOAPElement) o;
  578.                     }
  579.                 }
  580.                
  581.                 if(nodeEsitoFile!=null){
  582.                     Element xomReference = MTOMUtilities.getIfExistsXomReference(this.messageFactory, nodeEsitoFile);
  583.                     if(xomReference!=null){
  584.                         try{
  585.                             String cid = MTOMUtilities.getCidXomReference(xomReference);
  586.                             if(cid==null){
  587.                                 throw new Exception("XomReference without cid reference");
  588.                             }
  589.                             AttachmentPart ap = MTOMUtilities.getAttachmentPart(this.msg, cid);
  590.                             scartoEsito = Utilities.getAsByteArray(ap.getDataHandler().getInputStream());
  591.                             if(scartoEsito==null || scartoEsito.length<=0){
  592.                                 throw new Exception("Contenuto non presente");
  593.                             }
  594.                         }catch(Exception e){
  595.                             this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  596.                                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  597.                                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_FILE+"] non valorizzato correttamente: "+e.getMessage(),e));
  598.                             return;
  599.                         }
  600.                     }else{
  601.                         if(nodeEsitoFile.getTextContent()==null){
  602.                             this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  603.                                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  604.                                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_FILE+"] non valorizzato"));
  605.                             return;
  606.                         }
  607.                         String base64Metadati = nodeEsitoFile.getTextContent();
  608.                         if(base64Metadati==null || "".equals(base64Metadati)){
  609.                             throw new Exception("Codifica Base64 non presente");
  610.                         }
  611.                         try{
  612.                             scartoEsito = Base64Utilities.decode(base64Metadati);
  613.                         }catch(Exception e){
  614.                             // un errore non dovrebbe mai capitare, la validazione sintattica garantisce la presenza
  615.                             this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  616.                                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  617.                                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_FILE+"] decodifica base64 non riuscita: "+e.getMessage(),e));
  618.                             return;
  619.                         }
  620.                     }
  621.                 }
  622.                
  623.             }
  624.                        
  625.         }catch(Exception e){
  626.             // un errore non dovrebbe mai capitare, la validazione sintattica garantisce la presenza
  627.             this.sdiValidazioneSemantica.erroriValidazione.add(this.sdiValidazioneSemantica.
  628.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  629.                     "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO_FILE+"] non accessibile: "+e.getMessage(),e));
  630.             return;
  631.         }
  632.         if(scartoEsito!=null){
  633.             this._validazioneScartoEsito(scartoEsito,this.sdiValidazioneSemantica.sdiProperties,this.sdiValidazioneSemantica.erroriValidazione,
  634.                     this.sdiValidazioneSemantica.validazioneUtils,this.sdiValidazioneSemantica.getProtocolFactory());
  635.         }
  636.        
  637.        
  638.     }
  639.    
  640.     private void _validazioneScartoEsito(byte[] esitoDoc, SDIProperties sdiProperties,
  641.             List<Eccezione> eccezioniValidazione, SDIValidazioneUtils validazioneUtils, IProtocolFactory<?> protocolFactory) throws Exception{
  642.    
  643.         boolean forceEccezioneLivelloInfo = false;
  644.         if(sdiProperties.isEnableAccessoMessaggi() == false) {
  645.             return;
  646.         }
  647.         else if(sdiProperties.isEnableAccessoMessaggiWarningMode()) {
  648.             forceEccezioneLivelloInfo = true;
  649.         }
  650.        
  651.         byte[] esito = esitoDoc;
  652.         if(sdiProperties.isEnableValidazioneMessaggiCompatibilitaNamespaceSenzaGov()){
  653.             esito = SDICompatibilitaNamespaceErrati.convertiXmlNamespaceSenzaGov(protocolFactory.getLogger(), esito);
  654.         }
  655.        
  656.         // validazione XSD file
  657.         if(sdiProperties.isEnableValidazioneXsdMessaggi()){
  658.             try{
  659.                 AbstractValidatoreXSD validatore =
  660.                         it.gov.fatturapa.sdi.messaggi.v1_0.utils.XSDValidatorWithSignature.getOpenSPCoop2MessageXSDValidator(protocolFactory.getLogger());
  661.                 validatore.valida(new ByteArrayInputStream(esito));
  662.             }catch(Exception e){
  663.                 eccezioniValidazione.add(
  664.                         validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  665.                                 "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO+"] contiene un file Notifica di Scarto Esito Committente non valido rispetto allo schema XSD: "+
  666.                                         e.getMessage(),e, forceEccezioneLivelloInfo));
  667.                 return; // esco anche in caso di forceEccezioneLivelloInfo poiche' i messaggi non sono ben formati e non ha senso andare avanti
  668.             }
  669.         }
  670.        
  671.         // Lettura
  672.         ScartoEsitoCommittenteType scartoEsitoObject = null;
  673.         try{
  674.             it.gov.fatturapa.sdi.messaggi.v1_0.utils.serializer.JaxbDeserializer deserializer =
  675.                     new it.gov.fatturapa.sdi.messaggi.v1_0.utils.serializer.JaxbDeserializer();
  676.             scartoEsitoObject = deserializer.readScartoEsitoCommittenteType(esito);
  677.             if(sdiProperties.isSaveMessaggiInContext()){
  678.                 this.msg.addContextProperty(SDICostanti.SDI_MESSAGE_CONTEXT_MESSAGGIO_SERVIZIO_SDI, scartoEsitoObject);
  679.             }
  680.         }catch(Exception e){
  681.             eccezioniValidazione.add(
  682.                     validazioneUtils.newEccezioneValidazione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO,
  683.                             "Elemento ["+SDICostantiServizioRiceviNotifica.NOTIFICA_ESITO_RISPOSTA_ELEMENT_SCARTO_ESITO+"] contiene un file Notifica di Scarto Esito Committente non valido: "+
  684.                                     e.getMessage(),e, forceEccezioneLivelloInfo));
  685.             return; // esco anche in caso di forceEccezioneLivelloInfo poiche' i messaggi non sono ben formati e non ha senso andare avanti
  686.         }
  687.        
  688.         // Esito.IdentificativoSdI
  689.         if(scartoEsitoObject.getIdentificativoSdI()!=null){
  690.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_IDENTIFICATIVO_SDI, scartoEsitoObject.getIdentificativoSdI().toString());
  691.         }
  692.        
  693.         // Esito.RiferimentoFattura
  694.         if(scartoEsitoObject.getRiferimentoFattura()!=null){
  695.             if(scartoEsitoObject.getRiferimentoFattura().getAnnoFattura()!=null){
  696.                 this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_RIFERIMENTO_FATTURA_ANNO, scartoEsitoObject.getRiferimentoFattura().getAnnoFattura().toString());
  697.             }
  698.             if(scartoEsitoObject.getRiferimentoFattura().getNumeroFattura()!=null){
  699.                 this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_RIFERIMENTO_FATTURA_NUMERO, scartoEsitoObject.getRiferimentoFattura().getNumeroFattura());
  700.             }
  701.             if(scartoEsitoObject.getRiferimentoFattura().getPosizioneFattura()!=null){
  702.                 this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_RIFERIMENTO_FATTURA_POSIZIONE, scartoEsitoObject.getRiferimentoFattura().getPosizioneFattura().toString());
  703.             }
  704.         }
  705.        
  706.         // Esito.Scarto
  707.         if(scartoEsitoObject.getScarto()!=null){
  708.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_SCARTO, scartoEsitoObject.getScarto().name());
  709.         }
  710.                        
  711.         // Esito.MessageId
  712.         if(scartoEsitoObject.getMessageId()!=null){
  713.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_MESSAGE_ID, scartoEsitoObject.getMessageId());
  714.         }
  715.         if(scartoEsitoObject.getMessageIdCommittente()!=null){
  716.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_MESSAGE_ID_COMMITTENTE, scartoEsitoObject.getMessageIdCommittente());
  717.         }
  718.        
  719.         // Esito.Note
  720.         if(scartoEsitoObject.getNote()!=null){
  721.             this.busta.addProperty(SDICostanti.SDI_BUSTA_EXT_NOTE, scartoEsitoObject.getNote());
  722.         }
  723.        
  724.     }
  725.    
  726. }