KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > axis > MessagePart


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
17 package org.jboss.axis;
18
19 import org.jboss.axis.encoding.DeserializationContext;
20 import org.jboss.axis.encoding.DeserializationContextImpl;
21 import org.jboss.axis.encoding.SerializationContextImpl;
22 import org.jboss.axis.message.InputStreamBody;
23 import org.jboss.axis.message.MimeHeadersImpl;
24 import org.jboss.axis.message.SOAPBodyAxisImpl;
25 import org.jboss.axis.message.SOAPDocumentImpl;
26 import org.jboss.axis.message.SOAPEnvelopeAxisImpl;
27 import org.jboss.axis.message.SOAPHeaderElementAxisImpl;
28 import org.jboss.axis.message.SOAPPartAxisImpl;
29 import org.jboss.axis.soap.SOAPConstants;
30 import org.jboss.axis.transport.http.HTTPConstants;
31 import org.jboss.axis.utils.Messages;
32 import org.jboss.axis.utils.SessionUtils;
33 import org.jboss.logging.Logger;
34 import org.w3c.dom.Attr JavaDoc;
35 import org.w3c.dom.CDATASection JavaDoc;
36 import org.w3c.dom.Comment JavaDoc;
37 import org.w3c.dom.DOMException JavaDoc;
38 import org.w3c.dom.DOMImplementation JavaDoc;
39 import org.w3c.dom.Document JavaDoc;
40 import org.w3c.dom.DocumentFragment JavaDoc;
41 import org.w3c.dom.DocumentType JavaDoc;
42 import org.w3c.dom.Element JavaDoc;
43 import org.w3c.dom.EntityReference JavaDoc;
44 import org.w3c.dom.NamedNodeMap JavaDoc;
45 import org.w3c.dom.Node JavaDoc;
46 import org.w3c.dom.NodeList JavaDoc;
47 import org.w3c.dom.ProcessingInstruction JavaDoc;
48 import org.w3c.dom.Text JavaDoc;
49 import org.xml.sax.InputSource JavaDoc;
50 import org.xml.sax.SAXException JavaDoc;
51
52 import javax.xml.namespace.QName JavaDoc;
53 import javax.xml.soap.SOAPException JavaDoc;
54 import javax.xml.soap.SOAPMessage JavaDoc;
55 import javax.xml.transform.Source JavaDoc;
56 import javax.xml.transform.dom.DOMSource JavaDoc;
57 import javax.xml.transform.stream.StreamSource JavaDoc;
58 import java.io.BufferedReader JavaDoc;
59 import java.io.ByteArrayInputStream JavaDoc;
60 import java.io.ByteArrayOutputStream JavaDoc;
61 import java.io.IOException JavaDoc;
62 import java.io.InputStream JavaDoc;
63 import java.io.Reader JavaDoc;
64 import java.io.StringReader JavaDoc;
65 import java.io.StringWriter JavaDoc;
66 import java.io.UnsupportedEncodingException JavaDoc;
67 import java.io.Writer JavaDoc;
68 import java.util.Enumeration JavaDoc;
69 import java.util.Iterator JavaDoc;
70 import java.util.Vector JavaDoc;
71
72 /**
73  * The SOAPPart provides access to the root part of the Message which
74  * contains the envelope.
75  * <p/>
76  * SOAPPart implements Part, providing common MIME operations.
77  * <p/>
78  * SOAPPart also allows access to its envelope,
79  * as a string, byte[], InputStream, or SOAPEnvelope. (This functionality
80  * used to be in Message, and has been moved here more or less verbatim
81  * pending further cleanup.)
82  *
83  * @author Rob Jellinghaus (robj@unrealities.com)
84  * @author Doug Davis (dug@us.ibm.com)
85  * @author Glen Daniels (gdaniels@allaire.com)
86  * @author Heejune Ahn (cityboy@tmax.co.kr)
87  */

88 public class MessagePart extends SOAPPartAxisImpl implements Part
89 {
90
91    private static Logger log = Logger.getLogger(MessagePart.class.getName());
92
93    public static final int FORM_STRING = 1;
94    public static final int FORM_INPUTSTREAM = 2;
95    public static final int FORM_SOAPENVELOPE = 3;
96    public static final int FORM_BYTES = 4;
97    public static final int FORM_BODYINSTREAM = 5;
98    public static final int FORM_FAULT = 6;
99    private int currentForm;
100
101    //private Hashtable headers = new Hashtable();
102
private MimeHeadersImpl mimeHeaders = new MimeHeadersImpl();
103
104    private static final String JavaDoc[] formNames =
105            {"", "FORM_STRING", "FORM_INPUTSTREAM", "FORM_SOAPENVELOPE",
106             "FORM_BYTES", "FORM_BODYINSTREAM", "FORM_FAULT"};
107
108    /**
109     * The current representation of the SOAP contents of this part.
110     * May be a String, byte[], InputStream, or SOAPEnvelope, depending
111     * on whatever was last asked for. (ack)
112     * <p/>
113     * currentForm must have the corresponding value.
114     * <p/>
115     * As someone once said: "Just a placeholder until we figure out what the actual Message
116     * object is."
117     */

118    private Object JavaDoc currentMessage;
119
120    // These two fields are used for caching in getAsString and getAsBytes
121
private String JavaDoc currentMessageAsString = null;
122    private byte[] currentMessageAsBytes = null;
123    private SOAPEnvelopeAxisImpl currentMessageAsEnvelope = null;
124
125    /**
126     * Message object this part is tied to. Used for serialization settings.
127     */

128    private Message msgObject;
129
130    /**
131     * Field contentSource.
132     */

133    private Source JavaDoc contentSource = null;
134
135    /**
136     * The original message. Again, may be String, byte[], InputStream,
137     * or SOAPEnvelope.
138     */

139    // private Object originalMessage ; //free up reference this is not in use.
140

141    /**
142     * Create a new SOAPPart.
143     * <p/>
144     * Do not call this directly! Should only be called by Message.
145     *
146     * @param parent the parent <code>Message</code>
147     * @param initialContents the initial contens <code>Object</code>
148     * @param isBodyStream if the body is in a stream
149     */

150    public MessagePart(Message parent, Object JavaDoc initialContents, boolean isBodyStream)
151    {
152
153       setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, SessionUtils.generateSessionId());
154       setMimeHeader(HTTPConstants.HEADER_CONTENT_TYPE, "text/xml");
155
156       msgObject = parent;
157       // originalMessage = initialContents;
158
int form = FORM_STRING;
159       if (initialContents instanceof SOAPEnvelopeAxisImpl)
160       {
161          form = FORM_SOAPENVELOPE;
162       }
163       else if (initialContents instanceof InputStream JavaDoc)
164       {
165          form = isBodyStream ? FORM_BODYINSTREAM : FORM_INPUTSTREAM;
166       }
167       else if (initialContents instanceof byte[])
168       {
169          form = FORM_BYTES;
170       }
171       else if (initialContents instanceof AxisFault)
172       {
173          form = FORM_FAULT;
174       }
175
176       if (log.isDebugEnabled())
177       {
178          log.debug("Enter: SOAPPart ctor(" + formNames[form] + ")");
179       }
180
181       setCurrentMessage(initialContents, form);
182
183       if (log.isDebugEnabled())
184       {
185          log.debug("Exit: SOAPPart ctor()");
186       }
187    }
188
189
190    /**
191     * Get the <code>Message</code> for this <code>Part</code>.
192     *
193     * @return the <code>Message</code> for this <code>Part</code>
194     */

