WSDLValidator.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.core.registry.wsdl;
- import java.io.ByteArrayOutputStream;
- import java.util.ArrayList;
- import java.util.List;
- import javax.xml.namespace.QName;
- import javax.xml.soap.SOAPBody;
- import javax.xml.soap.SOAPElement;
- import javax.xml.soap.SOAPEnvelope;
- import org.apache.commons.lang.StringUtils;
- import org.openspcoop2.core.registry.Message;
- import org.openspcoop2.core.registry.MessagePart;
- import org.openspcoop2.core.registry.Operation;
- import org.openspcoop2.core.registry.PortType;
- import org.openspcoop2.core.registry.constants.BindingStyle;
- import org.openspcoop2.core.registry.constants.BindingUse;
- import org.openspcoop2.core.registry.constants.CostantiRegistroServizi;
- import org.openspcoop2.core.registry.driver.DriverRegistroServiziException;
- import org.openspcoop2.core.registry.driver.IDAccordoFactory;
- import org.openspcoop2.message.MessageUtils;
- import org.openspcoop2.message.OpenSPCoop2Message;
- import org.openspcoop2.message.constants.MessageType;
- import org.openspcoop2.message.soap.SoapUtils;
- import org.openspcoop2.utils.UtilsException;
- import org.openspcoop2.utils.wsdl.WSDLException;
- import org.openspcoop2.utils.xml.AbstractValidatoreXSD;
- import org.openspcoop2.utils.xml.AbstractXMLUtils;
- import org.openspcoop2.utils.xml.ValidatoreXSD;
- import org.slf4j.Logger;
- import org.w3c.dom.Attr;
- import org.w3c.dom.Comment;
- import org.w3c.dom.Document;
- import org.w3c.dom.Element;
- import org.w3c.dom.NamedNodeMap;
- import org.w3c.dom.Node;
- import org.w3c.dom.Text;
- /**
- * Classe utilizzata per validare i messaggi applicativi.
- *
- * @author Poli Andrea (apoli@link.it)
- * @author Lezza Aldo (lezza@openspcoop.org)
- * @author Lorenzo Nardi (nardi@link.it)
- * @author $Author$
- * @version $Rev$, $Date$
- */
- public class WSDLValidator {
- public static final String XMLSCHEMA_INSTANCE_NAMESPACE = "http://www.w3.org/2001/XMLSchema-instance";
- public static final String XMLSCHEMA_INSTANCE_LOCAL_NAME_TYPE = "type";
- private static final String PREFIX_RPC_AGGIUNTO = "op2RPC";
-
- /** OpenSPCoop2Message */
- private OpenSPCoop2Message openspcoop2Message;
- /** SOAPVersion */
- private MessageType messageType;
- /** Element */
- private Element element;
- /** WSDL Associato al servizio */
- private AccordoServizioWrapper accordoServizioWrapper = null;
- /** Logger */
- private Logger logger = null;
- /** XMLUtils */
- private AbstractXMLUtils xmlUtils = null;
-
- /** Nodo xsiType Aggiunto */
- private boolean gestioneXsiTypeRpcLiteral;
- private SOAPElement rpcChildElement;
- private QName rpcChildElementNamespaceAggiunto;
- private QName rpcChildElementXSITypeAggiunto;
-
- /** Nodo rpc root element */
- private boolean rpcAcceptRootElementUnqualified;
-
- /** XSI Type */
- private boolean validationXsdAddNamespaceXSITypeIfNotExists;
- private boolean validationRpcAddNamespaceXSITypeIfNotExists;
- private boolean validationDocumentAddNamespaceXSITypeIfNotExists;
- /** Prefix error */
- private boolean addPrefixError = true;
- public boolean isAddPrefixError() {
- return this.addPrefixError;
- }
- public void setAddPrefixError(boolean addPrefixError) {
- this.addPrefixError = addPrefixError;
- }
-
- /* ------ Costruttore -------------- */
- private static Element getEngineEnvelopeCatchException(OpenSPCoop2Message msg, boolean bufferMessageReadOnly, String idTransazione) throws WSDLException {
- try {
- boolean checkSoapBodyEmpty = true;
- return MessageUtils.getContentElement(msg, checkSoapBodyEmpty, bufferMessageReadOnly, idTransazione);
- }catch(Exception e){
- throw new WSDLException(e.getMessage(),e);
- }
- }
- public WSDLValidator(OpenSPCoop2Message msg,AbstractXMLUtils xmlUtils,AccordoServizioWrapper accordoServizioWrapper,Logger log,
- WSDLValidatorConfig config, boolean addPrefixError,
- boolean bufferMessageReadOnly, String idTransazione)throws WSDLException{
- this(msg.getMessageType(), getEngineEnvelopeCatchException(msg,bufferMessageReadOnly,idTransazione), xmlUtils, accordoServizioWrapper, log,
- config, addPrefixError);
- this.openspcoop2Message = msg;
- }
- // Il costruttore sottostante non puo' sfruttare la funzionalita' addNamespaceXSITypeIfNotExists
- // per questo e' stato reso privato, poiche' tale funzionalita' richiede openspcoop2Message
- private WSDLValidator(MessageType messageType, Element element,AbstractXMLUtils xmlUtils,AccordoServizioWrapper accordoServizioWrapper,Logger log,
- WSDLValidatorConfig config, boolean addPrefixError)throws WSDLException{
-
- this.messageType = messageType;
-
- if(element==null){
- throw new WSDLException("Contenuto da validatore non fornito");
- }
- this.element = element;
- if(MessageType.SOAP_11.equals(this.messageType) || MessageType.SOAP_12.equals(this.messageType)){
- SOAPEnvelope envelope = (SOAPEnvelope) element;
- SOAPBody body = null;
- try{
- body = envelope.getBody();
- }catch(Exception e){
- if(this.logger!=null) {
- this.logger.error("SOAPEnvelope.getBody failed: "+e.getMessage(),e);
- }
- throw new WSDLException("SOAPEnvelope senza body");
- }
-
- if(body==null || (body.hasChildNodes()==false)){
- throw new WSDLException("SOAPBody non esistente");
- }
- }
-
- this.logger = log;
- this.xmlUtils = xmlUtils;
- this.accordoServizioWrapper = accordoServizioWrapper;
-
- this.gestioneXsiTypeRpcLiteral = config.isGestioneXsiTypeRpcLiteral();
-
- this.rpcAcceptRootElementUnqualified = config.isRpcAcceptRootElementUnqualified();
-
- this.validationXsdAddNamespaceXSITypeIfNotExists = config.isValidationXsdAddNamespaceXSITypeIfNotExists();
- this.validationRpcAddNamespaceXSITypeIfNotExists = config.isValidationRpcAddNamespaceXSITypeIfNotExists();
- this.validationDocumentAddNamespaceXSITypeIfNotExists = config.isValidationDocumentAddNamespaceXSITypeIfNotExists();
-
- this.addPrefixError = addPrefixError;
- }
-
-
-
-
-
-
-
- /* -------------- FINALIZE --------------------- */
- public void wsdlConformanceCheck_restoreOriginalDocument(){
- if(this.gestioneXsiTypeRpcLiteral && this.rpcChildElement!=null){
- try{
- if(this.rpcChildElementXSITypeAggiunto!=null){
- this.rpcChildElement.removeAttribute(this.rpcChildElementXSITypeAggiunto);
- }
- }catch(Exception e){
- this.logger.error("Errore durante l'eliminazione dell'attributo ["+this.rpcChildElementXSITypeAggiunto+"] dal rpc element");
- }
- try{
- if(this.rpcChildElementNamespaceAggiunto!=null){
- // alcune implementazioni usano l'uno o l'altro per eliminarlo
- this.rpcChildElement.removeAttribute(this.rpcChildElementNamespaceAggiunto);
- this.rpcChildElement.removeNamespaceDeclaration(PREFIX_RPC_AGGIUNTO);
- }
- }catch(Exception e){
- this.logger.error("Errore durante l'eliminazione dell'attributo ["+this.rpcChildElementNamespaceAggiunto+"] dal rpc element");
- }
- }
- }
-
-
-
-
-
-
-
- /* -------------- VALIDAZIONE XSD SENZA WSDL --------------------- */
-
- /**
- * Validazione xsd
- *
- * @param isRichiesta Indicazione sul tipo di messaggio applicativo da gestire
- * @throws WSDLException (contiene codice e msg di errore)
- */
- public void validateAgainstXSDSchema(boolean isRichiesta,String operationName) throws WSDLException,WSDLValidatorException{
- this.validateAgainstXSDSchema(isRichiesta, operationName, this.ptWsdlConformanceCheck, this.opWsdlConformanceCheck);
- }
- public void validateAgainstXSDSchema(boolean isRichiesta,String operationName,PortType portType,Operation operation) throws WSDLException,WSDLValidatorException{
- AbstractValidatoreXSD validatoreBodyApplicativo = null;
- try{
- if(this.accordoServizioWrapper.getSchema()!=null){
- validatoreBodyApplicativo = new ValidatoreXSD(this.accordoServizioWrapper.getSchema());
- }else{
- throw new Exception("Schema non costruito?");
- }
- }catch(Exception e){
- throw new WSDLException("Riscontrato errore durante la costruzione del validatore XSD per il contenuto applicativo: "+e.getMessage(),e);
- }
-
-
- /** ricerca ulteriore port type e operation in caso di validazione xsd */
- if(portType==null && this.accordoServizioWrapper.getNomePortType()!=null){
- // provo a cercarlo. Magari non e' stato fatto girare prima il metodo wsdlConformanceCheck
- // o magari volutamente non c'e' un wsdl perche' la validazione prevista e' XSD
- // in tal caso non e' un errore se il port type non e' presente.
- portType = this.accordoServizioWrapper.getPortType(this.accordoServizioWrapper.getNomePortType());
- if(portType==null){
- try{
- IDAccordoFactory idAccordoFactory = IDAccordoFactory.getInstance();
- String uriAccordo = idAccordoFactory.getUriFromIDAccordo(this.accordoServizioWrapper.getIdAccordoServizio());
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- this.logger.debug("Port-Type ["+this.accordoServizioWrapper.getNomePortType()+"] non esistente nei wsdl registrati all'interno dell'accordo di servizio "+uriAccordo);
- }else{
- this.logger.debug("Servizio ["+this.accordoServizioWrapper.getNomePortType()+"] non esistente nell'accordo di servizio "+uriAccordo);
- }
- }catch(Exception e){
- this.logger.error("Errore durante l'emissione del log che indica la non esistenza del porttype/servizio ["+this.accordoServizioWrapper.getNomePortType()+
- "] nei wsdl registrati all'interno dell'accordo di servizio: "+e.getMessage(),e);
- }
- }
- }
- if(operation==null && operationName!=null && portType!=null){
- // provo a cercare l'operation. Magari non e' stato fatto girare prima il metodo wsdlConformanceCheck
- // o magari volutamente non c'e' un wsdl perche' la validazione prevista e' XSD
- // in tal caso non e' un errore se l'operation non e' presente.
- for(int i=0; i<portType.sizeAzioneList();i++){
- if(operationName.equals(portType.getAzione(i).getNome())){
- operation = portType.getAzione(i);
- break;
- }
- }
- }
-
-
- StringBuilder errorMsgValidazioneXSD = new StringBuilder();
-
-
- /** Validazione XSD senza considerare gli usi e gli stili (rpc/document e literal/encoded) */
- if(portType==null || operation==null){
- this.logger.debug("Validazione XSD senza considerare il WSDLAccordoServizio e quindi senza considerare style (document/rpc) e gli use (literal/encoded)");
-
- List<Node> nodeList = new ArrayList<Node>();
- if(MessageType.SOAP_11.equals(this.messageType) || MessageType.SOAP_12.equals(this.messageType)){
- SOAPEnvelope envelope = (SOAPEnvelope) this.element;
- SOAPBody body = null;
- try{
- body = envelope.getBody();
- }catch(Exception e){
- // eccezione che non dovrebbe accadere. Lo stesso controllo viene fatto nel costruttore
- throw new RuntimeException(e.getMessage(),e);
- }
- org.w3c.dom.NodeList nl = body.getChildNodes();
- for(int i=0; i<nl.getLength(); i++){
- if ( (nl.item(i) instanceof Text) || (nl.item(i) instanceof Comment) ){
- continue;
- }
- nodeList.add(nl.item(i));
- }
- }
- else{
- nodeList.add(this.element);
- }
-
- for(int i=0; i<nodeList.size(); i++){
- String nomeElemento = null;
- String namespaceElemento = null;
- Node n = null;
- try{
- n = nodeList.get(i);
- nomeElemento = n.getLocalName();
- namespaceElemento = n.getNamespaceURI();
-
- // Bug Fix: OPPT-784: Validazione fallisce in presenza di xsi:type e normalizzazione da axiom
- if(this.openspcoop2Message!=null && this.validationXsdAddNamespaceXSITypeIfNotExists) {
- this.openspcoop2Message.addNamespaceXSITypeIfNotExists(n, this.element);
- }
-
- validatoreBodyApplicativo.valida(n,true);
- }catch(Exception e){
- if(errorMsgValidazioneXSD.length()==0){
- if(this.addPrefixError) {
- if(isRichiesta) {
- errorMsgValidazioneXSD.append("Request");
- }
- else {
- errorMsgValidazioneXSD.append("Response");
- }
- errorMsgValidazioneXSD.append("content not conform to XSD specification\n");
- }
- }else{
- errorMsgValidazioneXSD.append("\n");
- }
- if(namespaceElemento!=null){
- nomeElemento = "{"+namespaceElemento+"}"+nomeElemento;
- }
- errorMsgValidazioneXSD.append("(element "+nomeElemento+") "+e.getMessage());
- String elementNonValidato = null;
- try{
- if(n!=null) {
- elementNonValidato = this.xmlUtils.toString(n);
- }
- }catch(Exception eString){
- this.logger.error("Errore durante la conversione del Node in String: "+eString.getMessage(),eString);
- }
- this.logger.error("Validazione fallita (elemento "+nomeElemento+") ["+elementNonValidato+"]: "+e.getMessage(),e);
- }
- }
- }
-
- /** Validazione XSD che considerare gli usi e gli stili (rpc/document e literal/encoded) */
- else{
- this.logger.debug("Validazione XSD che considera il WSDLAccordoServizio (ho localizzato prima il port-type:"+portType.getNome()+" e l'operation:"+operation.getNome()+")");
- BindingStyle style = CostantiRegistroServizi.WSDL_STYLE_DOCUMENT;
- BindingUse use = CostantiRegistroServizi.WSDL_USE_LITERAL;
- String azione = operationName;
-
- try{
-
- if(portType.getStyle()!=null && ("".equals(portType.getStyle().getValue())==false) &&
- CostantiRegistroServizi.WSDL_STYLE_RPC.equals(portType.getStyle()))
- style = CostantiRegistroServizi.WSDL_STYLE_RPC;
-
- if(operation.getStyle()!=null && ("".equals(operation.getStyle().getValue())==false)){
- if(CostantiRegistroServizi.WSDL_STYLE_RPC.equals(operation.getStyle()))
- style = CostantiRegistroServizi.WSDL_STYLE_RPC;
- else if(CostantiRegistroServizi.WSDL_STYLE_DOCUMENT.equals(operation.getStyle()))
- style = CostantiRegistroServizi.WSDL_STYLE_DOCUMENT;
- }
-
- }catch(Exception e){
- if(errorMsgValidazioneXSD.length()>0){
- errorMsgValidazioneXSD.append("\n");
- }
- errorMsgValidazioneXSD.append("Error in recognizing wsdl style rpc/document '"+e.getMessage()+"'");
- this.logger.error("Validazione fallita durante il riconoscimento del wsdl style rpc/document: "+e.getMessage(),e);
- }
-
- try{
- if(isRichiesta){
- if(operation.getMessageInput()!=null && operation.getMessageInput().getUse()!=null &&
- ("".equals(operation.getMessageInput().getUse().getValue())==false) &&
- CostantiRegistroServizi.WSDL_USE_ENCODED.equals(operation.getMessageInput().getUse()))
- use = CostantiRegistroServizi.WSDL_USE_ENCODED;
- }else{
- if(operation.getMessageOutput()!=null && operation.getMessageOutput().getUse()!=null &&
- ("".equals(operation.getMessageOutput().getUse().getValue())==false) &&
- CostantiRegistroServizi.WSDL_USE_ENCODED.equals(operation.getMessageOutput().getUse()))
- use = CostantiRegistroServizi.WSDL_USE_ENCODED;
- }
- }catch(Exception e){
- if(errorMsgValidazioneXSD.length()>0){
- errorMsgValidazioneXSD.append("\n");
- }
- errorMsgValidazioneXSD.append("Error in recognizing wsdl use literal/encoded '"+e.getMessage()+"'");
- this.logger.error("Validazione fallita durante il riconoscimento del wsdl style literal/encoded: "+e.getMessage(),e);
- }
-
- if(errorMsgValidazioneXSD.length()==0){
- this.logger.debug("Validazione XSD con style["+style+"] e use["+use+"]...");
-
- List<Node> nodeList = new ArrayList<Node>();
- if(MessageType.SOAP_11.equals(this.messageType) || MessageType.SOAP_12.equals(this.messageType)){
- SOAPEnvelope envelope = (SOAPEnvelope) this.element;
- SOAPBody body = null;
- try{
- body = envelope.getBody();
- }catch(Exception e){
- // eccezione che non dovrebbe accadere. Lo stesso controllo viene fatto nel costruttore
- throw new RuntimeException(e.getMessage(),e);
- }
- org.w3c.dom.NodeList nl = body.getChildNodes();
- for(int i=0; i<nl.getLength(); i++){
- if ( (nl.item(i) instanceof Text) || (nl.item(i) instanceof Comment) ){
- continue;
- }
- nodeList.add(nl.item(i));
- }
- }
- else{
- nodeList.add(this.element);
- }
-
- if(CostantiRegistroServizi.WSDL_STYLE_RPC.equals(style)){
- int children=0;
- for(int i=0; i<nodeList.size(); i++){
- children++;
- }
-
- if(children>1){
- errorMsgValidazioneXSD.append("Operation '"+azione+"' (style RPC) bring more than one root element");
- }
- }
- if(errorMsgValidazioneXSD.length()==0){
- for(int i=0; i<nodeList.size(); i++){
- String nomeElemento = null;
- String namespaceElemento = null;
- Node n = null;
- Node nodo = null;
- Node nChild = null;
- try{
- n = nodeList.get(i);
- nomeElemento = n.getLocalName();
- namespaceElemento = n.getNamespaceURI();
- if(CostantiRegistroServizi.WSDL_USE_ENCODED.equals(use)){
- this.logger.debug("Validazione XSD con style["+style+"] e use["+use+"], richiede la pulizia dei xsi:types prima della validazione...");
- nodo = this.cleanXSITypes(n);
- }else{
- nodo = n;
- }
-
- if(CostantiRegistroServizi.WSDL_STYLE_RPC.equals(style)){
- this.logger.debug("Validazione XSD con style["+style+"] e use["+use+"] RPC Validation...");
- String nomeAtteso = azione;
- if(isRichiesta==false)
- nomeAtteso = azione+"Response";
- if(nomeAtteso.equals(nomeElemento)==false){
- throw new Exception("Root element ["+nomeElemento+"] non equivale all'operation name "+nomeAtteso +" (RPC Style)");
- }
- // Valido figli
- org.w3c.dom.NodeList nlChilds = nodo.getChildNodes();
- this.logger.debug("Valido figli size: "+nlChilds.getLength());
- for(int j=0; j<nlChilds.getLength(); j++){
- //this.logger.debug("Tipo["+j+"]: "+nlChilds.item(j).getClass().getName());
- //if (nlChilds.item(j) instanceof Text && ((Text) nlChilds.item(j)).getData().trim().length() == 0) { continue; }
- if ( (nlChilds.item(j) instanceof Text) || (nlChilds.item(j) instanceof Comment) ){
- continue;
- }
- nChild = nlChilds.item(j);
-
- // Bug Fix: OPPT-784: Validazione fallisce in presenza di xsi:type e normalizzazione da axiom
- if(this.openspcoop2Message!=null && this.validationRpcAddNamespaceXSITypeIfNotExists) {
- this.openspcoop2Message.addNamespaceXSITypeIfNotExists(nChild, this.element);
- }
-
- validatoreBodyApplicativo.valida(nChild,true);
- }
- }else{
- this.logger.debug("Validazione XSD con style["+style+"] e use["+use+"] Document Validation...");
-
- // Bug Fix: OPPT-784: Validazione fallisce in presenza di xsi:type e normalizzazione da axiom
- if(this.openspcoop2Message!=null && this.validationDocumentAddNamespaceXSITypeIfNotExists) {
- this.openspcoop2Message.addNamespaceXSITypeIfNotExists(nodo, this.element);
- }
-
- validatoreBodyApplicativo.valida(nodo,true);
- }
-
- }catch(Exception e){
- if(errorMsgValidazioneXSD.length()==0){
- if(this.addPrefixError) {
- if(isRichiesta) {
- errorMsgValidazioneXSD.append("Request");
- }
- else {
- errorMsgValidazioneXSD.append("Response");
- }
- errorMsgValidazioneXSD.append("content not conform to XSD specification\n");
- }
- }else{
- errorMsgValidazioneXSD.append("\n");
- }
- if(namespaceElemento!=null){
- nomeElemento = "{"+namespaceElemento+"}"+nomeElemento;
- }
- errorMsgValidazioneXSD.append("(element "+nomeElemento+") "+e.getMessage());
-
- String elementNonValidato = null;
- try{
- if(n!=null) {
- elementNonValidato = this.xmlUtils.toString(n);
- }
- }catch(Exception eString){
- this.logger.error("Errore durante la conversione del Node in String: "+eString.getMessage(),eString);
- }
-
- String elementNonValidato_cleanXSIType = null;
- try{
- if(nodo!=null) {
- elementNonValidato_cleanXSIType = this.xmlUtils.toString(nodo);
- }
- }catch(Exception eString){
- this.logger.error("Errore durante la conversione del Node (clean xsiType) in String: "+eString.getMessage(),eString);
- }
-
- String elementNonValidato_child = null;
- try{
- if(nChild!=null)
- elementNonValidato_child = this.xmlUtils.toString(nChild);
- }catch(Exception eString){
- this.logger.error("Errore durante la conversione del Node (clean xsiType) in String: "+eString.getMessage(),eString);
- }
-
- this.logger.error("Validazione fallita (elemento "+nomeElemento+") originale["+
- elementNonValidato+"] cleanXsiType["+
- elementNonValidato_cleanXSIType+"] nChild["+
- elementNonValidato_child+"]: "+e.getMessage(),e);
- }
- }
- }
- }
- }
- if(errorMsgValidazioneXSD.length()>0){
- throw new WSDLValidatorException(errorMsgValidazioneXSD.toString());
- }
- }
-
-
-
-
-
-
-
-
-
-
- /* -------------- VALIDAZIONE XSD CON WSDL --------------------- */
-
- /**
- * Validazione WSDL
- *
- * @param isRichiesta Indicazione sul tipo di messaggio applicativo da gestire
- *
- */
- private PortType ptWsdlConformanceCheck = null;
- private Operation opWsdlConformanceCheck = null;
- public PortType getPtWsdlConformanceCheck() {
- return this.ptWsdlConformanceCheck;
- }
- public Operation getOpWsdlConformanceCheck() {
- return this.opWsdlConformanceCheck;
- }
- // public void wsdlConformanceCheck(boolean isRichiesta,String soapAction,String operationName) throws WSDLValidatorException {
- // this.wsdlConformanceCheck(isRichiesta, soapAction, operationName, true, false);
- // }
- public void wsdlConformanceCheck(boolean isRichiesta,String soapAction,String operationName,boolean throwSOAPActionException,boolean logErrorAsDebug) throws WSDLValidatorException {
-
- String portType = this.accordoServizioWrapper.getNomePortType();
-
- if(portType!=null){
-
- // l'accordo di servizio parte specifica e' stato collegato ad un port type nella parte comune.
- // In tal caso uso la validazione ottimale rispetto al port type ed all'operation
-
- // l'azione busta deve essere obbligatoriamente presente.
- if(operationName==null){
- throw new WSDLValidatorException("Operation name undefined");
- }
-
- this.logger.info("WSDL, effettuo validazione wsdlConformanceCheck ottimale sia con port type che operation ...");
- this._engineWsdlConformanceCheck(isRichiesta, soapAction, portType, operationName, throwSOAPActionException, logErrorAsDebug);
-
- // se la validazione ha avuto successo salvo il pt e l'operation
- this.ptWsdlConformanceCheck = this.accordoServizioWrapper.getPortType(portType);
- for(int i=0; i<this.ptWsdlConformanceCheck.sizeAzioneList(); i++){
- Operation operationAS = this.ptWsdlConformanceCheck.getAzione(i);
- if (operationAS.getNome().equals(operationName)) {
- this.opWsdlConformanceCheck = operationAS;
- break;
- }
- }
- }
- else{
-
- // l'accordo di servizio parte specifica non e' stato collegato ad un port type nella parte comune.
- // effettuo una validazione meno stringente.
-
- if(operationName!=null){
-
- // *** cerco l'operation all'interno del wsdl. Se esiste una o piu' operation con tale nome, proviamo a validare il messaggio. ***
- this.logger.info("WSDL, effettuo validazione wsdlConformanceCheck cercando una qualche operation con nome ["+operationName+"]...");
- StringBuilder bfEccezione = new StringBuilder();
- boolean operationFound = _engineWsdlConformanceCheckAll(isRichiesta, soapAction, operationName, bfEccezione, throwSOAPActionException, logErrorAsDebug);
- if(operationFound){
- if(bfEccezione.length()>0){
- throw new WSDLValidatorException(bfEccezione.toString());
- }
- else{
- return;
- }
- }else{
- try{
- IDAccordoFactory idAccordoFactory = IDAccordoFactory.getInstance();
- String uriAccordo = idAccordoFactory.getUriFromIDAccordo(this.accordoServizioWrapper.getIdAccordoServizio());
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Operation '"+operationName+"' undefined in the WSDL specification '"+uriAccordo+"'");
- }else{
- throw new WSDLValidatorException("Operation '"+operationName+"' undefined in the API specification '"+uriAccordo+"'");
- }
- }catch(DriverRegistroServiziException de){
- String msgErrore = "Errore durante la registrazione del messaggio di errore Operation ["+operationName+"] non trovata in alcun port-type esistente nei wsdl registrati all'interno dell'accordo di servizio";
- if(logErrorAsDebug){
- this.logger.debug(msgErrore);
- }else{
- this.logger.error(msgErrore,de);
- }
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Operation '"+operationName+"' undefined in the WSDL specification");
- }else{
- throw new WSDLValidatorException("Operation '"+operationName+"' undefined in the API specification");
- }
- }
- }
- }
- else{
-
- // ***
- // non avendo trovato una azione che matchava con il nome dell'operation name,
- // valido rispetto a tutti i messaggi possibili, rispettando pero' il ruolo tra richiesta e risposta
- // ***
- StringBuilder bfEccezione = new StringBuilder();
- this.logger.info("WSDL, effettuo validazione wsdlConformanceCheck utilizzando una qualunque operation ...");
- _engineWsdlConformanceCheckAll(isRichiesta, soapAction, null, bfEccezione, throwSOAPActionException, logErrorAsDebug);
- if(bfEccezione.length()>0){
- throw new WSDLValidatorException(bfEccezione.toString());
- }
- else{
- return;
- }
-
- }
-
- }
-
- }
-
- private boolean _engineWsdlConformanceCheckAll(boolean isRichiesta,String soapAction,String operationName, StringBuilder bfEccezione,boolean throwSOAPActionException,boolean logErrorAsDebug) throws WSDLValidatorException{
-
- try{
-
- IDAccordoFactory idAccordoFactory = IDAccordoFactory.getInstance();
- String uriAccordo = idAccordoFactory.getUriFromIDAccordo(this.accordoServizioWrapper.getIdAccordoServizio());
-
- PortType [] pts = this.accordoServizioWrapper.getPortTypeList();
- if(pts==null || pts.length<=0){
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("PortTypes undefined in the WSDL specification '"+uriAccordo+"'");
- }else{
- throw new WSDLValidatorException("PortTypes undefined in the API specification '"+uriAccordo+"'");
- }
- }
- boolean operationFound = false;
- for (int i = 0; i < pts.length; i++) {
- PortType pt = pts[i];
- List<Operation> ops = pt.getAzioneList();
- if(ops==null || ops.size()<=0){
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Operations undefined in PortType '"+pt.getNome()+"' of the WSDL specification '"+uriAccordo+"'");
- }else{
- throw new WSDLValidatorException("Operations undefined in Service '"+pt.getNome()+"' of the API specification '"+uriAccordo+"'");
- }
- }
- boolean validazioneCompletataConSuccesso = false;
- for (Operation operation : ops) {
-
- boolean verify = false;
- if(operationName==null){
- verify = true;
- }
- else{
- verify = (operation.getNome().equals(operationName));
- if(verify){
- operationFound = true;
- }
- }
-
- if(verify){
- try{
- this.logger.info("WSDL, effettuo validazione wsdlConformanceCheck per operation ["+operation.getNome()+"] del port type ["+pt.getNome()+"]...");
- this._engineWsdlConformanceCheck(isRichiesta, soapAction, pt.getNome(), operation.getNome(), throwSOAPActionException, logErrorAsDebug);
-
- // se la validazione ha avuto successo salvo il pt e l'operation
- this.ptWsdlConformanceCheck = pt;
- this.opWsdlConformanceCheck = operation;
-
- validazioneCompletataConSuccesso = true;
- break;
-
- }catch(WSDLValidatorException exception){
- // if(bfEccezione.length()>0){
- bfEccezione.append("\n");
- //}
- bfEccezione.append("[Tentativo validazione come PortType:").
- append(pt.getNome()).
- append(" Operation:").
- append(operation.getNome()).
- append(" fallito]: ").
- append(exception.getMessage());
- }
- }
- }
-
- if(validazioneCompletataConSuccesso){
- break;
- }
- }
-
- return operationFound;
-
- }catch(WSDLValidatorException e){
- throw e;
- }catch(Exception e){
- // Si entra in questo catch solo in caso di bug
- String msgErrore = "Validazione WSDL ("+isRichiesta+") fallita: "+e.getMessage();
- if(logErrorAsDebug){
- this.logger.debug(msgErrore);
- }else{
- this.logger.error(msgErrore,e);
- }
- throw new WSDLValidatorException("WSDL Validation 'all-"+(isRichiesta?"request":"response")+"' failed: "+e.getMessage(),e);
- }
- }
-
- private void _engineWsdlConformanceCheck(boolean isRichiesta,String soapAction,String portType,String operation,boolean throwSOAPActionException,boolean logErrorAsDebug) throws WSDLValidatorException {
-
- String errorMsgValidazioneXSD = null;
- try{
-
- SOAPEnvelope envelope = null;
- SOAPBody body = null;
- if(MessageType.SOAP_11.equals(this.messageType) || MessageType.SOAP_12.equals(this.messageType)){
- envelope = (SOAPEnvelope) this.element;
- try{
- body = envelope.getBody();
- }catch(Exception e){
- // eccezione che non dovrebbe accadere. Lo stesso controllo viene fatto nel costruttore
- throw new RuntimeException(e.getMessage(),e);
- }
- }
- else{
- throw new Exception("Tipo di validazione non supportata con Service Binding REST e tipologia messaggio: "+this.messageType.getMessageVersionAsString());
- }
-
-
- // cerco port-type
- BindingStyle style = CostantiRegistroServizi.WSDL_STYLE_DOCUMENT;
- BindingUse use = CostantiRegistroServizi.WSDL_USE_LITERAL;
- String namespaceRPC = null;
- Node rpcElement = null;
- IDAccordoFactory idAccordoFactory = IDAccordoFactory.getInstance();
- String uriAccordo = idAccordoFactory.getUriFromIDAccordo(this.accordoServizioWrapper.getIdAccordoServizio());
- PortType portTypeAS = this.accordoServizioWrapper.getPortType(portType);
- if(portTypeAS==null){
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("PortType ["+portType+"] undefined in the WSDL specification '"+uriAccordo+"'");
- }else{
- throw new WSDLValidatorException("Service ["+portType+"] undefined in the API specification '"+uriAccordo+"'");
- }
- }
- if(portTypeAS.getStyle()!=null && ("".equals(portTypeAS.getStyle().getValue())==false) &&
- CostantiRegistroServizi.WSDL_STYLE_RPC.equals(portTypeAS.getStyle()))
- style = CostantiRegistroServizi.WSDL_STYLE_RPC;
-
- //si itera sulle operazioni del portType perche' potrebbe esserci
- //overload di operazioni
- if(portTypeAS.sizeAzioneList()<=0)
- throw new Exception("operations per il port type ["+portType+"] non presenti");
- boolean matchingNameOperation = false, matchingArgomentsOperation = false;
- String soapActionWSDL = null;
- StringBuilder eccezioni = new StringBuilder();
- StringBuilder eccezioneActionMatch = new StringBuilder();
- for(int i=0; i<portTypeAS.sizeAzioneList(); i++){
- Operation operationAS = portTypeAS.getAzione(i);
- if (operationAS.getNome().equals(operation)) {
- matchingNameOperation = true;
- // Prendo la definizione del messaggio di input se e' una richiesta, di output se e' una risposta
- Message argumentsOperation = isRichiesta ? operationAS.getMessageInput() : operationAS.getMessageOutput();
-
- if(operationAS.getStyle()!=null && ("".equals(operationAS.getStyle().getValue())==false)){
- if(CostantiRegistroServizi.WSDL_STYLE_RPC.equals(operationAS.getStyle()))
- style = CostantiRegistroServizi.WSDL_STYLE_RPC;
- else if(CostantiRegistroServizi.WSDL_STYLE_DOCUMENT.equals(operationAS.getStyle()))
- style = CostantiRegistroServizi.WSDL_STYLE_DOCUMENT;
- }
-
- if(argumentsOperation!=null && argumentsOperation.getUse()!=null &&
- ("".equals(argumentsOperation.getUse().getValue())==false) &&
- CostantiRegistroServizi.WSDL_USE_ENCODED.equals(argumentsOperation.getUse()))
- use = CostantiRegistroServizi.WSDL_USE_ENCODED;
-
- if(CostantiRegistroServizi.WSDL_STYLE_RPC.equals(style)){
- if(argumentsOperation!=null && argumentsOperation.getSoapNamespace()!=null &&
- (!"".equals(argumentsOperation.getSoapNamespace()))){
- namespaceRPC = argumentsOperation.getSoapNamespace();
- }
- }
-
- this.logger.debug("WSDL, esamino operation["+operation+"] con style["+style+"] e use["+use+"] (RPCNamespace:"+namespaceRPC+") ...");
-
- // il controllo sul nome dell'operation non basta.
- // Vi puo' essere overriding del metodo per parametri diversi
- // controllo matching dei parametri
- org.w3c.dom.NodeList nodiContenutoApplicativo = null;
- Node nodoPossiedeContenutoApplicativo = null; // body nel caso document, rpc-element nel caso rpc
- if(CostantiRegistroServizi.WSDL_STYLE_RPC.equals(style)){
- // RPC
- String nomeAtteso = operation;
- if(isRichiesta==false)
- nomeAtteso = operation+"Response";
- SOAPElement childRPCElement = SoapUtils.getNotEmptyFirstChildSOAPElement(body);
- if(childRPCElement==null){
- this.logger.debug("WSDL, esamino operation["+operation+"] con style["+style+"] e use["+use+"]: Root element RCP non trovato rispetto all'operation name "+nomeAtteso +" (RPC Style)");
- continue;
- }
- if(nomeAtteso.equals(childRPCElement.getLocalName())==false){
- this.logger.debug("WSDL, esamino operation["+operation+"] con style["+style+"] e use["+use+"]: Root element ["+childRPCElement.getLocalName()+"] non equivale all'operation name "+nomeAtteso +" (RPC Style)");
- continue;
- }
-
- nodiContenutoApplicativo = body.getChildNodes();
- for(int ii=0;ii<nodiContenutoApplicativo.getLength();ii++){
- // if (!(nodiContenutoApplicativo.item(ii) instanceof Text &&
- // ((Text) nodiContenutoApplicativo.item(ii)).getData().trim().length() == 0)) {
- if (! ( (nodiContenutoApplicativo.item(ii) instanceof Text) || (nodiContenutoApplicativo.item(ii) instanceof Comment) )){
- nodoPossiedeContenutoApplicativo = nodiContenutoApplicativo.item(ii);
- rpcElement = nodoPossiedeContenutoApplicativo;
- nodiContenutoApplicativo = nodoPossiedeContenutoApplicativo.getChildNodes();
- break;
- }
- }
-
- }else{
- // Document
- nodiContenutoApplicativo = body.getChildNodes();
- nodoPossiedeContenutoApplicativo = body;
- }
-
- int sizeArgumentsOperation = 0;
- if(argumentsOperation!=null){
- sizeArgumentsOperation = argumentsOperation.sizePartList();
- }
- int nodiContenutoApplicativoLength = 0;
- StringBuilder nodiMessaggioErrore = new StringBuilder();
- for(int ii=0;ii<nodiContenutoApplicativo.getLength();ii++){
- // if (!(nodiContenutoApplicativo.item(ii) instanceof Text &&
- // ((Text) nodiContenutoApplicativo.item(ii)).getData().trim().length() == 0)) {
- if (! ( (nodiContenutoApplicativo.item(ii) instanceof Text) || (nodiContenutoApplicativo.item(ii) instanceof Comment) )){
-
- if(nodiMessaggioErrore.length()>0){
- nodiMessaggioErrore.append(", ");
- }
- Node n = nodiContenutoApplicativo.item(ii);
- RootElementBody rootElementBody = new RootElementBody(envelope, nodoPossiedeContenutoApplicativo,
- CostantiRegistroServizi.WSDL_STYLE_RPC.equals(style), n);
- nodiMessaggioErrore.append(rootElementBody.toString());
-
- nodiContenutoApplicativoLength++;
- continue;
- }
- }
- if(sizeArgumentsOperation!=nodiContenutoApplicativoLength){
-
- if(eccezioneActionMatch.length()>0){
- eccezioneActionMatch.append("\n");
- }
- eccezioneActionMatch.append("Found "+nodiContenutoApplicativoLength+" parameter"+(nodiContenutoApplicativoLength>1?"s":"")+": ");
- eccezioneActionMatch.append(nodiMessaggioErrore.toString());
-
- this.logger.debug("WSDL, esamino operation["+operation+"] con style["+style+"] e use["+use+"]: Argomenti attesi["+sizeArgumentsOperation+"], trovati nel body["+nodiContenutoApplicativo.getLength()+"]");
- continue;
- }
-
- String tipo = "output";
- if(isRichiesta)
- tipo = "input";
-
- if(argumentsOperation!=null && argumentsOperation.sizePartList()>0){
-
- // Mi conservo gli elementi presenti nel body
- List<RootElementBody> elementRootBody = new ArrayList<RootElementBody>();
- StringBuilder bodyElements = new StringBuilder();
- int numeroBodyElements = 0;
- int realIndexBody = 0;
- for(int indexBody = 0 ; indexBody<nodiContenutoApplicativo.getLength(); indexBody++){
- // if (nodiContenutoApplicativo.item(indexBody) instanceof Text &&
- // ((Text) nodiContenutoApplicativo.item(indexBody)).getData().trim().length() == 0) {
- if ( (nodiContenutoApplicativo.item(indexBody) instanceof Text) || (nodiContenutoApplicativo.item(indexBody) instanceof Comment) ){
- continue;
- }
-
- Node n = nodiContenutoApplicativo.item(indexBody);
-
- RootElementBody rootElementBody = new RootElementBody(envelope, nodoPossiedeContenutoApplicativo,
- CostantiRegistroServizi.WSDL_STYLE_RPC.equals(style), n);
- elementRootBody.add(rootElementBody);
-
- if(realIndexBody>0)
- bodyElements.append(",");
- realIndexBody++;
- bodyElements.append(rootElementBody.toString());
- }
- numeroBodyElements = elementRootBody.size();
-
- int soapBodyArguments = nodiContenutoApplicativoLength;
- //per ogni tipo si itera
- int wsdlIndex=0;
- for( ; wsdlIndex<argumentsOperation.sizePartList(); wsdlIndex++){
- if (wsdlIndex == soapBodyArguments) {
- //più oggetti definiti nel WSDL di quanti ce ne siano nel messaggio
- this.logger.debug("WSDL, esamino operation["+operation+"] con style["+style+"] e use["+use+"]: Più oggetti definiti nel WSDL di quanti ce ne siano nel messaggio");
- continue;
- }
- MessagePart argument = argumentsOperation.getPart(wsdlIndex);
- String nomeElementAtteso = null;
- String namespaceElementAtteso = null;
- String tipoXSIAtteso = null;
- boolean validazioneTipologiaElement = (argument.getElementName()!=null);
- String argomentoAtteso = null;
- if(argument.getElementName()!=null){
- nomeElementAtteso = argument.getElementName();
- namespaceElementAtteso = argument.getElementNamespace();
- }
- else{
- nomeElementAtteso = argument.getName(); // definito nel message del wsdl
- namespaceElementAtteso = argument.getTypeNamespace();
- tipoXSIAtteso = argument.getTypeName();
- }
- argomentoAtteso = RootElementBody.toString(nomeElementAtteso, namespaceElementAtteso, tipoXSIAtteso);
- boolean find = false;
- for(int indexBody = 0 ; indexBody<elementRootBody.size(); indexBody++){
- RootElementBody r = elementRootBody.get(indexBody);
- if(validazioneTipologiaElement){
- if(nomeElementAtteso.equals(r.getLocalName()) && namespaceElementAtteso.equals(r.getNamespace())){
- find = true;
- elementRootBody.remove(indexBody);
- continue;
- }
- else if(CostantiRegistroServizi.WSDL_USE_ENCODED.equals(use)){
- if(nomeElementAtteso.equals(r.getLocalName()) && namespaceElementAtteso.equals(r.getNamespaceElementoCheContieneXSIType())){
- find = true;
- elementRootBody.remove(indexBody);
- continue;
- }
- }
- }
- else{
- if(nomeElementAtteso.equals(r.getLocalName()) &&
- namespaceElementAtteso.equals(r.getNamespace()) &&
- tipoXSIAtteso.equals(r.getXsiType())){
- find = true;
- elementRootBody.remove(indexBody);
- continue;
- }
- }
- }
-
- if (!find) { //tipi non concordi nella sequenza
- boolean error = true;
- if(CostantiRegistroServizi.WSDL_STYLE_RPC.equals(style) && CostantiRegistroServizi.WSDL_USE_LITERAL.equals(use) &&
- tipoXSIAtteso!=null &&
- elementRootBody.size()==1 && // elementi nel body sono uno
- argumentsOperation.sizePartList()==1 // elementi attesi nel wsdl uno
- ){
-
- SOAPElement rpcOperation = SoapUtils.getNotEmptyFirstChildSOAPElement(body);
- if(rpcOperation!=null){
- SOAPElement childRpc = SoapUtils.getNotEmptyFirstChildSOAPElement(rpcOperation);
- if(this.gestioneXsiTypeRpcLiteral &&
- childRpc!=null && nomeElementAtteso!=null && nomeElementAtteso.equals(childRpc.getLocalName())){
- try{
- // System.out.println("PRIMA: "+org.openspcoop2.message.OpenSPCoop2MessageFactory.getMessageFactory().createEmptySOAPMessage(SOAPVersion.SOAP11).
- // getAsString(childRpc, false));
-
- QName namespaceId = new QName("xmlns:"+PREFIX_RPC_AGGIUNTO);
- childRpc.addAttribute(namespaceId, namespaceElementAtteso);
- this.rpcChildElementNamespaceAggiunto = namespaceId;
-
- QName id = new QName(XMLSCHEMA_INSTANCE_NAMESPACE,XMLSCHEMA_INSTANCE_LOCAL_NAME_TYPE,"xsi");
- String value = PREFIX_RPC_AGGIUNTO+":"+tipoXSIAtteso;
- childRpc.addAttribute(id, value);
- this.rpcChildElementXSITypeAggiunto = id;
-
- // System.out.println("DOPO: "+org.openspcoop2.message.OpenSPCoop2MessageFactory.getMessageFactory().createEmptySOAPMessage(SOAPVersion.SOAP11).
- // getAsString(childRpc, false));
- error= false;
- this.rpcChildElement = childRpc;
- }catch(Exception e){
- this.logger.error("Errore durante la registrazione degli attributi richiesti per la validazione rpc con type: "+e.getMessage(),e);
- try{
- if(this.rpcChildElementNamespaceAggiunto!=null){
- // ripulisco
- // alcune implementazioni usano l'uno o l'altro per eliminarlo
- this.rpcChildElement.removeAttribute(this.rpcChildElementNamespaceAggiunto);
- this.rpcChildElement.removeNamespaceDeclaration(PREFIX_RPC_AGGIUNTO);
- }
- }catch(Exception eClose){
- // ignore
- }
- }
- }
- }
- }
- if(error){
- eccezioni.append("\nRequired "+tipo+" parameter '"+argomentoAtteso+"' undefined in "+numeroBodyElements+" body root-element("+(numeroBodyElements>1?"s":"")+") founded: "+bodyElements);
- this.logger.debug("WSDL, esamino operation["+operation+"] con style["+style+"] e use["+use+"]: Atteso "+argomentoAtteso+" body "+bodyElements);
- break;
- }
- }
- }
- if (wsdlIndex == soapBodyArguments) {
- soapActionWSDL = operationAS.getSoapAction();
- matchingArgomentsOperation = true;
- continue;
- }
- }
- } //fine if
- }
- if (!matchingArgomentsOperation) {
- if (matchingNameOperation) {
- if(eccezioni.length()>0){
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Invalid "+(isRichiesta?"request":"response")+" by WSDL specification '"+uriAccordo+"' (port-type:"+portType+", operation:"+operation+", style:"+style+", use:"+use+"): "+eccezioni.toString());
- }else{
- throw new WSDLValidatorException("Invalid "+(isRichiesta?"request":"response")+" by API specification '"+uriAccordo+"' (service:"+portType+", operation:"+operation+", style:"+style+", use:"+use+"): "+eccezioni.toString());
- }
- }
- else if(eccezioneActionMatch.length()>0){
- StringBuilder bfMessage = new StringBuilder();
- for(int i=0; i<portTypeAS.sizeAzioneList(); i++){
- Operation operationAS = portTypeAS.getAzione(i);
- if (operationAS.getNome().equals(operation)) {
- Message argumentsOperation = isRichiesta ? operationAS.getMessageInput() : operationAS.getMessageOutput();
- int length = 0;
- if(argumentsOperation!=null && argumentsOperation.getPartList()!=null){
- length = argumentsOperation.getPartList().size();
- }
- bfMessage.append("\n");
- bfMessage.append("Expected "+length+" parameter"+(length>1?"s":"")+": ");
- if(length>0){
- for (int j = 0; j < length; j++) {
- MessagePart argument = argumentsOperation.getPart(j);
- String nomeElementAtteso = null;
- String namespaceElementAtteso = null;
- String tipoXSIAtteso = null;
- String argomentoAtteso = null;
- if(argument.getElementName()!=null){
- nomeElementAtteso = argument.getElementName();
- namespaceElementAtteso = argument.getElementNamespace();
- }
- else{
- nomeElementAtteso = argument.getName(); // definito nel message del wsdl
- namespaceElementAtteso = argument.getTypeNamespace();
- tipoXSIAtteso = argument.getTypeName();
- }
- argomentoAtteso = RootElementBody.toString(nomeElementAtteso, namespaceElementAtteso, tipoXSIAtteso);
- if(j>0){
- bfMessage.append(", ");
- }
- bfMessage.append(argomentoAtteso);
- }
- }
- }
- }
- bfMessage.append("\n").append(eccezioneActionMatch.toString());
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Invalid "+(isRichiesta?"request":"response")+" by WSDL specification '"+uriAccordo+"' (port-type:"+portType+", operation:"+operation+", style:"+style+", use:"+use+"): "+bfMessage.toString());
- }else{
- throw new WSDLValidatorException("Invalid "+(isRichiesta?"request":"response")+" by API specification '"+uriAccordo+"' (service:"+portType+", operation:"+operation+", style:"+style+", use:"+use+"): "+bfMessage.toString());
- }
- }
- else{
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Invalid "+(isRichiesta?"request":"response")+" by WSDL specification '"+uriAccordo+"' (port-type:"+portType+", operation:"+operation+", style:"+style+", use:"+use+")");
- }else{
- throw new WSDLValidatorException("Invalid "+(isRichiesta?"request":"response")+" by API specification '"+uriAccordo+"' (service:"+portType+", operation:"+operation+", style:"+style+", use:"+use+")");
- }
- }
- } else {
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Operation '"+operation+"' undefined in PortType '"+portType+"' of the WSDL specification '"+uriAccordo+"'");
- }else{
- throw new WSDLValidatorException("Operation '"+operation+"' undefined in Service '"+portType+"' of the API specification '"+uriAccordo+"'");
- }
- }
- }
-
- if( isRichiesta && soapActionWSDL!=null){
- this.logger.debug("CheckSOAPAction");
- String soapActionRipulita = null;
- if(soapAction!=null){
- soapActionRipulita = soapAction.trim();
- if(soapActionRipulita.startsWith("\"")){
- soapActionRipulita = soapActionRipulita.substring(1);
- }
- if(soapActionRipulita.endsWith("\"")){
- soapActionRipulita = soapActionRipulita.substring(0,(soapActionRipulita.length()-1));
- }
- }
- if(soapActionWSDL.equalsIgnoreCase(soapActionRipulita)==false){
- boolean tmpThrowSOAPActionException = throwSOAPActionException;
- if(soapActionRipulita==null && MessageType.SOAP_12.equals(this.messageType)){
- // The SOAP 1.1 mandatory SOAPAction HTTP header has been removed in SOAP 1.2. In its place is an optional action parameter on the application/soap+xml media type.
- // Quindi se nella richiesta non era presente una soapAction, non devo sollevare eccezione
- tmpThrowSOAPActionException = false;
- }
- // Validazione SOAPAction
- if(tmpThrowSOAPActionException){
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Invalid soap action '"+soapActionRipulita+"' by WSDL specification '"+uriAccordo+"' (port-type:"+portType+", operation:"+operation+", soap action:"+soapActionWSDL+")");
- }else{
- throw new WSDLValidatorException("Invalid soap action '"+soapActionRipulita+"' by API specification '"+uriAccordo+"' (service:"+portType+", operation:"+operation+", soap action:"+soapActionWSDL+")");
- }
- }
- }
- }
-
- // Controllo sul namespace RPC.
- if(namespaceRPC!=null && rpcElement!=null){
- this.logger.debug("CheckRPCNamespace");
-
- if( (rpcElement.getNamespaceURI()==null || StringUtils.isEmpty(rpcElement.getNamespaceURI())) ){
- if(!this.rpcAcceptRootElementUnqualified) {
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Unqualified rpc "+(isRichiesta?"request":"response")+" element '"+rpcElement.getLocalName()+"' by WSDL specification '"+uriAccordo+"' (port-type:"+portType+", operation:"+operation+")");
- }else{
- throw new WSDLValidatorException("Unqualified rpc "+(isRichiesta?"request":"response")+" element '"+rpcElement.getLocalName()+"' by API specification '"+uriAccordo+"' (service:"+portType+", operation:"+operation+")");
- }
- }
- }
- else {
- if(!rpcElement.getNamespaceURI().equals(namespaceRPC)){
- if(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()){
- throw new WSDLValidatorException("Invalid rpc "+(isRichiesta?"request":"response")+" element '"+rpcElement.getLocalName()+"' by WSDL specification '"+uriAccordo+"' (port-type:"+portType+", operation:"+operation+"): expected namespace '"+namespaceRPC+"'; found namespace '"+rpcElement.getNamespaceURI()+"'");
- }else{
- throw new WSDLValidatorException("Invalid rpc "+(isRichiesta?"request":"response")+" element '"+rpcElement.getLocalName()+"' by API specification '"+uriAccordo+"' (service:"+portType+", operation:"+operation+"): expected namespace '"+namespaceRPC+"'; found namespace '"+rpcElement.getNamespaceURI()+"'");
- }
- }
- }
- }
-
- }catch(Exception e){
- String msgErrore = "Validazione WSDL ("+isRichiesta+") fallita: "+e.getMessage();
- if(logErrorAsDebug){
- this.logger.debug(msgErrore);
- }else{
- this.logger.error(msgErrore,e);
- }
- if( (e instanceof WSDLValidatorException)==false )
- this.logger.debug("Validazione WSDL fallita",e);
- // è gia nella definizione dell'error
- StringBuilder errorMsgValidazioneXSDBuilder = new StringBuilder();
- if(this.addPrefixError) {
- if(isRichiesta) {
- errorMsgValidazioneXSDBuilder.append("Request");
- }
- else {
- errorMsgValidazioneXSDBuilder.append("Response");
- }
- errorMsgValidazioneXSDBuilder.append(" content not conform to ").append(this.accordoServizioWrapper.isPortTypesLoadedFromWSDL()?"WSDL":"API").append(" specification; ");
- }
- errorMsgValidazioneXSDBuilder.append(e.getMessage());
- errorMsgValidazioneXSD = errorMsgValidazioneXSDBuilder.toString();
- }
- if(errorMsgValidazioneXSD!=null){
- throw new WSDLValidatorException(errorMsgValidazioneXSD);
- }
-
- }
-
-
-
-
-
-
-
-
-
- /* -------------- VALIDAZIONE UTILITIES --------------------- */
-
- public Element cleanXSITypes(Node node) throws Exception{
-
- //La versione non e' rilevante.
- byte[] element = this.eraserType (this.xmlUtils.toByteArray(node,true));
- Document doc = this.xmlUtils.newDocument(element);
- Element domElem = doc.getDocumentElement();
-
- /* vecchia impl:
- MessageElement daClonare = (MessageElement) node;
- //System.out.println("PRIMA ["+daClonare.getAsString()+"] ");
- byte[]element = this.eraserType(daClonare.getAsString().getBytes());
- //System.out.println("DOPO ["+new String(element)+"] ");
- Element e = XMLUtils.newElement(element);
- */
-
- return domElem;
- }
- /**
- * Metodo che si occupa di effettuare l'eliminazione degli xsd:type String
- *
- * utility che elimina gli xsd type
- * @param xml Xml su cui effettuare la pulizia dell'header.
- * @return byte[] contenente un xml 'pulito'.
- *
- */
- public byte[] eraserType(byte[] xml) throws UtilsException{
- ByteArrayOutputStream cleanXML = null;
- String prefix = "";
- try{
- cleanXML = new ByteArrayOutputStream();
- // Elimino import
- for(int i=0; i<xml.length ; ){
- if(xml[i] == ' '){
- // Cerco Stringa " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\""
- String importXSITYPE = "http://www.w3.org/2001/XMLSchema-instance";
- if(i+"xmlns:".length() < xml.length){
- if( (xml[i+1] == 'x') &&
- (xml[i+2] == 'm') &&
- (xml[i+3] == 'l') &&
- (xml[i+4] == 'n') &&
- (xml[i+5] == 's') &&
- (xml[i+6] == ':')){
- StringBuilder test = new StringBuilder("xmlns:");
- StringBuilder prefixTest = new StringBuilder();
- int contatoreFineAttributo = 0;
- for(int k=7 ; ; k++){
- if((i+k)>=xml.length)
- break;
- if((char)xml[i+k] == '"')
- contatoreFineAttributo++;
- if(contatoreFineAttributo==0)
- prefixTest.append((char)xml[i+k]);
- test.append((char)xml[i+k]);
- if(contatoreFineAttributo>=2)
- break;
- }
- //System.out.println("TROVATO ["+test.toString()+"] PREFIX["+prefixTest.toString()+"]");
- // Prelevo valore
- int indexFirst = test.toString().indexOf('"');
- int secondFirst = test.toString().indexOf('"', indexFirst+1);
- String testEquals = test.toString().substring(indexFirst+1, secondFirst);
- //System.out.println("TROVATO SUBSTRING ["+testEquals+"]");
- if(importXSITYPE.equalsIgnoreCase(testEquals)){
- //System.out.println("CANCELLO");
- prefix = prefixTest.toString().substring(0, prefixTest.length()-1);
- //System.out.println("CANCELLO P["+prefix+"]");
- // Cancello la stringa trovata
- i = i + test.toString().length() +1;
- continue;
- }
- }
- }
-
- cleanXML.write(xml[i]);
- i++;
- }else{
- cleanXML.write(xml[i]);
- i++;
- }
- }
- byte [] risultato = cleanXML.toByteArray();
- cleanXML = new ByteArrayOutputStream();
- //System.out.println("DOPO step 1 ["+new String(risultato)+"] ");
- cleanXML.close();
-
- // Elimino xsi type
- for(int i=0; i<risultato.length ; ){
- if(risultato[i] == ' '){
- // Cerco Stringa " xsi:type=\"xsd:TYPE\""
- String XSITYPE_PREFIX = prefix+":type=\"";
- if(i+XSITYPE_PREFIX.length()+2 < risultato.length){
- StringBuilder test = new StringBuilder("");
- int contatoreFineAttributo = 0;
- for(int k=1 ; ; k++){
- if((i+k)>=risultato.length)
- break;
- if((char)risultato[i+k] == '"')
- contatoreFineAttributo++;
- test.append((char)risultato[i+k]);
- if(contatoreFineAttributo>=2)
- break;
- }
- //stem.out.println("TROVATO ["+test.toString()+"] START WITH["+XSITYPE_PREFIX+"]");
- if(test.toString().startsWith(XSITYPE_PREFIX)){
- // Cancello la stringa trovata
- //System.out.println("CANCELLO");
- i = i + test.toString().length()+1;
- continue;
- }
- }
-
- cleanXML.write(risultato[i]);
- i++;
- }else{
- cleanXML.write(risultato[i]);
- i++;
- }
- }
- risultato = cleanXML.toByteArray();
- cleanXML.close();
-
- return risultato;
- } catch(Exception e) {
- this.logger.error("Utilities.eraserType",e);
- try{
- if(cleanXML!=null)
- cleanXML.close();
- }catch(Exception eis){
- // ignore
- }
- throw new UtilsException("Eliminazione xsi:type per validazione non riuscita "+e.getMessage(),e);
- }
- }
-
-
-
-
-
-
- }
- class RootElementBody{
-
- private String localName;
- private String namespace;
- private String xsiType;
-
- // Questo elemento viene valorizzato solo nei casi di wsdl encoded dove gli elementi vengono definiti con wsdl:part element e non type.
- private String namespaceElementoCheContieneXSIType;
-
- public RootElementBody(SOAPEnvelope soapEnvelope,Node nodoPadre,boolean rpc, Node n) throws Exception{
-
- NamedNodeMap attributes = n.getAttributes();
- this.localName = n.getLocalName();
-
- // Prima verifico presenza di xsi:types ...
- if(attributes!=null && attributes.getLength()>0){
- for (int i = 0; i < attributes.getLength(); i++) {
- Node attribute = attributes.item(i);
- if(attribute instanceof Attr){
- Attr a = (Attr) attribute;
- //String attrName = a.getName(); // type
- //String attrPrefix = a.getPrefix(); // xsi
- String attrLocalName = a.getLocalName();
- String attrNamespace = a.getNamespaceURI(); // http://www.w3.org/2001/XMLSchema-instance
- String value = a.getNodeValue(); // messaggioSII:esitoProcessMessaggioSIIType
- //System.out.println("ATTRNAME["+attrName+"] ATTRPREFIX["+attrPrefix+"] ATTRNAMESPACE["+attrNamespace+"] VALUE["+value+"]");
- if(WSDLValidator.XMLSCHEMA_INSTANCE_NAMESPACE.equals(attrNamespace) &&
- WSDLValidator.XMLSCHEMA_INSTANCE_LOCAL_NAME_TYPE.equals(attrLocalName) &&
- value!=null){
- String prefix = "";
- String typeName = value;
- if(value.contains(":")){
- prefix = value.split(":")[0];
- typeName = value.split(":")[1];
- }
- this.xsiType = typeName;
-
- // Cerco namespace corrispondente al prefix.
- // 1. cerco prima nel nodo stesso
- this.namespace = this.mappingPrefixToNamespace(n, prefix);
- if(this.namespace==null){
- if(rpc){
- // 2. cerco nel rpc element
- this.namespace = this.mappingPrefixToNamespace(nodoPadre, prefix);
- if(this.namespace==null){
- // 3. cerco nel soap body
- this.namespace = this.mappingPrefixToNamespace(soapEnvelope.getBody(), prefix);
- if(this.namespace==null){
- // 4. cerco nel soap envelope
- this.namespace = this.mappingPrefixToNamespace(soapEnvelope, prefix);
- if(this.namespace==null){
- throw new Exception("[RPCStyle] Namespace (for prefix "+prefix+") not found for element ["+n.getLocalName()+"] with xsi:type=\""+value+"\"");
- }
- }
- }
- }else{
- // 2. cerco nel soap body (il nodo padre)
- this.namespace = this.mappingPrefixToNamespace(nodoPadre, prefix);
- if(this.namespace==null){
- // 3. cerco nel soap envelope
- this.namespace = this.mappingPrefixToNamespace(soapEnvelope, prefix);
- if(this.namespace==null){
- throw new Exception("[DocumentStyle] Namespace (for prefix "+prefix+") not found for element ["+n.getLocalName()+"] with xsi:type=\""+value+"\"");
- }
- }
- }
- }
- }
- }
- }
- }
-
- if(this.xsiType==null){
- this.namespace = n.getNamespaceURI();
- }
- else{
- this.namespaceElementoCheContieneXSIType = n.getNamespaceURI();
- }
- }
-
- private String mappingPrefixToNamespace(Node n,String prefix) {
- NamedNodeMap attributes = n.getAttributes();
- if(attributes==null || attributes.getLength()<=0){
- return null;
- }
- for (int i = 0; i < attributes.getLength(); i++) {
- Node attribute = attributes.item(i);
- if(attribute instanceof Attr){
- Attr a = (Attr) attribute;
- String attrName = a.getName(); // type
- //String attrPrefix = a.getPrefix(); // xsi
- //String attrNamespace = a.getNamespaceURI(); // http://www.w3.org/2001/XMLSchema-instance
- String value = a.getNodeValue(); // messaggioSII:esitoProcessMessaggioSIIType
- //System.out.println("CHECK XMLNS Search["+prefix+"] ATTRNAME["+attrName+"] ATTRPREFIX["+attrPrefix+"] ATTRNAMESPACE["+attrNamespace+"] VALUE["+value+"]");
-
- if(attrName.startsWith("xmlns")){
-
- if(prefix==null || prefix.equals("")){
- if("xmlns".equals(attrName)){
- //System.out.println("FOUND! ["+value+"]");
- return value;
- }
- }
- else{
- if(attrName.equals("xmlns:"+prefix)){
- //System.out.println("FOUND! ["+value+"]");
- return value;
- }
- }
-
- }
-
- }
- }
- return null;
- }
-
- public String getLocalName() {
- return this.localName;
- }
- public void setLocalName(String localName) {
- this.localName = localName;
- }
- public String getNamespace() {
- return this.namespace;
- }
- public void setNamespace(String namespace) {
- this.namespace = namespace;
- }
- public String getXsiType() {
- return this.xsiType;
- }
- public void setXsiType(String xsiType) {
- this.xsiType = xsiType;
- }
- public String getNamespaceElementoCheContieneXSIType() {
- return this.namespaceElementoCheContieneXSIType;
- }
- public void setNamespaceElementoCheContieneXSIType(
- String namespaceElementoCheContieneXSIType) {
- this.namespaceElementoCheContieneXSIType = namespaceElementoCheContieneXSIType;
- }
-
- @Override
- public String toString(){
- return RootElementBody.toString(this.localName, this.namespace, this.xsiType, this.namespaceElementoCheContieneXSIType);
- }
-
- public static String toString(String localName,String namespace,String xsiType){
- return toString(localName, namespace, xsiType, null);
- }
- private static String toString(String localName,String namespace,String xsiType,String namespaceElementoCheContieneXSIType){
- StringBuilder bf = new StringBuilder();
- if(xsiType==null){
- bf.append("{");
- bf.append(namespace);
- bf.append("}");
- bf.append(localName);
- }else{
- bf.append("[xsi:type=\"{");
- bf.append(namespace);
- bf.append("\"}"+xsiType+"]");
- // Questo elemento viene valorizzato solo nei casi di wsdl encoded dove gli elementi vengono definiti con wsdl:part element e non type.
- if(namespaceElementoCheContieneXSIType!=null){
- bf.append("{");
- bf.append(namespaceElementoCheContieneXSIType);
- bf.append("}");
- }
- bf.append(localName);
- }
- return bf.toString();
- }
- }