SPCoopValidazioneConSchema.java
/*
* GovWay - A customizable API Gateway
* https://govway.org
*
* Copyright (c) 2005-2024 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.protocol.spcoop.validator;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import javax.xml.soap.SOAPBody;
import javax.xml.soap.SOAPElement;
import org.openspcoop2.message.OpenSPCoop2Message;
import org.openspcoop2.message.OpenSPCoop2MessageFactory;
import org.openspcoop2.message.constants.MessageType;
import org.openspcoop2.message.xml.ValidatoreXSD;
import org.openspcoop2.message.xml.MessageXMLUtils;
import org.openspcoop2.protocol.basic.BasicStateComponentFactory;
import org.openspcoop2.protocol.sdk.Eccezione;
import org.openspcoop2.protocol.sdk.IProtocolFactory;
import org.openspcoop2.protocol.sdk.ProtocolException;
import org.openspcoop2.protocol.sdk.constants.CodiceErroreCooperazione;
import org.openspcoop2.protocol.sdk.constants.ContestoCodificaEccezione;
import org.openspcoop2.protocol.sdk.constants.LivelloRilevanza;
import org.openspcoop2.protocol.sdk.state.IState;
import org.openspcoop2.protocol.sdk.validator.IValidazioneConSchema;
import org.openspcoop2.protocol.spcoop.SPCoopBustaRawContent;
import org.openspcoop2.protocol.spcoop.config.SPCoopProperties;
import org.openspcoop2.utils.LoggerWrapperFactory;
import org.openspcoop2.utils.xml.XSDResourceResolver;
import org.slf4j.Logger;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;
/**
* Classe che implementa, in base al protocollo SPCoop, l'interfaccia {@link org.openspcoop2.protocol.sdk.validator.IValidazioneConSchema}
* Utilizzata per effettuare una validazione con schema xsd di SPCoop.
*
* @author Poli Andrea (apoli@link.it)
* @author $Author$
* @version $Rev$, $Date$
*/
public class SPCoopValidazioneConSchema extends BasicStateComponentFactory implements IValidazioneConSchema {
/** Validatore della busta SPCoop */
private static HashMap<String, ValidatoreXSD> validatoreBustaSPCoop_map = new HashMap<String, ValidatoreXSD>();
/** Errori di validazione riscontrati sulla busta */
private java.util.List<Eccezione> erroriValidazione;
/** Errori di processamento riscontrati sulla busta */
private java.util.List<Eccezione> erroriProcessamento;
/**
* Costruttore.
*
* @param protocolFactory ProtocolFactory
* @throws ProtocolException
*
*/
public SPCoopValidazioneConSchema(IProtocolFactory<?> protocolFactory,IState state) throws ProtocolException{
super(protocolFactory, state);
}
/**
* Ritorna un List contenente eventuali eccezioni di validazione riscontrate nella busta SPCoop.
*
* @return Eccezioni riscontrate nella busta SPCoop.
*
*/
@Override
public java.util.List<Eccezione> getEccezioniValidazione(){
return this.erroriValidazione;
}
/**
* Ritorna un List contenente eventuali eccezioni di processamento riscontrate nella busta SPCoop.
*
* @return Eccezioni riscontrate nella busta SPCoop.
*
*/
@Override
public java.util.List<Eccezione> getEccezioniProcessamento(){
return this.erroriProcessamento;
}
/**
* Metodo che si occupa di inizializzare lo schema della busta SPCoop utilizzato per la validazione.
*
*
*/
public static synchronized boolean initializeSchema(OpenSPCoop2MessageFactory messageFactory, Logger log) {
String key = messageFactory.getClass().getName();
if(!validatoreBustaSPCoop_map.containsKey(key)) {
if(log==null)
log = LoggerWrapperFactory.getLogger("ValidazioneConSchemaSPCoop");
try{
SPCoopProperties spcoopProperties = SPCoopProperties.getInstance(log);
log.info("Inizializzazione dello schema per il protocollo spcoop (possono essere necessari alcuni minuti...)");
String[] schemiXSDDaImportare = spcoopProperties.getSchemiXSDImportatiValidazioneXSDBusta();
String schemaXSD = spcoopProperties.getSchemaXSDValidazioneXSDBusta();
ValidatoreXSD val = SPCoopValidazioneConSchema.createSchemaValidator(messageFactory, log,schemiXSDDaImportare, schemaXSD);
validatoreBustaSPCoop_map.put(key, val);
log.info("Inizializzazione dello schema per il protocollo spcoop terminata.");
return true;
}catch (Exception e) {
log.error("Riscontrato errore durante l'inizializzazione dello schema per il protocollo spcoop: "+e.getMessage(),e);
return false;
}
}
return true; // gia' inizializzato
}
private static ValidatoreXSD getValidatoreXSD(OpenSPCoop2MessageFactory messageFactory, Logger log) {
String key = messageFactory.getClass().getName();
if(!validatoreBustaSPCoop_map.containsKey(key)) {
initializeSchema(messageFactory, log);
}
return validatoreBustaSPCoop_map.get(key);
}
private static ValidatoreXSD createSchemaValidator(OpenSPCoop2MessageFactory messageFactory,Logger log,String[] schemiXSDDaImportare,String schemaXSD) throws Exception{
// ** Schemi importati **
XSDResourceResolver xsdResourceResolver = new XSDResourceResolver();
if(schemiXSDDaImportare!=null){
for(int i=0;i<schemiXSDDaImportare.length;i++){
File fXsd = new File(schemiXSDDaImportare[i]);
InputStream is = null;
try{
if(fXsd.exists()){
is = new FileInputStream(fXsd);
}else{
is = SPCoopValidazioneConSchema.class.getResourceAsStream("/"+schemiXSDDaImportare[i]);
}
xsdResourceResolver.addResource(fXsd.getName(), is);
}finally{
try{
if(is!=null){
is.close();
}
}catch(Exception e){
// close
} //?????? Close effettuato dentro xsdResolver ??? : riabilitato il close.
}
}
}
// ** Schema principale **
File fXsd = new File(schemaXSD);
InputStream is = null;
try{
if(fXsd.exists()){
is = new FileInputStream(fXsd);
}else{
is = SPCoopValidazioneConSchema.class.getResourceAsStream("/"+schemaXSD);
}
// ** Creo Validatore **
return new ValidatoreXSD(messageFactory,log,xsdResourceResolver,is);
}finally{
try{
if(is!=null){
is.close();
}
}catch(Exception e){
// close
} //?????? Close effettuato dentro xsdResolver ???? : riabilitato il close.
}
}
/**
* Metodo che effettua la validazione dei soggetti di una busta, controllando la loro registrazione nel registro dei servizi.
*
* Mano mano che sono incontrati errori di validazione, viene creato un oggetto
* {@link Eccezione}, e viene inserito nel List <var>errors</var>.
*
*
*/
@Override
public void valida(OpenSPCoop2Message message, boolean isSPCoopErroreProcessamento, boolean isSPCoopErroreIntestazione,
boolean isMessaggioConAttachments, boolean validazioneManifestAttachments) throws ProtocolException{
this.erroriValidazione = new java.util.ArrayList<Eccezione>();
this.erroriProcessamento = new java.util.ArrayList<Eccezione>();
MessageXMLUtils xmlUtils = MessageXMLUtils.getInstance(message.getFactory());
ValidatoreXSD validatoreBustaSPCoop = getValidatoreXSD(message.getFactory(), this.log);
if(validatoreBustaSPCoop == null){
throw new ProtocolException("Validatore con schema XSD non inizializzato");
}
// Validazione eGov
try {
SPCoopBustaRawContent bustaElement = (SPCoopBustaRawContent) this.protocolFactory.createValidazioneSintattica(this.state).getBustaRawContent_senzaControlli(message);
SOAPElement header = bustaElement.getElement();
if(isSPCoopErroreProcessamento==false && isSPCoopErroreIntestazione==false){
// VALIDAZIONE
validatoreBustaSPCoop.valida(
xmlUtils.newDocument(OpenSPCoop2MessageFactory.getAsByte(message.getFactory(), header,false)));
}
else{
// Validazione Lista Eccezioni.
Iterator<?> itChilds = header.getChildElements();
SOAPElement listaEccezioni = null;
while(itChilds.hasNext()){
Object element = itChilds.next();
if(!(element instanceof SOAPElement)){
continue;
}
SOAPElement elemInterno = (SOAPElement) element;
if("ListaEccezioni".equals(elemInterno.getLocalName())){
listaEccezioni = elemInterno;
break;
}
}
if(listaEccezioni==null){
if(isSPCoopErroreIntestazione)
throw new SAXException("ListaEccezioni non presente in un messaggio SPCoopErrore");
}
// VALIDAZIONE
if(listaEccezioni!=null){
validatoreBustaSPCoop.valida(
xmlUtils.newDocument(OpenSPCoop2MessageFactory.getAsByte(message.getFactory(), listaEccezioni,false)));
}
}
} catch (SAXException e) {
// instance document is invalid!
Eccezione ecc = new Eccezione();
ecc.setContestoCodifica(ContestoCodificaEccezione.INTESTAZIONE);
ecc.setCodiceEccezione(CodiceErroreCooperazione.FORMATO_INTESTAZIONE_NON_CORRETTO);
ecc.setRilevanza(LivelloRilevanza.ERROR);
ecc.setDescrizione(e.getMessage());
this.erroriValidazione.add(ecc);
}catch (Exception e) {
Eccezione ecc = new Eccezione();
ecc.setContestoCodifica(ContestoCodificaEccezione.PROCESSAMENTO);
ecc.setCodiceEccezione(CodiceErroreCooperazione.ERRORE_GENERICO_PROCESSAMENTO_MESSAGGIO);
ecc.setRilevanza(LivelloRilevanza.ERROR);
ecc.setDescrizione("Validazione con schema xsd dell'header egov non riuscita: errore di processamento");
this.log.error("Validazione con schema xsd dell'header egov non riuscita non riuscita",e);
this.erroriProcessamento.add(ecc);
}
// Validazione ManifestAttachments
SOAPBody soapBody = null;
if(validazioneManifestAttachments && isMessaggioConAttachments) {
try{
soapBody = message.castAsSoap().getSOAPBody();
}catch(Exception e){
throw new ProtocolException(e.getMessage(),e);
}
}
if(soapBody!=null){
try {
// Validazione
Element firstElement = OpenSPCoop2MessageFactory.getFirstChildElement(message.getFactory(), MessageType.SOAP_11, soapBody);
//validatoreBustaSPCoop.valida(xmlUtils.newDocument(OpenSPCoop2MessageFactory.getAsByte(message.getFactory(), firstElement, false)));
validatoreBustaSPCoop.valida(firstElement);
} catch (SAXException e) {
// instance document is invalid!
Eccezione ecc = new Eccezione();
ecc.setContestoCodifica(ContestoCodificaEccezione.INTESTAZIONE);
ecc.setCodiceEccezione(CodiceErroreCooperazione.FORMATO_CORPO_NON_CORRETTO);
ecc.setRilevanza(LivelloRilevanza.ERROR);
ecc.setDescrizione("ManifestAttachments: "+e.getMessage());
this.log.error("Validazione con schema xsd del manifest degli attachments fallita",e);
this.erroriValidazione.add(ecc);
}catch (Exception e) {
Eccezione ecc = new Eccezione();
ecc.setContestoCodifica(ContestoCodificaEccezione.PROCESSAMENTO);
ecc.setCodiceEccezione(CodiceErroreCooperazione.ERRORE_GENERICO_PROCESSAMENTO_MESSAGGIO);
ecc.setRilevanza(LivelloRilevanza.ERROR);
ecc.setDescrizione("Validazione con schema xsd del manifest degli attachments non riuscita: errore di processamento");
this.log.error("Validazione con schema xsd del manifest degli attachments non riuscita",e);
this.erroriProcessamento.add(ecc);
}
}
}
@Override
public boolean initialize(OpenSPCoop2MessageFactory messageFactory) {
return SPCoopValidazioneConSchema.initializeSchema(messageFactory, this.log);
}
}