Example usage for org.apache.commons.io.input TeeInputStream read

List of usage examples for org.apache.commons.io.input TeeInputStream read

Introduction

In this page you can find the example usage for org.apache.commons.io.input TeeInputStream read.

Prototype

public int read(byte[] bts) throws IOException 

Source Link

Document

Reads bytes from the proxied input stream and writes the read bytes to the associated output stream.

Usage

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
            }
        }
    }

}