195    public Message getMessage()
196    {
197       return msgObject;
198    }
199
200    /**
201     * Set the Message for this Part.
202     * Do not call this Directly. Called by Message.
203     *
204     * @param msg the <code>Message</code> for this part
205     */

206    public void setMessage(Message msg)
207    {
208       this.msgObject = msg;
209    }
210
211    /**
212     * Content type is always "text/xml" for SOAPParts.
213     *
214     * @return the content type
215     */

216    public String JavaDoc getContentType()
217    {
218       return "text/xml";
219    }
220
221    /**
222     * Get the content length for this SOAPPart.
223     * This will force buffering of the SOAPPart, but it will
224     * also cache the byte[] form of the SOAPPart.
225     *
226     * @return the content length in bytes
227     */

228    public int getContentLength()
229    {
230       try
231       {
232          byte[] bytes = this.getAsBytes();
233          return bytes.length;
234       }
235       catch (AxisFault fault)
236       {
237          return 0; // ?
238
}
239    }
240
241    /**
242     * This set the SOAP Envelope for this part.
243     * <p/>
244     * Note: It breaks the chicken/egg created.
245     * I need a message to create an attachment...
246     * From the attachment I should be able to get a reference...
247     * I now want to edit elements in the envelope in order to
248     * place the attachment reference to it.
249     * How do I now update the SOAP envelope with what I've changed?
250     *
251     * @param env the <code>SOAPEnvelope</CODE> for this <code>SOAPPart</code>
252     */

253
254    public void setSOAPEnvelope(SOAPEnvelopeAxisImpl env)
255    {
256       setCurrentMessage(env, FORM_SOAPENVELOPE);
257    }
258
259    /**
260     * Get the total size in bytes, including headers, of this Part.
261     * TODO: For now, since we aren't actually doing MIME yet,
262     * this is the same as getContentLength(). Soon it will be
263     * different.
264     *
265     * @return the total size
266     */

267    public int getSize()
268    {
269       // for now, we don't ever do headers! ha ha
270
return this.getContentLength();
271    }
272
273    /**
274     * Write the contents to the specified writer.
275     *
276     * @param writer the <code>Writer</code> to write to
277     */

278    public void writeTo(Writer JavaDoc writer) throws IOException JavaDoc
279    {
280       if (currentForm == FORM_FAULT)
281       {
282          AxisFault env = (AxisFault)currentMessage;
283          try
284          {
285             env.output(new SerializationContextImpl(writer, getMessage().getMessageContext()));
286          }
287          catch (Exception JavaDoc e)
288          {
289             log.error(Messages.getMessage("exception00"), e);
290             throw env;
291          }
292       }
293
294       else if (currentForm == FORM_SOAPENVELOPE)
295       {
296          SOAPEnvelopeAxisImpl env = (SOAPEnvelopeAxisImpl)currentMessage;
297          try
298          {
299             env.output(new SerializationContextImpl(writer, getMessage().getMessageContext()));
300          }
301          catch (Exception JavaDoc e)
302          {
303             throw AxisFault.makeFault(e);
304          }
305       }
306
307       else
308       {
309          String JavaDoc xmlMessage = getAsString();
310          writer.write(xmlMessage);
311       }
312    }
313
314    /**
315     * Get the current message, in whatever form it happens to be right now.
316     * Will return a String, byte[], InputStream, or SOAPEnvelope, depending
317     * on circumstances.
318     * <p/>
319     * The method name is historical.
320     * TODO: rename this for clarity; should be more like getContents.
321     *
322     * @return the current content
323     */

324    public Object JavaDoc getCurrentMessage()
325    {
326       return currentMessage;
327    }
328
329    /**
330     * Set the current message
331     *
332     * @param currMsg
333     * @param form
334     */

335    public void setCurrentMessage(Object JavaDoc currMsg, int form)
336    {
337       setCurrentForm(currMsg, form);
338    }
339
340    /**
341     * Set the current contents of this Part.
342     * The method name is historical.
343     * TODO: rename this for clarity to something more like setContents???
344     *
345     * @param currMsg the new content of this part
346     * @param form the form of the message
347     */

