1 8 package org.jboss.axis.attachments; 9 10 import org.jboss.axis.AxisFault; 11 import org.jboss.axis.Part; 12 import org.jboss.axis.transport.http.HTTPConstants; 13 import org.jboss.axis.utils.Messages; 14 import org.jboss.logging.Logger; 15 16 import javax.activation.DataHandler ; 17 import javax.mail.Header ; 18 import javax.mail.MessagingException ; 19 import javax.mail.internet.ContentType ; 20 import javax.mail.internet.InternetHeaders ; 21 import javax.mail.internet.MimeUtility ; 22 import javax.mail.internet.ParseException ; 23 import java.io.ByteArrayInputStream ; 24 import java.io.ByteArrayOutputStream ; 25 import java.io.IOException ; 26 import java.io.InputStream ; 27 import java.util.Arrays ; 28 import java.util.Collection ; 29 import java.util.Enumeration ; 30 import java.util.HashMap ; 31 import java.util.LinkedList ; 32 33 38 public class MultiPartRelatedInputStream extends MultiPartInputStream 39 { 40 41 44 private static Logger log = Logger.getLogger(MultiPartRelatedInputStream.class.getName()); 45 46 49 public static final String MIME_MULTIPART_RELATED = "multipart/related"; 50 51 54 protected HashMap parts = new HashMap (); 55 56 59 protected LinkedList orderedParts = new LinkedList (); 60 61 64 protected int rootPartLength = 0; 65 66 69 protected boolean closed = false; 71 74 protected boolean eos = 75 false; 77 80 83 protected BoundaryDelimitedStream boundaryDelimitedStream = 84 null; 85 86 89 protected InputStream soapStream = 90 null; 92 95 protected InputStream soapStreamBDS = 96 null; 98 101 protected byte[] boundary = null; 102 103 106 protected ByteArrayInputStream cachedSOAPEnvelope = 107 null; 109 111 114 protected String contentLocation = null; 115 116 119 protected String contentId = null; 120 121 128 public MultiPartRelatedInputStream(String contentType, InputStream stream) 129 throws AxisFault 130 { 131 132 super(null); 134 try 135 { 136 137 ContentType ct = 140 new ContentType (contentType); 141 String rootPartContentId = 142 ct.getParameter("start"); 144 if (rootPartContentId != null) 145 { 146 rootPartContentId = rootPartContentId.trim(); 147 148 if (rootPartContentId.startsWith("<")) 149 { 150 rootPartContentId = rootPartContentId.substring(1); 151 } 152 153 if (rootPartContentId.endsWith(">")) 154 { 155 rootPartContentId = rootPartContentId.substring(0, 156 rootPartContentId.length() - 1); 157 } 158 159 } 160 161 if (ct.getParameter("boundary") != null) 162 { 163 String boundaryStr = 164 "--" 165 + ct.getParameter("boundary"); 167 168 byte[][] boundaryMarker = new byte[2][boundaryStr.length() + 2]; 172 173 stream.read(boundaryMarker[0]); 174 175 boundary = (boundaryStr + "\r\n").getBytes("US-ASCII"); 176 177 int current = 0; 178 179 for (boolean found = false; !found; ++current) 182 { 183 if (!(found = 184 Arrays.equals(boundaryMarker[current & 0x1], 185 boundary))) 186 { 187 System.arraycopy(boundaryMarker[current & 0x1], 1, 188 boundaryMarker[(current + 1) & 0x1], 0, 189 boundaryMarker[0].length - 1); 190 191 if (stream.read(boundaryMarker[(current + 1) & 0x1], 192 boundaryMarker[0].length - 1, 1) < 1) 193 { 194 throw new AxisFault(Messages.getMessage("mimeErrorNoBoundary", new String (boundary))); 195 } 196 } 197 } 198 199 boundaryStr = "\r\n" + boundaryStr; 202 boundary = boundaryStr.getBytes("US-ASCII"); 203 } 204 else 205 { 206 for (boolean found = false; !found;) 208 { 209 boundary = readLine(stream); 210 if (boundary == null) 211 throw new AxisFault(Messages.getMessage("mimeErrorNoBoundary", "--")); 212 found = boundary.length > 4 && boundary[2] == '-' && boundary[3] == '-'; 213 } 214 } 215 216 boundaryDelimitedStream = 218 new BoundaryDelimitedStream(stream, 219 boundary, 1024); 220 221 String contentTransferEncoding = null; 223 224 do 225 { 226 contentId = null; 227 contentLocation = null; 228 contentTransferEncoding = null; 229 230 InternetHeaders headers = 232 new InternetHeaders (boundaryDelimitedStream); 233 234 contentId = headers.getHeader(HTTPConstants.HEADER_CONTENT_ID, 236 null); 237 238 if (contentId != null) 240 { 241 contentId = contentId.trim(); 242 243 if (contentId.startsWith("<")) 244 { 245 contentId = contentId.substring(1); 246 } 247 248 if (contentId.endsWith(">")) 249 { 250 contentId = contentId.substring(0, contentId.length() 251 - 1); 252 } 253 254 contentId = contentId.trim(); 255 256 } 262 263 contentLocation = 264 headers.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 265 null); 266 267 if (contentLocation != null) 268 { 269 contentLocation = contentLocation.trim(); 270 271 if (contentLocation.startsWith("<")) 272 { 273 contentLocation = contentLocation.substring(1); 274 } 275 276 if (contentLocation.endsWith(">")) 277 { 278 contentLocation = contentLocation.substring(0, contentLocation.length() - 1); 279 } 280 281 contentLocation = contentLocation.trim(); 282 } 283 284 contentType = 285 headers.getHeader(HTTPConstants.HEADER_CONTENT_TYPE, null); 286 287 if (contentType != null) 288 { 289 contentType = contentType.trim(); 290 } 291 292 contentTransferEncoding = headers.getHeader(HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, null); 293 294 if (contentTransferEncoding != null) 295 { 296 contentTransferEncoding = contentTransferEncoding.trim(); 297 } 298 299 InputStream decodedStream = boundaryDelimitedStream; 300 301 if ((contentTransferEncoding != null) 302 && (0 != contentTransferEncoding.length())) 303 { 304 decodedStream = MimeUtility.decode(decodedStream, 305 contentTransferEncoding); 306 } 307 308 if ((rootPartContentId != null) && !rootPartContentId.equals(contentId)) 309 { DataHandler dh = new DataHandler (new ManagedMemoryDataSource(decodedStream, contentType)); 311 AttachmentPartImpl ap = new AttachmentPartImpl(dh); 312 313 if (contentId != null) 314 { 315 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, 316 contentId); 317 } 318 319 if (contentLocation != null) 320 { 321 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 322 contentLocation); 323 } 324 325 for (Enumeration en = 326 headers.getNonMatchingHeaders(new String []{ 327 HTTPConstants.HEADER_CONTENT_ID, 328 HTTPConstants.HEADER_CONTENT_LOCATION, 329 HTTPConstants.HEADER_CONTENT_TYPE}); en.hasMoreElements();) 330 { 331 Header header = 332 (Header )en.nextElement(); 333 String name = header.getName(); 334 String value = header.getValue(); 335 336 if ((name != null) && (value != null)) 337 { 338 name = name.trim(); 339 340 if (name.length() != 0) 341 { 342 ap.addMimeHeader(name, value); 343 } 344 } 345 } 346 347 addPart(contentId, contentLocation, ap); 348 349 boundaryDelimitedStream = 350 boundaryDelimitedStream.getNextStream(); } 352 } 353 while ((null != boundaryDelimitedStream) 354 && (rootPartContentId != null) 355 && !rootPartContentId.equals(contentId)); 356 357 if (boundaryDelimitedStream == null) 358 { 359 throw new AxisFault(Messages.getMessage("noRoot", rootPartContentId)); 360 } 361 362 soapStreamBDS = boundaryDelimitedStream; 363 364 if ((contentTransferEncoding != null) 365 && (0 != contentTransferEncoding.length())) 366 { 367 soapStream = MimeUtility.decode(boundaryDelimitedStream, 368 contentTransferEncoding); 369 } 370 else 371 { 372 soapStream = 373 boundaryDelimitedStream; } 375 376 } 378 catch (ParseException e) 379 { 380 throw new AxisFault(Messages.getMessage("mimeErrorParsing", e.getMessage())); 381 } 382 catch (IOException e) 383 { 384 throw new AxisFault(Messages.getMessage("readError", e.getMessage())); 385 } 386 catch (MessagingException e) 387 { 388 throw new AxisFault(Messages.getMessage("readError", e.getMessage())); 389 } 390 } 391 392 private final byte[] readLine(InputStream is) throws IOException 394 { 395 396 ByteArrayOutputStream input = new ByteArrayOutputStream (1024); 397 int c = 0; 398 input.write('\r'); 399 input.write('\n'); 400 401 int next = -1; 402 for (; c != -1;) 403 { 404 c = -1 != next ? next : is.read(); 405 next = -1; 406 switch (c) 407 { 408 case -1: 409 break; 410 case '\r': 411 next = is.read(); 412 if (next == '\n') return input.toByteArray(); 414 if (next == -1) return null; 415 default: 417 input.write((byte)c); 418 break; 419 } 420 } 421 return null; 423 } 424 425 432 public Part getAttachmentByReference(final String [] id) 433 throws AxisFault 434 { 435 436 Part ret = null; 438 439 for (int i = id.length - 1; (ret == null) && (i > -1); --i) 440 { 441 ret = (AttachmentPartImpl)parts.get(id[i]); 442 } 443 444 if (null == ret) 445 { 446 ret = readTillFound(id); 447 } 448 449 log.debug(Messages.getMessage("return02", 450 "getAttachmentByReference(\"" + id 451 + "\"", ((ret == null) 452 ? "null" 453 : ret.toString()))); 454 455 return ret; 456 } 457 458 465 protected void addPart(String contentId, String locationId, 466 AttachmentPartImpl ap) 467 { 468 469 if ((contentId != null) && (contentId.trim().length() != 0)) 470 { 471 parts.put(contentId, ap); 472 } 473 474 if ((locationId != null) && (locationId.trim().length() != 0)) 475 { 476 parts.put(locationId, ap); 477 } 478 479 orderedParts.add(ap); 480 } 481 482 485 protected static final String [] READ_ALL = { 486 " * \0 ".intern()}; 488 493 protected void readAll() throws AxisFault 494 { 495 readTillFound(READ_ALL); 496 } 497 498 504 public Collection getAttachments() 505 throws AxisFault 506 { 507 508 readAll(); 509 510 return orderedParts; 511 } 512 513 520 protected Part readTillFound(final String [] id) 521 throws AxisFault 522 { 523 524 if (boundaryDelimitedStream == null) 525 { 526 return null; } 528 529 Part ret = null; 530 531 try 532 { 533 if (soapStreamBDS 534 == boundaryDelimitedStream) 535 { if (!eos) 537 { ByteArrayOutputStream soapdata = 539 new ByteArrayOutputStream (1024 * 8); 540 byte[] buf = 541 new byte[1024 * 16]; 542 int byteread = 0; 543 544 do 545 { 546 byteread = soapStream.read(buf); 547 548 if (byteread > 0) 549 { 550 soapdata.write(buf, 0, byteread); 551 } 552 } 553 while (byteread > -1); 554 555 soapdata.close(); 556 557 soapStream = new ByteArrayInputStream (soapdata.toByteArray()); 558 } 559 560 boundaryDelimitedStream = 561 boundaryDelimitedStream.getNextStream(); 562 } 563 564 if (null != boundaryDelimitedStream) 566 { 567 do 568 { 569 String contentType = null; 570 String contentId = null; 571 String contentTransferEncoding = null; 572 String contentLocation = null; 573 574 InternetHeaders headers = 576 new InternetHeaders (boundaryDelimitedStream); 577 578 contentId = headers.getHeader("Content-Id", null); 579 580 if (contentId != null) 581 { 582 contentId = contentId.trim(); 583 584 if (contentId.startsWith("<")) 585 { 586 contentId = contentId.substring(1); 587 } 588 589 if (contentId.endsWith(">")) 590 { 591 contentId = 592 contentId.substring(0, contentId.length() - 1); 593 } 594 595 599 contentId = contentId.trim(); 600 } 601 602 contentType = 603 headers.getHeader(HTTPConstants.HEADER_CONTENT_TYPE, 604 null); 605 606 if (contentType != null) 607 { 608 contentType = contentType.trim(); 609 } 610 611 contentLocation = 612 headers.getHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 613 null); 614 615 if (contentLocation != null) 616 { 617 contentLocation = contentLocation.trim(); 618 } 619 620 contentTransferEncoding = headers.getHeader(HTTPConstants.HEADER_CONTENT_TRANSFER_ENCODING, null); 621 622 if (contentTransferEncoding != null) 623 { 624 contentTransferEncoding = 625 contentTransferEncoding.trim(); 626 } 627 628 InputStream decodedStream = boundaryDelimitedStream; 629 630 if ((contentTransferEncoding != null) 631 && (0 != contentTransferEncoding.length())) 632 { 633 decodedStream = 634 MimeUtility.decode(decodedStream, 635 contentTransferEncoding); 636 } 637 638 ManagedMemoryDataSource source = new ManagedMemoryDataSource(decodedStream, contentType); 639 DataHandler dh = new DataHandler (source); 640 AttachmentPartImpl ap = new AttachmentPartImpl(dh); 641 642 if (contentId != null) 643 { 644 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_ID, 645 contentId); 646 } 647 648 if (contentLocation != null) 649 { 650 ap.setMimeHeader(HTTPConstants.HEADER_CONTENT_LOCATION, 651 contentLocation); 652 } 653 654 for (Enumeration en = 655 headers.getNonMatchingHeaders(new String []{ 656 HTTPConstants.HEADER_CONTENT_ID, 657 HTTPConstants.HEADER_CONTENT_LOCATION, 658 HTTPConstants.HEADER_CONTENT_TYPE}); en.hasMoreElements();) 659 { 660 Header header = 661 (Header )en.nextElement(); 662 String name = header.getName(); 663 String value = header.getValue(); 664 665 if ((name != null) && (value != null)) 666 { 667 name = name.trim(); 668 669 if (name.length() != 0) 670 { 671 ap.addMimeHeader(name, value); 672 } 673 } 674 } 675 676 addPart(contentId, contentLocation, ap); 677 678 for (int i = id.length - 1; (ret == null) && (i > -1); 679 --i) 680 { 681 if ((contentId != null) && id[i].equals(contentId)) 682 { ret = ap; 684 } 685 else if ((contentLocation != null) 686 && id[i].equals(contentLocation)) 687 { 688 ret = ap; 689 } 690 } 691 692 boundaryDelimitedStream = 693 boundaryDelimitedStream.getNextStream(); 694 } 695 while ((null == ret) && (null != boundaryDelimitedStream)); 696 } 697 } 698 catch (Exception e) 699 { 700 throw AxisFault.makeFault(e); 701 } 702 703 return ret; 704 } 705 706 712 public String getContentLocation() 713 { 714 return contentLocation; 715 } 716 717 723 public String getContentId() 724 { 725 return contentId; 726 } 727 728 737 public int read(byte[] b, int off, int len) throws IOException 738 { 739 740 if (closed) 741 { 742 throw new IOException (Messages.getMessage("streamClosed")); 743 } 744 745 if (eos) 746 { 747 return -1; 748 } 749 750 int read = soapStream.read(b, off, len); 751 752 if (read < 0) 753 { 754 eos = true; 755 } 756 757 return read; 758 } 759 760 767 public int read(byte[] b) throws IOException 768 { 769 return read(b, 0, b.length); 770 } 771 772 778 public int read() throws IOException 779 { 780 781 if (closed) 782 { 783 throw new IOException (Messages.getMessage("streamClosed")); 784 } 785 786 if (eos) 787 { 788 return -1; 789 } 790 791 int ret = soapStream.read(); 792 793 if (ret < 0) 794 { 795 eos = true; 796 } 797 798 return ret; 799 } 800 801 806 public void close() throws IOException 807 { 808 809 closed = true; 810 811 soapStream.close(); 812 } 813 } 814 | Popular Tags |