List of usage examples for org.apache.commons.io.input TeeInputStream read
public int read(byte[] bts) throws IOException
From source file:org.apache.james.mailbox.store.StoreMessageManager.java
/** * @see org.apache.james.mailbox.MessageManager#appendMessage(java.io.InputStream, * java.util.Date, org.apache.james.mailbox.MailboxSession, boolean, * javax.mail.Flags)/* w w w . j a v a 2s . co m*/ */ public long appendMessage(InputStream msgIn, Date internalDate, final MailboxSession mailboxSession, boolean isRecent, Flags flagsToBeSet) throws MailboxException { File file = null; TeeInputStream tmpMsgIn = null; BodyOffsetInputStream bIn = null; FileOutputStream out = null; SharedFileInputStream contentIn = null; if (!isWriteable(mailboxSession)) { throw new ReadOnlyException(getMailboxPath(), mailboxSession.getPathDelimiter()); } try { // Create a temporary file and copy the message to it. We will work // with the file as // source for the InputStream file = File.createTempFile("imap", ".msg"); out = new FileOutputStream(file); tmpMsgIn = new TeeInputStream(msgIn, out); bIn = new BodyOffsetInputStream(tmpMsgIn); // Disable line length... This should be handled by the smtp server // component and not the parser itself // https://issues.apache.org/jira/browse/IMAP-122 MimeConfig config = MimeConfig.custom().setMaxLineLen(-1).setMaxHeaderLen(-1).build(); final MimeTokenStream parser = new MimeTokenStream(config, new DefaultBodyDescriptorBuilder()); parser.setRecursionMode(RecursionMode.M_NO_RECURSE); parser.parse(bIn); final HeaderImpl header = new HeaderImpl(); EntityState next = parser.next(); while (next != EntityState.T_BODY && next != EntityState.T_END_OF_STREAM && next != EntityState.T_START_MULTIPART) { if (next == EntityState.T_FIELD) { header.addField(parser.getField()); } next = parser.next(); } final MaximalBodyDescriptor descriptor = (MaximalBodyDescriptor) parser.getBodyDescriptor(); final PropertyBuilder propertyBuilder = new PropertyBuilder(); final String mediaType; final String mediaTypeFromHeader = descriptor.getMediaType(); final String subType; if (mediaTypeFromHeader == null) { mediaType = "text"; subType = "plain"; } else { mediaType = mediaTypeFromHeader; subType = descriptor.getSubType(); } propertyBuilder.setMediaType(mediaType); propertyBuilder.setSubType(subType); propertyBuilder.setContentID(descriptor.getContentId()); propertyBuilder.setContentDescription(descriptor.getContentDescription()); propertyBuilder.setContentLocation(descriptor.getContentLocation()); propertyBuilder.setContentMD5(descriptor.getContentMD5Raw()); propertyBuilder.setContentTransferEncoding(descriptor.getTransferEncoding()); propertyBuilder.setContentLanguage(descriptor.getContentLanguage()); propertyBuilder.setContentDispositionType(descriptor.getContentDispositionType()); propertyBuilder.setContentDispositionParameters(descriptor.getContentDispositionParameters()); propertyBuilder.setContentTypeParameters(descriptor.getContentTypeParameters()); // Add missing types final String codeset = descriptor.getCharset(); if (codeset == null) { if ("TEXT".equalsIgnoreCase(mediaType)) { propertyBuilder.setCharset("us-ascii"); } } else { propertyBuilder.setCharset(codeset); } final String boundary = descriptor.getBoundary(); if (boundary != null) { propertyBuilder.setBoundary(boundary); } if ("text".equalsIgnoreCase(mediaType)) { final CountingInputStream bodyStream = new CountingInputStream(parser.getInputStream()); bodyStream.readAll(); long lines = bodyStream.getLineCount(); bodyStream.close(); next = parser.next(); if (next == EntityState.T_EPILOGUE) { final CountingInputStream epilogueStream = new CountingInputStream(parser.getInputStream()); epilogueStream.readAll(); lines += epilogueStream.getLineCount(); epilogueStream.close(); } propertyBuilder.setTextualLineCount(lines); } final Flags flags; if (flagsToBeSet == null) { flags = new Flags(); } else { flags = flagsToBeSet; // Check if we need to trim the flags trimFlags(flags, mailboxSession); } if (isRecent) { flags.add(Flags.Flag.RECENT); } if (internalDate == null) { internalDate = new Date(); } byte[] discard = new byte[4096]; while (tmpMsgIn.read(discard) != -1) { // consume the rest of the stream so everything get copied to // the file now // via the TeeInputStream } int bodyStartOctet = (int) bIn.getBodyStartOffset(); if (bodyStartOctet == -1) { bodyStartOctet = 0; } contentIn = new SharedFileInputStream(file); final int size = (int) file.length(); final List<MessageAttachment> attachments = extractAttachments(contentIn); final MailboxMessage message = createMessage(internalDate, size, bodyStartOctet, contentIn, flags, propertyBuilder, attachments); new QuotaChecker(quotaManager, quotaRootResolver, mailbox).tryAddition(1, size); return locker.executeWithLock(mailboxSession, getMailboxPath(), new MailboxPathLocker.LockAwareExecution<Long>() { @Override public Long execute() throws MailboxException { MessageMetaData data = appendMessageToStore(message, attachments, mailboxSession); SortedMap<Long, MessageMetaData> uids = new TreeMap<Long, MessageMetaData>(); uids.put(data.getUid(), data); dispatcher.added(mailboxSession, uids, getMailboxEntity()); return data.getUid(); } }, true); } catch (IOException e) { throw new MailboxException("Unable to parse message", e); } catch (MimeException e) { throw new MailboxException("Unable to parse message", e); } finally { IOUtils.closeQuietly(bIn); IOUtils.closeQuietly(tmpMsgIn); IOUtils.closeQuietly(out); IOUtils.closeQuietly(contentIn); // delete the temporary file if one was specified if (file != null) { if (!file.delete()) { // Don't throw an IOException. The message could be appended // and the temporary file // will be deleted hopefully some day } } } }