348    private void setCurrentForm(Object JavaDoc currMsg, int form)
349    {
350
351       if (currentForm == FORM_SOAPENVELOPE && currentMessageAsEnvelope.isProcessingRPCInvocation() && form == FORM_STRING)
352       {
353          log.debug("Preventing FORM_STRING while processing RPCInvocation");
354          return;
355       }
356
357       log.debug("Changing message form: " + formNames[currentForm] + " -> " + formNames[form]);
358
359       currentMessageAsString = null;
360       currentMessageAsBytes = null;
361       currentMessageAsEnvelope = null;
362
363       currentMessage = currMsg;
364       currentForm = form;
365
366       if (currentForm == FORM_STRING && log.isTraceEnabled())
367       {
368          log.trace(currMsg);
369       }
370
371       if (currentForm == FORM_SOAPENVELOPE)
372       {
373          currentMessageAsEnvelope = (SOAPEnvelopeAxisImpl)currMsg;
374       }
375    }
376
377    /**
378     * Get the contents of this Part (not the headers!), as a byte
379     * array. This will force buffering of the message.
380     *
381     * @return an array of bytes containing a byte representation of this Part
382     * @throws AxisFault if this Part can't be serialized to the byte array
383     */

384    public byte[] getAsBytes() throws AxisFault
385    {
386       log.debug("Enter: SOAPPart::getAsBytes");
387       if (currentForm == FORM_BYTES)
388       {
389          log.debug("Exit: SOAPPart::getAsBytes");
390          return (byte[])currentMessage;
391       }
392
393       if (currentForm == FORM_BODYINSTREAM)
394       {
395          try
396          {
397             getAsSOAPEnvelope();
398          }
399          catch (Exception JavaDoc e)
400          {
401             log.fatal(Messages.getMessage("makeEnvFail00"), e);
402             log.debug("Exit: SOAPPart::getAsBytes");
403             return null;
404          }
405       }
406
407       if (currentForm == FORM_INPUTSTREAM)
408       {
409          // Assumes we don't need a content length
410
try
411          {
412             InputStream JavaDoc inp = null;
413             byte[] buf = null;
414             try
415             {
416                inp = (InputStream JavaDoc)currentMessage;
417                ByteArrayOutputStream JavaDoc baos = new ByteArrayOutputStream JavaDoc();
418                buf = new byte[4096];
419                int len;
420                while ((len = inp.read(buf, 0, 4096)) != -1)
421                   baos.write(buf, 0, len);
422                buf = baos.toByteArray();
423             }
424             finally
425             {
426                if (inp != null &&
427                        currentMessage instanceof org.jboss.axis.transport.http.SocketInputStream)
428                   inp.close();
429             }
430             setCurrentForm(buf, FORM_BYTES);
431             log.debug("Exit: SOAPPart::getAsBytes");
432             return (byte[])currentMessage;
433          }
434          catch (Exception JavaDoc e)
435          {
436             log.error(Messages.getMessage("exception00"), e);
437          }
438          log.debug("Exit: SOAPPart::getAsBytes");
439          return null;
440       }
441
442       if (currentForm == FORM_SOAPENVELOPE ||
443               currentForm == FORM_FAULT)
444       {
445          // Set message to FORM_STRING and
446
// translate to bytes below
447
getAsString();
448       }
449
450       if (currentForm == FORM_STRING)
451       {
452          // If the current message was already converted from
453
// a byte[] to String, return the byte[] representation
454
// (this is done to avoid unnecessary conversions)
455
if (currentMessage == currentMessageAsString &&
456                  currentMessageAsBytes != null)
457          {
458             if (log.isDebugEnabled())
459             {
460                log.debug("Exit: SOAPPart::getAsBytes()");
461             }
462             return currentMessageAsBytes;
463          }
464          // Save this message in case it is requested later in getAsString
465
currentMessageAsString = (String JavaDoc)currentMessage;
466          try
467          {
468             // set encoding of string from parent.
469
String JavaDoc encoding = null;
470             if (msgObject != null)
471             {
472                try
473                {
474                   encoding = (String JavaDoc)msgObject.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
475                }
476                catch (SOAPException JavaDoc e)
477                {
478                }
479             }
480             if (encoding == null)
481             {
482                encoding = "UTF-8";
483             }
484             setCurrentForm(((String JavaDoc)currentMessage).getBytes(encoding),
485                     FORM_BYTES);
486          }
487          catch (UnsupportedEncodingException JavaDoc ue)
488          {
489             setCurrentForm(((String JavaDoc)currentMessage).getBytes(),
490                     FORM_BYTES);
491          }
492          currentMessageAsBytes = (byte[])currentMessage;
493
494          log.debug("Exit: SOAPPart::getAsBytes");
495          return (byte[])currentMessage;
496       }
497
498       log.error(Messages.getMessage("cantConvert00", "" + currentForm));
499
500       log.debug("Exit: SOAPPart::getAsBytes");
501       return null;
502    }
503
504    /**
505     * Get the contents of this Part (not the headers!), as a String.
506     * This will force buffering of the message.
507     *
508     * @return a <code>String</code> containing the content of this message
509     * @throws AxisFault if there is an error serializing this part
510     */

