KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > message > SOAPFaultBuilder


1 /*
2  * Copyright 2001-2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package org.jboss.axis.message;
17
18 import org.jboss.axis.AxisFault;
19 import org.jboss.axis.Constants;
20 import org.jboss.axis.encoding.Callback;
21 import org.jboss.axis.encoding.CallbackTarget;
22 import org.jboss.axis.encoding.DeserializationContext;
23 import org.jboss.axis.encoding.Deserializer;
24 import org.jboss.axis.soap.SOAPConstants;
25 import org.jboss.axis.utils.ClassUtils;
26 import org.jboss.axis.utils.Messages;
27 import org.jboss.logging.Logger;
28 import org.w3c.dom.Element JavaDoc;
29 import org.xml.sax.Attributes JavaDoc;
30 import org.xml.sax.SAXException JavaDoc;
31
32 import javax.xml.namespace.QName JavaDoc;
33 import java.lang.reflect.Constructor JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.List JavaDoc;
36 import java.util.Vector JavaDoc;
37
38 /**
39  * Build a Fault body element.
40  *
41  * @author Sam Ruby (rubys@us.ibm.com)
42  * @author Glen Daniels (gdaniels@apache.org)
43  * @author Tom Jordahl (tomj@macromedia.com)
44  */

45 public class SOAPFaultBuilder extends SOAPHandler implements Callback
46 {
47    boolean waiting = false;
48    boolean passedEnd = false;
49
50    protected SOAPFaultImpl element;
51    protected DeserializationContext context;
52    static HashMap JavaDoc fields_soap11 = new HashMap JavaDoc();
53    static HashMap JavaDoc fields_soap12 = new HashMap JavaDoc();
54
55    // Fault data
56
protected QName JavaDoc faultCode = null;
57    protected QName JavaDoc[] faultSubCode = null;
58    protected String JavaDoc faultString = null;
59    protected String JavaDoc faultActor = null;
60    protected Element JavaDoc[] faultDetails;
61    protected String JavaDoc faultNode = null;
62
63    protected SOAPFaultCodeBuilder code;
64
65    protected Class JavaDoc faultClass = null;
66    protected Object JavaDoc faultData = null;
67
68    private static Logger log = Logger.getLogger(SOAPFaultBuilder.class.getName());
69
70    static
71    {
72       fields_soap11.put(Constants.ELEM_FAULT_CODE, Constants.XSD_QNAME);
73       fields_soap11.put(Constants.ELEM_FAULT_STRING, Constants.XSD_STRING);
74       fields_soap11.put(Constants.ELEM_FAULT_ACTOR, Constants.XSD_STRING);
75       fields_soap11.put(Constants.ELEM_FAULT_DETAIL, null);
76    }
77
78    static
79    {
80       fields_soap12.put(Constants.ELEM_FAULT_REASON_SOAP12, null);
81       fields_soap12.put(Constants.ELEM_FAULT_ROLE_SOAP12, Constants.XSD_STRING);
82       fields_soap12.put(Constants.ELEM_FAULT_NODE_SOAP12, Constants.XSD_STRING);
83       fields_soap12.put(Constants.ELEM_FAULT_DETAIL_SOAP12, null);
84    }
85
86    public SOAPFaultBuilder(SOAPFaultImpl element,
87                            DeserializationContext context)
88    {
89       this.element = element;
90       this.context = context;
91    }
92
93    public void startElement(String JavaDoc namespace, String JavaDoc localName,
94                             String JavaDoc prefix, Attributes JavaDoc attributes,
95                             DeserializationContext context)
96            throws SAXException JavaDoc
97    {
98       SOAPConstants soapConstants = Constants.DEFAULT_SOAP_VERSION;
99       if (context.getMessageContext() != null)
100          soapConstants = context.getMessageContext().getSOAPConstants();
101
102       if (soapConstants == SOAPConstants.SOAP12_CONSTANTS &&
103               attributes.getValue(Constants.URI_SOAP12_ENV, Constants.ATTR_ENCODING_STYLE) != null)
104       {
105
106          AxisFault fault = new AxisFault(Constants.FAULT_SOAP12_SENDER,
107                  null, Messages.getMessage("noEncodingStyleAttrAppear", "Fault"), null, null, null);
108
109          throw new SAXException JavaDoc(fault);
110       }
111
112       super.startElement(namespace, localName, prefix, attributes, context);
113    }
114
115    void setFaultData(Object JavaDoc data)
116    {
117       faultData = data;
118       if (waiting && passedEnd)
119       {
120          // This happened after the end of the <soap:Fault>, so make
121
// sure we set up the fault.
122
createFault();
123       }
124       waiting = false;
125    }
126
127    public void setFaultClass(Class JavaDoc faultClass)
128    {
129       this.faultClass = faultClass;
130    }
131
132    /**
133     * Final call back where we can populate the exception with data.
134     */

135    public void endElement(String JavaDoc namespace, String JavaDoc localName,
136                           DeserializationContext context)
137            throws SAXException JavaDoc
138    {
139       super.endElement(namespace, localName, context);
140       if (!waiting)
141       {
142          createFault();
143       }
144       else
145       {
146          passedEnd = true;
147       }
148    }
149
150    void setWaiting(boolean waiting)
151    {
152       this.waiting = waiting;
153    }
154
155    /**
156     * When we're sure we have everything, this gets called.
157     */

158    private void createFault()
159    {
160       AxisFault f = null;
161
162       SOAPConstants soapConstants = context.getMessageContext() == null ?
163               SOAPConstants.SOAP11_CONSTANTS :
164               context.getMessageContext().getSOAPConstants();
165
166       if (faultClass != null)
167       {
168          // Custom fault handling
169
try
170          {
171
172             // If we have an element which is fault data, It can be:
173
// 1. A simple type that needs to be passed in to the constructor
174
// 2. A complex type that is the exception itself
175
if (faultData != null)
176             {
177                if (faultData instanceof AxisFault)
178                {
179                   // This is our exception class
180
f = (AxisFault)faultData;
181                }
182                // If the faultData is of the expected faultClass type
183
else if (faultClass.isAssignableFrom(faultData.getClass()))
184                {
185                   f = AxisFault.makeFault((Exception JavaDoc)faultData);
186                }
187
188                // Create the exception, passing the data to the constructor.
189
if (f == null)
190                {
191                   try
192                   {
193                      Constructor JavaDoc ctor = faultClass.getConstructor(new Class JavaDoc[]{faultData.getClass()});
194                      f = (AxisFault)ctor.newInstance(new Object JavaDoc[]{faultData});
195                   }
196                   catch (Exception JavaDoc ignore)
197                   {
198                      // Don't do anything here
199
}
200                }
201
202                // Create the exception, passing the data to the constructor.
203
if (f == null && Exception JavaDoc.class.isAssignableFrom(faultData.getClass()))
204                {
205                   // if an exception, try to construct it using known parameters
206
try
207                   {
208                      Constructor JavaDoc ctor = faultClass.getConstructor(new Class JavaDoc[]{String JavaDoc.class});
209                      Exception JavaDoc custEx = (Exception JavaDoc)ctor.newInstance(new Object JavaDoc[]{((Exception JavaDoc)faultData).getMessage()});
210                      f = AxisFault.makeFault(custEx);
211                   }
212                   catch (Exception JavaDoc ignore)
213                   {
214                      // Don't do anything here
215
}
216                }
217
218             }
219
220             // If we have an AxisFault, set the fields
221
if (AxisFault.class.isAssignableFrom(faultClass))
222             {
223                if (f == null)
224                {
225                   // this is to support the <exceptionName> detail
226
f = (AxisFault)faultClass.newInstance();
227                }
228
229                if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
230                {
231                   f.setFaultCode(code.getFaultCode());
232
233                   SOAPFaultCodeBuilder c = code;
234                   while ((c = c.getNext()) != null)
235                   {
236                      f.addFaultSubCode(c.getFaultCode());
237                   }
238                }
239                else
240                {
241                   f.setFaultCode(faultCode);
242                }
243
244                f.setFaultString(faultString);
245                f.setFaultActor(faultActor);
246                f.setFaultNode(faultNode);
247                f.setFaultDetail(faultDetails);
248             }
249          }
250          catch (Exception JavaDoc e)
251          {
252             // Don't do anything here, since a problem above means
253
// we'll just fall through and use a plain AxisFault.
254
}
255       }
256
257       // if faultClass null and faultString is not, try to create from that.
258
if (faultClass == null && faultString != null && faultString.indexOf(' ') < 0)
259       {
260          try
261          {
262             // if is an exception, try to construct it using known parameters
263
Class JavaDoc argClass = ClassUtils.forName(faultString);
264
265             Constructor JavaDoc[] constructs = argClass.getConstructors();
266             for (int x = 0; x < constructs.length; x++)
267             {
268                // try to find just string parameter constructor
269
Constructor JavaDoc construct = constructs[x];
270                Class JavaDoc[] params = construct.getParameterTypes();
271                if (params.length == 1 && params[0].isAssignableFrom(String JavaDoc.class))
272                {
273                   Exception JavaDoc custEx = (Exception JavaDoc)construct.newInstance(new Object JavaDoc[]{""});
274                   f = AxisFault.makeFault(custEx);
275                   break;
276                }
277             }
278          }
279          catch (Exception JavaDoc e)
280          {
281             log.debug("Cannot create a fault instance of class: " + faultString);
282          }
283       }
284
285
286       if (f == null)
287       {
288          if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
289          {
290             faultCode = code.getFaultCode();
291             if (code.getNext() != null)
292             {
293                Vector JavaDoc v = new Vector JavaDoc();
294
295                SOAPFaultCodeBuilder c = code;
296                while ((c = c.getNext()) != null)
297                   v.add(c.getFaultCode());
298
299                faultSubCode = (QName JavaDoc[])v.toArray(new QName JavaDoc[v.size()]);
300             }
301          }
302
303          f = new AxisFault(faultCode,
304                  faultSubCode,
305                  faultString,
306                  faultActor,
307                  faultNode,
308                  faultDetails);
309
310          try
311          {
312             Vector JavaDoc headers = element.getEnvelope().getHeaders();
313             for (int i = 0; i < headers.size(); i++)
314             {
315                SOAPHeaderElementAxisImpl header =
316                        (SOAPHeaderElementAxisImpl)headers.elementAt(i);
317                f.addHeader(header);
318             }
319          }
320          catch (AxisFault axisFault)
321          {
322             // What to do here?
323
}
324       }
325
326       element.setFault(f);
327    }
328
329    public SOAPHandler onStartChild(String JavaDoc namespace,
330                                    String JavaDoc name,
331                                    String JavaDoc prefix,
332                                    Attributes JavaDoc attributes,
333                                    DeserializationContext context)
334            throws SAXException JavaDoc
335    {
336       SOAPHandler retHandler = null;
337
338       SOAPConstants soapConstants = context.getMessageContext() == null ?
339               SOAPConstants.SOAP11_CONSTANTS :
340               context.getMessageContext().getSOAPConstants();
341
342       QName JavaDoc qName = null;
343       // If we found the type for this field, get the deserializer
344
// otherwise, if this is the details element, use the special
345
// SOAPFaultDetailsBuilder handler to take care of custom fault data
346
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
347       {
348          qName = (QName JavaDoc)fields_soap12.get(name);
349          if (qName == null)
350          {
351             QName JavaDoc thisQName = new QName JavaDoc(namespace, name);
352             if (thisQName.equals(Constants.QNAME_FAULTCODE_SOAP12))
353                return (code = new SOAPFaultCodeBuilder());
354             else if (thisQName.equals(Constants.QNAME_FAULTREASON_SOAP12))
355                return new SOAPFaultReasonBuilder(this);
356             else if (thisQName.equals(Constants.QNAME_FAULTDETAIL_SOAP12))
357                return new SOAPFaultDetailsBuilder(this);
358
359          }
360       }
361       else
362       {
363          qName = (QName JavaDoc)fields_soap11.get(name);
364          if (qName == null && name.equals(Constants.ELEM_FAULT_DETAIL))
365             return new SOAPFaultDetailsBuilder(this);
366       }
367
368       if (qName != null)
369       {
370          Deserializer currentDeser = context.getDeserializerForType(qName);
371          if (currentDeser != null)
372          {
373             currentDeser.registerValueTarget(new CallbackTarget(this, new QName JavaDoc(namespace, name)));
374          }
375          retHandler = (SOAPHandler)currentDeser;
376       }
377
378       return retHandler;
379    }
380
381    public void onEndChild(String JavaDoc namespace, String JavaDoc localName,
382                           DeserializationContext context)
383            throws SAXException JavaDoc
384    {
385       if (Constants.ELEM_FAULT_DETAIL.equals(localName))
386       {
387          SOAPElementAxisImpl el = context.getCurElement();
388          List JavaDoc children = el.getChildren();
389          if (children != null)
390          {
391             Element JavaDoc[] elements = new Element JavaDoc[children.size()];
392             for (int i = 0; i < elements.length; i++)
393             {
394                try
395                {
396                   elements[i] = ((SOAPElementAxisImpl)children.get(i)).
397                           getAsDOM();
398
399                }
400                catch (Exception JavaDoc e)
401                {
402                   throw new SAXException JavaDoc(e);
403                }
404             }
405             faultDetails = elements;
406          }
407       }
408    }
409
410    /*
411     * Defined by Callback.
412     * This method gets control when the callback is invoked.
413     * @param is the value to set.
414     * @param hint is an Object that provide additional hint information.
415     */

416    public void setValue(Object JavaDoc value, Object JavaDoc hint)
417    {
418       String JavaDoc local = ((QName JavaDoc)hint).getLocalPart();
419       if (((QName JavaDoc)hint).getNamespaceURI().equals(Constants.URI_SOAP12_ENV))
420       {
421          if (local.equals(Constants.ELEM_FAULT_ROLE_SOAP12))
422          {
423             faultActor = (String JavaDoc)value;
424          }
425          else if (local.equals(Constants.ELEM_TEXT_SOAP12))
426          {
427             faultString = (String JavaDoc)value;
428          }
429          else if (local.equals(Constants.ELEM_FAULT_NODE_SOAP12))
430          {
431             faultNode = (String JavaDoc)value;
432          }
433       }
434       else
435       {
436          if (local.equals(Constants.ELEM_FAULT_CODE))
437          {
438             faultCode = (QName JavaDoc)value;
439          }
440          else if (local.equals(Constants.ELEM_FAULT_STRING))
441          {
442             faultString = (String JavaDoc)value;
443          }
444          else if (local.equals(Constants.ELEM_FAULT_ACTOR))
445          {
446             faultActor = (String JavaDoc)value;
447          }
448       }
449
450    }
451
452    /**
453     * A simple map of holder objects and their primitive types
454     */

455    private static HashMap JavaDoc TYPES = new HashMap JavaDoc(7);
456
457    static
458    {
459       TYPES.put(java.lang.Integer JavaDoc.class, int.class);
460       TYPES.put(java.lang.Float JavaDoc.class, float.class);
461       TYPES.put(java.lang.Boolean JavaDoc.class, boolean.class);
462       TYPES.put(java.lang.Double JavaDoc.class, double.class);
463       TYPES.put(java.lang.Byte JavaDoc.class, byte.class);
464       TYPES.put(java.lang.Short JavaDoc.class, short.class);
465       TYPES.put(java.lang.Long JavaDoc.class, long.class);
466    }
467
468    /**
469     * Internal method to convert wrapper classes to their base class
470     */

471    private Class JavaDoc ConvertWrapper(Class JavaDoc cls)
472    {
473       Class JavaDoc ret = (Class JavaDoc)TYPES.get(cls);
474       if (ret != null)
475       {
476          return ret;
477       }
478       return cls;
479    }
480 }
Popular Tags