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