511    public String JavaDoc getAsString() throws AxisFault
512    {
513
514       log.debug("Enter: SOAPPart::getAsString");
515
516       if (currentForm == FORM_STRING)
517       {
518          if (log.isDebugEnabled())
519          {
520             log.debug("Exit: SOAPPart::getAsString()");
521          }
522          return (String JavaDoc)currentMessage;
523       }
524
525       if (currentForm == FORM_INPUTSTREAM || currentForm == FORM_BODYINSTREAM)
526       {
527          // Fall thru to "Bytes"
528
getAsBytes();
529       }
530
531       if (currentForm == FORM_BYTES)
532       {
533
534          // If the current message was already converted from
535
// a String to byte[], return the String representation
536
// (this is done to avoid unnecessary conversions)
537
if (currentMessage == currentMessageAsBytes && currentMessageAsString != null)
538          {
539             if (log.isDebugEnabled())
540             {
541                log.debug("Exit: SOAPPart::getAsString()");
542             }
543             return currentMessageAsString;
544          }
545
546          // Save this message in case it is requested later in getAsBytes
547
currentMessageAsBytes = (byte[])currentMessage;
548          try
549          {
550             setCurrentForm(new String JavaDoc((byte[])currentMessage, "UTF-8"), FORM_STRING);
551          }
552          catch (UnsupportedEncodingException JavaDoc ue)
553          {
554             setCurrentForm(new String JavaDoc((byte[])currentMessage), FORM_STRING);
555          }
556
557          currentMessageAsString = (String JavaDoc)currentMessage;
558          if (log.isDebugEnabled())
559          {
560             log.debug("Exit: SOAPPart::getAsString()");
561          }
562
563          return (String JavaDoc)currentMessage;
564       }
565
566       if (currentForm == FORM_FAULT)
567       {
568          StringWriter JavaDoc writer = new StringWriter JavaDoc();
569          try
570          {
571             this.writeTo(writer);
572          }
573          catch (Exception JavaDoc e)
574          {
575             log.error(Messages.getMessage("exception00"), e);
576             return null;
577          }
578          setCurrentForm(writer.getBuffer().toString(), FORM_STRING);
579          if (log.isDebugEnabled())
580          {
581             log.debug("Exit: SOAPPart::getAsString(): " + currentMessage);
582          }
583          return (String JavaDoc)currentMessage;
584       }
585
586       if (currentForm == FORM_SOAPENVELOPE)
587       {
588          StringWriter JavaDoc writer = new StringWriter JavaDoc();
589          try
590          {
591             writeTo(writer);
592          }
593          catch (Exception JavaDoc e)
594          {
595             throw AxisFault.makeFault(e);
596          }
597
598          String JavaDoc msgAsString = writer.getBuffer().toString();
599          setCurrentForm(msgAsString, FORM_STRING);
600          if (log.isDebugEnabled())
601          {
602             log.debug("Exit: SOAPPart::getAsString()");
603          }
604
605          return msgAsString;
606       }
607
608       log.error(Messages.getMessage("cantConvert01", "" + currentForm));
609
610       log.debug("Exit: SOAPPart::getAsString()");
611       return null;
612    }
613
614    /**
615     * Get the contents of this Part (not the MIME headers!), as a
616     * SOAPEnvelope. This will force a complete parse of the
617     * message.
618     *
619     * @return a <code>SOAPEnvelope</code> containing the message content
620     * @throws AxisFault if the envelope could not be constructed
621     */

622    public SOAPEnvelopeAxisImpl getAsSOAPEnvelope() throws AxisFault
623    {
624
625       if (log.isDebugEnabled())
626       {
627          log.debug("Enter: SOAPPart::getAsSOAPEnvelope()");
628          log.debug(Messages.getMessage("currForm", formNames[currentForm]));
629       }
630
631       if (currentForm == FORM_SOAPENVELOPE)
632       {
633          SOAPEnvelopeAxisImpl env = (SOAPEnvelopeAxisImpl)currentMessage;
634          return env;
635       }
636
637       if (currentForm == FORM_BODYINSTREAM)
638       {
639          InputStreamBody bodyEl = new InputStreamBody((InputStream JavaDoc)currentMessage);
640          SOAPEnvelopeAxisImpl env = new SOAPEnvelopeAxisImpl();
641          env.addBodyElement(bodyEl);
642          setCurrentForm(env, FORM_SOAPENVELOPE);
643          return env;
644       }
645
646       InputSource JavaDoc is;
647
648       if (currentForm == FORM_INPUTSTREAM)
649       {
650          is = new InputSource JavaDoc((InputStream JavaDoc)currentMessage);
651          // set encoding of input source from parent.
652
String JavaDoc encoding = null;
653          if (msgObject != null)
654          {
655             try
656             {
657                encoding = (String JavaDoc)msgObject.getProperty(SOAPMessage.CHARACTER_SET_ENCODING);
658             }
659             catch (SOAPException JavaDoc e)
660             {
661             }
662          }
663          if (encoding != null)
664          {
665             is.setEncoding(encoding);
666          }
667       }
668       else if (currentForm == FORM_BYTES)
669       {
670          is = new InputSource JavaDoc(new ByteArrayInputStream JavaDoc((byte[])currentMessage));
671       }
672       else
673       {
674          is = new InputSource JavaDoc(new StringReader JavaDoc(getAsString()));
675       }
676
677       DeserializationContext dser = new DeserializationContextImpl(is,
678               getMessage().getMessageContext(),
679               getMessage().getMessageType());
680
681       // This may throw a SAXException
682
try
683       {
684          dser.parse();
685       }
686       catch (SAXException JavaDoc e)
687       {
688          Exception JavaDoc real = e.getException();
689          if (real == null)
690             real = e;
691          throw AxisFault.makeFault(real);
692       }
693
694       SOAPEnvelopeAxisImpl env = dser.getEnvelope();
695       if (currentMessageAsEnvelope != null)
696       {
697          // Don't know if there is a btter place to check this.... For BP2725.
698
checkMustUnderstand(getMessage().getMessageContext(), env);
699
700          //Need to synchronize back processed header info.
701
Vector JavaDoc newHeaders = env.getHeaders();
702          Vector JavaDoc oldHeaders = currentMessageAsEnvelope.getHeaders();
703          if (null != newHeaders && null != oldHeaders)
704          {
705             Iterator JavaDoc ohi = oldHeaders.iterator();
706             Iterator JavaDoc nhi = newHeaders.iterator();
707             while (ohi.hasNext() && nhi.hasNext())
708             {
709                SOAPHeaderElementAxisImpl nhe = (SOAPHeaderElementAxisImpl)nhi.next();
710                SOAPHeaderElementAxisImpl ohe = (SOAPHeaderElementAxisImpl)ohi.next();
711
712                if (ohe.isProcessed()) nhe.setProcessed(true);
713             }
714          }
715       }
716
717       ((SOAPBodyAxisImpl)env.getBody()).setAllImmutable(true);
718
719       setCurrentForm(env, FORM_SOAPENVELOPE);
720
721       log.debug("Exit: SOAPPart::getAsSOAPEnvelope");
722       return (SOAPEnvelopeAxisImpl)currentMessage;
723    }
724
725    /**
726     * Check whether we should throw MustUnderstand fault. Now, if there is an actor that is not
727     * service actor and there is a MustUnderstand flat to 1, we will need to throw the fault exception
728     * since we don't know how to handle it.
729     *
730     * @param msgContext
731     * @throws AxisFault
732     */

