use of com.zimbra.common.util.TruncatingWriter in project zm-mailbox by Zimbra.
the class ToXML method addContent.
/** Adds the decoded text content of a message part to the {@link Element}.
* The content is added as the value of a new <tt><content></tt>
* sub-element. <i>Note: This method will only extract the content of a
* <b>text/*</b> or <b>xml/*</b> message part.</i>
*
* @param elt The element to add the <tt><content></tt> to.
* @param mpi The message part to extract the content from.
* @param maxSize The maximum number of characters to inline (<=0 is unlimited).
* @param neuter Whether to "neuter" image <tt>src</tt> attributes.
* @parame defaultCharset The user's default charset preference.
* @throws MessagingException when message parsing or CTE-decoding fails
* @throws IOException on error during parsing or defanging
* @see HtmlDefang#defang(String, boolean) */
private static void addContent(Element elt, MPartInfo mpi, int maxSize, boolean neuter, String defaultCharset, MsgContent wantContent) throws IOException, MessagingException {
// TODO: support other parts
String ctype = mpi.getContentType();
if (!ctype.matches(MimeConstants.CT_TEXT_WILD) && !ctype.matches(MimeConstants.CT_XML_WILD)) {
return;
}
MimePart mp = mpi.getMimePart();
Mime.repairTransferEncoding(mp);
String data = null;
String originalContent = null;
wantContent = wantContent == null ? MsgContent.full : wantContent;
try {
if (maxSize <= 0) {
maxSize = (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize();
} else {
maxSize = Math.min(maxSize, (int) Provisioning.getInstance().getLocalServer().getMailContentMaxSize());
}
} catch (ServiceException e) {
ZimbraLog.soap.warn("Unable to determine max content size", e);
}
boolean wasTruncated = false;
if (ctype.equals(MimeConstants.CT_TEXT_HTML)) {
String charset = mpi.getContentTypeParameter(MimeConstants.P_CHARSET);
InputStream stream = null;
StringWriter sw = new StringWriter();
TruncatingWriter tw = null;
Writer out = sw;
if (maxSize > 0) {
tw = new TruncatingWriter(sw, maxSize + 1);
out = tw;
}
Reader reader = null;
try {
stream = mp.getInputStream();
if (charset != null && !charset.trim().isEmpty()) {
// make sure to feed getTextReader() a full Content-Type header, not just the primary/subtype portion
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
BrowserDefang defanger = DefangFactory.getDefanger(mp.getContentType());
defanger.defang(reader, neuter, out);
data = sw.toString();
} else {
String cte = mp.getEncoding();
if (cte != null && !cte.trim().toLowerCase().equals(MimeConstants.ET_7BIT)) {
try {
DefangFactory.getDefanger(ctype).defang(stream, neuter, out);
data = sw.toString();
} catch (IOException e) {
}
}
if (data == null) {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
DefangFactory.getDefanger(ctype).defang(reader, neuter, out);
data = sw.toString();
}
}
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = removeQuotedText(data, true);
}
} finally {
if (tw != null) {
wasTruncated = tw.wasTruncated();
}
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
} else if (ctype.equals(MimeConstants.CT_TEXT_ENRICHED)) {
// Enriched text handling is a little funky because TextEnrichedHandler
// doesn't use Reader and Writer. As a result, we truncate
// the source before converting to HTML.
InputStream stream = mp.getInputStream();
Reader reader = null;
try {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
String enriched = ByteUtil.getContent(reader, maxChars, false);
if (enriched.length() == maxChars) {
// The normal check for truncated data won't work because
// the length of the converted text is different than the length
// of the source, so set the attr here.
wasTruncated = true;
}
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = TextEnrichedHandler.convertToHTML(removeQuotedText(enriched, false));
}
data = TextEnrichedHandler.convertToHTML(enriched);
} finally {
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
} else {
InputStream stream = mp.getInputStream();
Reader reader = null;
try {
reader = Mime.getTextReader(stream, mp.getContentType(), defaultCharset);
int maxChars = (maxSize > 0 ? maxSize + 1 : -1);
data = ByteUtil.getContent(reader, maxChars, false);
if (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both)) {
originalContent = removeQuotedText(data, false);
}
if (data.length() == maxChars) {
wasTruncated = true;
}
} finally {
ByteUtil.closeStream(stream);
Closeables.closeQuietly(reader);
}
}
if (data != null && !wantContent.equals(MsgContent.original)) {
data = StringUtil.stripControlCharacters(data);
if (wasTruncated) {
elt.addAttribute(MailConstants.A_TRUNCATED_CONTENT, true);
if (data.length() > maxSize) {
data = data.substring(0, maxSize);
}
}
elt.addAttribute(MailConstants.E_CONTENT, data, Element.Disposition.CONTENT);
}
if (originalContent != null && (wantContent.equals(MsgContent.original) || wantContent.equals(MsgContent.both))) {
originalContent = StringUtil.stripControlCharacters(originalContent);
elt.addUniqueElement(MailConstants.E_ORIG_CONTENT).setText(originalContent);
}
// TODO: CDATA worth the effort?
}
use of com.zimbra.common.util.TruncatingWriter in project zm-mailbox by Zimbra.
the class TestUtilCode method doTruncatingWriterTest.
private void doTruncatingWriterTest(int maxChars) throws Exception {
String original = "Come talk to me";
StringWriter sw = new StringWriter();
Writer w = new TruncatingWriter(sw, maxChars);
w.append(original);
String s = sw.toString();
int actualChars = Math.min(maxChars, original.length());
assertEquals(actualChars, s.length());
assertEquals(original.substring(0, actualChars), s);
}
Aggregations