1 16 package org.apache.axis.attachments; 17 18 import org.apache.axis.Part; 19 import org.apache.axis.components.logger.LogFactory; 20 import org.apache.axis.transport.http.HTTPConstants; 21 import org.apache.axis.utils.Messages; 22 import org.apache.axis.utils.IOUtils; 23 import org.apache.commons.logging.Log; 24 25 import javax.activation.DataHandler ; 26 import javax.mail.internet.MimeUtility ; 27 import java.io.IOException ; 28 import java.io.BufferedInputStream ; 29 30 35 public class MultiPartRelatedInputStream extends MultiPartInputStream{ 36 37 38 protected static Log log = 39 LogFactory.getLog(MultiPartRelatedInputStream.class.getName()); 40 41 42 public static final String MIME_MULTIPART_RELATED = "multipart/related"; 43 44 45 protected java.util.HashMap parts = new java.util.HashMap (); 46 47 48 protected java.util.LinkedList orderedParts = new java.util.LinkedList (); 49 50 51 protected int rootPartLength = 0; 52 53 54 protected boolean closed = false; 56 57 protected boolean eos = 58 false; 60 63 64 protected org.apache.axis.attachments.BoundaryDelimitedStream boundaryDelimitedStream = 65 null; 66 67 68 protected java.io.InputStream soapStream = 69 null; 71 72 protected java.io.InputStream soapStreamBDS = 73 null; 75 76 protected byte[] boundary = null; 77 78 79 protected java.io.ByteArrayInputStream cachedSOAPEnvelope = 80 null; 82 84 85 protected String contentLocation = null; 86 87 88 protected String contentId = null; 89 90 91 private static final int MAX_CACHED = 16 * 1024; 92 93 100 public MultiPartRelatedInputStream( 101 String contentType, java.io.InputStream stream) 102 throws org.apache.axis.AxisFault { 103 104 super(null); 106 if(!(stream instanceof BufferedInputStream )) { 107 stream = new BufferedInputStream (stream); 108 } 109 110 try { 111 112 javax.mail.internet.ContentType ct = 115 new javax.mail.internet.ContentType (contentType); 116 String rootPartContentId = 117 ct.getParameter("start"); 119 if (rootPartContentId != null) { 120 rootPartContentId = rootPartContentId.trim(); 121 122 if (rootPartContentId.startsWith("<")) { 123 rootPartContentId = rootPartContentId.substring(1); 124 } 125 126 if (rootPartContentId.endsWith(">")) { 127 rootPartContentId = rootPartContentId.substring(0, 128 rootPartContentId.length() - 1); 129 } 130 131 } 132 133 if(ct.getParameter("boundary") != null) { 134 String boundaryStr = 135 "--" 136 + ct.getParameter( 137 "boundary"); 139 140 byte[][] boundaryMarker = new byte[2][boundaryStr.length() + 2]; 144 145 IOUtils.readFully(stream, boundaryMarker[0]); 146 147 boundary = (boundaryStr + "\r\n").getBytes("US-ASCII"); 148 149 int current = 0; 150 151 for (boolean found = false; !found; ++current) { 154 if (!(found = 155 java.util.Arrays.equals(boundaryMarker[current & 0x1], 156 boundary))) { 157 System.arraycopy(boundaryMarker[current & 0x1], 1, 158 boundaryMarker[(current + 1) & 0x1], 0, 159 boundaryMarker[0].length - 1); 160 161 if (stream.read( 162 boundaryMarker[(current + 1) & 0x1], 163 boundaryMarker[0].length - 1, 1) < 1) { 164 throw new org.apache.axis.AxisFault( 165 Messages.getMessage( 166 "mimeErrorNoBoundary", new String (boundary))); 167 } 168 } 169 } 170 171 boundaryStr = "\r\n" + boundaryStr; 174 boundary = boundaryStr.getBytes("US-ASCII"); 175 } else { 176 for (boolean found = false; !found;) { 178 boundary= readLine(stream); 179 if( boundary == null) 180 throw new org.apache.axis.AxisFault( 181 Messages.getMessage( 182 "mimeErrorNoBoundary", "--")); 183 found = boundary.length >4 && boundary[2] == '-' && boundary[3]== '-'; 184 } 185 } 186 187 boundaryDelimitedStream = 189 new org.apache.axis.attachments.BoundaryDelimitedStream(stream, 190 boundary, 1024); 191 192 String contentTransferEncoding = null; 194 195 do { 196 contentId = null; 197 contentLocation = null; 198 contentTransferEncoding = null; 199 200 javax.mail.internet.InternetHeaders headers = 202 new javax.mail.internet.InternetHeaders ( 203 boundaryDelimitedStream); 204 205 contentId = headers.getHeader(HTTPConstants.HEADER_CONTENT_ID, 207 null); 208 209 if (contentId != null) { 211 contentId = contentId.trim(); 212 213 if (contentId.startsWith("<")) { 214 contentId = contentId.substring(1); 215 } 216 217 if (contentId.endsWith(">")) { 218 contentId = contentId.substring(0, contentId.length() 219 - 1); 220 } 221 222 contentId = contentId.trim(); 223 224 } 230 231 contentLocation = 232 headers.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 233 null); 234 235 if (contentLocation != null) { 236 contentLocation = contentLocation.trim(); 237 238 if (contentLocation.startsWith("<")) { 239 contentLocation = contentLocation.substring(1); 240 } 241 242 if (contentLocation.endsWith(">")) { 243 contentLocation = contentLocation.substring( 244 0, contentLocation.length() - 1); 245 } 246 247 contentLocation = contentLocation.trim(); 248 } 249 250 contentType = 251 headers.getHeader(HTTPConstants.HEADER_CONTENT_TYPE, null); 252 253 if (contentType != null) { 254 contentType = contentType.trim(); 255 } 256 257 contentTransferEncoding = headers.getHeader( 258 HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, null); 259 260 if (contentTransferEncoding != null) { 261 contentTransferEncoding = contentTransferEncoding.trim(); 262 } 263 264 java.io.InputStream decodedStream = boundaryDelimitedStream; 265 266 if ((contentTransferEncoding != null) 267 && (0 != contentTransferEncoding.length())) { 268 decodedStream = MimeUtility.decode(decodedStream, 269 contentTransferEncoding); 270 } 271 272 if ((rootPartContentId != null) && !rootPartContentId.equals( 273 contentId)) { javax.activation.DataHandler dh = 275 new javax.activation.DataHandler ( 276 new org.apache.axis.attachments.ManagedMemoryDataSource( 277 decodedStream, MAX_CACHED, contentType, true)); 278 AttachmentPart ap = new AttachmentPart(dh); 279 280 if (contentId != null) { 281 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, 282 contentId); 283 } 284 285 if (contentLocation != null) { 286 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 287 contentLocation); 288 } 289 290 for (java.util.Enumeration en = 291 headers.getNonMatchingHeaders(new String []{ 292 HTTPConstants.HEADER_CONTENT_ID, 293 HTTPConstants.HEADER_CONTENT_LOCATION, 294 HTTPConstants.HEADER_CONTENT_TYPE}); en.hasMoreElements();) { 295 javax.mail.Header header = 296 (javax.mail.Header ) en.nextElement(); 297 String name = header.getName(); 298 String value = header.getValue(); 299 300 if ((name != null) && (value != null)) { 301 name = name.trim(); 302 303 if (name.length() != 0) { 304 ap.addMimeHeader(name, value); 305 } 306 } 307 } 308 309 addPart(contentId, contentLocation, ap); 310 311 boundaryDelimitedStream = 312 boundaryDelimitedStream.getNextStream(); } 314 } while ((null != boundaryDelimitedStream) 315 && (rootPartContentId != null) 316 && !rootPartContentId.equals(contentId)); 317 318 if (boundaryDelimitedStream == null) { 319 throw new org.apache.axis.AxisFault( 320 Messages.getMessage("noRoot", rootPartContentId)); 321 } 322 323 soapStreamBDS = boundaryDelimitedStream; 324 325 if ((contentTransferEncoding != null) 326 && (0 != contentTransferEncoding.length())) { 327 soapStream = MimeUtility.decode(boundaryDelimitedStream, 328 contentTransferEncoding); 329 } else { 330 soapStream = 331 boundaryDelimitedStream; } 333 334 } catch (javax.mail.internet.ParseException e) { 336 throw new org.apache.axis.AxisFault( 337 Messages.getMessage("mimeErrorParsing", e.getMessage())); 338 } catch (java.io.IOException e) { 339 throw new org.apache.axis.AxisFault( 340 Messages.getMessage("readError", e.getMessage())); 341 } catch (javax.mail.MessagingException e) { 342 throw new org.apache.axis.AxisFault( 343 Messages.getMessage("readError", e.getMessage())); 344 } 345 } 346 347 private final byte[] readLine(java.io.InputStream is) throws IOException { 349 350 java.io.ByteArrayOutputStream input = new java.io.ByteArrayOutputStream (1024); 351 int c = 0; 352 input.write('\r'); 353 input.write('\n'); 354 355 int next = -1; 356 for (;c != -1;) { 357 c = -1 != next ? next : is.read(); 358 next = -1; 359 switch (c) { 360 case -1: 361 break; 362 case '\r': 363 next = is.read(); 364 if(next == '\n') return input.toByteArray(); 366 if(next == -1) return null; 367 default: 369 input.write((byte)c); 370 break; 371 } 372 } 373 return null; 375 } 376 377 public Part getAttachmentByReference(final String [] id) 378 throws org.apache.axis.AxisFault { 379 380 Part ret = null; 382 383 for (int i = id.length - 1; (ret == null) && (i > -1); --i) { 384 ret = (AttachmentPart) parts.get(id[i]); 385 } 386 387 if (null == ret) { 388 ret = readTillFound(id); 389 } 390 391 log.debug(Messages.getMessage("return02", 392 "getAttachmentByReference(\"" + id 393 + "\"", ((ret == null) 394 ? "null" 395 : ret.toString()))); 396 397 return ret; 398 } 399 400 408 protected void addPart(String contentId, String locationId, 409 AttachmentPart ap) { 410 411 if ((contentId != null) && (contentId.trim().length() != 0)) { 412 parts.put(contentId, ap); 413 } 414 415 if ((locationId != null) && (locationId.trim().length() != 0)) { 416 parts.put(locationId, ap); 417 } 418 419 orderedParts.add(ap); 420 } 421 422 423 protected static final String [] READ_ALL = { 424 " * \0 ".intern()}; 426 432 protected void readAll() throws org.apache.axis.AxisFault { 433 readTillFound(READ_ALL); 434 } 435 436 public java.util.Collection getAttachments() 437 throws org.apache.axis.AxisFault { 438 439 readAll(); 440 441 return orderedParts; 442 } 443 444 453 protected Part readTillFound(final String [] id) 454 throws org.apache.axis.AxisFault { 455 456 if (boundaryDelimitedStream == null) { 457 return null; } 459 460 Part ret = null; 461 462 try { 463 if (soapStreamBDS 464 == boundaryDelimitedStream) { if (!eos) { java.io.ByteArrayOutputStream soapdata = 467 new java.io.ByteArrayOutputStream (1024 * 8); 468 byte[] buf = 469 new byte[1024 * 16]; 470 int byteread = 0; 471 472 do { 473 byteread = soapStream.read(buf); 474 475 if (byteread > 0) { 476 soapdata.write(buf, 0, byteread); 477 } 478 } while (byteread > -1); 479 480 soapdata.close(); 481 482 soapStream = new java.io.ByteArrayInputStream ( 483 soapdata.toByteArray()); 484 } 485 486 boundaryDelimitedStream = 487 boundaryDelimitedStream.getNextStream(); 488 } 489 490 if (null != boundaryDelimitedStream) { 492 do { 493 String contentType = null; 494 String contentId = null; 495 String contentTransferEncoding = null; 496 String contentLocation = null; 497 498 javax.mail.internet.InternetHeaders headers = 500 new javax.mail.internet.InternetHeaders ( 501 boundaryDelimitedStream); 502 503 contentId = headers.getHeader("Content-Id", null); 504 505 if (contentId != null) { 506 contentId = contentId.trim(); 507 508 if (contentId.startsWith("<")) { 509 contentId = contentId.substring(1); 510 } 511 512 if (contentId.endsWith(">")) { 513 contentId = 514 contentId.substring(0, contentId.length() - 1); 515 } 516 517 521 contentId = contentId.trim(); 522 } 523 524 contentType = 525 headers.getHeader(HTTPConstants.HEADER_CONTENT_TYPE, 526 null); 527 528 if (contentType != null) { 529 contentType = contentType.trim(); 530 } 531 532 contentLocation = 533 headers.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 534 null); 535 536 if (contentLocation != null) { 537 contentLocation = contentLocation.trim(); 538 } 539 540 contentTransferEncoding = headers.getHeader( 541 HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, null); 542 543 if (contentTransferEncoding != null) { 544 contentTransferEncoding = 545 contentTransferEncoding.trim(); 546 } 547 548 java.io.InputStream decodedStream = boundaryDelimitedStream; 549 550 if ((contentTransferEncoding != null) 551 && (0 != contentTransferEncoding.length())) { 552 decodedStream = 553 MimeUtility.decode(decodedStream, 554 contentTransferEncoding); 555 } 556 557 ManagedMemoryDataSource source = new ManagedMemoryDataSource( 558 decodedStream, ManagedMemoryDataSource.MAX_MEMORY_DISK_CACHED, contentType, true); 559 DataHandler dh = new DataHandler (source); 560 AttachmentPart ap = new AttachmentPart(dh); 561 562 if (contentId != null) { 563 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, 564 contentId); 565 } 566 567 if (contentLocation != null) { 568 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 569 contentLocation); 570 } 571 572 for (java.util.Enumeration en = 573 headers.getNonMatchingHeaders(new String []{ 574 HTTPConstants.HEADER_CONTENT_ID, 575 HTTPConstants.HEADER_CONTENT_LOCATION, 576 HTTPConstants.HEADER_CONTENT_TYPE}); en.hasMoreElements();) { 577 javax.mail.Header header = 578 (javax.mail.Header ) en.nextElement(); 579 String name = header.getName(); 580 String value = header.getValue(); 581 582 if ((name != null) && (value != null)) { 583 name = name.trim(); 584 585 if (name.length() != 0) { 586 ap.addMimeHeader(name, value); 587 } 588 } 589 } 590 591 addPart(contentId, contentLocation, ap); 592 593 for (int i = id.length - 1; (ret == null) && (i > -1); 594 --i) { 595 if ((contentId != null) && id[i].equals( 596 contentId)) { ret = ap; 598 } else if ((contentLocation != null) 599 && id[i].equals(contentLocation)) { 600 ret = ap; 601 } 602 } 603 604 boundaryDelimitedStream = 605 boundaryDelimitedStream.getNextStream(); 606 } while ((null == ret) && (null != boundaryDelimitedStream)); 607 } 608 } catch (Exception e) { 609 throw org.apache.axis.AxisFault.makeFault(e); 610 } 611 612 return ret; 613 } 614 615 public String getContentLocation() { 616 return contentLocation; 617 } 618 619 public String getContentId() { 620 return contentId; 621 } 622 623 public int read(byte[] b, int off, int len) throws java.io.IOException { 624 625 if (closed) { 626 throw new java.io.IOException (Messages.getMessage("streamClosed")); 627 } 628 629 if (eos) { 630 return -1; 631 } 632 633 int read = soapStream.read(b, off, len); 634 635 if (read < 0) { 636 eos = true; 637 } 638 639 return read; 640 } 641 642 public int read(byte[] b) throws java.io.IOException { 643 return read(b, 0, b.length); 644 } 645 646 public int read() throws java.io.IOException { 647 648 if (closed) { 649 throw new java.io.IOException (Messages.getMessage("streamClosed")); 650 } 651 652 if (eos) { 653 return -1; 654 } 655 656 int ret = soapStream.read(); 657 658 if (ret < 0) { 659 eos = true; 660 } 661 662 return ret; 663 } 664 665 public void close() throws java.io.IOException { 666 667 closed = true; 668 669 soapStream.close(); 670 } 671 672 public int available() throws java.io.IOException { 673 return (closed || eos) ? 0 : soapStream.available(); 674 } 675 676 } 677 | Popular Tags |