733    private void checkMustUnderstand(MessageContext msgContext, SOAPEnvelopeAxisImpl envelope) throws AxisFault
734    {
735       String JavaDoc svcActor = ""; // can't handle other actor for now.
736

737       Vector JavaDoc headers = null; // TODO get only headers with actors.
738
try
739       {
740          headers = envelope.getHeaders();
741       }
742       catch (AxisFault axisFault)
743       {
744          axisFault.printStackTrace(); // Need to really handle this.
745
}
746
747       Vector JavaDoc misunderstoodHeaders = null;
748       Enumeration JavaDoc en = headers.elements();
749       while (en.hasMoreElements())
750       {
751          SOAPHeaderElementAxisImpl header = (SOAPHeaderElementAxisImpl)en.
752                  nextElement();
753
754          if (header.getActor() != null && header.getMustUnderstand() &&
755                  header.getActor() != svcActor)
756          {
757             if (misunderstoodHeaders == null)
758                misunderstoodHeaders = new Vector JavaDoc();
759             misunderstoodHeaders.addElement(header);
760          }
761       }
762
763       SOAPConstants soapConstants = msgContext.getSOAPConstants();
764       // !!! we should indicate SOAP1.2 compliance via the
765
// MessageContext, not a boolean here....
766

767       if (misunderstoodHeaders != null)
768       {
769          AxisFault fault =
770                  new AxisFault(soapConstants.getMustunderstandFaultQName(),
771                          null, null,
772                          null, null,
773                          null);
774
775          StringBuffer JavaDoc whatWasMissUnderstood = new StringBuffer JavaDoc(256);
776
777          // !!! If SOAP 1.2, insert misunderstood fault headers here
778
if (soapConstants == SOAPConstants.SOAP12_CONSTANTS)
779          {
780             en = misunderstoodHeaders.elements();
781             while (en.hasMoreElements())
782             {
783                SOAPHeaderElementAxisImpl badHeader = (SOAPHeaderElementAxisImpl)en.
784                        nextElement();
785                QName JavaDoc badQName = new QName JavaDoc(badHeader.getNamespaceURI(),
786                        badHeader.getName());
787
788                if (whatWasMissUnderstood.length() != 0) whatWasMissUnderstood.append(", ");
789                whatWasMissUnderstood.append(badQName.toString());
790
791                SOAPHeaderElementAxisImpl newHeader = new
792                        SOAPHeaderElementAxisImpl(Constants.URI_SOAP12_ENV,
793                                Constants.ELEM_NOTUNDERSTOOD);
794                newHeader.addAttribute(null,
795                        Constants.ATTR_QNAME,
796                        badQName);
797
798                fault.addHeader(newHeader);
799             }
800          }
801
802          fault.setFaultString(Messages.getMessage("noUnderstand00",
803                  whatWasMissUnderstood.toString()));
804
805          throw fault;
806       }
807    }
808
809    /**
810     * Add the specified MIME header, as per JAXM.
811     *
812     * @param header the header to add
813     * @param value the value of that header
814     */

815    public void addMimeHeader(String JavaDoc header, String JavaDoc value)
816    {
817       mimeHeaders.addHeader(header, value);
818    }
819
820    /**
821     * Get the specified MIME header.
822     *
823     * @param header the name of a MIME header
824     * @return the value of the first header named <code>header</code>
825     */

826    private String JavaDoc getFirstMimeHeader(String JavaDoc header)
827    {
828       String JavaDoc[] values = mimeHeaders.getHeader(header);
829       if (values != null && values.length > 0)
830          return values[0];
831       return null;
832    }
833
834    /**
835     * Total size in bytes (of all content and headers, as encoded).
836     public abstract int getSize();
837     */

838
839    /**
840     * Content location.
841     *
842     * @return the content location
843     */

844    public String JavaDoc getContentLocation()
845    {
846       return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION);
847    }
848
849    /**
850     * Set content location.
851     *
852     * @param loc the content location
853     */

854    public void setContentLocation(String JavaDoc loc)
855    {
856       setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, loc);
857    }
858
859    /**
860     * Sets Content-Id of this part.
861     * already defined.
862     *
863     * @param newCid new Content-Id
864     */

865    public void setContentId(String JavaDoc newCid)
866    {
867       setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, newCid);
868    }
869
870    /**
871     * Content ID.
872     *
873     * @return the content ID
874     */

875    public String JavaDoc getContentId()
876    {
877       return getFirstMimeHeader(HTTPConstants.HEADER_CONTENT_ID);
878    }
879
880    /**
881     * Content ID.
882     *
883     * @return the contentId reference value that should be used directly
884     * as an href in a SOAP element to reference this attachment.
885     * <B>Not part of JAX-RPC, JAX-M, SAAJ, etc. </B>
886     */

