KickJava   Java API By Example, From Geeks To Geeks.

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

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

123     public void endElement(String JavaDoc namespace, String JavaDoc localName,
124                            DeserializationContext context)
125             throws SAXException JavaDoc {
126         super.endElement(namespace, localName, context);
127         if (!waiting) {
128             createFault();
129         } else {
130             passedEnd = true;
131         }
132     }
133
134     void setWaiting(boolean waiting) {
135         this.waiting = waiting;
136     }
137
138     /**
139      * When we're sure we have everything, this gets called.
140      */

141     private void createFault() {
142         AxisFault f = null;
143         
144         SOAPConstants soapConstants = context.getMessageContext() == null ?
145                                         SOAPConstants.SOAP11_CONSTANTS :
146                                         context.getMessageContext().getSOAPConstants();
147
148         if (faultClass != null) {
149             // Custom fault handling
150
try {
151                 
152                 // If we have an element which is fault data, It can be:
153
// 1. A simple type that needs to be passed in to the constructor
154
// 2. A complex type that is the exception itself
155
if (faultData != null) {
156                     if (faultData instanceof AxisFault) {
157                         // This is our exception class
158
f = (AxisFault) faultData;
159                     } else {
160                         // We need to create the exception,
161
// passing the data to the constructor.
162
Class JavaDoc argClass = ConvertWrapper(faultData.getClass());
163                         try {
164                             Constructor JavaDoc con =
165                                     faultClass.getConstructor(
166                                             new Class JavaDoc[] { argClass });
167                             f = (AxisFault) con.newInstance(new Object JavaDoc[] { faultData });
168                         } catch(Exception JavaDoc e){
169                             // Don't do anything here, since a problem above means
170
// we'll just fall through and use a plain AxisFault.
171
}
172                         if (f == null && faultData instanceof Exception JavaDoc) {
173                             f = AxisFault.makeFault((Exception JavaDoc)faultData);
174                         }
175                     }
176                 }
177                 // If we have an AxisFault, set the fields
178
if (AxisFault.class.isAssignableFrom(faultClass)) {
179                     if (f == null) {
180                         // this is to support the <exceptionName> detail
181
f = (AxisFault) faultClass.newInstance();
182                     }
183     
184                     if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) {
185                         f.setFaultCode(code.getFaultCode());
186
187                         SOAPFaultCodeBuilder c = code;
188                         while ((c = c.getNext()) != null) {
189                             f.addFaultSubCode(c.getFaultCode());
190                         }
191                     } else {
192                         f.setFaultCode(faultCode);
193                     }
194
195                     f.setFaultString(faultString);
196                     f.setFaultActor(faultActor);
197                     f.setFaultNode(faultNode);
198                     f.setFaultDetail(faultDetails);
199                 }
200             } catch (Exception JavaDoc e) {
201                 // Don't do anything here, since a problem above means
202
// we'll just fall through and use a plain AxisFault.
203
}
204         }
205
206         if (f == null) {
207             if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) {
208                 faultCode = code.getFaultCode();
209                 if (code.getNext() != null)
210                 {
211                     Vector JavaDoc v = new Vector JavaDoc();
212
213                     SOAPFaultCodeBuilder c = code;
214                     while ((c = c.getNext()) != null)
215                         v.add(c.getFaultCode());
216                     
217                     faultSubCode = (QName JavaDoc[])v.toArray(new QName JavaDoc[v.size()]);
218                 }
219             }
220     
221             f = new AxisFault(faultCode,
222                                faultSubCode,
223                                faultString,
224                                faultActor,
225                                faultNode,
226                                faultDetails);
227
228             try {
229                 Vector JavaDoc headers = element.getEnvelope().getHeaders();
230                 for (int i = 0; i < headers.size(); i++) {
231                     SOAPHeaderElement header =
232                             (SOAPHeaderElement) headers.elementAt(i);
233                     f.addHeader(header);
234                 }
235             } catch (AxisFault axisFault) {
236                 // What to do here?
237
}
238         }
239
240         element.setFault(f);
241     }
242
243     public SOAPHandler onStartChild(String JavaDoc namespace,
244                                     String JavaDoc name,
245                                     String JavaDoc prefix,
246                                     Attributes JavaDoc attributes,
247                                     DeserializationContext context)
248         throws SAXException JavaDoc
249     {
250         SOAPHandler retHandler = null;
251
252         SOAPConstants soapConstants = context.getMessageContext() == null ?
253                 SOAPConstants.SOAP11_CONSTANTS :
254                 context.getMessageContext().getSOAPConstants();
255         
256         QName JavaDoc qName = null;
257         // If we found the type for this field, get the deserializer
258
// otherwise, if this is the details element, use the special
259
// SOAPFaultDetailsBuilder handler to take care of custom fault data
260
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS) {
261             qName = (QName JavaDoc)fields_soap12.get(name);
262             if (qName == null) {
263                 QName JavaDoc thisQName = new QName JavaDoc(namespace, name);
264                 if (thisQName.equals(Constants.QNAME_FAULTCODE_SOAP12))
265                     return (code = new SOAPFaultCodeBuilder());
266                 else if (thisQName.equals(Constants.QNAME_FAULTREASON_SOAP12))
267                     return new SOAPFaultReasonBuilder(this);
268                 else if (thisQName.equals(Constants.QNAME_FAULTDETAIL_SOAP12))
269                     return new SOAPFaultDetailsBuilder(this);
270
271             }
272         } else {
273             qName = (QName JavaDoc)fields_soap11.get(name);
274             if (qName == null && name.equals(Constants.ELEM_FAULT_DETAIL))
275                 return new SOAPFaultDetailsBuilder(this);
276         }
277         
278         if (qName != null) {
279             Deserializer currentDeser = context.getDeserializerForType(qName);
280             if (currentDeser != null) {
281                 currentDeser.registerValueTarget(new CallbackTarget(this, new QName JavaDoc(namespace, name)));
282             }
283             retHandler = (SOAPHandler) currentDeser;
284         }
285         
286         return retHandler;
287     }
288
289     public void onEndChild(String JavaDoc namespace, String JavaDoc localName,
290                            DeserializationContext context)
291             throws SAXException JavaDoc {
292         if (Constants.ELEM_FAULT_DETAIL.equals(localName)) {
293             MessageElement el = context.getCurElement();
294             List JavaDoc children = el.getChildren();
295             if (children != null) {
296                 Element JavaDoc [] elements = new Element JavaDoc [children.size()];
297                 for (int i = 0; i < elements.length; i++) {
298                     try {
299                         elements[i] = ((MessageElement)children.get(i)).
300                                                                     getAsDOM();
301                         
302                     } catch (Exception JavaDoc e) {
303                         throw new SAXException JavaDoc(e);
304                     }
305                 }
306                 faultDetails = elements;
307             }
308         }
309     }
310
311     /*
312      * Defined by Callback.
313      * This method gets control when the callback is invoked.
314      * @param is the value to set.
315      * @param hint is an Object that provide additional hint information.
316      */

