1 57 58 package org.apache.soap.transport; 59 60 import java.io.*; 61 import java.util.*; 62 import javax.activation.*; 63 import javax.mail.*; 64 import javax.mail.internet.*; 65 import javax.xml.parsers.*; 66 import org.w3c.dom.*; 67 import org.xml.sax.*; 68 import org.apache.soap.*; 69 import org.apache.soap.encoding.*; 70 import org.apache.soap.rpc.*; 71 import org.apache.soap.util.*; 72 import org.apache.soap.util.xml.*; 73 import org.apache.soap.util.mime.*; 74 import org.apache.soap.transport.EnvelopeEditor; 75 76 81 public class TransportMessage implements Serializable { 82 protected String contentType = null; 83 protected int offset = 0; 84 protected byte[] bytes = null; 85 protected String envelope = null; 86 protected Hashtable headers = null; 87 protected SOAPContext ctx = null; 88 89 92 public TransportMessage() { 93 } 94 95 100 public TransportMessage(String envelope, SOAPContext ctx, 101 Hashtable headers) 102 throws IllegalArgumentException , MessagingException, 103 IOException, SOAPException { 104 this.envelope = envelope; 105 this.ctx = ctx; 106 if (headers != null) 107 this.headers = headers; 108 else 109 this.headers = new Hashtable(); 110 } 111 112 118 public TransportMessage(InputStream is, int contentLength, 119 String contentType, SOAPContext ctx, 120 Hashtable headers) 121 throws IllegalArgumentException , MessagingException, 122 IOException, SOAPException { 123 if (headers != null) 124 this.headers = headers; 125 else 126 this.headers = new Hashtable(); 127 this.ctx = ctx; 128 this.contentType = contentType; 129 130 if (contentLength < 0) 131 throw new SOAPException (Constants.FAULT_CODE_PROTOCOL, 132 "Content length must be specified."); 133 134 bytes = new byte[contentLength]; 135 int offset = 0; 136 int bytesRead = 0; 137 138 while ((offset < contentLength) && (bytesRead >= 0)) { 141 bytesRead = is.read(bytes, offset, contentLength - offset); 142 offset += bytesRead; 143 } 144 if (offset < contentLength) 145 throw new SOAPException (Constants.FAULT_CODE_PROTOCOL, 146 "Premature end of stream. Data is truncated. Read " 147 + offset + " bytes successfully, expected " 148 + contentLength); 149 } 150 151 156 public void editIncoming(EnvelopeEditor editor) 157 throws SOAPException, IOException, MessagingException { 158 editEnvelope(editor, true); 159 } 160 161 166 public void editOutgoing(EnvelopeEditor editor) 167 throws SOAPException, IOException, MessagingException { 168 editEnvelope(editor, false); 169 } 170 171 174 protected void editEnvelope(EnvelopeEditor editor, boolean isIncoming) 175 throws SOAPException, IOException, MessagingException { 176 if (editor != null) { 177 if (getEnvelope() == null) 179 return; 180 StringWriter tout = new StringWriter(); 182 if (isIncoming) 183 editor.editIncoming(getEnvelopeReader(), tout); 184 else 185 editor.editOutgoing(getEnvelopeReader(), tout); 186 tout.flush(); 187 envelope = tout.toString(); 188 } 189 } 190 191 198 public String read() 199 throws IllegalArgumentException , MessagingException, 200 IOException, SOAPException { 201 202 ContentType cType = null; 204 try { 205 int pos = contentType.indexOf( ";;" ); 207 if ( pos != -1 ) 208 contentType = contentType.substring(0,pos) + 209 contentType.substring(pos+1) ; 210 cType = new ContentType(contentType); 211 } catch(ParseException pe) { 212 } 213 if (cType == null) 214 throw new SOAPException(Constants.FAULT_CODE_PROTOCOL, 215 "Missing content type."); 216 MimeBodyPart rootPart; 217 ContentType rootContentType; 218 byte[] rootBytes; 219 if (cType.match(Constants.HEADERVAL_CONTENT_TYPE_MULTIPART_PRIMARY + 220 "/*")) { 221 ByteArrayDataSource ds = new ByteArrayDataSource(bytes, 223 contentType); 224 225 ctx.readMultipart(ds); 227 228 rootPart = ctx.getRootPart(); 230 rootContentType = new ContentType(rootPart.getContentType()); 231 ByteArrayDataSource bads = new ByteArrayDataSource( 232 rootPart.getInputStream(), null); 233 rootBytes = bads.toByteArray(); 234 } else { 235 rootBytes = bytes; 236 rootContentType = cType; 237 ByteArrayDataSource ds = new ByteArrayDataSource(bytes, 239 contentType); 240 DataHandler dh = new DataHandler(ds); 241 rootPart = new MimeBodyPart(); 242 rootPart.setDataHandler(dh); 243 ctx.addBodyPart(rootPart); 244 } 245 246 if (rootContentType.match("text/*")) { 250 String charset = rootContentType.getParameter("charset"); 251 if (charset == null || charset.equals("")) 253 charset = Constants.HEADERVAL_DEFAULT_CHARSET; 254 envelope = new String (rootBytes, MimeUtility.javaCharset(charset)); 255 } 256 257 return envelope; 258 } 259 260 263 public Envelope unmarshall(DocumentBuilder xdb) 264 throws SOAPException { 265 Document doc; 266 try { 267 doc = xdb.parse(new InputSource(getEnvelopeReader())); 268 } catch(Exception e) { 269 throw new SOAPException(Constants.FAULT_CODE_CLIENT, 270 "parsing error: " + e); 271 } 272 if (doc == null) { 273 throw new SOAPException(Constants.FAULT_CODE_CLIENT, 274 "parsing error: received empty document"); 275 } 276 277 return Envelope.unmarshall(doc.getDocumentElement()); 278 } 279 280 284 public void save() 285 throws IllegalArgumentException , MessagingException, IOException { 286 290 String rootContentType = null; 291 if (ctx.isRootPartSet()) { 292 MimeBodyPart rootPart = ctx.getRootPart(); 293 if (rootPart != null) 294 rootContentType = rootPart.getHeader( 298 Constants.HEADER_CONTENT_TYPE, null); 299 } 300 if (rootContentType == null) 301 rootContentType = Constants.HEADERVAL_CONTENT_TYPE_UTF8; 302 if (getEnvelope() != null) 303 ctx.setRootPart(envelope, rootContentType); 304 305 ByteArrayOutputStream payload = 307 new ByteArrayOutputStream(); 308 ctx.writeTo(payload); 309 bytes = payload.toByteArray(); 310 311 StringBuffer namebuf = new StringBuffer (); 316 StringBuffer valuebuf = new StringBuffer (); 317 boolean parsingName = true; 318 for (offset = 0; offset < bytes.length; offset++) { 319 if (bytes[offset] == '\n') { 320 if ((bytes[offset + 1] == ' ') 323 || (bytes[offset + 1] == '\t')) { 324 while ((bytes[(++offset) + 1] == ' ') 325 || (bytes[offset + 1] == '\t')); 326 continue; 327 } 328 if (namebuf.length() == 0) { 329 offset++; 330 break; 331 } 332 String name = namebuf.toString(); 333 if (name.equals(Constants.HEADER_CONTENT_TYPE)) { 336 contentType = valuebuf.toString(); 337 if (ctx.getCount() > 1) { 338 String rootCID = ctx.getRootPart().getContentID(); 339 rootCID = rootCID.substring(1, rootCID.length() - 1); 341 contentType += "; type=\"" 342 + Constants.HEADERVAL_CONTENT_TYPE 343 + "\"; start=\"" + rootCID + '"'; 344 } 345 } 346 namebuf = new StringBuffer (); 347 valuebuf = new StringBuffer (); 348 parsingName = true; 349 } 350 else if (bytes[offset] != '\r') { 351 if (parsingName) { 352 if (bytes[offset] == ':') { 353 parsingName = false; 354 offset++; 355 } 356 else 357 namebuf.append((char)bytes[offset]); 358 } 359 else 360 valuebuf.append((char)bytes[offset]); 361 } 362 } 363 } 364 365 368 public SOAPContext getSOAPContext() { 369 return ctx; 370 } 371 372 377 public String getEnvelope() throws MessagingException, IOException { 378 if (envelope == null) { 379 MimeBodyPart rootPart = ctx.getRootPart(); 380 if (rootPart != null) 381 if (rootPart.isMimeType("text/*")) { 382 ByteArrayDataSource ds = new ByteArrayDataSource( 383 rootPart.getInputStream(), rootPart.getContentType()); 384 envelope = ds.getText(); 385 } 386 } 387 return envelope; 388 } 389 390 394 public Reader getEnvelopeReader() throws MessagingException, IOException { 395 if (getEnvelope() == null) 396 return null; 397 else 398 return new StringReader(envelope); 399 } 400 401 404 public void setEnvelope(String envelope) { 405 this.envelope = envelope; 406 } 407 408 411 public String getContentType() { 412 return contentType; 413 } 414 415 418 public void setContentType(String contentType) { 419 this.contentType = contentType; 420 } 421 422 425 public int getContentLength() { 426 return bytes.length - offset; 427 } 428 429 432 public void setHeader(String name, String value) { 433 headers.put(name, value); 434 } 435 436 439 public String getHeader(String name) { 440 return (String )headers.get(name); 441 } 442 443 446 public Enumeration getHeaderNames() { 447 return headers.keys(); 448 } 449 450 453 public Hashtable getHeaders() { 454 return headers; 455 } 456 457 460 public void writeTo(OutputStream outStream) throws IOException { 461 outStream.write(bytes, offset, bytes.length - offset); 462 outStream.flush(); 463 } 464 465 468 public void setBytes(byte[] data) { 469 offset = 0; 470 bytes = data; 471 } 472 473 476 public void readFully(InputStream is) throws IOException { 477 offset = 0; 478 ByteArrayDataSource bads = new ByteArrayDataSource(is, null); 479 bytes = bads.toByteArray(); 480 } 481 482 485 public byte[] getBytes() { 486 if (offset != 0) { 488 byte[] data = new byte[bytes.length - offset]; 489 System.arraycopy(bytes, offset, data, 0, data.length); 490 bytes = data; 491 offset = 0; 492 } 493 return bytes; 494 } 495 } 496 | Popular Tags |