887    public String JavaDoc getContentIdRef()
888    {
889       return org.jboss.axis.attachments.Attachments.CIDprefix +
890               getContentId();
891    }
892
893
894    /**
895     * Get all headers that match.
896     *
897     * @param match an array of <code>String</code>s giving mime header names
898     * @return an <code>Iterator</code> over all values matching these headers
899     */

900    public java.util.Iterator JavaDoc getMatchingMimeHeaders(final String JavaDoc[] match)
901    {
902       return mimeHeaders.getMatchingHeaders(match);
903    }
904
905    /**
906     * Get all headers that do not match.
907     *
908     * @param match an array of <code>String</code>s giving mime header names
909     * @return an <code>Iterator</code> over all values not matching these
910     * headers
911     */

912    public java.util.Iterator JavaDoc getNonMatchingMimeHeaders(final String JavaDoc[] match)
913    {
914       return mimeHeaders.getNonMatchingHeaders(match);
915    }
916
917    /**
918     * Sets the content of the <CODE>SOAPEnvelope</CODE> object
919     * with the data from the given <CODE>Source</CODE> object.
920     *
921     * @param source javax.xml.transform.Source</CODE> object with the data to
922     * be set
923     * @throws SOAPException if there is a problem in
924     * setting the source
925     * @see #getContent() getContent()
926     */

927    public void setContent(Source JavaDoc source) throws SOAPException JavaDoc
928    {
929
930       if (source == null)
931          throw new SOAPException JavaDoc(Messages.getMessage("illegalArgumentException00"));
932
933       contentSource = source;
934       InputSource JavaDoc in = org.jboss.axis.utils.XMLUtils.sourceToInputSource(contentSource);
935       InputStream JavaDoc is = in.getByteStream();
936       if (is != null)
937       {
938          setCurrentMessage(is, FORM_INPUTSTREAM);
939       }
940       else
941       {
942          Reader JavaDoc r = in.getCharacterStream();
943          if (r == null)
944          {
945             throw new SOAPException JavaDoc(Messages.getMessage("noCharacterOrByteStream"));
946          }
947          BufferedReader JavaDoc br = new BufferedReader JavaDoc(r);
948          String JavaDoc line = null;
949          StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
950          try
951          {
952             while ((line = br.readLine()) != null)
953             {
954                sb.append(line);
955             }
956          }
957          catch (IOException JavaDoc e)
958          {
959             throw new SOAPException JavaDoc(Messages.getMessage("couldNotReadFromCharStream"), e);
960          }
961          setCurrentMessage(sb.toString(), FORM_STRING);
962       }
963    }
964
965    /**
966     * Returns the content of the SOAPEnvelope as a JAXP <CODE>
967     * Source</CODE> object.
968     *
969     * @return the content as a <CODE>
970     * javax.xml.transform.Source</CODE> object
971     * @throws SOAPException if the implementation cannot
972     * convert the specified <CODE>Source</CODE> object
973     * @see #setContent(javax.xml.transform.Source) setContent(javax.xml.transform.Source)
974     */

975    public Source JavaDoc getContent() throws SOAPException JavaDoc
976    {
977       if (contentSource == null)
978       {
979          switch (currentForm)
980          {
981             case FORM_STRING:
982                String JavaDoc s = (String JavaDoc)currentMessage;
983                contentSource = new StreamSource JavaDoc(new StringReader JavaDoc(s));
984                break;
985             case FORM_INPUTSTREAM:
986                contentSource = new StreamSource JavaDoc((InputStream JavaDoc)currentMessage);
987                break;
988             case FORM_SOAPENVELOPE:
989                SOAPEnvelopeAxisImpl se = (SOAPEnvelopeAxisImpl)currentMessage;
990                try
991                {
992                   contentSource = new DOMSource JavaDoc(se.getAsDocument());
993                }
994                catch (Exception JavaDoc e)
995                {
996                   throw new SOAPException JavaDoc(Messages.getMessage("errorGetDocFromSOAPEnvelope"), e);
997                }
998                break;
999             case FORM_BYTES:
1000               byte[] bytes = (byte[])currentMessage;
1001               contentSource = new StreamSource JavaDoc(new ByteArrayInputStream JavaDoc(bytes));
1002               break;
1003            case FORM_BODYINSTREAM:
1004               contentSource = new StreamSource JavaDoc((InputStream JavaDoc)currentMessage);
1005               break;
1006         }
1007      }
1008      return contentSource;
1009   }
1010
1011   /**
1012    * Retrieves all the headers for this <CODE>SOAPPart</CODE>
1013    * object as an iterator over the <CODE>MimeHeader</CODE>
1014    * objects.
1015    *
1016    * @return an <CODE>Iterator</CODE> object with all of the Mime
1017    * headers for this <CODE>SOAPPart</CODE> object
1018    */

1019   public Iterator JavaDoc getAllMimeHeaders()
1020   {
1021      return mimeHeaders.getAllHeaders();
1022   }
1023
1024   /**
1025    * Changes the first header entry that matches the given
1026    * header name so that its value is the given value, adding a
1027    * new header with the given name and value if no existing
1028    * header is a match. If there is a match, this method clears
1029    * all existing values for the first header that matches and
1030    * sets the given value instead. If more than one header has
1031    * the given name, this method removes all of the matching
1032    * headers after the first one.
1033    * <p/>
1034    * <P>Note that RFC822 headers can contain only US-ASCII
1035    * characters.</P>
1036    *
1037    * @param name a <CODE>String</CODE> giving the
1038    * header name for which to search
1039    * @param value a <CODE>String</CODE> giving the
1040    * value to be set. This value will be substituted for the
1041    * current value(s) of the first header that is a match if
1042    * there is one. If there is no match, this value will be
1043    * the value for a new <CODE>MimeHeader</CODE> object.
1044    * @ throws java.lang.IllegalArgumentException if
1045    * there was a problem with the specified mime header name
1046    * or value
1047    * @see #getMimeHeader(java.lang.String) getMimeHeader(java.lang.String)
1048    */

