001 /****************************************************************
002 * Licensed to the Apache Software Foundation (ASF) under one *
003 * or more contributor license agreements. See the NOTICE file *
004 * distributed with this work for additional information *
005 * regarding copyright ownership. The ASF licenses this file *
006 * to you under the Apache License, Version 2.0 (the *
007 * "License"); you may not use this file except in compliance *
008 * with the License. You may obtain a copy of the License at *
009 * *
010 * http://www.apache.org/licenses/LICENSE-2.0 *
011 * *
012 * Unless required by applicable law or agreed to in writing, *
013 * software distributed under the License is distributed on an *
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015 * KIND, either express or implied. See the License for the *
016 * specific language governing permissions and limitations *
017 * under the License. *
018 ****************************************************************/
019 package org.apache.james.mailbox.jpa.mail.model.openjpa;
020
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.util.Date;
024
025 import javax.mail.Flags;
026 import javax.mail.internet.SharedInputStream;
027 import javax.mail.util.SharedByteArrayInputStream;
028 import javax.persistence.Column;
029 import javax.persistence.Entity;
030 import javax.persistence.FetchType;
031 import javax.persistence.Table;
032
033 import org.apache.commons.io.IOUtils;
034 import org.apache.james.mailbox.exception.MailboxException;
035 import org.apache.james.mailbox.jpa.mail.model.JPAMailbox;
036 import org.apache.james.mailbox.store.mail.model.Message;
037 import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder;
038 import org.apache.openjpa.persistence.Persistent;
039
040 /**
041 * JPA implementation of {@link AbstractJPAMessage} which use openjpas {@link Persistent} type to
042 * be able to stream the message content without loading it into the memory at all.
043 *
044 * This is not supported for all DB's yet. See <a href="http://openjpa.apache.org/builds/latest/docs/manual/ref_guide_mapping_jpa.html">Additional JPA Mappings</a>
045 *
046 * If your DB is not supported by this, use {@link JPAMessage}
047 *
048 * TODO: Fix me!
049 */
050 @Entity(name="Message")
051 @Table(name="JAMES_MAIL")
052 public class JPAStreamingMessage extends AbstractJPAMessage {
053
054 @SuppressWarnings("unused")
055 @Persistent(optional = false, fetch = FetchType.LAZY)
056 @Column(name = "MAIL_BYTES", length = 1048576000, nullable = false)
057 private InputStream body;
058
059 @SuppressWarnings("unused")
060 @Persistent(optional = false, fetch = FetchType.LAZY)
061 @Column(name = "HEADER_BYTES", length = 10485760, nullable = false)
062 private InputStream header;
063
064 private SharedInputStream content;
065
066 @Deprecated
067 public JPAStreamingMessage() {}
068
069 public JPAStreamingMessage(JPAMailbox mailbox, Date internalDate, int size, Flags flags, SharedInputStream content, int bodyStartOctet,final PropertyBuilder propertyBuilder) throws MailboxException {
070 super(mailbox, internalDate, flags, size ,bodyStartOctet, propertyBuilder);
071 this.content = content;
072
073 try {
074 this.header = getHeaderContent();
075 this.body = getBodyContent();
076
077 } catch (IOException e) {
078 throw new MailboxException("Unable to parse message",e);
079 }
080 }
081
082 /**
083 * Create a copy of the given message
084 *
085 * @param message
086 * @throws IOException
087 */
088 public JPAStreamingMessage(JPAMailbox mailbox, long uid, long modSeq, Message<?> message) throws MailboxException {
089 super(mailbox, uid, modSeq, message);
090 try {
091 this.content = new SharedByteArrayInputStream(IOUtils.toByteArray(message.getFullContent()));
092 this.header = getHeaderContent();
093 this.body = getBodyContent();
094 } catch (IOException e) {
095 throw new MailboxException("Unable to parse message",e);
096 }
097 }
098
099
100 /**
101 * @see org.apache.james.mailbox.store.mail.model.Message#getBodyContent()
102 */
103 public InputStream getBodyContent() throws IOException {
104 return content.newStream(getBodyStartOctet(), -1);
105 }
106
107 /**
108 * @see org.apache.james.mailbox.store.mail.model.Message#getHeaderContent()
109 */
110 public InputStream getHeaderContent() throws IOException {
111 int headerEnd = getBodyStartOctet() -2;
112 if (headerEnd < 0) {
113 headerEnd = 0;
114 }
115 return content.newStream(0, headerEnd);
116 }
117
118 }