317     public void setValue(Object JavaDoc value, Object JavaDoc hint)
318     {
319         String JavaDoc local = ((QName JavaDoc)hint).getLocalPart();
320         if (((QName JavaDoc)hint).getNamespaceURI().equals(Constants.URI_SOAP12_ENV)) {
321             if (local.equals(Constants.ELEM_FAULT_ROLE_SOAP12)) {
322                 faultActor = (String JavaDoc) value;
323             } else if (local.equals(Constants.ELEM_TEXT_SOAP12)) {
324                 faultString = (String JavaDoc) value;
325             } else if (local.equals(Constants.ELEM_FAULT_NODE_SOAP12)) {
326                 faultNode = (String JavaDoc) value;
327             }
328         } else {
329             if (local.equals(Constants.ELEM_FAULT_CODE)) {
330                 faultCode = (QName JavaDoc)value;
331             } else if (local.equals(Constants.ELEM_FAULT_STRING)) {
332                 faultString = (String JavaDoc) value;
333             } else if (local.equals(Constants.ELEM_FAULT_ACTOR)) {
334                 faultActor = (String JavaDoc) value;
335             }
336         }
337
338     }
339
340     /**
341      * A simple map of holder objects and their primitive types
342      */

343     private static HashMap JavaDoc TYPES = new HashMap JavaDoc(7);
344
345     static {
346         TYPES.put(java.lang.Integer JavaDoc.class, int.class);
347         TYPES.put(java.lang.Float JavaDoc.class, float.class);
348         TYPES.put(java.lang.Boolean JavaDoc.class, boolean.class);
349         TYPES.put(java.lang.Double JavaDoc.class, double.class);
350         TYPES.put(java.lang.Byte JavaDoc.class, byte.class);
351         TYPES.put(java.lang.Short JavaDoc.class, short.class);
352         TYPES.put(java.lang.Long JavaDoc.class, long.class);
353     }
354     
355     /**
356      * Internal method to convert wrapper classes to their base class
357      */

358     private Class JavaDoc ConvertWrapper(Class JavaDoc cls) {
359         Class JavaDoc ret = (Class JavaDoc) TYPES.get(cls);
360         if (ret != null) {
361             return ret;
362         }
363         return cls;
364     }
365 }
366
Popular Tags