1049   public void setMimeHeader(String JavaDoc name, String JavaDoc value)
1050   {
1051      mimeHeaders.setHeader(name, value);
1052   }
1053
1054   /**
1055    * Gets all the values of the <CODE>MimeHeader</CODE> object
1056    * in this <CODE>SOAPPart</CODE> object that is identified by
1057    * the given <CODE>String</CODE>.
1058    *
1059    * @param name the name of the header; example:
1060    * "Content-Type"
1061    * @return a <CODE>String</CODE> array giving all the values for
1062    * the specified header
1063    * @see #setMimeHeader(java.lang.String, java.lang.String) setMimeHeader(java.lang.String, java.lang.String)
1064    */

1065   public String JavaDoc[] getMimeHeader(String JavaDoc name)
1066   {
1067      return mimeHeaders.getHeader(name);
1068   }
1069
1070   /**
1071    * Removes all the <CODE>MimeHeader</CODE> objects for this
1072    * <CODE>SOAPEnvelope</CODE> object.
1073    */

1074   public void removeAllMimeHeaders()
1075   {
1076      mimeHeaders.removeAllHeaders();
1077   }
1078
1079   /**
1080    * Removes all MIME headers that match the given name.
1081    *
1082    * @param header a <CODE>String</CODE> giving
1083    * the name of the MIME header(s) to be removed
1084    */

1085   public void removeMimeHeader(String JavaDoc header)
1086   {
1087      mimeHeaders.removeHeader(header);
1088   }
1089
1090   /**
1091    * Gets the <CODE>SOAPEnvelope</CODE> object associated with
1092    * this <CODE>SOAPPart</CODE> object. Once the SOAP envelope is
1093    * obtained, it can be used to get its contents.
1094    *
1095    * @return the <CODE>SOAPEnvelope</CODE> object for this <CODE>
1096    * SOAPPart</CODE> object
1097    * @throws SOAPException if there is a SOAP error
1098    */

1099   public javax.xml.soap.SOAPEnvelope JavaDoc getEnvelope() throws SOAPException JavaDoc
1100   {
1101      try
1102      {
1103         return getAsSOAPEnvelope();
1104      }
1105      catch (AxisFault af)
1106      {
1107         throw new SOAPException JavaDoc(af);
1108      }
1109   }
1110
1111   /**
1112    * Implementation of org.w3c.Document
1113    * Most of methods will be implemented using the delgate
1114    * instance of SOAPDocumentImpl
1115    * This is for two reasons:
1116    * - possible change of message classes, by extenstion of xerces implementation
1117    * - we cannot extends SOAPPart (multiple inheritance),
1118    * since it is defined as Abstract class
1119    * ***********************************************************
1120    */

1121
1122   private Document JavaDoc document = new SOAPDocumentImpl(this);
1123
1124   /**
1125    * @since SAAJ 1.2
1126    */

1127   public Document JavaDoc getSOAPDocument()
1128   {
1129      if (document == null)
1130      {
1131         document = new SOAPDocumentImpl(this);
1132      }
1133      return document;
1134   }
1135
1136   /**
1137    * @return
1138    */

1139   public DocumentType JavaDoc getDoctype()
1140   {
1141      return document.getDoctype();
1142   }
1143
1144   /**
1145    * @return
1146    */

1147   public DOMImplementation JavaDoc getImplementation()
1148   {
1149      return document.getImplementation();
1150   }
1151
1152   /**
1153    * SOAPEnvelope is the Document Elements of this XML docuement
1154    */

1155   protected Document JavaDoc mDocument;
1156
1157   public Element JavaDoc getDocumentElement()
1158   {
1159      try
1160      {
1161         return getEnvelope();
1162      }
1163      catch (SOAPException JavaDoc se)
1164      {
1165         return null;
1166      }
1167   }
1168
1169   /**
1170    * @param tagName
1171    * @return
1172    * @throws DOMException
1173    */

1174   public Element JavaDoc createElement(String JavaDoc tagName) throws DOMException JavaDoc
1175   {
1176      return document.createElement(tagName);
1177   }
1178
1179   public DocumentFragment JavaDoc createDocumentFragment()
1180   {
1181      return document.createDocumentFragment();
1182   }
1183
1184   public Text JavaDoc createTextNode(String JavaDoc data)
1185   {
1186      return document.createTextNode(data);
1187   }
1188
1189   public Comment JavaDoc createComment(String JavaDoc data)
1190   {
1191      return document.createComment(data);
1192   }
1193
1194   public CDATASection JavaDoc createCDATASection(String JavaDoc data) throws DOMException JavaDoc
1195   {
1196      return document.createCDATASection(data);
1197   }
1198
1199   public ProcessingInstruction JavaDoc createProcessingInstruction(String JavaDoc target, String JavaDoc data)
1200           throws DOMException JavaDoc
1201   {
1202      return document.createProcessingInstruction(target, data);
1203   }
1204
1205   public Attr JavaDoc createAttribute(String JavaDoc name) throws DOMException JavaDoc
1206   {
1207      return document.createAttribute(name);
1208   }
1209
1210   public EntityReference JavaDoc createEntityReference(String JavaDoc name) throws DOMException JavaDoc
1211   {
1212      return document.createEntityReference(name);
1213   }
1214
1215   public NodeList JavaDoc getElementsByTagName(String JavaDoc tagname)
1216   {
1217      return document.getElementsByTagName(tagname);
1218   }
1219
1220   public Node JavaDoc importNode(Node JavaDoc importedNode, boolean deep)
1221           throws DOMException JavaDoc
1222   {
1223      return document.importNode(importedNode, deep);
1224   }
1225
1226   public Element JavaDoc createElementNS(String JavaDoc namespaceURI, String JavaDoc qualifiedName)
1227           throws DOMException JavaDoc
1228   {
1229      return document.createElementNS(namespaceURI, qualifiedName);
1230   }
1231
1232   public Attr JavaDoc createAttributeNS(String JavaDoc namespaceURI, String JavaDoc qualifiedName)
1233           throws DOMException JavaDoc
1234   {
1235      return document.createAttributeNS(namespaceURI, qualifiedName);
1236   }
1237
1238   public NodeList JavaDoc getElementsByTagNameNS(String JavaDoc namespaceURI, String JavaDoc localName)
1239   {
1240      return document.getElementsByTagNameNS(namespaceURI, localName);
1241   }
1242
1243   public Element JavaDoc getElementById(String JavaDoc elementId)
1244   {
1245      return document.getElementById(elementId);
1246   }
1247
1248   /////////////////////////////////////////////////////////////
1249

