Propchange: james/server/trunk/mailet-function/ ------------------------------------------------------------------------------ --- svn:ignore (added) +++ svn:ignore Wed Jul 16 14:34:15 2008 @@ -0,0 +1 @@ +.*
Added: james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalFetchBodyStructureTest.java URL: http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalFetchBodyStructureTest.java?rev=677437&view=auto ============================================================================== --- james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalFetchBodyStructureTest.java (added) +++ james/server/trunk/phoenix-deployment/src/test/org/apache/james/experimental/imapserver/ExperimentalFetchBodyStructureTest.java Wed Jul 16 14:34:15 2008 @@ -0,0 +1,30 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.experimental.imapserver; + +import org.apache.james.test.functional.imap.AbstractTestFetchBodyStructure; + +public class ExperimentalFetchBodyStructureTest extends AbstractTestFetchBodyStructure { + + public ExperimentalFetchBodyStructureTest() throws Exception { + super(HostSystemFactory.createStandardImap()); + } + +} Modified: james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTest.java URL: http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTest.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTest.java (original) +++ james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTest.java Wed Jul 16 14:34:15 2008 @@ -78,12 +78,6 @@ mr = MailboxRowPeer.retrieveByPK(mr.getMailboxId()); assertEquals(1, mr.getLastUid()); - List messageResult=IteratorUtils.toList(torqueMailbox.getMessages(MessageRangeImpl.oneUid(1l),FetchGroupImpl.MIME_MESSAGE, session)); - assertNotNull(messageResult); - assertEquals(1,messageResult.size()); - //((MessageResult)messageResult.get(0)).getMimeMessage().writeTo(System.out); - assertTrue(TorqueTestUtil.contentEquals(mm,((MessageResult)messageResult.get(0)).getMimeMessage(),true)); - Flags f=new Flags(); f.add(Flags.Flag.DELETED); torqueMailbox.setFlags(f,true,false, MessageRangeImpl.oneUid(1l), FetchGroupImpl.MINIMAL, session); Added: james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTestCase.java URL: http://svn.apache.org/viewvc/james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTestCase.java?rev=677437&view=auto ============================================================================== --- james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTestCase.java (added) +++ james/server/trunk/phoenix-deployment/src/test/org/apache/james/mailboxmanager/torque/TorqueMailboxTestCase.java Wed Jul 16 14:34:15 2008 @@ -0,0 +1,89 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailboxmanager.torque; + +import java.util.Date; +import java.util.List; + +import javax.mail.Flags; +import javax.mail.internet.MimeMessage; + +import org.apache.commons.collections.IteratorUtils; +import org.apache.james.mailboxmanager.MessageResult; +import org.apache.james.mailboxmanager.TestUtil; +import org.apache.james.mailboxmanager.impl.FetchGroupImpl; +import org.apache.james.mailboxmanager.impl.MessageRangeImpl; +import org.apache.james.mailboxmanager.impl.MailboxListenerCollector; +import org.apache.james.mailboxmanager.mailbox.Mailbox; +import org.apache.james.mailboxmanager.torque.om.MailboxRow; +import org.apache.james.mailboxmanager.torque.om.MailboxRowPeer; +import org.apache.james.mailboxmanager.torque.om.MessageRow; +import org.apache.james.mailboxmanager.torque.om.MessageRowPeer; +import org.apache.torque.TorqueException; +import org.apache.torque.util.Criteria; + +import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock; + +public class TorqueMailboxTestCase extends AbstractTorqueTestCase { + + public TorqueMailboxTestCase() throws TorqueException { + super(); + } + + public void testAppendGetDeleteMessage() throws Exception { + MailboxRow mr = new MailboxRow("#users.tuser.INBOX", 100); + mr.save(); + mr=MailboxRowPeer.retrieveByName("#users.tuser.INBOX"); + Mailbox torqueMailbox = new TorqueMailbox(mr, new WriterPreferenceReadWriteLock(),null); + torqueMailbox.addListener(new MailboxListenerCollector()); + assertEquals(0,torqueMailbox.getMessageCount(session)); + + long time = System.currentTimeMillis(); + time = time - (time % 1000); + Date date = new Date(time); + MimeMessage mm=TestUtil.createMessage(); + Flags flags=new Flags(); + flags.add(Flags.Flag.ANSWERED); + flags.add(Flags.Flag.SEEN); + mm.setFlags(flags,true); + mm.writeTo(System.out); + torqueMailbox.appendMessage(mm, date, FetchGroupImpl.MINIMAL, session); + assertEquals(1,torqueMailbox.getMessageCount(session)); + List l = MessageRowPeer.doSelect(new Criteria()); + assertEquals(1, l.size()); + MessageRow msg = (MessageRow) l.get(0); + assertEquals(mr.getMailboxId(), msg.getMailboxId()); + assertEquals(1, msg.getUid()); + + assertEquals(date, msg.getInternalDate()); + assertEquals(flags, msg.getMessageFlags().getFlagsObject()); + + mr = MailboxRowPeer.retrieveByPK(mr.getMailboxId()); + assertEquals(1, mr.getLastUid()); + + Flags f=new Flags(); + f.add(Flags.Flag.DELETED); + torqueMailbox.setFlags(f,true,false, MessageRangeImpl.oneUid(1l), FetchGroupImpl.MINIMAL, session); + List messageResults=IteratorUtils.toList(torqueMailbox.expunge(MessageRangeImpl.all(),FetchGroupImpl.MINIMAL, session)); + assertEquals(1,messageResults.size()); + assertEquals(1l,((MessageResult)messageResults.get(0)).getUid()); + } + +} Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MessageRowUtils.java Wed Jul 16 14:34:15 2008 @@ -118,10 +118,6 @@ messageResult.setUid(messageRow.getUid()); if (fetchGroup != null) { int content = fetchGroup.content(); - if ((content & FetchGroup.MIME_MESSAGE) > 0) { - messageResult.setMimeMessage(TorqueMimeMessage.createMessage(messageRow)); - content -= FetchGroup.MIME_MESSAGE; - } if ((content & FetchGroup.FLAGS) > 0) { org.apache.james.mailboxmanager.torque.om.MessageFlags messageFlags = messageRow.getMessageFlags(); @@ -150,6 +146,10 @@ addFullContent(messageRow, messageResult); content -= FetchGroup.FULL_CONTENT; } + if ((content & FetchGroup.MIME_DESCRIPTOR) > 0) { + addMimeDescriptor(messageRow, messageResult); + content -= FetchGroup.MIME_DESCRIPTOR; + } if (content != 0) { throw new TorqueException("Unsupported result: " + content); } @@ -162,6 +162,15 @@ return messageResult; } + private static void addMimeDescriptor(MessageRow messageRow, MessageResultImpl messageResult) throws TorqueException { + try { + MessageResult.MimeDescriptor descriptor = MimeDescriptorImpl.build(toInput(messageRow)); + messageResult.setMimeDescriptor(descriptor); + } catch (IOException e) { + throw new TorqueException("Cannot parse message", e); + } + } + private static void addFullContent(final MessageRow messageRow, MessageResultImpl messageResult) throws TorqueException, MailboxManagerException { final List headers = messageResult.getHeaders(); final Content content = createFullContent(messageRow, headers); @@ -214,9 +223,15 @@ final InputStream stream = toInput(row); PartContentBuilder result = new PartContentBuilder(); result.parse(stream); - for (int i = 0; i < path.length; i++) { - final int next = path[i]; - result.to(next); + try { + for (int i = 0; i < path.length; i++) { + final int next = path[i]; + result.to(next); + } + } catch (PartContentBuilder.PartNotFoundException e) { + // Missing parts should return zero sized content + // See http://markmail.org/message/2jconrj7scvdi5dj + result.markEmpty(); } return result; } Added: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java?rev=677437&view=auto ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java (added) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/MimeDescriptorImpl.java Wed Jul 16 14:34:15 2008 @@ -0,0 +1,206 @@ +/**************************************************************** + * Licensed to the Apache Software Foundation (ASF) under one * + * or more contributor license agreements. See the NOTICE file * + * distributed with this work for additional information * + * regarding copyright ownership. The ASF licenses this file * + * to you under the Apache License, Version 2.0 (the * + * "License"); you may not use this file except in compliance * + * with the License. You may obtain a copy of the License at * + * * + * http://www.apache.org/licenses/LICENSE-2.0 * + * * + * Unless required by applicable law or agreed to in writing, * + * software distributed under the License is distributed on an * + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * + * KIND, either express or implied. See the License for the * + * specific language governing permissions and limitations * + * under the License. * + ****************************************************************/ + +package org.apache.james.mailboxmanager.torque; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.apache.james.mailboxmanager.MessageResult; +import org.apache.james.mailboxmanager.MessageResult.MimeDescriptor; +import org.apache.james.mime4j.MaximalBodyDescriptor; +import org.apache.james.mime4j.MimeException; +import org.apache.james.mime4j.MimeTokenStream; + +public class MimeDescriptorImpl implements MessageResult.MimeDescriptor { + + public static MimeDescriptorImpl build(final InputStream stream) throws IOException { + final MimeTokenStream parser = MimeTokenStream.createMaximalDescriptorStream(); + parser.parse(stream); + int next = parser.next(); + while (next != MimeTokenStream.T_BODY && next != MimeTokenStream.T_END_OF_STREAM) { + next = parser.next(); + } + + if (next == MimeTokenStream.T_END_OF_STREAM) { + throw new MimeException("Premature end of stream"); + } + + MaximalBodyDescriptor descriptor = (MaximalBodyDescriptor) parser.getBodyDescriptor(); + final InputStream body = parser.getInputStream(); + long bodyOctets = 0; + long lines = 0; + for (int n=body.read();n>=0;n=body.read()) { + if (n == '\r') { + lines++; + } + bodyOctets++; + } + + final String contentDescription = descriptor.getContentDescription(); + final String contentId = descriptor.getContentId(); + + final String subType = descriptor.getSubType(); + final String type = descriptor.getMediaType(); + final String transferEncoding = descriptor.getTransferEncoding(); + final Collection headers = new ArrayList(); + final Collection contentTypeParameters = new ArrayList(); + final Map valuesByName = descriptor.getContentTypeParameters(); + for (final Iterator it=valuesByName.keySet().iterator(); it.hasNext(); ) { + final String name = (String) it.next(); + final String value = (String) valuesByName.get(name); + contentTypeParameters.add(new Header(name, value)); + } + final String codeset = descriptor.getCharset(); + Header header; + if (codeset == null) { + if ("TEXT".equals(type)) { + header = new Header("charset", "us-ascii"); + } else { + header = null; + } + } else { + header = new Header("charset", codeset); + } + if (header != null) { + contentTypeParameters.add(header); + } + final List languages = descriptor.getContentLanguage(); + final String disposition = descriptor.getContentDispositionType(); + final Map dispositionParams = descriptor.getContentDispositionParameters(); + final MessageResult.MimeDescriptor embeddedMessage = null; + final Collection parts = new ArrayList(); + final String location = descriptor.getContentLocation(); + final String md5 = descriptor.getContentMD5Raw(); + return new MimeDescriptorImpl(bodyOctets, contentDescription, contentId, lines, subType, type, transferEncoding, + headers, contentTypeParameters, languages, disposition, dispositionParams, embeddedMessage, parts, + location, md5); + } + + private final long bodyOctets; + private final String contentDescription; + private final String contentId; + private final long lines; + private final String subType; + private final String type; + private final String transferEncoding; + private final List languages; + private final Collection headers; + private final Collection contentTypeParameters; + private final String disposition; + private final Map dispositionParams; + private final MessageResult.MimeDescriptor embeddedMessage; + private final Collection parts; + private final String location; + private final String md5; + + public MimeDescriptorImpl(final long bodyOctets, final String contentDescription, final String contentId, + final long lines, final String subType, final String type, final String transferEncoding, final Collection headers, + final Collection contentTypeParameters, final List languages, String disposition, Map dispositionParams, + final MimeDescriptor embeddedMessage, final Collection parts, final String location, + final String md5) { + super(); + this.type = type; + this.bodyOctets = bodyOctets; + this.contentDescription = contentDescription; + this.contentId = contentId; + this.lines = lines; + this.subType = subType; + this.transferEncoding = transferEncoding; + this.headers = headers; + this.contentTypeParameters = contentTypeParameters; + this.embeddedMessage = embeddedMessage; + this.parts = parts; + this.languages = languages; + this.disposition = disposition; + this.dispositionParams = dispositionParams; + this.location = location; + this.md5 = md5; + } + + public Iterator contentTypeParameters() { + return contentTypeParameters.iterator(); + } + + public MessageResult.MimeDescriptor embeddedMessage() { + return embeddedMessage; + } + + public long getBodyOctets() { + return bodyOctets; + } + + public String getContentDescription() { + return contentDescription; + } + + public String getContentID() { + return contentId; + } + + public long getLines() { + return lines; + } + + public String getMimeSubType() { + return subType; + } + + public String getMimeType() { + return type; + } + + public String getTransferContentEncoding() { + return transferEncoding; + } + + public Iterator headers() { + return headers.iterator(); + } + + public Iterator parts() { + return parts.iterator(); + } + + public List getLanguages() { + return languages; + } + + public String getDisposition() { + return disposition; + } + + public Map getDispositionParams() { + return dispositionParams; + } + + public String getContentLocation() { + return location; + } + + public String getContentMD5() { + return md5; + } + +} Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/PartContentBuilder.java Wed Jul 16 14:34:15 2008 @@ -22,6 +22,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import org.apache.james.mailboxmanager.MessageResult.Content; @@ -30,12 +31,19 @@ public class PartContentBuilder { + private static final byte[] EMPTY = {}; + private MimeTokenStream parser; + private boolean empty = false; public PartContentBuilder() { parser = new MimeTokenStream(); } + public void markEmpty() { + empty = true; + } + public void parse(final InputStream in) { parser.setRecursionMode(MimeTokenStream.M_RECURSE); parser.parse(in); @@ -46,6 +54,11 @@ for (int count=0;count<position;) { final int state = parser.next(); switch (state) { + case MimeTokenStream.T_BODY: + if (position == 1) { + count++; + } + break; case MimeTokenStream.T_START_BODYPART: count++; break; @@ -60,7 +73,7 @@ } } catch (IllegalStateException e) { - throw new MimeException("Cannot find part " + position, e); + throw new PartNotFoundException(position, e); } } @@ -89,16 +102,21 @@ } private byte[] messageBodyContent() throws IOException, MimeException { - advancedToMessage(); - parser.setRecursionMode(MimeTokenStream.M_FLAT); - for ( int state = parser.getState(); - state != MimeTokenStream.T_BODY && state != MimeTokenStream.T_START_MULTIPART; - state = parser.next()) { - if (state == MimeTokenStream.T_END_OF_STREAM) { - throw new IOException("Unexpected EOF"); + final byte[] content; + if (empty) { + content = EMPTY; + } else { + advancedToMessage(); + parser.setRecursionMode(MimeTokenStream.M_FLAT); + for ( int state = parser.getState(); + state != MimeTokenStream.T_BODY && state != MimeTokenStream.T_START_MULTIPART; + state = parser.next()) { + if (state == MimeTokenStream.T_END_OF_STREAM) { + throw new IOException("Unexpected EOF"); + } } + content = MessageUtils.toByteArray(parser.getInputStream()); } - final byte[] content = MessageUtils.toByteArray(parser.getInputStream()); return content; } @@ -108,51 +126,67 @@ } private byte[] mimeBodyContent() throws IOException, MimeException { - parser.setRecursionMode(MimeTokenStream.M_FLAT); - for ( int state = parser.getState(); - state != MimeTokenStream.T_BODY && state != MimeTokenStream.T_START_MULTIPART; - state = parser.next()) { - if (state == MimeTokenStream.T_END_OF_STREAM) { - throw new IOException("Unexpected EOF"); + final byte[] content; + if (empty) { + content = EMPTY; + } else { + parser.setRecursionMode(MimeTokenStream.M_FLAT); + for ( int state = parser.getState(); + state != MimeTokenStream.T_BODY && state != MimeTokenStream.T_START_MULTIPART; + state = parser.next()) { + if (state == MimeTokenStream.T_END_OF_STREAM) { + throw new IOException("Unexpected EOF"); + } } + content = MessageUtils.toByteArray(parser.getInputStream()); } - final byte[] content = MessageUtils.toByteArray(parser.getInputStream()); + String temp = new String(content); return content; } public List getMimeHeaders() throws IOException, MimeException { - final List results = new ArrayList(); - for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser.next()) { - switch (state) { - case MimeTokenStream.T_END_OF_STREAM: - throw new IOException("Unexpected EOF"); - - case MimeTokenStream.T_FIELD: - final String fieldValue = parser.getFieldValue().trim(); - final String fieldName = parser.getFieldName(); - Header header = new Header(fieldName, fieldValue); - results.add(header); - break; + final List results; + if (empty) { + results = Collections.EMPTY_LIST; + } else { + results = new ArrayList(); + for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser.next()) { + switch (state) { + case MimeTokenStream.T_END_OF_STREAM: + throw new IOException("Unexpected EOF"); + + case MimeTokenStream.T_FIELD: + final String fieldValue = parser.getFieldValue().trim(); + final String fieldName = parser.getFieldName(); + Header header = new Header(fieldName, fieldValue); + results.add(header); + break; + } } } return results; } public List getMessageHeaders() throws IOException, MimeException { - advancedToMessage(); - - final List results = new ArrayList(); - for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser.next()) { - switch (state) { - case MimeTokenStream.T_END_OF_STREAM: - throw new IOException("Unexpected EOF"); - - case MimeTokenStream.T_FIELD: - final String fieldValue = parser.getFieldValue().trim(); - final String fieldName = parser.getFieldName(); - Header header = new Header(fieldName, fieldValue); - results.add(header); - break; + final List results; + if (empty) { + results = Collections.EMPTY_LIST; + } else { + advancedToMessage(); + + results = new ArrayList(); + for (int state = parser.getState(); state != MimeTokenStream.T_END_HEADER; state = parser.next()) { + switch (state) { + case MimeTokenStream.T_END_OF_STREAM: + throw new IOException("Unexpected EOF"); + + case MimeTokenStream.T_FIELD: + final String fieldValue = parser.getFieldValue().trim(); + final String fieldName = parser.getFieldName(); + Header header = new Header(fieldName, fieldValue); + results.add(header); + break; + } } } return results; @@ -173,7 +207,11 @@ private final int position; public PartNotFoundException(int position) { - super("Part " + position + " not found."); + this(position, null); + } + + public PartNotFoundException(int position, Exception e) { + super("Part " + position + " not found.", e); this.position = position; } Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailbox.java Wed Jul 16 14:34:15 2008 @@ -41,10 +41,10 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.impl.AvalonLogger; -import org.apache.james.mailboxmanager.MessageRange; import org.apache.james.mailboxmanager.MailboxListener; import org.apache.james.mailboxmanager.MailboxManagerException; import org.apache.james.mailboxmanager.MailboxSession; +import org.apache.james.mailboxmanager.MessageRange; import org.apache.james.mailboxmanager.MessageResult; import org.apache.james.mailboxmanager.SearchQuery; import org.apache.james.mailboxmanager.MessageResult.FetchGroup; @@ -168,8 +168,13 @@ } private void populateFlags(MimeMessage message, MessageRow messageRow) throws MessagingException, TorqueException { + final Flags flags = message.getFlags(); + buildFlags(messageRow, flags); + } + + private void buildFlags(MessageRow messageRow, final Flags flags) throws TorqueException { MessageFlags messageFlags = new MessageFlags(); - messageFlags.setFlags(message.getFlags()); + messageFlags.setFlags(flags); messageRow.addMessageFlags(messageFlags); } @@ -210,7 +215,7 @@ return size; } - private void save(MessageRow messageRow) throws Exception { + private void save(MessageRow messageRow) throws TorqueException, InterruptedException { try { lock.writeLock().acquire(); messageRow.save(); @@ -708,6 +713,76 @@ super.enableLogging(logger); setLog(new AvalonLogger(logger)); } + + public void copyTo(MessageRange set, TorqueMailbox toMailbox, MailboxSession session) throws MailboxManagerException { + try { + lock.readLock().acquire(); + try { + checkAccess(); + try { + Criteria c = criteriaForMessageSet(set); + c.add(MessageFlagsPeer.MAILBOX_ID,getMailboxRow().getMailboxId()); + List rows = MessageRowPeer.doSelectJoinMessageFlags(c); + toMailbox.copy(rows, session); + } catch (TorqueException e) { + throw new MailboxManagerException(e); + } catch (MessagingException e) { + throw new MailboxManagerException(e); + } + } finally { + lock.readLock().release(); + } + } catch (InterruptedException e) { + throw new MailboxManagerException(e); + } + } - -} + private void copy(List rows, MailboxSession session) throws MailboxManagerException { + try { + for (Iterator iter = rows.iterator(); iter.hasNext();) { + MessageRow fromRow = (MessageRow) iter.next(); + final MailboxRow mailbox = reserveNextUid(); + + if (mailbox != null) { + // To be thread safe, we first get our own copy and the + // exclusive + // Uid + // TODO create own message_id and assign uid later + // at the moment it could lead to the situation that uid 5 is + // inserted long before 4, when + // mail 4 is big and comes over a slow connection. + long uid = mailbox.getLastUid(); + this.mailboxRow = mailbox; + + MessageRow newRow = new MessageRow(); + newRow.setMailboxId(getMailboxRow().getMailboxId()); + newRow.setUid(uid); + newRow.setInternalDate(fromRow.getInternalDate()); + newRow.setSize(fromRow.getSize()); + buildFlags(newRow, fromRow.getMessageFlags().getFlagsObject()); + + final List headers = fromRow.getMessageHeaders(); + for (Iterator iterator = headers.iterator(); iterator.hasNext();) { + final MessageHeader fromHeader = (MessageHeader) iterator.next(); + final MessageHeader newHeader = new MessageHeader(fromHeader.getField(), fromHeader.getValue(), fromHeader.getLineNumber()); + newRow.addMessageHeader(newHeader); + } + + MessageBody mb = new MessageBody(fromRow.getBodyContent()); + newRow.addMessageBody(mb); + + save(newRow); + MessageResult messageResult = fillMessageResult(newRow, FetchGroupImpl.MINIMAL); + getUidChangeTracker().found(messageResult); + } + } + } + catch (TorqueException e) { + throw new MailboxManagerException(e); + } catch (InterruptedException e) { + throw new MailboxManagerException(e); + } catch (MessagingException e) { + throw new MailboxManagerException(e); + } + } +} \ No newline at end of file Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueMailboxManager.java Wed Jul 16 14:34:15 2008 @@ -27,20 +27,15 @@ import java.util.Map; import java.util.Random; -import javax.mail.internet.MimeMessage; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.impl.SimpleLog; -import org.apache.james.mailboxmanager.MessageRange; import org.apache.james.mailboxmanager.ListResult; import org.apache.james.mailboxmanager.MailboxExistsException; import org.apache.james.mailboxmanager.MailboxManagerException; import org.apache.james.mailboxmanager.MailboxNotFoundException; import org.apache.james.mailboxmanager.MailboxSession; -import org.apache.james.mailboxmanager.MessageResult; -import org.apache.james.mailboxmanager.MessageResult.FetchGroup; -import org.apache.james.mailboxmanager.impl.FetchGroupImpl; +import org.apache.james.mailboxmanager.MessageRange; import org.apache.james.mailboxmanager.impl.ListResultImpl; import org.apache.james.mailboxmanager.mailbox.Mailbox; import org.apache.james.mailboxmanager.manager.MailboxExpression; @@ -52,11 +47,10 @@ import org.apache.torque.util.Criteria; import EDU.oswego.cs.dl.util.concurrent.ReadWriteLock; -import EDU.oswego.cs.dl.util.concurrent.WriterPreferenceReadWriteLock; +import EDU.oswego.cs.dl.util.concurrent.ReentrantWriterPreferenceReadWriteLock; public class TorqueMailboxManager implements MailboxManager { - private static final FetchGroupImpl FROM_FETCH_GROUP = new FetchGroupImpl(FetchGroup.MIME_MESSAGE | FetchGroup.INTERNAL_DATE); private static final char SQL_WILDCARD_CHAR = '%'; private final static Random random = new Random(); @@ -67,12 +61,16 @@ private final Map managers; public TorqueMailboxManager() { - this.lock = new WriterPreferenceReadWriteLock(); + this.lock = new ReentrantWriterPreferenceReadWriteLock(); managers = new HashMap(); } public Mailbox getMailbox(String mailboxName, boolean autoCreate) throws MailboxManagerException { + return doGetMailbox(mailboxName, autoCreate); + } + + private TorqueMailbox doGetMailbox(String mailboxName, boolean autoCreate) throws MailboxManagerException { if (autoCreate && !existsMailbox(mailboxName)) { getLog().info("autocreated mailbox " + mailboxName); createMailbox(mailboxName); @@ -85,7 +83,7 @@ if (mailboxRow != null) { getLog().debug("Loaded mailbox "+mailboxName); - Mailbox torqueMailbox = (Mailbox) managers.get(mailboxName); + TorqueMailbox torqueMailbox = (TorqueMailbox) managers.get(mailboxName); if (torqueMailbox == null) { torqueMailbox = new TorqueMailbox(mailboxRow, lock, getLog()); managers.put(mailboxName, torqueMailbox); @@ -206,14 +204,9 @@ } public void copyMessages(MessageRange set, String from, String to, MailboxSession session) throws MailboxManagerException { - Mailbox toMailbox= getMailbox(to, false); - Mailbox fromMailbox = getMailbox(from, false); - Iterator it = fromMailbox.getMessages(set, FROM_FETCH_GROUP, session); - while (it.hasNext()) { - final MessageResult result = (MessageResult) it.next(); - final MimeMessage mimeMessage = result.getMimeMessage(); - toMailbox.appendMessage(mimeMessage, result.getInternalDate(), FetchGroupImpl.MINIMAL, session); - } + TorqueMailbox toMailbox= doGetMailbox(to, false); + TorqueMailbox fromMailbox = doGetMailbox(from, false); + fromMailbox.copyTo(set, toMailbox, session); } public ListResult[] list(final MailboxExpression mailboxExpression) throws MailboxManagerException { Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueResultIterator.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueResultIterator.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueResultIterator.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/TorqueResultIterator.java Wed Jul 16 14:34:15 2008 @@ -152,7 +152,7 @@ return 0; } - public Iterator iterateHeaders() throws MailboxManagerException { + public Iterator headers() throws MailboxManagerException { throw exception; } @@ -186,6 +186,10 @@ public Content getMimeBody(MimePath path) throws MailboxManagerException { throw exception; } + + public MimeDescriptor getMimeDescriptor() throws MailboxManagerException { + throw exception; + } } } Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/BaseMessageRow.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/BaseMessageRow.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/BaseMessageRow.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/BaseMessageRow.java Wed Jul 16 14:34:15 2008 @@ -1212,7 +1212,7 @@ * * @throws Exception */ - public void save() throws Exception + public void save() throws TorqueException { save(MessageRowPeer.DATABASE_NAME); } Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageHeader.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageHeader.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageHeader.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageHeader.java Wed Jul 16 14:34:15 2008 @@ -47,4 +47,11 @@ setField(field); setValue(value); } + + public MessageHeader(final String field, final String value, int position) { + super(); + setField(field); + setValue(value); + setLineNumber(position); + } } Modified: james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageRow.java URL: http://svn.apache.org/viewvc/james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageRow.java?rev=677437&r1=677436&r2=677437&view=diff ============================================================================== --- james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageRow.java (original) +++ james/server/trunk/torque-mailboxmanager-function/src/main/java/org/apache/james/mailboxmanager/torque/om/MessageRow.java Wed Jul 16 14:34:15 2008 @@ -44,6 +44,8 @@ */ private static final long serialVersionUID = -75081490028686786L; + public MessageRow() {} + public MessageFlags getMessageFlags() throws TorqueException { MessageFlags mf =null; List l = getMessageFlagss(); --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]