private static SOAPEnvelope createFaultEnvelope()

in modules/kernel/src/org/apache/axis2/util/MessageContextBuilder.java [446:757]


    private static SOAPEnvelope createFaultEnvelope(MessageContext context, Throwable e) {
        SOAPEnvelope envelope;
        
        if(log.isDebugEnabled()){
        	log.debug("start createFaultEnvelope()");
        }
        if (context.isSOAP11()) {
            envelope = OMAbstractFactory.getSOAP11Factory().getDefaultFaultEnvelope();
        } else {
            // Following will make SOAP 1.2 as the default, too.
            envelope = OMAbstractFactory.getSOAP12Factory().getDefaultFaultEnvelope();
        }
        SOAPFault fault = envelope.getBody().getFault();
        SOAPProcessingException soapException = null;
        AxisFault axisFault = null;

        if (e == null) return envelope;

        if (e instanceof AxisFault) {
            axisFault = (AxisFault) e;
        } else if (e.getCause() instanceof AxisFault) {
            axisFault = (AxisFault) e.getCause();
        }

        if (axisFault != null) {
            Iterator iter = axisFault.headerIterator();
            while (iter.hasNext()) {
                SOAPHeaderBlock header = (SOAPHeaderBlock) iter.next();
                envelope.getHeader().addChild(header);
            }
        }

        if (e instanceof SOAPProcessingException) {
            soapException = (SOAPProcessingException) e;
        } else if (axisFault != null) {
            if (axisFault.getCause() instanceof SOAPProcessingException) {
                soapException = (SOAPProcessingException) axisFault.getCause();
            }
        }

        // user can set the fault information to the message context or to the AxisFault itself.
        // whatever user sets to the message context, supercedes eerything.
        
        Object faultCode = context.getProperty(SOAP12Constants.SOAP_FAULT_CODE_LOCAL_NAME);
        String soapFaultCode = "";

        if (faultCode != null) {
        	if(log.isDebugEnabled()){
        		log.debug("faultCode != null");
        	}
            fault.setCode((SOAPFaultCode) faultCode);
            soapFaultCode = ((SOAPFaultCode) faultCode).getText();
        } else if (soapException != null) {
        	if(log.isDebugEnabled()){
        		log.debug("soapException != null");
        	}
            soapFaultCode = soapException.getFaultCode();
            OMNamespace namespace = null;
            if(envelope!=null){
            	if(log.isDebugEnabled()){
            		log.debug("envelope!=null");
            	}	
            	namespace = envelope.getNamespace();
            }
            
            if (namespace != null){
                String sfcLocalPart = soapFaultCode.substring(soapFaultCode.lastIndexOf(":")+1);
      
                //If the fault code is one of the predefined ones that make sure the prefix 
                //matches that of the envelope NS
                if (sfcLocalPart.equals(SOAPConstants.FAULT_CODE_VERSION_MISMATCH) ||
                    sfcLocalPart.equals(SOAPConstants.FAULT_CODE_MUST_UNDERSTAND) ||
                    sfcLocalPart.equals(SOAPConstants.FAULT_CODE_DATA_ENCODING_UNKNOWN) ||
                    sfcLocalPart.equals(SOAPConstants.FAULT_CODE_RECEIVER) ||
                    sfcLocalPart.equals(SOAPConstants.FAULT_CODE_SENDER)) {
                
                    if(log.isDebugEnabled()){
                        log.debug("SoapFaultCode local part= " +sfcLocalPart);
                    }

                    String prefix = namespace.getPrefix() + ":";

                    if (!soapFaultCode.contains(":")) {
                        soapFaultCode = prefix + soapFaultCode;
                    } else {
                        soapFaultCode = prefix + soapFaultCode.substring(soapFaultCode.indexOf(":")+1);
                    }

                    if(log.isDebugEnabled()){
                        log.debug("SoapFaultCode reset to " +soapFaultCode);
                    }

                }
            } else {
                if(log.isDebugEnabled()){
                    log.debug("Namespace is null, cannot attach prefix to SOAPFaultCode");
                }
            }
            
            if(log.isDebugEnabled()){        	
                log.debug("SoapFaultCode ="+soapFaultCode);        	
            }
        	
        } else if (axisFault != null) {
        	if(log.isDebugEnabled()){
        		log.debug("axisFault != null");
        	}
            if (axisFault.getFaultCodeElement() != null) {
                fault.setCode(axisFault.getFaultCodeElement());
                soapFaultCode = axisFault.getFaultCodeElement().getText();               
            } else {
                QName faultCodeQName = axisFault.getFaultCode();
                if (faultCodeQName != null) {
                	if(log.isDebugEnabled()){
                		log.debug("prefix ="+faultCodeQName.getPrefix());
                		log.debug("Fault Code namespace ="+faultCodeQName.getNamespaceURI());
                		log.debug("Fault Code ="+faultCodeQName.getLocalPart());
                	}
                    if (faultCodeQName.getLocalPart().indexOf(":") == -1) {
                    	if(log.isDebugEnabled()){
                    		log.debug("faultCodeQName.getLocalPart().indexOf(\":\") == -1");
                    	}
                        String prefix = faultCodeQName.getPrefix();
                        if(log.isDebugEnabled()){
                        	log.debug("prefix = "+prefix);
                        }
                        String uri = faultCodeQName.getNamespaceURI();
                        // Get the specified uri
                        uri = uri == null || "" .equals(uri) ?
                                fault.getNamespace().getNamespaceURI() : uri;
                        // Make sure the prefix and uri are declared on the fault, and 
                        // get the resulting prefix. If no prefix is defined, let declareNamespace
                        // generate one.
                        prefix = fault.declareNamespace(uri, prefix.length() == 0 ? null : prefix).getPrefix();
                        soapFaultCode = prefix + ":" + faultCodeQName.getLocalPart();
                        if(log.isDebugEnabled()){
                        	log.debug("Altered soapFaultCode ="+soapFaultCode);
                        }
                    } else {
                        soapFaultCode = faultCodeQName.getLocalPart();
                    }
                }
            }
        }

        // defaulting to fault code Receiver, if no message is available
        if (faultCode == null && context.getEnvelope() != null) {
            soapFaultCode = ("".equals(soapFaultCode) || (soapFaultCode == null))
                    ? SOAP12Constants.SOAP_DEFAULT_NAMESPACE_PREFIX + ":" +
                        context.getEnvelope().getVersion().getReceiverFaultCode().getLocalPart()
                    : soapFaultCode;
        }
        
        if (faultCode == null) {
        	if(log.isDebugEnabled()){
        		log.debug("faultCode == null");
        	}
            if (context.isSOAP11()) {
            	if(log.isDebugEnabled()){
            		log.debug("context.isSOAP11() = true");
            		SOAPFaultCode code = (fault!=null)?fault.getCode():null;
            		SOAPFaultValue value = (code!=null)?code.getValue():null;
            		if(value !=null){
            			QName name = value.getQName();
            			log.debug("prefix ="+name.getPrefix());
            			log.debug("Fault Code namespace ="+name.getNamespaceURI());
            			log.debug("Fault Code ="+name.getLocalPart());
            		}
            	}

                fault.getCode().setText(soapFaultCode);
            } else {
            	if(log.isDebugEnabled()){
            		log.debug("context.isSOAP11() = false");
            		SOAPFaultCode code = (fault!=null)?fault.getCode():null;
            		SOAPFaultValue value = (code!=null)?code.getValue():null;
            		if(value !=null){
            			QName name = value.getQName();
            			log.debug("prefix ="+name.getPrefix());
            			log.debug("Fault Code namespace ="+name.getNamespaceURI());
            			log.debug("Fault Code ="+name.getLocalPart());
            		}
            	}
                SOAPFaultValue value = fault.getCode().getValue();
                if(log.isDebugEnabled()){
                    log.debug("soapFaultCode originally was set to : " + soapFaultCode);
                }
                OMNamespace namespace = value.getNamespace();
                soapFaultCode = switchNamespacePrefix(soapFaultCode, namespace);
                value.setText(soapFaultCode);
            }
        }
        
        if (axisFault != null && !context.isSOAP11()) {
            if (axisFault.getFaultSubCodes() != null) {
                
                List faultSubCodes = axisFault.getFaultSubCodes();
                
                QName faultSubCodeQName;

                for (Object faultSubCode : faultSubCodes) {

                    faultSubCodeQName = (QName)faultSubCode;

                    SOAPFactory sf = (SOAPFactory)envelope.getOMFactory();
                    SOAPFaultSubCode soapFaultSubCode = sf.createSOAPFaultSubCode(fault.getCode());
                    SOAPFaultValue saopFaultValue = sf.createSOAPFaultValue(fault.getCode());
                    saopFaultValue.setText(faultSubCodeQName);
                    soapFaultSubCode.setValue(saopFaultValue);
                    fault.getCode().setSubCode(soapFaultSubCode);
                }
                
            } 
        }

        SOAPFaultReason faultReason = (SOAPFaultReason)context.getProperty(
                                            SOAP12Constants.SOAP_FAULT_REASON_LOCAL_NAME);

        if (faultReason == null && axisFault != null) {
            faultReason = axisFault.getFaultReasonElement();
        }
        if (faultReason != null) {
            fault.setReason(faultReason);
        } else {
            String message = "";
            if (soapException != null) {
                message = soapException.getMessage();
            } else if (axisFault != null) {
                // Couldn't find FaultReasonElement, try reason string
                message = axisFault.getReason();
            }

            if (message == null || "".equals(message)) {
                message = getFaultReasonFromException(e, context);
            }

            if (message == null || "".equals(message)) message = "unknown";

            if (context.isSOAP11()) {
                fault.getReason().setText(message);
            } else {
                fault.getReason().getFirstSOAPText().setLang("en-US");
                fault.getReason().getFirstSOAPText().setText(message);
            }
        }

        Object faultRole = context.getProperty(SOAP12Constants.SOAP_FAULT_ROLE_LOCAL_NAME);
        if (faultRole != null) {
            fault.getRole().setText((String) faultRole);
        } else if (axisFault != null) {
            if (axisFault.getFaultRoleElement() != null) {
                fault.setRole(axisFault.getFaultRoleElement());
            }
        }

        Object faultNode = context.getProperty(SOAP12Constants.SOAP_FAULT_NODE_LOCAL_NAME);
        if (faultNode != null) {
            SOAPFaultNode soapFaultNode = fault.getNode();
            if(soapFaultNode != null) {
                soapFaultNode.setText((String) faultNode);
            }
        } else if (axisFault != null) {
            if (axisFault.getFaultNodeElement() != null) {
                fault.setNode(axisFault.getFaultNodeElement());
            }
        }

        // Allow handlers to override the sendStacktraceDetailsWithFaults setting from the Configuration to allow
        // WS-* protocol faults to not include the exception.
        boolean sendStacktraceDetailsWithFaults = false;
        OperationContext oc = context.getOperationContext();
        Object flagFromContext = null;
        if (oc != null) {
            flagFromContext = context.getOperationContext()
                    .getProperty(Constants.Configuration.SEND_STACKTRACE_DETAILS_WITH_FAULTS);
        }
        if (flagFromContext != null) {
            sendStacktraceDetailsWithFaults = JavaUtils.isTrue(flagFromContext);
        } else {
            Parameter param = context.getParameter(
                    Constants.Configuration.SEND_STACKTRACE_DETAILS_WITH_FAULTS);
            if (param != null) {
                sendStacktraceDetailsWithFaults = JavaUtils.isTrue(param.getValue());
            }
        }

        Object faultDetail = context.getProperty(SOAP12Constants.SOAP_FAULT_DETAIL_LOCAL_NAME);
        if (faultDetail != null) {
            fault.setDetail((SOAPFaultDetail) faultDetail);
        } else if (axisFault != null) {
            if (axisFault.getFaultDetailElement() != null) {
                fault.setDetail(axisFault.getFaultDetailElement());
            } else {
                OMElement detail = axisFault.getDetail();
                if (detail != null) {
                    fault.getDetail().addDetailEntry(detail);
                } else if (sendStacktraceDetailsWithFaults) {
                    fault.setException(axisFault);
                }
            }
        } else if (fault.getException() == null && sendStacktraceDetailsWithFaults) {
            if (e instanceof Exception) {
                fault.setException((Exception) e);
            } else {
                fault.setException(new Exception(e));
            }
        }
        
        if(log.isDebugEnabled())
            log.debug("End createFaultEnvelope()");
        return envelope;
    }