1250   public String JavaDoc getEncoding()
1251   {
1252      throw new UnsupportedOperationException JavaDoc("Not yet implemented.69");
1253   }
1254
1255   public void setEncoding(String JavaDoc s)
1256   {
1257      throw new UnsupportedOperationException JavaDoc("Not yet implemented.70");
1258   }
1259
1260   public boolean getStandalone()
1261   {
1262      throw new UnsupportedOperationException JavaDoc("Not yet implemented.71");
1263   }
1264
1265
1266   public void setStandalone(boolean flag)
1267   {
1268      throw new UnsupportedOperationException JavaDoc("Not yet implemented.72");
1269   }
1270
1271   public boolean getStrictErrorChecking()
1272   {
1273      throw new UnsupportedOperationException JavaDoc("Not yet implemented.73");
1274   }
1275
1276
1277   public void setStrictErrorChecking(boolean flag)
1278   {
1279      throw new UnsupportedOperationException JavaDoc("Not yet implemented. 74");
1280   }
1281
1282
1283   public String JavaDoc getVersion()
1284   {
1285      throw new UnsupportedOperationException JavaDoc("Not yet implemented. 75");
1286   }
1287
1288
1289   public void setVersion(String JavaDoc s)
1290   {
1291      throw new UnsupportedOperationException JavaDoc("Not yet implemented.76");
1292   }
1293
1294
1295   public Node JavaDoc adoptNode(Node JavaDoc node)
1296           throws DOMException JavaDoc
1297   {
1298      throw new UnsupportedOperationException JavaDoc("Not yet implemented.77");
1299   }
1300
1301   /**
1302    * Node Implementation
1303    */

1304
1305   public String JavaDoc getNodeName()
1306   {
1307      return document.getNodeName();
1308   }
1309
1310   public String JavaDoc getNodeValue() throws DOMException JavaDoc
1311   {
1312      return document.getNodeValue();
1313   }
1314
1315   public void setNodeValue(String JavaDoc nodeValue) throws DOMException JavaDoc
1316   {
1317      document.setNodeValue(nodeValue);
1318   }
1319
1320   public short getNodeType()
1321   {
1322      return document.getNodeType();
1323   }
1324
1325   public Node JavaDoc getParentNode()
1326   {
1327      return document.getParentNode();
1328   }
1329
1330   public NodeList JavaDoc getChildNodes()
1331   {
1332      return document.getChildNodes();
1333   }
1334
1335   public Node JavaDoc getFirstChild()
1336   {
1337      return document.getFirstChild();
1338   }
1339
1340   public Node JavaDoc getLastChild()
1341   {
1342      return document.getLastChild();
1343   }
1344
1345   public Node JavaDoc getPreviousSibling()
1346   {
1347      return document.getPreviousSibling();
1348   }
1349
1350   public Node JavaDoc getNextSibling()
1351   {
1352      return document.getNextSibling();
1353   }
1354
1355   public NamedNodeMap JavaDoc getAttributes()
1356   {
1357      return document.getAttributes();
1358   }
1359
1360   public Document JavaDoc getOwnerDocument()
1361   {
1362      return document.getOwnerDocument();
1363   }
1364
1365   public Node JavaDoc insertBefore(Node JavaDoc newChild, Node JavaDoc refChild) throws DOMException JavaDoc
1366   {
1367      return document.insertBefore(newChild, refChild);
1368   }
1369
1370   public Node JavaDoc replaceChild(Node JavaDoc newChild, Node JavaDoc oldChild) throws DOMException JavaDoc
1371   {
1372      return document.replaceChild(newChild, oldChild);
1373   }
1374
1375   public Node JavaDoc removeChild(Node JavaDoc oldChild) throws DOMException JavaDoc
1376   {
1377      return document.removeChild(oldChild);
1378   }
1379
1380   public Node JavaDoc appendChild(Node JavaDoc newChild) throws DOMException JavaDoc
1381   {
1382      return document.appendChild(newChild);
1383   }
1384
1385   public boolean hasChildNodes()
1386   {
1387      return document.hasChildNodes();
1388   }
1389
1390   public Node JavaDoc cloneNode(boolean deep)
1391   {
1392      return document.cloneNode(deep);
1393   }
1394
1395   public void normalize()
1396   {
1397      document.normalize();
1398   }
1399
1400   public boolean isSupported(String JavaDoc feature, String JavaDoc version)
1401   {
1402      return document.isSupported(feature, version);
1403   }
1404
1405   public String JavaDoc getNamespaceURI()
1406   {
1407      return document.getNamespaceURI();
1408   }
1409
1410   public String JavaDoc getPrefix()
1411   {
1412      return document.getPrefix();
1413   }
1414
1415   public void setPrefix(String JavaDoc prefix) throws DOMException JavaDoc
1416   {
1417      document.setPrefix(prefix);
1418   }
1419
1420   public String JavaDoc getLocalName()
1421   {
1422      return document.getLocalName();
1423   }
1424
1425   public boolean hasAttributes()
1426   {
1427      return document.hasAttributes();
1428   }
1429}
1430
1431
Popular Tags