package org.jboss.axis.message;
import org.jboss.axis.AxisFault;
import org.jboss.axis.Constants;
import org.jboss.axis.encoding.Callback;
import org.jboss.axis.encoding.CallbackTarget;
import org.jboss.axis.encoding.DeserializationContext;
import org.jboss.axis.encoding.Deserializer;
import org.jboss.axis.soap.SOAPConstants;
import org.jboss.axis.utils.ClassUtils;
import org.jboss.axis.utils.Messages;
import org.jboss.logging.Logger;
import org.w3c.dom.Element;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import javax.xml.namespace.QName;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
public class SOAPFaultBuilder extends SOAPHandler implements Callback
{
boolean waiting = false;
boolean passedEnd = false;
protected SOAPFaultImpl element;
protected DeserializationContext context;
static HashMap fields_soap11 = new HashMap();
static HashMap fields_soap12 = new HashMap();
protected QName faultCode = null;
protected QName[] faultSubCode = null;
protected String faultString = null;
protected String faultActor = null;
protected Element[] faultDetails;
protected String faultNode = null;
protected SOAPFaultCodeBuilder code;
protected Class faultClass = null;
protected Object faultData = null;
private static Logger log = Logger.getLogger(SOAPFaultBuilder.class.getName());
static
{
fields_soap11.put(Constants.ELEM_FAULT_CODE, Constants.XSD_QNAME);
fields_soap11.put(Constants.ELEM_FAULT_STRING, Constants.XSD_STRING);
fields_soap11.put(Constants.ELEM_FAULT_ACTOR, Constants.XSD_STRING);
fields_soap11.put(Constants.ELEM_FAULT_DETAIL, null);
}
static
{
fields_soap12.put(Constants.ELEM_FAULT_REASON_SOAP12, null);
fields_soap12.put(Constants.ELEM_FAULT_ROLE_SOAP12, Constants.XSD_STRING);
fields_soap12.put(Constants.ELEM_FAULT_NODE_SOAP12, Constants.XSD_STRING);
fields_soap12.put(Constants.ELEM_FAULT_DETAIL_SOAP12, null);
}
public SOAPFaultBuilder(SOAPFaultImpl element,
DeserializationContext context)
{
this.element = element;
this.context = context;
}
public void startElement(String namespace, String localName,
String prefix, Attributes attributes,
DeserializationContext context)
throws SAXException
{
SOAPConstants soapConstants = Constants.DEFAULT_SOAP_VERSION;
if (context.getMessageContext() != null)
soapConstants = context.getMessageContext().getSOAPConstants();
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS &&
attributes.getValue(Constants.URI_SOAP12_ENV, Constants.ATTR_ENCODING_STYLE) != null)
{
AxisFault fault = new AxisFault(Constants.FAULT_SOAP12_SENDER,
null, Messages.getMessage("noEncodingStyleAttrAppear", "Fault"), null, null, null);
throw new SAXException(fault);
}
super.startElement(namespace, localName, prefix, attributes, context);
}
void setFaultData(Object data)
{
faultData = data;
if (waiting && passedEnd)
{
createFault();
}
waiting = false;
}
public void setFaultClass(Class faultClass)
{
this.faultClass = faultClass;
}
public void endElement(String namespace, String localName,
DeserializationContext context)
throws SAXException
{
super.endElement(namespace, localName, context);
if (!waiting)
{
createFault();
}
else
{
passedEnd = true;
}
}
void setWaiting(boolean waiting)
{
this.waiting = waiting;
}
private void createFault()
{
AxisFault f = null;
SOAPConstants soapConstants = context.getMessageContext() == null ?
SOAPConstants.SOAP11_CONSTANTS :
context.getMessageContext().getSOAPConstants();
if (faultClass != null)
{
try
{
if (faultData != null)
{
if (faultData instanceof AxisFault)
{
f = (AxisFault)faultData;
}
else if (faultClass.isAssignableFrom(faultData.getClass()))
{
f = AxisFault.makeFault((Exception)faultData);
}
if (f == null)
{
try
{
Constructor ctor = faultClass.getConstructor(new Class[]{faultData.getClass()});
f = (AxisFault)ctor.newInstance(new Object[]{faultData});
}
catch (Exception ignore)
{
}
}
if (f == null && Exception.class.isAssignableFrom(faultData.getClass()))
{
try
{
Constructor ctor = faultClass.getConstructor(new Class[]{String.class});
Exception custEx = (Exception)ctor.newInstance(new Object[]{((Exception)faultData).getMessage()});
f = AxisFault.makeFault(custEx);
}
catch (Exception ignore)
{
}
}
}
if (AxisFault.class.isAssignableFrom(faultClass))
{
if (f == null)
{
f = (AxisFault)faultClass.newInstance();
}
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
{
f.setFaultCode(code.getFaultCode());
SOAPFaultCodeBuilder c = code;
while ((c = c.getNext()) != null)
{
f.addFaultSubCode(c.getFaultCode());
}
}
else
{
f.setFaultCode(faultCode);
}
f.setFaultString(faultString);
f.setFaultActor(faultActor);
f.setFaultNode(faultNode);
f.setFaultDetail(faultDetails);
}
}
catch (Exception e)
{
}
}
if (faultClass == null && faultString != null && faultString.indexOf(' ') < 0)
{
try
{
Class argClass = ClassUtils.forName(faultString);
Constructor[] constructs = argClass.getConstructors();
for (int x = 0; x < constructs.length; x++)
{
Constructor construct = constructs[x];
Class[] params = construct.getParameterTypes();
if (params.length == 1 && params[0].isAssignableFrom(String.class))
{
Exception custEx = (Exception)construct.newInstance(new Object[]{""});
f = AxisFault.makeFault(custEx);
break;
}
}
}
catch (Exception e)
{
log.debug("Cannot create a fault instance of class: " + faultString);
}
}
if (f == null)
{
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
{
faultCode = code.getFaultCode();
if (code.getNext() != null)
{
Vector v = new Vector();
SOAPFaultCodeBuilder c = code;
while ((c = c.getNext()) != null)
v.add(c.getFaultCode());
faultSubCode = (QName[])v.toArray(new QName[v.size()]);
}
}
f = new AxisFault(faultCode,
faultSubCode,
faultString,
faultActor,
faultNode,
faultDetails);
try
{
Vector headers = element.getEnvelope().getHeaders();
for (int i = 0; i < headers.size(); i++)
{
SOAPHeaderElementAxisImpl header =
(SOAPHeaderElementAxisImpl)headers.elementAt(i);
f.addHeader(header);
}
}
catch (AxisFault axisFault)
{
}
}
element.setFault(f);
}
public SOAPHandler onStartChild(String namespace,
String name,
String prefix,
Attributes attributes,
DeserializationContext context)
throws SAXException
{
SOAPHandler retHandler = null;
SOAPConstants soapConstants = context.getMessageContext() == null ?
SOAPConstants.SOAP11_CONSTANTS :
context.getMessageContext().getSOAPConstants();
QName qName = null;
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
{
qName = (QName)fields_soap12.get(name);
if (qName == null)
{
QName thisQName = new QName(namespace, name);
if (thisQName.equals(Constants.QNAME_FAULTCODE_SOAP12))
return (code = new SOAPFaultCodeBuilder());
else if (thisQName.equals(Constants.QNAME_FAULTREASON_SOAP12))
return new SOAPFaultReasonBuilder(this);
else if (thisQName.equals(Constants.QNAME_FAULTDETAIL_SOAP12))
return new SOAPFaultDetailsBuilder(this);
}
}
else
{
qName = (QName)fields_soap11.get(name);
if (qName == null && name.equals(Constants.ELEM_FAULT_DETAIL))
return new SOAPFaultDetailsBuilder(this);
}
if (qName != null)
{
Deserializer currentDeser = context.getDeserializerForType(qName);
if (currentDeser != null)
{
currentDeser.registerValueTarget(new CallbackTarget(this, new QName(namespace, name)));
}
retHandler = (SOAPHandler)currentDeser;
}
return retHandler;
}
public void onEndChild(String namespace, String localName,
DeserializationContext context)
throws SAXException
{
if (Constants.ELEM_FAULT_DETAIL.equals(localName))
{
SOAPElementAxisImpl el = context.getCurElement();
List children = el.getChildren();
if (children != null)
{
Element[] elements = new Element[children.size()];
for (int i = 0; i < elements.length; i++)
{
try
{
elements[i] = ((SOAPElementAxisImpl)children.get(i)).
getAsDOM();
}
catch (Exception e)
{
throw new SAXException(e);
}
}
faultDetails = elements;
}
}
}
public void setValue(Object value, Object hint)
{
String local = ((QName)hint).getLocalPart();
if (((QName)hint).getNamespaceURI().equals(Constants.URI_SOAP12_ENV))
{
if (local.equals(Constants.ELEM_FAULT_ROLE_SOAP12))
{
faultActor = (String)value;
}
else if (local.equals(Constants.ELEM_TEXT_SOAP12))
{
faultString = (String)value;
}
else if (local.equals(Constants.ELEM_FAULT_NODE_SOAP12))
{
faultNode = (String)value;
}
}
else
{
if (local.equals(Constants.ELEM_FAULT_CODE))
{
faultCode = (QName)value;
}
else if (local.equals(Constants.ELEM_FAULT_STRING))
{
faultString = (String)value;
}
else if (local.equals(Constants.ELEM_FAULT_ACTOR))
{
faultActor = (String)value;
}
}
}
private static HashMap TYPES = new HashMap(7);
static
{
TYPES.put(java.lang.Integer.class, int.class);
TYPES.put(java.lang.Float.class, float.class);
TYPES.put(java.lang.Boolean.class, boolean.class);
TYPES.put(java.lang.Double.class, double.class);
TYPES.put(java.lang.Byte.class, byte.class);
TYPES.put(java.lang.Short.class, short.class);
TYPES.put(java.lang.Long.class, long.class);
}
private Class ConvertWrapper(Class cls)
{
Class ret = (Class)TYPES.get(cls);
if (ret != null)
{
return ret;
}
return cls;
}
}