?? mimemultipart.java
字號:
parse(); return preamble; } /** * Set the preamble text to be included before the first * body part. Applications should generally not include * any preamble text. In some cases it may be helpful to * include preamble text with instructions for users of * pre-MIME software. The preamble text should be complete * lines, including newlines. * * @param preamble the preamble text * @since JavaMail 1.4 */ public synchronized void setPreamble(String preamble) throws MessagingException { this.preamble = preamble; } /** * Update headers. The default implementation here just * calls the <code>updateHeaders</code> method on each of its * children BodyParts. <p> * * Note that the boundary parameter is already set up when * a new and empty MimeMultipart object is created. <p> * * This method is called when the <code>saveChanges</code> * method is invoked on the Message object containing this * Multipart. This is typically done as part of the Message * send process, however note that a client is free to call * it any number of times. So if the header updating process is * expensive for a specific MimeMultipart subclass, then it * might itself want to track whether its internal state actually * did change, and do the header updating only if necessary. */ protected void updateHeaders() throws MessagingException { for (int i = 0; i < parts.size(); i++) ((MimeBodyPart)parts.elementAt(i)).updateHeaders(); } /** * Iterates through all the parts and outputs each MIME part * separated by a boundary. */ public synchronized void writeTo(OutputStream os) throws IOException, MessagingException { parse(); String boundary = "--" + (new ContentType(contentType)).getParameter("boundary"); LineOutputStream los = new LineOutputStream(os); // if there's a preamble, write it out if (preamble != null) { byte[] pb = ASCIIUtility.getBytes(preamble); los.write(pb); // make sure it ends with a newline if (pb.length > 0 && !(pb[pb.length-1] == '\r' || pb[pb.length-1] == '\n')) { los.writeln(); } // XXX - could force a blank line before start boundary } for (int i = 0; i < parts.size(); i++) { los.writeln(boundary); // put out boundary ((MimeBodyPart)parts.elementAt(i)).writeTo(os); los.writeln(); // put out empty line } // put out last boundary los.writeln(boundary + "--"); } /** * Parse the InputStream from our DataSource, constructing the * appropriate MimeBodyParts. The <code>parsed</code> flag is * set to true, and if true on entry nothing is done. This * method is called by all other methods that need data for * the body parts, to make sure the data has been parsed. * * @since JavaMail 1.2 */ protected synchronized void parse() throws MessagingException { if (parsed) return; if (bmparse) { parsebm(); return; } InputStream in = null; SharedInputStream sin = null; long start = 0, end = 0; try { in = ds.getInputStream(); if (!(in instanceof ByteArrayInputStream) && !(in instanceof BufferedInputStream) && !(in instanceof SharedInputStream)) in = new BufferedInputStream(in); } catch (Exception ex) { throw new MessagingException("No inputstream from datasource", ex); } if (in instanceof SharedInputStream) sin = (SharedInputStream)in; ContentType cType = new ContentType(contentType); String boundary = null; String bp = cType.getParameter("boundary"); if (bp != null) boundary = "--" + bp; else if (!ignoreMissingBoundaryParameter) throw new MessagingException("Missing boundary parameter"); try { // Skip and save the preamble LineInputStream lin = new LineInputStream(in); StringBuffer preamblesb = null; String line; String lineSeparator = null; while ((line = lin.readLine()) != null) { /* * Strip trailing whitespace. Can't use trim method * because it's too aggressive. Some bogus MIME * messages will include control characters in the * boundary string. */ int i; for (i = line.length() - 1; i >= 0; i--) { char c = line.charAt(i); if (!(c == ' ' || c == '\t')) break; } line = line.substring(0, i + 1); if (boundary != null) { if (line.equals(boundary)) break; } else { /* * Boundary hasn't been defined, does this line * look like a boundary? If so, assume it is * the boundary and save it. */ if (line.startsWith("--")) { boundary = line; break; } } // save the preamble after skipping blank lines if (line.length() > 0) { // if we haven't figured out what the line seprator // is, do it now if (lineSeparator == null) { try { lineSeparator = System.getProperty("line.separator", "\n"); } catch (SecurityException ex) { lineSeparator = "\n"; } } // accumulate the preamble if (preamblesb == null) preamblesb = new StringBuffer(line.length() + 2); preamblesb.append(line).append(lineSeparator); } } if (line == null) throw new MessagingException("Missing start boundary"); if (preamblesb != null) preamble = preamblesb.toString(); // save individual boundary bytes for easy comparison later byte[] bndbytes = ASCIIUtility.getBytes(boundary); int bl = bndbytes.length; /* * Read and process body parts until we see the * terminating boundary line (or EOF). */ boolean done = false; getparts: while (!done) { InternetHeaders headers = null; if (sin != null) { start = sin.getPosition(); // skip headers while ((line = lin.readLine()) != null && line.length() > 0) ; if (line == null) { if (!ignoreMissingEndBoundary) throw new MessagingException( "missing multipart end boundary"); // assume there's just a missing end boundary complete = false; break getparts; } } else { // collect the headers for this body part headers = createInternetHeaders(in); } if (!in.markSupported()) throw new MessagingException("Stream doesn't support mark"); ByteArrayOutputStream buf = null; // if we don't have a shared input stream, we copy the data if (sin == null) buf = new ByteArrayOutputStream(); else end = sin.getPosition(); int b; boolean bol = true; // beginning of line flag // the two possible end of line characters int eol1 = -1, eol2 = -1; /* * Read and save the content bytes in buf. */ for (;;) { if (bol) { /* * At the beginning of a line, check whether the * next line is a boundary. */ int i; in.mark(bl + 4 + 1000); // bnd + "--\r\n" + lots of LWSP // read bytes, matching against the boundary for (i = 0; i < bl; i++) if (in.read() != (bndbytes[i] & 0xff)) break; if (i == bl) { // matched the boundary, check for last boundary int b2 = in.read(); if (b2 == '-') { if (in.read() == '-') { complete = true; done = true; break; // ignore trailing text } } // skip linear whitespace while (b2 == ' ' || b2 == '\t') b2 = in.read(); // check for end of line if (b2 == '\n') break; // got it! break out of the loop if (b2 == '\r') { in.mark(1); if (in.read() != '\n') in.reset(); break; // got it! break out of the loop } } // failed to match, reset and proceed normally in.reset(); // if this is not the first line, write out the // end of line characters from the previous line if (buf != null && eol1 != -1) { buf.write(eol1); if (eol2 != -1) buf.write(eol2); eol1 = eol2 = -1; } } // read the next byte if ((b = in.read()) < 0) { if (!ignoreMissingEndBoundary) throw new MessagingException( "missing multipart end boundary"); complete = false; done = true; break; } /* * If we're at the end of the line, save the eol characters * to be written out before the beginning of the next line. */ if (b == '\r' || b == '\n') { bol = true; if (sin != null) end = sin.getPosition() - 1; eol1 = b; if (b == '\r') { in.mark(1); if ((b = in.read()) == '\n') eol2 = b; else in.reset(); } } else { bol = false; if (buf != null) buf.write(b); } } /* * Create a MimeBody element to represent this body part. */ MimeBodyPart part; if (sin != null) part = createMimeBodyPart(sin.newStream(start, end)); else part = createMimeBodyPart(headers, buf.toByteArray()); super.addBodyPart(part); } } catch (IOException ioex) { throw new MessagingException("IO Error", ioex); } finally { try { in.close(); } catch (IOException cex) { // ignore } } parsed = true; } /** * Parse the InputStream from our DataSource, constructing the * appropriate MimeBodyParts. The <code>parsed</code> flag is * set to true, and if true on entry nothing is done. This * method is called by all other methods that need data for * the body parts, to make sure the data has been parsed. * * @since JavaMail 1.2 */ /* * Boyer-Moore version of parser. Keep both versions around * until we're sure this new one works. */ private synchronized void parsebm() throws MessagingException { if (parsed) return; InputStream in = null; SharedInputStream sin = null; long start = 0, end = 0; try { in = ds.getInputStream(); if (!(in instanceof ByteArrayInputStream) && !(in instanceof BufferedInputStream) && !(in instanceof SharedInputStream)) in = new BufferedInputStream(in); } catch (Exception ex) { throw new MessagingException("No inputstream from datasource", ex); } if (in instanceof SharedInputStream) sin = (SharedInputStream)in; ContentType cType = new ContentType(contentType); String boundary = null; String bp = cType.getParameter("boundary"); if (bp != null) boundary = "--" + bp; else if (!ignoreMissingBoundaryParameter) throw new MessagingException("Missing boundary parameter"); try { // Skip and save the preamble LineInputStream lin = new LineInputStream(in); StringBuffer preamblesb = null; String line; String lineSeparator = null; while ((line = lin.readLine()) != null) { /*
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -