You are viewing a plain text version of this content. The canonical link for it is here.
Posted to server-dev@james.apache.org by no...@apache.org on 2009/10/29 14:24:17 UTC

svn commit: r830933 [1/4] - in /james/hupa/trunk: ./ client/src/main/java/org/apache/hupa/client/mvp/ client/src/main/java/org/apache/hupa/client/widgets/ server/src/main/java/org/apache/hupa/server/ server/src/main/java/org/apache/hupa/server/guice/ s...

Author: norman
Date: Thu Oct 29 13:24:15 2009
New Revision: 830933

URL: http://svn.apache.org/viewvc?rev=830933&view=rev
Log:
Commit patch for HUPA-44. Increased test coverage, added msg fixtures, many fixes. Thx to Manuel Carrasco!

Added:
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/HasURL.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/Iframe.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPFolder.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPStore.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockSMTPTransport.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/HupaDispatchServlet.java
    james/hupa/trunk/server/src/main/resources/
    james/hupa/trunk/server/src/main/resources/mime/
    james/hupa/trunk/server/src/main/resources/mime/0.msg
    james/hupa/trunk/server/src/main/resources/mime/1.msg
    james/hupa/trunk/server/src/main/resources/mime/2.msg
    james/hupa/trunk/server/src/main/resources/mime/3.msg
    james/hupa/trunk/server/src/main/resources/mime/4.msg
    james/hupa/trunk/server/src/main/resources/mime/5.msg
    james/hupa/trunk/server/src/main/resources/mime/6.msg
    james/hupa/trunk/server/src/main/resources/mime/7.msg
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/DemoModeTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/FetchMessagesHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/GetMessageDetailsHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/servlet/
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/servlet/DownloadAttachmentServletTest.java
Removed:
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/DemoModeIMAPStore.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/DemoModeSMTPTransport.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/mock/MockIMAPFolder.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/mock/MockIMAPStore.java
Modified:
    james/hupa/trunk/.classpath
    james/hupa/trunk/README.txt
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessagePresenter.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageView.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/InMemoryIMAPStoreCache.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DispatchServletModule.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/ServerModul.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractFetchMessagesHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/FetchFoldersHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetMessageDetailsHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/JavamailUtil.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/DownloadAttachmentServlet.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/ServerModulTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbstractHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/CreateFolderHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/DeleteFolderHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/DeleteMessageByUidHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/FetchFoldersHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/LoginUserHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/LogoutUserHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/NoopHandlerTest.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/Util.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/Message.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/MessageDetails.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/rpc/FetchFoldersResult.java

Modified: james/hupa/trunk/.classpath
URL: http://svn.apache.org/viewvc/james/hupa/trunk/.classpath?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/.classpath (original)
+++ james/hupa/trunk/.classpath Thu Oct 29 13:24:15 2009
@@ -6,8 +6,9 @@
 	<classpathentry kind="src" output="widgets/target/classes" path="widgets/src/main/java"/>
 	<classpathentry kind="src" output="client/war/WEB-INF/classes" path="client/src/main/java"/>
 	<classpathentry excluding="**" kind="src" output="client/war/WEB-INF/classes" path="client/src/main/resources"/>
+	<classpathentry kind="src" output="client/war/WEB-INF/classes" path="server/src/main/resources"/>
 	<classpathentry kind="con" path="com.google.gwt.eclipse.core.GWT_CONTAINER"/>
 	<classpathentry kind="con" path="org.maven.ide.eclipse.MAVEN2_CLASSPATH_CONTAINER"/>
 	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
-	<classpathentry kind="output" path="target/classes"/>
+	<classpathentry kind="output" path="war/WEB-INF/classes"/>
 </classpath>

Modified: james/hupa/trunk/README.txt
URL: http://svn.apache.org/viewvc/james/hupa/trunk/README.txt?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/README.txt (original)
+++ james/hupa/trunk/README.txt Thu Oct 29 13:24:15 2009
@@ -4,6 +4,28 @@
 
 * mvn clean package
 
+###### Configuring server side  ################
+
+Hupa uses a properties file to know the IMAP and SMTP servers configuration.
+There is an example configuration file in 'server/src/main/webapp/WEB-INF/conf/config.properties'
+
+- You can put your configuration parameters in either of these files:
+  $HOME/.hupa/config.properties
+  /etc/default/hupa
+- Or anywhere if you start your application server with the parameter:
+  -Dhupa.config.file=full_path_to_your_properties_file
+
+###### Using hupa in demo mode #################
+
+In demo mode there is not necessary any imap or smtp server.
+A bunch of example messages and folders are shown to the useri to be manipulated.
+Almost every hupa feature work in demo mode.
+
+To enable demo mode for incomming messages set 'IMAPServerAddress=demo-mode' and
+'SMTPServerAddress=demo-mode' for outgoing messages.
+
+To login into the system in thi mode use the user 'demo' with password 'demo'  
+
 ###### Eclipse GWT Plugin notes ################
 
 - If you want to run hupa in hosted mode be sure to add the following line as "vm argument" in the Run configuration:

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageListView.java Thu Oct 29 13:24:15 2009
@@ -376,8 +376,12 @@
             
             dispatcher.execute(new FetchMessages(folder, request.getStartRow(), request.getNumRows(),searchValue),new HupaCallback<FetchMessagesResult>(dispatcher, eventBus) {
                 public void callback(final FetchMessagesResult result) {
-                    eventBus.fireEvent(new MessagesReceivedEvent(folder,result.getMessages()));
-                     TableModelHelper.Response<Message> response = new TableModelHelper.Response<Message>() {
+                	// Update folder information before notifying presenter
+                	folder.setMessageCount(result.getRealCount());
+                	folder.setUnseenMessageCount(result.getRealUnreadCount());
+                	// Notify presenter to update folder tree view
+                    eventBus.fireEvent(new MessagesReceivedEvent(folder, result.getMessages()));
+                    TableModelHelper.Response<Message> response = new TableModelHelper.Response<Message>() {
                         @Override
                         public Iterator<Message> getRowValues() {
                             return result.getMessages().iterator();

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessagePresenter.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessagePresenter.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessagePresenter.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessagePresenter.java Thu Oct 29 13:24:15 2009
@@ -31,6 +31,7 @@
 import org.apache.hupa.client.CachingDispatchAsync;
 import org.apache.hupa.client.HupaCallback;
 import org.apache.hupa.client.widgets.HasDialog;
+import org.apache.hupa.client.widgets.HasURL;
 import org.apache.hupa.shared.Util;
 import org.apache.hupa.shared.data.IMAPFolder;
 import org.apache.hupa.shared.data.Message;
@@ -62,8 +63,8 @@
         public HasText getCc();
 
         public HasText getSubject();
-        public Frame getShowRawMessageFrame();
-        public HasDialog getShowRawMessageDialog();
+        public HasURL getRawMessageURL();
+        public HasDialog getRawMessageDialog();
         public HasHTML getContent();
         public HasClickHandlers getShowRawMessageClick();
         public HasClickHandlers getDeleteButtonClick();
@@ -106,8 +107,10 @@
         display.getTo().setText(Util.arrayToString(message.getTo()));
         display.getSubject().setText(message.getSubject());
         String con = messageDetails.getText();
+        // TODO: do this in the server so it is easier to test.
+        // The server should send all the messages as html.
         if (messageDetails.isHTML() == false) {
-            con = Util.toHtml(con);
+        	con = "<pre>" + Util.escapeHtmlTags(con) + "</pre>";
         }
         display.getContent().setHTML(con);
         display.setAttachments(messageDetails.getMessageAttachments(), folder.getFullName(),message.getUid());
@@ -168,8 +171,8 @@
 
             public void onClick(ClickEvent event) {
                 String message_url = "/hupa/messageSourceServlet?uid=" + message.getUid() + "&folder=" + folder.getFullName();
-                display.getShowRawMessageFrame().setUrl(message_url);
-                display.getShowRawMessageDialog().center();
+                display.getRawMessageURL().setUrl(message_url);
+                display.getRawMessageDialog().center();
             }
             
         }));

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageView.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageView.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageView.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/IMAPMessageView.java Thu Oct 29 13:24:15 2009
@@ -25,6 +25,8 @@
 import org.apache.hupa.client.bundles.HupaImageBundle;
 import org.apache.hupa.client.mvp.IMAPMessagePresenter.Display;
 import org.apache.hupa.client.widgets.HasDialog;
+import org.apache.hupa.client.widgets.HasURL;
+import org.apache.hupa.client.widgets.Iframe;
 import org.apache.hupa.client.widgets.Loading;
 import org.apache.hupa.client.widgets.MyDialogBox;
 import org.apache.hupa.shared.data.MessageAttachment;
@@ -41,7 +43,6 @@
 import com.google.gwt.user.client.Window;
 import com.google.gwt.user.client.ui.Composite;
 import com.google.gwt.user.client.ui.FlowPanel;
-import com.google.gwt.user.client.ui.Frame;
 import com.google.gwt.user.client.ui.Grid;
 import com.google.gwt.user.client.ui.HTML;
 import com.google.gwt.user.client.ui.HasHTML;
@@ -73,7 +74,7 @@
     private Hyperlink backButton = new Hyperlink(constants.backButton(),"");
     private FlowPanel attachments = new FlowPanel();
     private MyDialogBox rawDialogBox = new MyDialogBox();
-    private Frame rawFrame = new Frame();
+    private Iframe rawFrame = new Iframe();
     public final static int DELETE_BUTTON = 0;
     public final static int REPLY_BUTTON = 1;
     public final static int REPLY_ALL_BUTTON = 2;
@@ -264,11 +265,11 @@
         return showRawButton;
     }
 
-    public HasDialog getShowRawMessageDialog() {
+    public HasDialog getRawMessageDialog() {
         return rawDialogBox;
     }
 
-    public Frame getShowRawMessageFrame() {
+    public HasURL getRawMessageURL() {
         return rawFrame;
     }
     

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MainPresenter.java Thu Oct 29 13:24:15 2009
@@ -416,11 +416,6 @@
         registerHandler(eventBus.addHandler(DecreaseUnseenEvent.TYPE, new DecreaseUnseenEventHandler() {
 
             public void onDecreaseUnseenEvent(DecreaseUnseenEvent event) {
-                // Check if the folder was the trash folder. If not increase the
-                // message count of the trash folder
-                if (user.getSettings().getTrashFolderName().equalsIgnoreCase(event.getFolder().getFullName()) == false) {
-                    display.increaseUnseenMessageCount(new IMAPFolder(user.getSettings().getTrashFolderName()), event.getAmount());
-                }
                 display.decreaseUnseenMessageCount(event.getFolder(), event.getAmount());
             }
 

Added: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/HasURL.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/HasURL.java?rev=830933&view=auto
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/HasURL.java (added)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/HasURL.java Thu Oct 29 13:24:15 2009
@@ -0,0 +1,25 @@
+/****************************************************************
+ * 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.hupa.client.widgets;
+
+public interface HasURL {
+    public String getUrl();
+    public void setUrl(String url);
+}

Added: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/Iframe.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/Iframe.java?rev=830933&view=auto
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/Iframe.java (added)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/widgets/Iframe.java Thu Oct 29 13:24:15 2009
@@ -0,0 +1,25 @@
+/****************************************************************
+ * 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.hupa.client.widgets;
+
+import com.google.gwt.user.client.ui.Frame;
+
+public class Iframe extends Frame implements HasURL {
+}

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/InMemoryIMAPStoreCache.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/InMemoryIMAPStoreCache.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/InMemoryIMAPStoreCache.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/InMemoryIMAPStoreCache.java Thu Oct 29 13:24:15 2009
@@ -28,6 +28,7 @@
 import javax.mail.Session;
 
 import org.apache.commons.logging.Log;
+import org.apache.hupa.server.mock.MockIMAPStore;
 import org.apache.hupa.shared.data.User;
 
 import com.google.inject.Inject;
@@ -116,7 +117,7 @@
     private CachedIMAPStore createCachedIMAPStore() throws NoSuchProviderException {
         CachedIMAPStore cstore;
         if (DEMO_MODE.equals(this.address)) {
-            cstore = new CachedIMAPStore(new DemoModeIMAPStore(session), 300);
+            cstore = new CachedIMAPStore(new MockIMAPStore(session), 300);
         } else if (useSSL) {
             cstore = new CachedIMAPStore((IMAPStore)session.getStore("imaps"),300);
         } else {

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DispatchServletModule.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DispatchServletModule.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DispatchServletModule.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/DispatchServletModule.java Thu Oct 29 13:24:15 2009
@@ -21,18 +21,17 @@
 
 
 import org.apache.hupa.server.servlet.DownloadAttachmentServlet;
+import org.apache.hupa.server.servlet.HupaDispatchServlet;
 import org.apache.hupa.server.servlet.MessageSourceServlet;
 import org.apache.hupa.server.servlet.UploadAttachmentServlet;
 
-import net.customware.gwt.dispatch.server.service.DispatchServiceServlet;
-
 import com.google.inject.servlet.ServletModule;
 
 
 public class DispatchServletModule extends ServletModule{
      @Override
         public void configureServlets() {
-             serve("/hupa/dispatch").with(DispatchServiceServlet.class );
+             serve("/hupa/dispatch").with(HupaDispatchServlet.class );
              serve("/hupa/downloadAttachmentServlet").with(DownloadAttachmentServlet.class);
              serve("/hupa/uploadAttachmentServlet").with(UploadAttachmentServlet.class);
              serve("/hupa/messageSourceServlet").with(MessageSourceServlet.class);

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/ServerModul.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/ServerModul.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/ServerModul.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/ServerModul.java Thu Oct 29 13:24:15 2009
@@ -28,7 +28,6 @@
 import net.customware.gwt.dispatch.server.guice.ActionHandlerModule;
 
 import org.apache.commons.logging.Log;
-import org.apache.hupa.server.DemoModeIMAPStore;
 import org.apache.hupa.server.FileItemRegistry;
 import org.apache.hupa.server.IMAPStoreCache;
 import org.apache.hupa.server.InMemoryIMAPStoreCache;
@@ -52,6 +51,7 @@
 import org.apache.hupa.server.handler.SendMessageHandler;
 import org.apache.hupa.server.handler.SetFlagsHandler;
 import org.apache.hupa.server.handler.TagMessagesHandler;
+import org.apache.hupa.server.mock.MockIMAPFolder;
 import org.apache.hupa.server.servlet.DownloadAttachmentServlet;
 import org.apache.hupa.server.servlet.MessageSourceServlet;
 import org.apache.hupa.server.servlet.UploadAttachmentServlet;
@@ -71,7 +71,8 @@
 
     public static final String[] CONFIG_PROPERTIES = {
             System.getenv("HOME") + "/.hupa/config.properties",
-            "/etc/default/hupa", "config.properties" };
+            "/etc/default/hupa"
+            };
     public static final String CONF_DIR = "WEB-INF" + File.separator + "conf" + File.separator;
 
     private String configDir;
@@ -117,12 +118,6 @@
         try {
             // Bind addresses and ports for imap and smtp
             properties = loadProperties();
-            // Configure default parameters for Hupa in demo mode
-            if (properties.get("IMAPServerAddress").equals(InMemoryIMAPStoreCache.DEMO_MODE)) {
-                properties.put("DefaultInboxFolder", DemoModeIMAPStore.DEMO_MODE_INBOX_FOLDER);
-                properties.put("DefaultTrashFolder", DemoModeIMAPStore.DEMO_MODE_TRASH_FOLDER);
-                properties.put("DefaultSentFolder", DemoModeIMAPStore.DEMO_MODE_SENT_FOLDER);
-            }
             Names.bindProperties(binder(), properties);
         } catch (Exception e) {
             throw new RuntimeException("Unable to to configure hupa server," +
@@ -142,13 +137,29 @@
 
         if (properties == null) {
             for (String name : CONFIG_PROPERTIES) {
-            
                 properties = loadProperties(name);
                 if (properties != null)
                     break;
             }
         }
 
+        // Configure default parameters for Hupa in demo mode
+        if (properties == null || InMemoryIMAPStoreCache.DEMO_MODE.equals(properties.get("IMAPServerAddress"))) {
+            properties = new Properties();
+			properties.put("IMAPServerAddress", InMemoryIMAPStoreCache.DEMO_MODE);
+			properties.put("IMAPServerPort", "143");
+			properties.put("IMAPS", "false");
+			properties.put("SMTPServerAddress", InMemoryIMAPStoreCache.DEMO_MODE);
+			properties.put("SMTPServerPort", "25");
+			properties.put("SMTPS", "false");
+			properties.put("SMTPAuth", "false");
+			
+			properties.put("DefaultInboxFolder", MockIMAPFolder.mockSettings.getInboxFolderName());
+			properties.put("DefaultTrashFolder", MockIMAPFolder.mockSettings.getTrashFolderName());
+			properties.put("DefaultSentFolder", MockIMAPFolder.mockSettings.getSentFolderName());
+			properties.put("PostFetchMessageCount", "0");
+        }
+        
         return properties;
     }
 
@@ -173,7 +184,7 @@
                 e.printStackTrace();
             }
         }
-
+        
         return properties;
     }
 

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractFetchMessagesHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractFetchMessagesHandler.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractFetchMessagesHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractFetchMessagesHandler.java Thu Oct 29 13:24:15 2009
@@ -82,9 +82,10 @@
             
             Message[] messages = getMessagesToConvert(f,action);
             
-            return new FetchMessagesResult(convert(action, f, messages),start,offset,exists,f.getUnreadMessageCount());
+            return new FetchMessagesResult(convert(offset, f, messages),start, offset,exists,f.getUnreadMessageCount());
             
         } catch (Exception e) {
+        	e.printStackTrace();
             logger.error("Error while fetching headers for user " + user.getName() + " in folder " + folder,e);
             throw new ActionException(
                     "Error while fetching headers for user " + user.getName() + " in folder " + folder);
@@ -102,17 +103,17 @@
     
     protected abstract Message[] getMessagesToConvert(com.sun.mail.imap.IMAPFolder f, A action) throws MessagingException;
     
-    protected ArrayList<org.apache.hupa.shared.data.Message> convert(FetchMessages action, com.sun.mail.imap.IMAPFolder f, Message[] messages) throws MessagingException {
+    protected ArrayList<org.apache.hupa.shared.data.Message> convert(int offset, com.sun.mail.imap.IMAPFolder folder, Message[] messages) throws MessagingException {
         ArrayList<org.apache.hupa.shared.data.Message> mList = new ArrayList<org.apache.hupa.shared.data.Message>();
         // Setup fetchprofile to limit the stuff which is fetched 
         FetchProfile fp = new FetchProfile();
         fp.add(FetchProfile.Item.ENVELOPE);
         fp.add(FetchProfile.Item.FLAGS);
         fp.add(FetchProfile.Item.CONTENT_INFO);
-        f.fetch(messages, fp);
-
+        folder.fetch(messages, fp);
+        
         // loop over the fetched messages
-        for (int i = 0; i < messages.length; i++) {
+        for (int i = 0; i < messages.length && i < offset; i++) {
             org.apache.hupa.shared.data.Message msg = new org.apache.hupa.shared.data.Message();
             Message m = messages[i];                
             String from = null;
@@ -162,7 +163,6 @@
 
             // Add flags
             ArrayList<IMAPFlag> iFlags = JavamailUtil.convert(m.getFlags());
-            
           
             ArrayList<Tag> tags = new ArrayList<Tag>();
             String[] userFlags = m.getFlags().getUserFlags();
@@ -173,15 +173,13 @@
                 }
             }
             
-            msg.setUid(f.getUID(m));
+            msg.setUid(folder.getUID(m));
             msg.setFlags(iFlags);
             msg.setTags(tags);
             msg.setHasAttachments(hasAttachment(m));
             
             mList.add(0, msg);
-            if (i > action.getOffset()) {
-                break;
-            }
+            
         }
         return mList;
     }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/AbstractSendMessageHandler.java Thu Oct 29 13:24:15 2009
@@ -49,10 +49,10 @@
 
 import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.logging.Log;
-import org.apache.hupa.server.DemoModeSMTPTransport;
 import org.apache.hupa.server.FileItemRegistry;
 import org.apache.hupa.server.IMAPStoreCache;
 import org.apache.hupa.server.InMemoryIMAPStoreCache;
+import org.apache.hupa.server.mock.MockSMTPTransport;
 import org.apache.hupa.shared.data.MessageAttachment;
 import org.apache.hupa.shared.data.SMTPMessage;
 import org.apache.hupa.shared.data.User;
@@ -179,7 +179,7 @@
         Transport transport;
     
         if (InMemoryIMAPStoreCache.DEMO_MODE.equals(address)) {
-            transport = new DemoModeSMTPTransport(session);
+            transport = new MockSMTPTransport(session);
         } else if (useSSL) {
             transport = session.getTransport("smtps");
         } else {

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/FetchFoldersHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/FetchFoldersHandler.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/FetchFoldersHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/FetchFoldersHandler.java Thu Oct 29 13:24:15 2009
@@ -68,13 +68,11 @@
             // loop over all folders
             for (int i = 0; i < folders.length; i++) {
                 Folder f = folders[i];
-
                 createIMAPFolderTree(fList, createFolder(f), f.list());
-                
             }
-            
             return new FetchFoldersResult(fList);
         } catch (Exception e) {
+            e.printStackTrace();
             logger.error("Unable to get folders for User " + user,e);
             throw new ActionException("Unable to get folders for User "
                     + user);
@@ -99,7 +97,7 @@
      */
     private IMAPFolder createFolder(Folder folder) {
 
-        String fullName = folder.getFullName();
+    	String fullName = folder.getFullName();
         String delimiter;
         IMAPFolder iFolder = null;
         
@@ -107,6 +105,8 @@
             delimiter = String.valueOf(folder.getSeparator());
             iFolder = new IMAPFolder(fullName);
             iFolder.setDelimiter(delimiter);
+            if("[Gmail]".equals(folder.getFullName()))
+            	return iFolder;
             iFolder.setMessageCount(folder.getMessageCount());
             iFolder.setSubscribed(folder.isSubscribed());
             iFolder.setUnseenMessageCount(folder.getUnreadMessageCount());

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetMessageDetailsHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetMessageDetailsHandler.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetMessageDetailsHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetMessageDetailsHandler.java Thu Oct 29 13:24:15 2009
@@ -93,25 +93,16 @@
             if (f.isOpen() == false) {
                 f.open(com.sun.mail.imap.IMAPFolder.READ_WRITE);
             }
+            
             MimeMessage message = (MimeMessage) f.getMessageByUID(uid);
-            MessageDetails mDetails = new MessageDetails();
-            mDetails.setUid(uid);
-
-            boolean isHTML = false;
-            Object con = message.getContent();
-
-            StringBuffer sbPlain = new StringBuffer();
-            ArrayList<MessageAttachment> attachmentList = new ArrayList<MessageAttachment>();
-
-            handleParts(message, con, sbPlain, isHTML, attachmentList);
-
-            mDetails.setText(sbPlain.toString());
-
-            mDetails.setIsHTML(isHTML);
-            mDetails.setMessageAttachments(attachmentList);
 
-            mDetails.setRawHeader(message.getAllHeaders().toString());
+            MessageDetails mDetails = mimeToDetails(message);
 
+            mDetails.setUid(uid);
+            if (mDetails.isHTML()) {
+            	mDetails.setText(changeHtmlLinks(mDetails.getText(), f.getFullName(), uid));
+            }
+            
             f.setFlags(new Message[] { message }, new Flags(Flag.SEEN), true);
 
             return mDetails;
@@ -132,23 +123,54 @@
         }
     }
 
+	protected MessageDetails mimeToDetails(MimeMessage message)
+            throws IOException, MessagingException,
+            UnsupportedEncodingException {
+	    MessageDetails mDetails = new MessageDetails();
+
+	    
+	    Object con = message.getContent();
+
+	    StringBuffer sbPlain = new StringBuffer();
+	    ArrayList<MessageAttachment> attachmentList = new ArrayList<MessageAttachment>();
+
+	    boolean isHTML = handleParts(message, con, sbPlain, attachmentList);
+
+	    mDetails.setText(sbPlain.toString());
+
+	    mDetails.setIsHTML(isHTML);
+	    mDetails.setMessageAttachments(attachmentList);
+
+	    mDetails.setRawHeader(message.getAllHeaders().toString());
+	    return mDetails;
+    }
+	
+	// TODO: use constants for servlet paths to match DispatchServlet configuration (also in client side)
+	protected String changeHtmlLinks(String html, String folderName, long uuid) {
+		html = html.replaceAll("(img\\s+src=\")cid:([^\"]+\")", 
+				"$1/hupa/downloadAttachmentServlet?folder_name=" 
+				+ folderName + "&message_uuid=" + uuid + "&attachment_name=$2");
+		return html;
+	}
+
     /**
      * Handle the parts of the given message. The method will call itself recursively to handle all nested parts
      * @param message the MimeMessage 
      * @param con the current processing Content
      * @param sbPlain the StringBuffer to fill with text
-     * @param isHTML identicate if the message is HTML
      * @param attachmentList ArrayList with attachments
      * @throws UnsupportedEncodingException
      * @throws MessagingException
      * @throws IOException
      */
-    private void handleParts(MimeMessage message, Object con,
-            StringBuffer sbPlain, boolean isHTML,
+    private boolean handleParts(MimeMessage message, Object con,
+            StringBuffer sbPlain,
             ArrayList<MessageAttachment> attachmentList)
             throws UnsupportedEncodingException, MessagingException,
             IOException {
+    	boolean isHTML = false;
         if (con instanceof String) {
+            System.out.println("sc: " + message.getContentType());
             if (message.getContentType().startsWith("text/html")) {
                 isHTML = true;
             } else {
@@ -161,9 +183,11 @@
             Multipart mp = (Multipart) con;
             String multipartContentType = mp.getContentType().toLowerCase();
             System.out.println("mc: " + multipartContentType);
+            
+            String text = null;
 
             if (multipartContentType.startsWith("multipart/alternative")) {
-                handleMultiPartAlternative(mp, sbPlain, isHTML);
+                isHTML = handleMultiPartAlternative(mp, sbPlain);
             } else {
                 for (int i = 0; i < mp.getCount(); i++) {
                     Part part = mp.getBodyPart(i);
@@ -171,21 +195,17 @@
                     String contentType = part.getContentType().toLowerCase();
                     System.out.println("c: " + contentType);
 
-                    if (contentType.startsWith("text/plain")) {
+                    if (text == null && contentType.startsWith("text/plain") ) {
                         isHTML = false;
+                        text = (String)part.getContent();
                     } else if (contentType.startsWith("text/html")) {
                         isHTML = true;
-                        sbPlain.append((String) part.getContent());
-
+                        text = (String)part.getContent();
                     } else if (contentType.startsWith("message/rfc822")) {
                         // Extract the message and pass it
-                        MimeMessage msg = (MimeMessage) part.getDataHandler()
-                                .getContent();
-                        handleParts(msg, msg.getContent(), sbPlain, isHTML,
-                                attachmentList);
-
+                        MimeMessage msg = (MimeMessage) part.getDataHandler().getContent();
+                        isHTML =  handleParts(msg, msg.getContent(), sbPlain, attachmentList);
                     } else {
-
                         if (part.getFileName() != null) {
                             MessageAttachment attachment = new MessageAttachment();
                             attachment.setName(MimeUtility.decodeText(part
@@ -195,37 +215,39 @@
 
                             attachmentList.add(attachment);
                         } else {
-                            handleParts(message, part, sbPlain, isHTML,
-                                    attachmentList);
+                            isHTML = handleParts(message, part.getContent(), sbPlain, attachmentList);
                         }
                     }
 
                 }
+                if (text != null)
+                	sbPlain.append(text);
             }
 
         }
+        return isHTML;
     }
     
-    private void handleMultiPartAlternative(Multipart mp,StringBuffer sbPlain, boolean isHTML) throws MessagingException, IOException {
+    private boolean handleMultiPartAlternative(Multipart mp, StringBuffer sbPlain) throws MessagingException, IOException {
         String text = null;
+        boolean isHTML = false;
         for (int i = 0; i < mp.getCount(); i++) {
             Part part = mp.getBodyPart(i);
             
             String contentType = part.getContentType().toLowerCase();
-            System.out.println("c: " + contentType);
+            System.out.println("m: " + contentType);
 
-            if (contentType.startsWith("text/plain")) {
-                // we prefer plain text of html.. Does this make sense for a webmail client ?
+            // we prefer html
+            if (text == null && contentType.startsWith("text/plain")) {
                 isHTML = false;
                 text = (String) part.getContent();
-                break;
-
             } else if (contentType.startsWith("text/html")) {
                 isHTML = true;
                 text = (String) part.getContent();
             } 
         }
         sbPlain.append(text);
+        return isHTML;
     }
-
+    
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/JavamailUtil.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/JavamailUtil.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/JavamailUtil.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/JavamailUtil.java Thu Oct 29 13:24:15 2009
@@ -54,12 +54,19 @@
             return IMAPFlag.SEEN;
         } else if (flag.equals(Flag.RECENT)) {
             return IMAPFlag.RECENT;
-        } else if (flag.equals(Flag.ANSWERED)) {
+        } else if (flag.equals(Flag.ANSWERED)) { 
             return IMAPFlag.ANSWERED;
         } else if (flag.equals(Flag.DELETED)) {
             return IMAPFlag.DELETED;
+        } else if (flag.equals(Flag.DRAFT)) {
+            return IMAPFlag.DRAFT;
+        } else if (flag.equals(Flag.FLAGGED)) {
+            return IMAPFlag.FLAGGED;
+        } else if (flag.equals(Flag.USER)) {
+            return IMAPFlag.USER;
         }
-        throw new IllegalArgumentException("Flag not supported");
+        
+        throw new IllegalArgumentException("Flag not supported " + flag);
     }
     /**
      * Convert the given ArrayList of IMAPFlags to a Flags object

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPFolder.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPFolder.java?rev=830933&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPFolder.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPFolder.java Thu Oct 29 13:24:15 2009
@@ -0,0 +1,372 @@
+/****************************************************************
+ * 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.hupa.server.mock;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.mail.FetchProfile;
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Store;
+import javax.mail.Flags.Flag;
+import javax.mail.internet.MimeMessage;
+import javax.mail.search.SearchTerm;
+
+import org.apache.hupa.shared.data.Settings;
+
+import com.sun.mail.imap.IMAPFolder;
+import com.sun.mail.imap.IMAPStore;
+
+public class MockIMAPFolder extends IMAPFolder {
+
+    public static final char SEPARATOR = '.';
+	public static final String DEMO_MODE_SENT_FOLDER = "Demo-Sent";
+	public static final String DEMO_MODE_TRASH_FOLDER = "Demo-Trash";
+	public static final String DEMO_MODE_INBOX_FOLDER = "Demo-Inbox";
+	public static final String DEMO_MODE_DEFAULT_FOLDER = "";
+	public static final String DEMO_MODE_MESSAGES_LOCATION = "mime" + File.separator;
+
+	public List<Message> messages = new ArrayList<Message>();
+    private boolean closed;
+    private boolean exists;
+    
+    public final static Settings mockSettings = new Settings() {
+		private static final long serialVersionUID = -6650449479903482066L;
+		{
+			setInboxFolderName(MockIMAPFolder.DEMO_MODE_INBOX_FOLDER);
+			setSentFolderName(MockIMAPFolder.DEMO_MODE_SENT_FOLDER);
+			setTrashFolderName(MockIMAPFolder.DEMO_MODE_TRASH_FOLDER);
+		}
+	};
+
+    public MockIMAPFolder(String fullName, IMAPStore store) {
+        super(fullName, (DEMO_MODE_DEFAULT_FOLDER.equals(fullName) ? '\0' : SEPARATOR), store);
+    }
+
+    @Override
+    public synchronized Message[] addMessages(Message[] mArray)
+            throws MessagingException {
+        checkExists();
+        messages.addAll(Arrays.asList(mArray));
+        return mArray;
+    }
+    
+    @Override
+    public void appendMessages(Message[] msgs) throws MessagingException {
+    	addMessages(msgs);
+    }
+
+    @Override
+    public synchronized void close(boolean expunge) throws MessagingException {
+        checkExists();
+        closed = true;
+    }
+
+    @Override
+    public Folder[] list() throws MessagingException {
+        List<MockIMAPFolder> folders = ((MockIMAPStore) store).getChilds(this);
+        return folders.toArray(new Folder[folders.size()]);
+    }
+
+    @Override
+    public synchronized void copyMessages(Message[] messages, Folder folder)
+            throws MessagingException {
+        checkExists();
+        ((MockIMAPFolder) folder).addMessages(messages);
+
+    }
+    
+    public void loadDemoMessages(Session session) {
+    	for(int i=0;;i++) {
+        	URL url = Thread.currentThread().getContextClassLoader().getResource(DEMO_MODE_MESSAGES_LOCATION + i + ".msg");
+        	if (url == null) break;
+    		try {
+	            FileInputStream is = new FileInputStream(url.getFile());
+	            addMessages(new Message[]{new MimeMessage(session, is)});
+            } catch (MessagingException e) {
+	            e.printStackTrace();
+            } catch (FileNotFoundException e) {
+	            e.printStackTrace();
+            }
+    	}
+    }
+
+    @Override
+    public synchronized boolean create(int type) throws MessagingException {
+        if (exists()) {
+            throw new MessagingException("Folder already exists!");
+        }
+        exists = true;
+        return ((MockIMAPStore) store).save(this);
+    }
+
+    @Override
+    public synchronized boolean delete(boolean recursive)
+            throws MessagingException {
+        exists = false;
+        return ((MockIMAPStore) store).delete(this, recursive);
+    }
+
+    @Override
+    public synchronized boolean exists() throws MessagingException {
+        return exists;
+    }
+
+    @Override
+    public synchronized void fetch(Message[] msgs, FetchProfile fp)
+            throws MessagingException {
+        // nothing todo
+        checkExists();
+    }
+
+    @Override
+    public synchronized int getDeletedMessageCount() throws MessagingException {
+        return 0;
+    }
+
+    @Override
+    public Folder getFolder(String name) throws MessagingException {
+        return super.getFolder(name);
+    }
+
+    @Override
+    public synchronized String getFullName() {
+        return fullName;
+    }
+
+    @Override
+    public synchronized Message getMessage(int msgnum)
+            throws MessagingException {
+        checkExists();
+        if (messages.size() < msgnum) {
+            throw new MessagingException();
+        }
+        return messages.get(msgnum);
+    }
+
+    @Override
+    public synchronized Message getMessageByUID(long uid)
+            throws MessagingException {
+        checkExists();
+        return getMessage(new Long(uid).intValue());
+    }
+
+    @Override
+    public synchronized int getMessageCount() throws MessagingException {
+        checkExists();
+        return messages.size();
+    }
+
+    @Override
+    public synchronized Message[] getMessagesByUID(long uidstart, long uidend)
+            throws MessagingException {
+        checkExists();
+        return getMessages(new Long(uidstart).intValue(), new Long(uidend)
+                .intValue());
+    }
+
+    @Override
+    public synchronized Message[] getMessagesByUID(long[] uids)
+            throws MessagingException {
+        checkExists();
+        int ints[] = new int[uids.length];
+        for (int i = 0; i < uids.length; i++) {
+            ints[i] = new Long(uids[i]).intValue();
+        }
+        return getMessages(ints);
+    }
+
+    @Override
+    public synchronized String getName() {
+        return name;
+    }
+
+    @Override
+    public synchronized int getNewMessageCount() throws MessagingException {
+        checkExists();
+        return 0;
+    }
+
+    @Override
+    public synchronized Folder getParent() throws MessagingException {
+        return ((MockIMAPStore) store).getParent(this);
+    }
+
+    @Override
+    public void idle() throws MessagingException {
+        checkExists();
+    }
+
+    @Override
+    public synchronized boolean isOpen() {
+        return closed == false;
+    }
+
+    @Override
+    public synchronized boolean isSubscribed() {
+        return true;
+    }
+
+    @Override
+    public synchronized void open(int arg0) throws MessagingException {
+        checkExists();
+        closed = false;
+    }
+
+    @Override
+    public synchronized boolean renameTo(Folder f) throws MessagingException {
+        checkExists();
+        return false;
+    }
+
+    @Override
+    public synchronized Message[] search(SearchTerm arg0, Message[] arg1)
+            throws MessagingException {
+        checkExists();
+        return arg1;
+    }
+
+    @Override
+    public synchronized Message[] expunge() throws MessagingException {
+        checkExists();
+        return expunge(messages.toArray(new Message[messages.size()]));
+    }
+
+    @Override
+    public synchronized Message[] expunge(Message[] msgs)
+            throws MessagingException {
+        checkExists();
+        List<Message> mList = new ArrayList<Message>();
+        for (int i = 0; i < msgs.length; i++) {
+            Message m = msgs[i];
+            if (m.getFlags().contains(Flag.DELETED)) {
+                if (messages.remove(m)) {
+                    mList.add(m);
+                }
+            }
+        }
+        return mList.toArray(new Message[mList.size()]);
+    }
+
+    @Override
+    public synchronized Message[] search(SearchTerm arg0)
+            throws MessagingException {
+        checkExists();
+        return getMessages();
+    }
+
+    @Override
+    public synchronized void setFlags(Message[] mArray, Flags flags,
+            boolean value) throws MessagingException {
+        checkExists();
+        for (int i = 0; i < mArray.length; i++) {
+            Message m = mArray[i];
+            for (int a = 0; a < messages.size(); a++) {
+                Message m2 = messages.get(a);
+                if (m2.equals(m)) {
+                    m2.setFlags(flags, value);
+                    break;
+                }
+            }
+        }
+    }
+
+    @Override
+    public synchronized Message[] getMessages() throws MessagingException {
+        checkExists();
+        return messages.toArray(new Message[messages.size()]);
+
+    }
+
+    @Override
+    public synchronized Message[] getMessages(int start, int end)
+            throws MessagingException {
+        checkExists();
+        Message[] array = new Message[end- --start];
+        for (int i=0; start<end; i++,start++) 
+            array[i] = messages.get(start);
+        return array;
+    }
+
+    @Override
+    public synchronized Message[] getMessages(int[] ints)
+            throws MessagingException {
+        checkExists();
+        Message[] array = new Message[ints.length];
+
+        for (int i = 0; i < ints.length; i++) {
+            int mInt = ints[i] - 1;
+            if (mInt > messages.size() || mInt < messages.size()) {
+                throw new MessagingException();
+            }
+            array[i] = messages.get(i);
+        }
+        return array;
+    }
+
+    @Override
+    public Store getStore() {
+        return store;
+    }
+
+    @Override
+    public synchronized void setFlags(int arg0, int arg1, Flags arg2,
+            boolean arg3) throws MessagingException {
+        checkExists();
+    }
+
+    @Override
+    public synchronized void setFlags(int[] arg0, Flags arg1, boolean arg2)
+            throws MessagingException {
+        checkExists();
+    }
+
+    @Override
+    public synchronized long getUID(Message message) throws MessagingException {
+        checkExists();
+        return messages.indexOf(message);
+    }
+
+    @Override
+    public synchronized int getUnreadMessageCount() throws MessagingException {
+    	int ret = getMessageCount();
+    	for (Message msg: messages) {
+    		if (msg.getFlags().contains(Flag.SEEN))
+    			ret --;
+    	}
+        return ret;
+    }
+
+    private void checkExists() throws MessagingException {
+        if (exists() == false) {
+            throw new MessagingException("Folder not exists");
+        }
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPStore.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPStore.java?rev=830933&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPStore.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockIMAPStore.java Thu Oct 29 13:24:15 2009
@@ -0,0 +1,215 @@
+/****************************************************************
+ * 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.hupa.server.mock;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.mail.AuthenticationFailedException;
+import javax.mail.Folder;
+import javax.mail.MessagingException;
+import javax.mail.Provider;
+import javax.mail.Session;
+import javax.mail.URLName;
+
+import org.apache.hupa.server.InMemoryIMAPStoreCache;
+
+import com.sun.mail.imap.IMAPStore;
+
+public class MockIMAPStore extends IMAPStore{
+
+    private Map<String, String> validLogins = new HashMap<String, String>();
+    private Map<String, Integer> validServers = new HashMap<String, Integer>();
+    private boolean connected = false;
+    private List<MockIMAPFolder> folders = new ArrayList<MockIMAPFolder>();
+    static final URLName demoUrl = new URLName(null, InMemoryIMAPStoreCache.DEMO_MODE, 143, null, null, null);
+    
+    /**
+     * Demo mode constructor
+     */
+    public MockIMAPStore(Session session) {
+        this(session, demoUrl);
+    }
+
+    /**
+     * Default constructor
+     */
+    public MockIMAPStore(Session session, URLName url) {
+        super(session, url);
+        
+        if (InMemoryIMAPStoreCache.DEMO_MODE.equals(url.getHost())) {
+            validServers.put(InMemoryIMAPStoreCache.DEMO_MODE, 143);
+            validLogins.put("demo", "demo");
+            try {
+                new MockIMAPFolder(MockIMAPFolder.DEMO_MODE_INBOX_FOLDER, this).create(Folder.HOLDS_FOLDERS | Folder.HOLDS_MESSAGES);
+                new MockIMAPFolder(MockIMAPFolder.DEMO_MODE_SENT_FOLDER, this).create(Folder.HOLDS_FOLDERS | Folder.HOLDS_MESSAGES);
+                new MockIMAPFolder(MockIMAPFolder.DEMO_MODE_TRASH_FOLDER, this).create(Folder.HOLDS_FOLDERS | Folder.HOLDS_MESSAGES);
+                ((MockIMAPFolder)getFolder(MockIMAPFolder.DEMO_MODE_INBOX_FOLDER)).loadDemoMessages(session);
+            } catch (Exception e) {
+            	e.printStackTrace();
+            }
+        }
+    }
+
+    public static Provider getProvider() {
+        return new Provider(Provider.Type.STORE,"mockimap",MockIMAPStore.class.getName(),"","");
+    }
+    
+    public boolean save(MockIMAPFolder folder) {
+        for (int i= 0; i < folders.size(); i++) {
+            if (folders.get(i).getFullName().equals(folder.getFullName())) {
+                return false;
+            }
+        }
+        folders.add(folder);
+        return true;
+    } 
+    
+    public boolean delete(MockIMAPFolder folder, boolean recursive) {
+        boolean found = false;
+        for (int i= 0; i < folders.size(); i++) {
+            if (folders.get(i).getFullName().equals(folder.getFullName())) {
+                folders.remove(i);
+                found = true;
+                if(recursive == false) {
+                    break;
+                }
+            } else if (folders.get(i).getFullName().startsWith(folder.getFullName() + MockIMAPFolder.SEPARATOR)) {
+                folders.remove(i);
+            }
+            
+        }
+        return found;
+    } 
+    
+    public MockIMAPFolder getParent(MockIMAPFolder folder) {
+        for (int i = 0; i < folders.size(); i++) {
+            MockIMAPFolder f = folders.get(i);
+            if ((f.getFullName() + MockIMAPFolder.SEPARATOR + folder.getName()).equals(folder.getFullName())) {
+                return f;
+            }
+        }
+        return null;
+    }
+    
+    public List<MockIMAPFolder> getChilds(MockIMAPFolder folder) {
+		List<MockIMAPFolder> childs = new ArrayList<MockIMAPFolder>();
+		if (MockIMAPFolder.DEMO_MODE_DEFAULT_FOLDER.equals(folder.getFullName())) {
+			for(MockIMAPFolder f: folders) {
+				if (! MockIMAPFolder.DEMO_MODE_DEFAULT_FOLDER.equals(f.getFullName()))
+					childs.add(f);
+			}
+			return folders;
+		} else {
+			for (int i = 0; i < folders.size(); i++) {
+				MockIMAPFolder f = folders.get(i);
+				if (f.getFullName().startsWith(
+				        folder.getFullName() + MockIMAPFolder.SEPARATOR)) {
+					childs.add(f);
+					
+				}
+			}
+		}
+		return childs;
+	}
+    
+    public void setValidLogins(Map<String,String> validLogins) {
+        this.validLogins = validLogins;
+    }
+
+    public void setValidServers(Map<String,Integer> validServers) {
+        this.validServers = validServers;
+    }
+    
+    public void clear() {
+        validLogins.clear();
+        validServers.clear();
+        folders.clear();
+        connected = false;
+    }
+    
+    @Override
+    public synchronized void close() throws MessagingException {
+        connected = false;
+    }
+
+    @Override
+    public synchronized Folder getDefaultFolder() throws MessagingException {
+    	return getFolder(MockIMAPFolder.DEMO_MODE_DEFAULT_FOLDER);
+    }
+
+    @Override
+    public synchronized Folder getFolder(String name) {
+        for (int i = 0; i < folders.size(); i++) {
+            MockIMAPFolder mfolder = folders.get(i);
+            if (mfolder.getFullName().equals(name)) {
+                return mfolder;
+            }
+        }
+        return new MockIMAPFolder(name,this);
+    }
+
+    @Override
+    public void idle() throws MessagingException {
+        // nothing todo
+    }
+
+    @Override
+    public synchronized boolean isConnected() {
+        return connected;
+    }
+
+    @Override
+    public void connect() throws MessagingException {
+        connected = true;
+    }
+
+    @Override
+    public synchronized void connect(String host, int port, String username,
+            String password) throws MessagingException {
+        Integer myPort = validServers.get(host);
+        if (myPort != null && myPort.intValue() == port) {
+            connect(username,password);
+        } else {
+        	throw new MessagingException("Can't connect to host");
+        }
+    }
+
+    @Override
+    public void connect(String host, String user, String password)
+            throws MessagingException {
+        if (validServers.containsKey(host) == false) {
+            throw new MessagingException("Can't connect to host");
+        }
+        connect(user,password);
+    }
+
+    @Override
+    public void connect(String user, String password) throws MessagingException {
+        String pass = validLogins.get(user);
+        if (pass != null && validLogins.get(user).equals(password)) {
+            connect();
+            return;
+        } 
+        throw new AuthenticationFailedException("Invalid login");
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockSMTPTransport.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockSMTPTransport.java?rev=830933&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockSMTPTransport.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockSMTPTransport.java Thu Oct 29 13:24:15 2009
@@ -0,0 +1,48 @@
+/****************************************************************
+ * 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.hupa.server.mock;
+
+import javax.mail.Address;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Session;
+import javax.mail.Transport;
+import javax.mail.URLName;
+
+import org.apache.hupa.server.InMemoryIMAPStoreCache;
+
+
+public class MockSMTPTransport extends Transport {
+
+    static final URLName demoUrl = new URLName(null, InMemoryIMAPStoreCache.DEMO_MODE, 143, null, null, null);
+    
+    public MockSMTPTransport(Session session) {
+        super(session, demoUrl);
+    }
+
+    @Override
+    public void sendMessage(Message msg, Address[] addresses) throws MessagingException {
+    }
+    
+    @Override
+    public void connect(String host, int port, String user, String password) throws MessagingException {
+    }
+    
+}

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/DownloadAttachmentServlet.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/DownloadAttachmentServlet.java?rev=830933&r1=830932&r2=830933&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/DownloadAttachmentServlet.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/DownloadAttachmentServlet.java Thu Oct 29 13:24:15 2009
@@ -34,7 +34,6 @@
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpSession;
 
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.InMemoryIMAPStoreCache;
@@ -75,74 +74,79 @@
     @Override
     protected void doGet(HttpServletRequest request,
             HttpServletResponse response) throws ServletException, IOException {
+    	
+    	User user = (User) request.getSession().getAttribute("user");
+    	if (user == null)
+    		throw new ServletException("Invalid session");
+    	
         String message_uuid = request.getParameter("message_uuid");
         String attachmentName = request.getParameter("attachment_name");
-        String sessionId = request.getParameter("sessionId");
         String folderName = request.getParameter("folder_name");
-        HttpSession session = request.getSession();
-        if (session.getId().equals(sessionId)) {
-            response.setContentType("application/download");
-            response.setHeader("Content-disposition", "attachment; filename="
-                    + attachmentName + "");
-            InputStream in = null;
-            OutputStream out = response.getOutputStream();
+        response.setHeader("Content-disposition", "attachment; filename="
+                + attachmentName + "");
+        InputStream in = null;
+        OutputStream out = response.getOutputStream();
+
+        IMAPFolder folder = null;
+        try {
+            Store store = cache.get(user);
+            folder = (IMAPFolder) store.getFolder(folderName);
+            if (folder.isOpen() == false) {
+                folder.open(Folder.READ_ONLY);
+            }
+            Message m = folder.getMessageByUID(Long.parseLong(message_uuid));
             
-
-            IMAPFolder folder = null;
-            try {
-                Store store = cache.get((User) request.getSession().getAttribute(
-                "user"));
-                folder = (IMAPFolder) store.getFolder(folderName);
-                if (folder.isOpen() == false) {
-                    folder.open(Folder.READ_ONLY);
-                }
-                Message m = folder.getMessageByUID(Long.parseLong(message_uuid));
-                Object content = m.getContent();
-                Part part  = handleMultiPart(content, attachmentName);
-                in = part.getInputStream();
-                if (in != null) {
-                    byte[] buffer = new byte[4096];
-                    int bytesRead;
-                    int bytesComplete = 0;
-                    while ((bytesRead = in.read(buffer)) != -1) {
-                        bytesComplete = bytesComplete + bytesRead;
-                        out.write(buffer, 0, bytesRead); // write
-                    }
-                    out.flush();
-                    response.setContentLength(bytesComplete);
-                } else {
-                    response.setContentLength(0);
-                }
-            } catch (Exception e) {
-                logger.error("Error while downloading attachment "
-                        + attachmentName + " of message " + message_uuid
-                        + " for sessionId " + sessionId, e);
-            } finally {
-                if (in != null) {
-                    try {
-                        in.close();
-                    } catch (IOException e) {
-                        // ignore on close
-                    }
+            Object content = m.getContent();
+            Part part  = handleMultiPart(content, attachmentName);
+            if (part.getContentType()!=null)
+            	response.setContentType(part.getContentType());
+            else
+                response.setContentType("application/download");
+            
+            in = part.getInputStream();
+            if (in != null) {
+                byte[] buffer = new byte[4096];
+                int bytesRead;
+                int bytesComplete = 0;
+                while ((bytesRead = in.read(buffer)) != -1) {
+                    bytesComplete = bytesComplete + bytesRead;
+                    out.write(buffer, 0, bytesRead); // write
+                }
+                response.setContentLength(bytesComplete);
+            } else {
+                response.setContentLength(0);
+            }
+            
+            out.flush();
+            
+        } catch (Exception e) {
+            logger.error("Error while downloading attachment "
+                    + attachmentName + " of message " + message_uuid
+                    + " for user " + user.getName(), e);
+        } finally {
+            if (in != null) {
+                try {
+                    in.close();
+                } catch (IOException e) {
+                    // ignore on close
                 }
-                if (out != null) {
-                    try {
-                        out.close();
-                    } catch (IOException e) {
-                        // ignore on close
-                    }
+            }
+            if (out != null) {
+                try {
+                    out.close();
+                } catch (IOException e) {
+                    // ignore on close
                 }
-                if (folder != null) {
-                    try {
-                        folder.close(false);
-                    } catch (MessagingException e) {
-                        // ignore on close
-                    }
+            }
+            if (folder != null) {
+                try {
+                    folder.close(false);
+                } catch (MessagingException e) {
+                    // ignore on close
                 }
-
             }
-        }
 
+        }
     }
     
     /**
@@ -154,45 +158,40 @@
      * @param content
      *            Content which should checked for attachments
      * @param attachmentName
-     *            The attachmentname for the searched attachment
+     *            The attachmentname or the unique id for the searched attachment
      * @throws MessagingException
      * @throws IOException
      */
-    private Part handleMultiPart(Object content, String attachmentName)
+    static protected Part handleMultiPart(Object content, String attachmentName)
             throws MessagingException, IOException {
         if (content instanceof Multipart) {
             Multipart part = (Multipart) content;
             for (int i = 0; i < part.getCount(); i++) {
-                Part p = part.getBodyPart(i);
-                if (isAttachment(p)) {
-                    if (MimeUtility.decodeText(p.getFileName()).equals(
-                            attachmentName)) {
-                        return p;
+                Part bodyPart = part.getBodyPart(i);
+                String fileName = bodyPart.getFileName();
+                String[] contentId = bodyPart.getHeader("Content-ID");
+                if (bodyPart.isMimeType("multipart/*")) {
+                    Part p = handleMultiPart(bodyPart.getContent(), attachmentName);
+                    if (p != null)
+                    	return p;
+                } else {
+                	if (contentId != null) {
+                    	for (String id: contentId) {
+                    		id = id.replaceAll("^.*<(.+)>.*$", "$1");
+                    		if (attachmentName.equals(id))
+                    			return bodyPart;
+                    	}
+                    } 
+                	if (fileName != null){
+                        if (attachmentName.equalsIgnoreCase(MimeUtility.decodeText(fileName))) 
+                            return bodyPart;
                     }
-
-                } else if (p.isMimeType("multipart/*")) {
-                    return handleMultiPart(p.getContent(), attachmentName);
-                }
+                } 
             }
+        } else {
+        	System.out.println("Unknown content: " + content.getClass().getName());
         }
         return null;
     }
 
-    /**
-     * Check if the given Part is an attachment
-     * 
-     * @param part
-     * @return isAttachment
-     * @throws MessagingException
-     */
-    private boolean isAttachment(Part part) throws MessagingException {
-        String disposition = part.getDisposition();
-        if (part.getContentType().toLowerCase().startsWith("application/")
-                || (disposition != null && (disposition.equals(Part.ATTACHMENT) || disposition
-                        .equals(Part.INLINE)))) {
-            return true;
-        }
-        return false;
-    }
-
 }

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/HupaDispatchServlet.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/HupaDispatchServlet.java?rev=830933&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/HupaDispatchServlet.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/HupaDispatchServlet.java Thu Oct 29 13:24:15 2009
@@ -0,0 +1,67 @@
+/****************************************************************
+ * 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.hupa.server.servlet;
+
+import org.apache.commons.logging.Log;
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import net.customware.gwt.dispatch.server.Dispatch;
+import net.customware.gwt.dispatch.server.service.DispatchServiceServlet;
+import net.customware.gwt.dispatch.shared.Action;
+import net.customware.gwt.dispatch.shared.ActionException;
+import net.customware.gwt.dispatch.shared.Result;
+
+/**
+ * Just a wrapper for the Dispatcher servlet in order to log received actions. 
+ *
+ */
+@Singleton
+public class HupaDispatchServlet extends DispatchServiceServlet {
+	
+	private Log logger;
+	
+	@Inject
+    public HupaDispatchServlet( Dispatch dispatch, Log logger) {
+    	super(dispatch);
+    	this.logger = logger;
+    }
+
+    
+    @Override
+    public Result execute( Action<?> action ) throws ActionException {
+    	try {
+        	logger.info("HupaDispatchServlet: executing: " + action.getClass().getName().replaceAll("^.*\\.",""));
+        	return super.execute(action);
+        } catch (ActionException e) {
+        	logger.error("HupaDispatchServlet returns an ActionException:" + e.getMessage());
+        	e.printStackTrace();
+        	throw e;
+        } catch (Exception e) {
+        	e.printStackTrace();
+        	logger.error("HupaDispatchServlet unexpected Exception:" + e.getMessage());
+        	return null;
+        }
+    }
+
+	private static final long serialVersionUID = 1L;
+
+}

Added: james/hupa/trunk/server/src/main/resources/mime/0.msg
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/resources/mime/0.msg?rev=830933&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/resources/mime/0.msg (added)
+++ james/hupa/trunk/server/src/main/resources/mime/0.msg Thu Oct 29 13:24:15 2009
@@ -0,0 +1,9 @@
+From: nobody@foo.com
+To: nobody@foo.com
+Subject: Incomplete headers
+
+This is a demo message without any content-type and date in the headers.
+This content has to be rendered as normal text without any format.
+These are a bunch of  html tags:
+
+<a> <b> <div> <pre> </pre> 



---------------------------------------------------------------------
To unsubscribe, e-mail: server-dev-unsubscribe@james.apache.org
For additional commands, e-mail: server-dev-help@james.apache.org