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 ma...@apache.org on 2009/12/01 16:05:02 UTC

svn commit: r885783 [1/2] - in /james/hupa/trunk: client/src/main/java/org/apache/hupa/client/ client/src/main/java/org/apache/hupa/client/mvp/ client/war/WEB-INF/ server/src/main/java/org/apache/hupa/server/guice/ server/src/main/java/org/apache/hupa/...

Author: manolo
Date: Tue Dec  1 15:05:00 2009
New Revision: 885783

URL: http://svn.apache.org/viewvc?rev=885783&view=rev
Log:
Fixed a bug in sending emails with attachments in client side because the uploader widget was not correctly reseted.
Fixed a bug in server side because attachment-registry was not multisession.
Forward and send actions handle correctly attachments now, but reply needs more work.
Fixed a bug in Demo-mode which produced unreacheable attachments in the sent-box.
Inline images are not shown in the attachment list.
Increased server test coverage.
Re-factoring: moved methods from handles to util classes, renamed classes, regexp, tests classes etc.
Rolled back in client side to use implementations instead of interfaces

Added:
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/MessageUtils.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/RegexPatterns.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaTestCase.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/MessageUtilsTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/RegexPatternsTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/TestUtils.java
      - copied, changed from r884868, james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/MsgUtils.java
Removed:
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/MsgUtils.java
Modified:
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaCallback.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/AppPresenter.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java
    james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java
    james/hupa/trunk/client/war/WEB-INF/web.xml
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerModule.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/ForwardMessageHandler.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/ReplyMessageHandler.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.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/DownloadAttachmentServlet.java
    james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/UploadAttachmentServlet.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceTestModule.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/AbtractSendMessageHandlerTest.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/FowardMessageHandlerTest.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/handler/LogoutUserHandlerTest.java
    james/hupa/trunk/server/src/test/java/org/apache/hupa/server/servlet/DownloadAttachmentServletTest.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/AbstractMessage.java
    james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/SMTPMessage.java

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaCallback.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaCallback.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaCallback.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/HupaCallback.java Tue Dec  1 15:05:00 2009
@@ -39,6 +39,8 @@
     private EventBus eventBus = null;
     private ServerStatusEvent available = new ServerStatusEvent(ServerStatus.Available); 
     private ServerStatusEvent unavailable = new ServerStatusEvent(ServerStatus.Unavailable); 
+
+    @SuppressWarnings("unused")
     private Display display = null;
 
     @Inject

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/AppPresenter.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/AppPresenter.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/AppPresenter.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/AppPresenter.java Tue Dec  1 15:05:00 2009
@@ -62,7 +62,7 @@
  */
 public class AppPresenter extends WidgetContainerPresenter<AppPresenter.Display>{
 
-    private static final int NOOP_INTERVAL = 15000;
+    private static final int NOOP_INTERVAL = 150000;
 
     public interface Display extends WidgetContainerDisplay {
         public HasClickHandlers getLogoutClick();

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendPresenter.java Tue Dec  1 15:05:00 2009
@@ -192,10 +192,6 @@
             
         }));
 
-        registerHandler(display.getUploader().addOnStatusChangedHandler(onStatusChangedHandler));
-        registerHandler(display.getUploader().addOnFinishUploadHandler(onFinishUploadHandler));
-        registerHandler(display.getUploader().addOnCancelUploadHandler(onCancelUploadHandler));
-        
         registerHandler(display.getSendClick().addClickHandler(new ClickHandler() {
 
             public void onClick(ClickEvent event) {
@@ -294,6 +290,8 @@
             }
             
         }));
+        
+        reset();
     }
 
     /**
@@ -301,6 +299,10 @@
      */
     private void reset() {
         display.resetUploader();
+        display.getUploader().addOnStatusChangedHandler(onStatusChangedHandler);
+        display.getUploader().addOnFinishUploadHandler(onFinishUploadHandler);
+        display.getUploader().addOnCancelUploadHandler(onCancelUploadHandler);
+        
         display.getBccText().setText("");
         display.getCcText().setText("");
         display.getToText().setText("");

Modified: james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java (original)
+++ james/hupa/trunk/client/src/main/java/org/apache/hupa/client/mvp/MessageSendView.java Tue Dec  1 15:05:00 2009
@@ -61,15 +61,17 @@
     private TextBox cc = new TextBox();
     private TextBox bcc = new TextBox();
     private TextBox subject = new TextBox();
-    private BaseUploadStatus uploadStatus = new BaseUploadStatus();
-    private MultiUploader uploader = new MultiUploader(uploadStatus);
+    private MultiUploader uploader = null;
     private Editor editor = new Editor();
     private EnableButton sendButton;
     private EnableHyperlink backButton;
     private Loading sendProgress = new Loading();
+    private HupaConstants constants;
+   
 
     @Inject
     public MessageSendView(HupaConstants constants) {
+        this.constants = constants;
         sendButton = new EnableButton(constants.sendButton());
         backButton = new EnableHyperlink(constants.backButton(),"");
         final VerticalPanel mPanel = new VerticalPanel();
@@ -98,7 +100,6 @@
         detailGrid.setWidget(2, 1, cc);
         detailGrid.setWidget(3, 1, bcc);
         detailGrid.setWidget(4, 1, subject);
-        detailGrid.setWidget(5, 1, uploader);
         detailGrid.getCellFormatter().setHorizontalAlignment(0, 0, HorizontalPanel.ALIGN_RIGHT);
         detailGrid.getCellFormatter().setHorizontalAlignment(1, 0, HorizontalPanel.ALIGN_RIGHT);
         detailGrid.getCellFormatter().setHorizontalAlignment(2, 0, HorizontalPanel.ALIGN_RIGHT);
@@ -159,11 +160,6 @@
         editor.setWidth("100%");
         editor.setHeight("400px");
 
-        uploadStatus.setCancelConfiguration(IUploadStatus.GMAIL_CANCEL_CFG);
-        uploader.setServletPath(GWT.getModuleBaseURL() + SConsts.SERVLET_UPLOAD);
-        uploader.avoidRepeatFiles(true);
-        uploader.setI18Constants(constants);
-        
         mPanel.add(detailGrid);
 
         HorizontalPanel buttonBar = new HorizontalPanel();
@@ -272,15 +268,20 @@
         return uploader;
     }
 
-    /*
-     * (non-Javadoc)
+    /* (non-Javadoc)
      * @see org.apache.hupa.client.mvp.MessageSendPresenter.Display#resetUploader()
      */
     public void resetUploader() {
-        uploader.removeFromParent();
-        uploader = new MultiUploader();
+        if (uploader != null && uploader.isAttached())
+            uploader.removeFromParent();
+        
+        BaseUploadStatus uploadStatus = new BaseUploadStatus();
+        uploadStatus.setCancelConfiguration(IUploadStatus.GMAIL_CANCEL_CFG);
+        uploader = new MultiUploader(uploadStatus);
         uploader.setServletPath(GWT.getModuleBaseURL() + SConsts.SERVLET_UPLOAD);
         uploader.avoidRepeatFiles(true);
+        uploader.setI18Constants(constants);        
+        
         detailGrid.setWidget(5, 1, uploader);        
     }
 

Modified: james/hupa/trunk/client/war/WEB-INF/web.xml
URL: http://svn.apache.org/viewvc/james/hupa/trunk/client/war/WEB-INF/web.xml?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/client/war/WEB-INF/web.xml (original)
+++ james/hupa/trunk/client/war/WEB-INF/web.xml Tue Dec  1 15:05:00 2009
@@ -10,19 +10,18 @@
 		<welcome-file>Hupa.html</welcome-file>
 	</welcome-file-list>
 
+	<!-- Max size of the upload request (10MB) -->
 	<context-param>
-		<!-- max size of the upload request (10MB) -->
 		<param-name>maxSize</param-name>
 		<param-value>10485760</param-value>
 	</context-param>
-	<context-param>
-		<!--
-			useful in development mode to see the upload progress bar in fast
-			networks
-		-->
+	<!-- Useful in development mode to see the upload progress bar in fast networks -->
+        <!--
+	    <context-param>
 		<param-name>slowUploads</param-name>
-		<param-value>true</param-value>
-	</context-param>
+		<param-value>100</param-value>
+	    </context-param>
+        -->
 	
 	<!-- servlet for incubator gwt stuff -->
 	<servlet>

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerModule.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerModule.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerModule.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/guice/GuiceServerModule.java Tue Dec  1 15:05:00 2009
@@ -28,7 +28,6 @@
 import net.customware.gwt.dispatch.server.guice.ActionHandlerModule;
 
 import org.apache.commons.logging.Log;
-import org.apache.hupa.server.FileItemRegistry;
 import org.apache.hupa.server.IMAPStoreCache;
 import org.apache.hupa.server.InMemoryIMAPStoreCache;
 import org.apache.hupa.server.handler.CheckSessionHandler;
@@ -41,10 +40,10 @@
 import org.apache.hupa.server.handler.FetchRecentMessagesHandler;
 import org.apache.hupa.server.handler.ForwardMessageHandler;
 import org.apache.hupa.server.handler.GetMessageDetailsHandler;
+import org.apache.hupa.server.handler.IdleHandler;
 import org.apache.hupa.server.handler.LoginUserHandler;
 import org.apache.hupa.server.handler.LogoutUserHandler;
 import org.apache.hupa.server.handler.MoveMessageHandler;
-import org.apache.hupa.server.handler.IdleHandler;
 import org.apache.hupa.server.handler.RenameFolderHandler;
 import org.apache.hupa.server.handler.ReplyMessageHandler;
 import org.apache.hupa.server.handler.SendMessageHandler;
@@ -71,7 +70,7 @@
     public static final String[] CONFIG_PROPERTIES = {
             System.getenv("HOME") + "/.hupa/" + CONFIG_FILE_NAME,
             "/etc/default/hupa"
-            };
+    };
     public static final String CONF_DIR = "WEB-INF/conf/";
 
     private String configDir;
@@ -101,7 +100,6 @@
         bindHandler(CreateFolderHandler.class);
         bindHandler(TagMessagesHandler.class);
         bindHandler(SetFlagsHandler.class);
-        bind(FileItemRegistry.class).in(Singleton.class);
         bind(IMAPStoreCache.class).to(InMemoryIMAPStoreCache.class).in(
                 Singleton.class);
         bind(Log.class).toProvider(LogProvider.class).in(Singleton.class);

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=885783&r1=885782&r2=885783&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 Tue Dec  1 15:05:00 2009
@@ -24,7 +24,6 @@
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
-import java.util.Arrays;
 import java.util.List;
 import java.util.Properties;
 
@@ -32,6 +31,7 @@
 import javax.activation.DataSource;
 import javax.mail.Address;
 import javax.mail.AuthenticationFailedException;
+import javax.mail.BodyPart;
 import javax.mail.Folder;
 import javax.mail.Message;
 import javax.mail.MessagingException;
@@ -40,7 +40,6 @@
 import javax.mail.Transport;
 import javax.mail.Flags.Flag;
 import javax.mail.internet.AddressException;
-import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMultipart;
@@ -55,6 +54,8 @@
 import org.apache.hupa.server.IMAPStoreCache;
 import org.apache.hupa.server.guice.DemoModeConstants;
 import org.apache.hupa.server.mock.MockSMTPTransport;
+import org.apache.hupa.server.utils.MessageUtils;
+import org.apache.hupa.server.utils.RegexPatterns;
 import org.apache.hupa.shared.data.MessageAttachment;
 import org.apache.hupa.shared.data.SMTPMessage;
 import org.apache.hupa.shared.data.User;
@@ -73,25 +74,57 @@
  */
 public abstract class AbstractSendMessageHandler<A extends SendMessage> extends AbstractSessionHandler<A,GenericResult> {
 
-    private final FileItemRegistry registry;
     private final Properties props = new Properties();
     private final boolean auth;
     private final String address;
     private final int port;
     private boolean useSSL = false;
+    private Provider<HttpSession> httpSessionProvider;
 
     @Inject
-    public AbstractSendMessageHandler(Log logger, FileItemRegistry registry, IMAPStoreCache store, Provider<HttpSession> provider, @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
+    public AbstractSendMessageHandler(Log logger, IMAPStoreCache store, Provider<HttpSession> provider, @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
         super(store,logger,provider);
-        this.registry = registry;
         this.auth = auth;
         this.address = address;
         this.port = port;
         this.useSSL  = useSSL;
+        this.httpSessionProvider = provider;
         props.put("mail.smtp.auth", auth);
     }
 
+    @Override
+    protected GenericResult executeInternal(A action, ExecutionContext context)
+            throws ActionException {
+        GenericResult result = new GenericResult();
+        try {
+            Session session = Session.getDefaultInstance(props);
 
+            Message message = createMessage(session, action);
+            message = fillBody(message,action);
+
+            sendMessage(session, getUser(), message);
+            saveSentMessage(session, getUser(), message);
+        
+            resetAttachments(action);
+        
+            // TODO: notify the user more accurately where is the error
+            // if the message was sent and the storage in the sent folder failed, etc.
+        } catch (AddressException e) {
+            result.setError("Error while parsing recipient: " + e.getMessage());
+            logger.error("Error while parsing recipient", e);
+        } catch (AuthenticationFailedException e) {
+            result.setError("Error while sending message: SMTP Authentication error.");
+            logger.error("SMTP Authentication error", e);
+        } catch (MessagingException e) {
+            result.setError("Error while sending message: " + e.getMessage());
+            logger.error("Error while sending message", e);
+        } catch (Exception e) {
+            result.setError("Unexpected exception while sendig message: " + e.getMessage());
+            logger.error("Unexpected exception while sendig message: ", e);
+        }
+        return result;
+    }
+    
     /**
      * Create basic Message which contains all headers. No body is filled
      * 
@@ -103,7 +136,7 @@
      * @throws ActionException
      */
     protected abstract Message createMessage(Session session, A action) throws AddressException, MessagingException,ActionException;
-    
+
     /**
      * Fill the body of the given message with data which the given action contain
      * 
@@ -116,30 +149,21 @@
      */
     protected Message fillBody(Message message, A action) throws MessagingException, ActionException, IOException {
 
-        SMTPMessage m = action.getMessage();
-        ArrayList<MessageAttachment> attachments = m.getMessageAttachments();
+        String html = restoreInlineLinks(action.getMessage().getText());
         
-        // Create the body
-        Multipart body = createMultipartAlternative(m.getText());
+        // TODO: client sends the message as html right now, 
+        // the idea is that it should be sent in both formats because
+        // it is easier to do the handle html in the browser. 
+        String text = htmlToText(html);
         
-        // check if there are any attachments to include
-        if (attachments == null || attachments.isEmpty()) {
-            message.setContent(body);
-        } else {
-            // create the message part with the  body
-            MimeBodyPart messageBodyPart = new MimeBodyPart();
-            messageBodyPart.setContent(body);
+        @SuppressWarnings("unchecked")
+        List items = getAttachments(action);
+        
+        return composeMessage(message, text, html, items);
+    }
 
-            // create the multipart which contains the message and attachments
-            Multipart multipart = new MimeMultipart();
-            multipart.addBodyPart(messageBodyPart);
-            multipart = handleAttachments(multipart, attachments);
-            
-            message.setContent(multipart);
-        }
-        // save message 
-        message.saveChanges();
-        return message;
+    protected String restoreInlineLinks(String s) {
+        return RegexPatterns.replaceAll(s, RegexPatterns.regex_revertInlineImg, RegexPatterns.repl_revertInlineImg);
     }
     
     protected String htmlToText(String s){
@@ -152,59 +176,52 @@
         return s;
     }
     
-    protected Multipart createMultipartAlternative(String html) throws MessagingException {
-        MimeMultipart mimeMultipart= new MimeMultipart();
-        mimeMultipart.setSubType("alternative");
-        
-        MimeBodyPart txtPart= new MimeBodyPart();
-        txtPart.setContent(htmlToText(html), "text/plain");
-        mimeMultipart.addBodyPart(txtPart);
-        
-        MimeBodyPart htmlPart= new MimeBodyPart();
-        htmlPart.setContent(html, "text/html");
-        htmlPart.setHeader("Content-Type", "text/html; format=flowed");
-        mimeMultipart.addBodyPart(htmlPart);
-        
-        return mimeMultipart;
-   
+    /**
+     * Get the attachments stored in the registry.
+     * 
+     * @param attachments
+     * @return
+     */
+    @SuppressWarnings("unchecked")
+    protected List getAttachments(A action) throws MessagingException, ActionException {
+        FileItemRegistry registry = MessageUtils.getSessionRegistry(httpSessionProvider.get(), logger); 
+        List<MessageAttachment> attachments = action.getMessage().getMessageAttachments();
+        ArrayList<FileItem> items = new ArrayList<FileItem>();
+        for (MessageAttachment attachment: attachments) {
+            FileItem fItem = registry.get(attachment.getName());
+            if (fItem != null)
+                items.add(fItem);
+        }
+        logger.debug("Found " + items.size() + " attachmets in the registry.");
+        return items;
     }
-
+    
+    /**
+     * Remove attachments from the registry
+     *  
+     * @param action
+     * @throws MessagingException
+     * @throws ActionException
+     */
     protected void resetAttachments(A action) throws MessagingException, ActionException {
-        SMTPMessage m = action.getMessage();
-        ArrayList<MessageAttachment> attachments = m.getMessageAttachments();
+        SMTPMessage msg = action.getMessage();
+        ArrayList<MessageAttachment> attachments = msg.getMessageAttachments();
         if (attachments != null && ! attachments.isEmpty()) {
             for(MessageAttachment attach : attachments) 
-                registry.remove(attach.getName());
+                MessageUtils.getSessionRegistry(httpSessionProvider.get(), logger).remove(attach.getName());
         }
     }
     
     /**
-     * Construct the multipart for the given attachments and return it
+     * Send the message using SMTP, if the configuration uses authenticated SMTP, it uses
+     * the user stored in session to get the given login and password.
      * 
-     * @param multipart 
-     * @param attachments
-     * @return multipart
+     * @param user
+     * @param session
+     * @param message
      * @throws MessagingException
      */
-    protected Multipart handleAttachments(Multipart multipart, ArrayList<MessageAttachment> attachments) throws MessagingException {
-        if (attachments != null) {
-            for(MessageAttachment attachment: attachments) {
-                // get the attachment from the registry
-                FileItem fItem = registry.get(attachment.getName());
-                if (fItem == null)
-                    continue;
-                // Part two is attachment
-                MimeBodyPart messageBodyPart = new MimeBodyPart();
-                DataSource source = new FileItemDataStore(fItem);
-                messageBodyPart.setDataHandler(new DataHandler(source));
-                messageBodyPart.setFileName(source.getName());
-                multipart.addBodyPart(messageBodyPart);
-            }
-        }
-        return multipart;
-    }
-
-    protected void sendMessage(User user, Session session, Message message) throws MessagingException {
+    protected void sendMessage(Session session, User user, Message message) throws MessagingException {
         Transport transport;
     
         if (DemoModeConstants.DEMO_MODE.equals(address)) {
@@ -234,7 +251,15 @@
         transport.sendMessage(message, recips);
     }
 
-    protected void saveSentMessage(User user, Message message) throws MessagingException {
+    /**
+     * Save the message in the sent folder
+     * 
+     * @param user
+     * @param message
+     * @throws MessagingException
+     * @throws IOException 
+     */
+    protected void saveSentMessage(Session session, User user, Message message) throws MessagingException, IOException {
         IMAPStore iStore = cache.get(user);
         IMAPFolder folder = (IMAPFolder) iStore.getFolder(user.getSettings().getSentFolderName());
         
@@ -248,6 +273,13 @@
             if (folder.isOpen() == false) {
                 folder.open(Folder.READ_WRITE);
             }
+
+            // It is necessary to copy the message, before putting it
+            // in the sent folder. If not, it is not guaranteed that it is 
+            // stored in ascii and is not possible to get the attachments
+            // size.
+            message = new MimeMessage((MimeMessage)message);
+
             message.setFlag(Flag.SEEN, true);
             folder.appendMessages(new Message[] {message});
             
@@ -256,135 +288,14 @@
             } catch (MessagingException e) {
                 // we don't care on close
             }
-
-        }
-    }
-    
-    
-
-    /**
-     * DataStore which wrap a FileItem
-     * 
-     */
-    protected static class FileItemDataStore implements DataSource {
-
-        private FileItem item;
-
-        public FileItemDataStore(FileItem item) {
-            this.item = item;
-        }
-
-        /*
-         * (non-Javadoc)
-         * @see javax.activation.DataSource#getContentType()
-         */
-        public String getContentType() {
-            return item.getContentType();
-        }
-
-        /*
-         * (non-Javadoc)
-         * @see javax.activation.DataSource#getInputStream()
-         */
-        public InputStream getInputStream() throws IOException {
-            return item.getInputStream();
-        }
-
-        /*
-         * (non-Javadoc)
-         * @see javax.activation.DataSource#getName()
-         */
-        public String getName() {
-            String fullName = item.getName();
-            
-            // Strip path from file
-            int index = fullName.lastIndexOf(File.separator);
-            if (index == -1) {
-                return fullName;
-            } else {
-                return fullName.substring(index +1 ,fullName.length());
-            }
         }
-
-        /*
-         * (non-Javadoc)
-         * @see javax.activation.DataSource#getOutputStream()
-         */
-        public OutputStream getOutputStream() throws IOException {
-            return null;
-        }
-
     }
 
-
-
-    @Override
-    protected GenericResult executeInternal(A action, ExecutionContext context)
-            throws ActionException {
-        GenericResult result = new GenericResult();
-        try {
-            Session session = Session.getDefaultInstance(props);
-
-            Message message = createMessage(session, action);
-            message = fillBody(message,action);
-
-            sendMessage(getUser(),session, message);
-            saveSentMessage(getUser(), message);
-            resetAttachments(action);
-        
-            // TODO: notify the user more accurately where is the error
-            // if the message was sent and the storage in the sent folder failed, etc.
-        } catch (AddressException e) {
-            result.setError("Error while parsing recipient: " + e.getMessage());
-            logger.error("Error while parsing recipient", e);
-        } catch (AuthenticationFailedException e) {
-            result.setError("Error while sending message: SMTP Authentication error.");
-            logger.error("SMTP Authentication error", e);
-        } catch (MessagingException e) {
-            result.setError("Error while sending message: " + e.getMessage());
-            logger.error("Error while sending message", e);
-        } catch (Exception e) {
-            result.setError("Unexpected exception while sendig message: " + e.getMessage());
-            logger.error("Unexpected exception while sendig message: ", e);
-        }
-        return result;
-    }
-    
     /**
-     * Get a Address array for a set of address passed as arguments 
+     * Fill the body of a message already created.
+     * The result message depends on the information given. 
      * 
-     * @param addresses
-     * @return Address array
-     * @throws AddressException
-     */
-    static protected Address[] getRecipients(String... addresses) throws AddressException {
-        return getRecipients(Arrays.asList(addresses));
-    }
-
-    /**
-     * Get a Address array for the given ArrayList 
-     * 
-     * @param recipients
-     * @return addressArray
-     * @throws AddressException
-     */
-    static protected Address[] getRecipients(List<String> recipients) throws AddressException {
-        if (recipients == null) {
-            return new InternetAddress[]{};
-        }
-        Address[] array = new Address[recipients.size()];
-        for (int i = 0; i < recipients.size(); i++) {
-            array[i] = new InternetAddress(recipients.get(i));
-        }
-        return array;
-
-    }
-    
-    /**
-     * Generate a mime-message 
-     * 
-     * 
-     * @param session
+     * @param message
      * @param text
      * @param html
      * @param items
@@ -392,13 +303,16 @@
      * @throws MessagingException
      * @throws IOException
      */
-    public static Message composeMessage (Session session, String text, String html, List<FileItem> items) throws MessagingException, IOException {
-        Message message = new MimeMessage(session);
+    @SuppressWarnings("unchecked")
+    public static Message composeMessage (Message message, String text, String html, List parts) throws MessagingException, IOException {
 
         MimeBodyPart txtPart = null;
         MimeBodyPart htmlPart = null;
         MimeMultipart mimeMultipart = null;
 
+        if (text == null && html == null) {
+           text = ""; 
+        }
         if (text != null) {
             txtPart = new MimeBodyPart();
             txtPart.setContent(text, "text/plain");
@@ -414,7 +328,7 @@
             mimeMultipart.addBodyPart(htmlPart);
         }
 
-        if (items == null || items.size() == 0) {
+        if (parts == null || parts.isEmpty()) {
             if (mimeMultipart != null) {
                 message.setContent(mimeMultipart);
             } else if (html != null) {
@@ -424,7 +338,6 @@
                 message.setText(text);
             }
         } else {
-            Multipart multipart = new MimeMultipart();
             MimeBodyPart bodyPart = new MimeBodyPart();
             if (mimeMultipart != null) {
                 bodyPart.setContent(mimeMultipart);
@@ -434,13 +347,14 @@
             } else if (text != null) {
                 bodyPart.setText(text);
             }
+            Multipart multipart = new MimeMultipart();
             multipart.addBodyPart(bodyPart);
-            for (FileItem fileItem: items) {
-                MimeBodyPart messageBodyPart = new MimeBodyPart();
-                DataSource source = new AbstractSendMessageHandler.FileItemDataStore(fileItem);
-                messageBodyPart.setDataHandler(new DataHandler(source));
-                messageBodyPart.setFileName(source.getName());
-                multipart.addBodyPart(messageBodyPart);
+            for (Object attachment: parts) {
+                if (attachment instanceof FileItem) {
+                    multipart.addBodyPart(fileitemToBodypart((FileItem)attachment));
+                } else {
+                    multipart.addBodyPart((BodyPart)attachment);
+                }
             }
             message.setContent(multipart);
         }
@@ -449,5 +363,68 @@
         return message;
 
     }
+    
+    private static BodyPart fileitemToBodypart(FileItem item) throws MessagingException {
+        MimeBodyPart messageBodyPart = new MimeBodyPart();
+        DataSource source = new AbstractSendMessageHandler.FileItemDataStore(item);
+        messageBodyPart.setDataHandler(new DataHandler(source));
+        messageBodyPart.setFileName(source.getName());
+        return messageBodyPart;
+    }
+    
+
+    /**
+     * DataStore which wrap a FileItem
+     * 
+     */
+    protected static class FileItemDataStore implements DataSource {
+
+        private FileItem item;
+
+        public FileItemDataStore(FileItem item) {
+            this.item = item;
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.activation.DataSource#getContentType()
+         */
+        public String getContentType() {
+            return item.getContentType();
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.activation.DataSource#getInputStream()
+         */
+        public InputStream getInputStream() throws IOException {
+            return item.getInputStream();
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.activation.DataSource#getName()
+         */
+        public String getName() {
+            String fullName = item.getName();
+            
+            // Strip path from file
+            int index = fullName.lastIndexOf(File.separator);
+            if (index == -1) {
+                return fullName;
+            } else {
+                return fullName.substring(index +1 ,fullName.length());
+            }
+        }
+
+        /*
+         * (non-Javadoc)
+         * @see javax.activation.DataSource#getOutputStream()
+         */
+        public OutputStream getOutputStream() throws IOException {
+            return null;
+        }
+
+    }
 
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ForwardMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ForwardMessageHandler.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ForwardMessageHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ForwardMessageHandler.java Tue Dec  1 15:05:00 2009
@@ -19,26 +19,31 @@
 
 package org.apache.hupa.server.handler;
 
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
 import java.util.List;
 
+import javax.activation.DataSource;
+import javax.mail.BodyPart;
 import javax.mail.Folder;
 import javax.mail.Message;
 import javax.mail.MessagingException;
-import javax.mail.Multipart;
 import javax.mail.Session;
 import javax.mail.internet.AddressException;
 import javax.mail.internet.InternetAddress;
-import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
-import javax.mail.internet.MimeMultipart;
 import javax.mail.internet.MimeMessage.RecipientType;
 import javax.servlet.http.HttpSession;
 
 import net.customware.gwt.dispatch.shared.ActionException;
 
+import org.apache.commons.fileupload.FileItem;
 import org.apache.commons.logging.Log;
-import org.apache.hupa.server.FileItemRegistry;
 import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.utils.MessageUtils;
 import org.apache.hupa.shared.data.SMTPMessage;
 import org.apache.hupa.shared.rpc.ForwardMessage;
 
@@ -50,82 +55,124 @@
 
 /**
  * Handler which handles the forwarding of a message
- * @author norman
- *
+ * 
  */
-public class ForwardMessageHandler extends AbstractSendMessageHandler<ForwardMessage>{
+public class ForwardMessageHandler extends AbstractSendMessageHandler<ForwardMessage> {
 
     @Inject
-    public ForwardMessageHandler(Log logger, FileItemRegistry registry,
-            IMAPStoreCache store, Provider<HttpSession> provider,
-            @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
-        super(logger, registry, store, provider, address, port, auth, useSSL);
+    public ForwardMessageHandler(Log logger, IMAPStoreCache store, Provider<HttpSession> provider, @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port,
+            @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
+        super(logger, store, provider, address, port, auth, useSSL);
     }
 
     @Override
-    protected Message createMessage(Session session, ForwardMessage action)
-            throws AddressException, MessagingException, ActionException {
-            MimeMessage message = new MimeMessage(session);
-            SMTPMessage m = action.getMessage();
-            message.setFrom(new InternetAddress(m.getFrom()));
-            List<String> to = m.getTo();
-            for (int i = 0; i < to.size(); i++) {
-                message.addRecipient(RecipientType.TO, new InternetAddress(to
-                        .get(i)));
-            }
-
-            List<String> cc = m.getCc();
-            for (int i = 0; cc != null && i < cc.size(); i++) {
-                message.addRecipient(RecipientType.CC, new InternetAddress(cc
-                        .get(i)));
-            }
-            message.setSubject(m.getSubject());
-            message.saveChanges();
-            return message;
-    }
-
-    @Override
-    protected Message fillBody(Message message,
-            ForwardMessage action) throws MessagingException, ActionException {
+    protected Message createMessage(Session session, ForwardMessage action) throws AddressException, MessagingException, ActionException {
+        MimeMessage message = new MimeMessage(session);
         SMTPMessage m = action.getMessage();
+        message.setFrom(new InternetAddress(m.getFrom()));
+        List<String> to = m.getTo();
+        for (int i = 0; i < to.size(); i++) {
+            message.addRecipient(RecipientType.TO, new InternetAddress(to.get(i)));
+        }
 
-        // create the message part
-        MimeBodyPart messageBodyPart = new MimeBodyPart();
+        List<String> cc = m.getCc();
+        for (int i = 0; cc != null && i < cc.size(); i++) {
+            message.addRecipient(RecipientType.CC, new InternetAddress(cc.get(i)));
+        }
+        message.setSubject(m.getSubject());
+        message.saveChanges();
+        return message;
+    }
 
-        // fill message
-        messageBodyPart.setText(m.getText());
 
-        Multipart multipart = new MimeMultipart();
-        multipart.addBodyPart(messageBodyPart);
-        
+    @Override
+    @SuppressWarnings("unchecked")
+    protected List getAttachments(ForwardMessage action) throws MessagingException, ActionException {
+        List<BodyPart> items = new ArrayList<BodyPart>();
         IMAPStore store = cache.get(getUser());
-        
+
         IMAPFolder folder = (IMAPFolder) store.getFolder(action.getFolder().getFullName());
         if (folder.isOpen() == false) {
             folder.open(Folder.READ_ONLY);
         }
-        Message fMessage = folder.getMessageByUID(action.getReplyMessageUid());
-        
-        // Create and fill part for the forwarded content
-        messageBodyPart = new MimeBodyPart();
-        messageBodyPart.setDataHandler(fMessage.getDataHandler());
-        multipart.addBodyPart(messageBodyPart);
-
-        multipart = handleAttachments(multipart, m.getMessageAttachments());
-        
-        
-        // Put parts in message
-        message.setContent(multipart);
-        message.saveChanges();
-        return message;
+        // Put the original attachments in the list 
+        Message msg = folder.getMessageByUID(action.getReplyMessageUid());
+        try {
+            items = MessageUtils.extractMessageAttachments(logger, msg.getContent());
+            logger.debug("Forwarding a message, extracted: " + items.size() + " from original.");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        // Put in the list the attachments uploaded by the user
+        items.addAll(super.getAttachments(action));
+        return items;
     }
 
     /*
      * (non-Javadoc)
+     * 
      * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
      */
     public Class<ForwardMessage> getActionType() {
         return ForwardMessage.class;
     }
 
+    /**
+     * DataStore which wrap a FileItem
+     * 
+     */
+    protected static class PartDataStore implements DataSource {
+
+        private FileItem item;
+
+        public PartDataStore(FileItem item) {
+            this.item = item;
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.activation.DataSource#getContentType()
+         */
+        public String getContentType() {
+            return item.getContentType();
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.activation.DataSource#getInputStream()
+         */
+        public InputStream getInputStream() throws IOException {
+            return item.getInputStream();
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.activation.DataSource#getName()
+         */
+        public String getName() {
+            String fullName = item.getName();
+
+            // Strip path from file
+            int index = fullName.lastIndexOf(File.separator);
+            if (index == -1) {
+                return fullName;
+            } else {
+                return fullName.substring(index + 1, fullName.length());
+            }
+        }
+
+        /*
+         * (non-Javadoc)
+         * 
+         * @see javax.activation.DataSource#getOutputStream()
+         */
+        public OutputStream getOutputStream() throws IOException {
+            return null;
+        }
+
+    }
+
 }

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=885783&r1=885782&r2=885783&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 Tue Dec  1 15:05:00 2009
@@ -22,7 +22,6 @@
 import java.io.IOException;
 import java.io.UnsupportedEncodingException;
 import java.util.ArrayList;
-import java.util.regex.Pattern;
 
 import javax.mail.Flags;
 import javax.mail.Message;
@@ -39,7 +38,7 @@
 
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.IMAPStoreCache;
-import org.apache.hupa.shared.SConsts;
+import static org.apache.hupa.server.utils.RegexPatterns.*;
 import org.apache.hupa.shared.data.IMAPFolder;
 import org.apache.hupa.shared.data.MessageAttachment;
 import org.apache.hupa.shared.data.MessageDetails;
@@ -199,13 +198,15 @@
                         isHTML =  handleParts(msg, msg.getContent(), sbPlain, attachmentList);
                     } else {
                         if (part.getFileName() != null) {
-                            MessageAttachment attachment = new MessageAttachment();
-                            attachment.setName(MimeUtility.decodeText(part
-                                    .getFileName()));
-                            attachment.setContentType(part.getContentType());
-                            attachment.setSize(part.getSize());
-
-                            attachmentList.add(attachment);
+                            // Inline images are not added to the attachment list
+                            // TODO: improve the in-line images detection 
+                            if (part.getHeader("Content-ID") == null) {
+                                MessageAttachment attachment = new MessageAttachment();
+                                attachment.setName(MimeUtility.decodeText(part.getFileName()));
+                                attachment.setContentType(part.getContentType());
+                                attachment.setSize(part.getSize());
+                                attachmentList.add(attachment);
+                            }
                         } else {
                             isHTML = handleParts(message, part.getContent(), sbPlain, attachmentList);
                         }
@@ -241,69 +242,21 @@
         return isHTML;
     }
     
-    
-    static String HTML_LINK_REGEXP =  "\\b?(https?://[\\w\\d:#@%/;$\\(\\)~_\\?\\+\\-=\\\\.&]*)\\b?";
-    static Pattern regex_http = Pattern.compile(HTML_LINK_REGEXP);
-    static String repl_http = "<a href=\"$1\">$1</a>";
-
-    static String EMAIL_REGEXP =  "\\b(?<![A-z0-9._%\\+\\-=])([A-z][A-z0-9._%\\+\\-]+@[A-z0-9\\.\\-]+\\.[A-z]{2,4})";
-    static Pattern regex_email = Pattern.compile("\\b"+ EMAIL_REGEXP);
-    static String repl_email = "<a href=\"mailto:$1\">$1</a>";
-    
-    static Pattern regex_inlineImg = Pattern.compile("(?si)(<\\s*img\\s+.*?src=[\"'])cid:([^\"']+[\"'])");
-    static String repl_inlineImg = "$1" + SConsts.HUPA + SConsts.SERVLET_DOWNLOAD 
-                            + "?" + SConsts.PARAM_FOLDER + "=%%FOLDER%%" 
-                            + "&" + SConsts.PARAM_UID + "=%%UID%%" 
-                            + "&" + SConsts.PARAM_NAME + "=$2";
-
-    static Pattern regex_badTags = Pattern.compile("(?si)<(script|style|head).*?</\\1\\s*>");
-    static String repl_badTags = "";
-
-    static Pattern regex_unneededTags = Pattern.compile("(?si)(</?(html|body)[^>]*?>)");
-    static String repl_unneededTags = "";
-
-    static String EVENT_ATTR_REGEX = "(?:on[dbl]*click)|(?:onmouse[a-z]+)|(?:onkey[a-z]+)";
-    static Pattern regex_badAttrs = Pattern.compile("(?si)(<\\w+[^<>]*)\\s+("+ EVENT_ATTR_REGEX + ")=[\"']?([^\\s<>]+?)[\"']?([\\s>])");
-    static String repl_badAttrs = "$1$4";
-    
-    static Pattern regex_orphandHttpLinks = Pattern.compile("(?si)(?!.*<a\\s?[^>]*?>.+</a\\s*>.*)(<[^<]*?>[^<>]*)" + HTML_LINK_REGEXP + "([^<>]*<[^>]*?>)");
-    static String repl_orphandHttpLinks = "$1<a href=\"$2\">$2</a>$3";
-    
-    static Pattern regex_existingHttpLinks = Pattern.compile("(?si)<a\\s[^>]*?href=[\"']?" + HTML_LINK_REGEXP + "[\"']?");
-    static String repl_existingHttpLinks = "<a onClick=\"openLink('$1');return false;\" href=\"$1\"";
-
-    static Pattern regex_orphandEmailLinks = Pattern.compile("(?si)(?!.*<a\\s?[^>]*?>.+</a\\s*>.*)(<[^<]*?>[^<>]*)" + EMAIL_REGEXP + "([^<>]*<[^>]*?>)");
-    static String repl_orphandEmailLinks = "$1<a href=\"mailto:$2\">$2</a>$3";
-
-    static Pattern regex_existingEmailLinks = Pattern.compile("(?si)<a\\s[^>]*?href=[\"']*mailto:[\"']?([^\"]+)[\"']?");
-    static String repl_existngEmailLinks = "<a onClick=\"mailTo('$1');return false;\" href=\"mailto:$1\"";
-    
-    
-    protected String replaceAll(String txt, Pattern pattern, String replacement) {
-        return pattern.matcher(txt).replaceAll(replacement);
-    }
-    
-    protected String replaceAllRecursive(String txt, Pattern pattern, String replacement) {
-        while (pattern.matcher(txt).find())
-            txt = pattern.matcher(txt).replaceAll(replacement);
-        return txt;
-    }
-
     protected String txtDocumentToHtml(String txt, String folderName, long uuid) {
         
         if (txt == null || txt.length()==0)
             return txt;
 
         // escape html tags symbols 
-        txt = txt.replaceAll("<", "&lt;");
-        txt = txt.replaceAll(">", "&gt;");
+        txt = replaceAll(txt, regex_lt, repl_lt);
+        txt = replaceAll(txt, regex_gt, repl_gt);
         
         // enclose between <a> http links and emails
-        txt = replaceAll(txt, regex_http, repl_http);
+        txt = replaceAll(txt, regex_htmllink, repl_htmllink);
         txt = replaceAll(txt, regex_email, repl_email);
         
         // put break lines
-        txt = txt.replaceAll("\r", "").replaceAll("\n", "<br/>\n");
+        txt = replaceAll(txt, regex_nl, repl_nl);
         
         txt = filterHtmlDocument(txt, folderName, uuid);
 

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ReplyMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ReplyMessageHandler.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ReplyMessageHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ReplyMessageHandler.java Tue Dec  1 15:05:00 2009
@@ -31,8 +31,8 @@
 import net.customware.gwt.dispatch.shared.ActionException;
 
 import org.apache.commons.logging.Log;
-import org.apache.hupa.server.FileItemRegistry;
 import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.utils.MessageUtils;
 import org.apache.hupa.shared.data.SMTPMessage;
 import org.apache.hupa.shared.rpc.ReplyMessage;
 
@@ -50,10 +50,9 @@
 public class ReplyMessageHandler extends AbstractSendMessageHandler<ReplyMessage>{
 
     @Inject
-    public ReplyMessageHandler(Log logger, FileItemRegistry registry,
-            IMAPStoreCache store, Provider<HttpSession> provider,
+    public ReplyMessageHandler(Log logger, IMAPStoreCache store, Provider<HttpSession> provider,
             @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
-        super(logger, registry, store, provider, address, port, auth, useSSL);
+        super(logger, store, provider, address, port, auth, useSSL);
     }
 
     /*
@@ -70,9 +69,9 @@
         Message rMessage =  folder.getMessageByUID(action.getReplyMessageUid()).reply(action.getReplyAll());
         SMTPMessage m = action.getMessage();
         // Use the new recipient list, maybe it has changed
-        rMessage.setRecipients(RecipientType.TO, getRecipients(m.getTo()));
-        rMessage.setRecipients(RecipientType.CC, getRecipients(m.getCc()));
-        rMessage.setRecipients(RecipientType.BCC, getRecipients(m.getBcc()));
+        rMessage.setRecipients(RecipientType.TO, MessageUtils.getRecipients(m.getTo()));
+        rMessage.setRecipients(RecipientType.CC, MessageUtils.getRecipients(m.getCc()));
+        rMessage.setRecipients(RecipientType.BCC, MessageUtils.getRecipients(m.getBcc()));
         rMessage.setFrom(new InternetAddress(m.getFrom()));
         // replace subject
         rMessage.setSubject(m.getSubject());

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java Tue Dec  1 15:05:00 2009
@@ -29,8 +29,8 @@
 import javax.servlet.http.HttpSession;
 
 import org.apache.commons.logging.Log;
-import org.apache.hupa.server.FileItemRegistry;
 import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.utils.MessageUtils;
 import org.apache.hupa.shared.data.SMTPMessage;
 import org.apache.hupa.shared.rpc.SendMessage;
 
@@ -46,9 +46,9 @@
 public class SendMessageHandler extends AbstractSendMessageHandler<SendMessage> {
 
     @Inject
-    public SendMessageHandler(Log logger, FileItemRegistry registry,
-            IMAPStoreCache store, Provider<HttpSession> provider,@Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
-        super(logger, registry, store, provider, address, port, auth,useSSL);
+    public SendMessageHandler(Log logger, IMAPStoreCache store, Provider<HttpSession> provider,
+            @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
+        super(logger, store, provider, address, port, auth,useSSL);
     }
 
     /*
@@ -60,9 +60,9 @@
         MimeMessage message = new MimeMessage(session);
         SMTPMessage m = action.getMessage();
         message.setFrom(new InternetAddress(m.getFrom()));
-        message.setRecipients(RecipientType.TO, getRecipients(m.getTo()));
-        message.setRecipients(RecipientType.CC, getRecipients(m.getCc()));
-        message.setRecipients(RecipientType.BCC, getRecipients(m.getBcc()));
+        message.setRecipients(RecipientType.TO, MessageUtils.getRecipients(m.getTo()));
+        message.setRecipients(RecipientType.CC, MessageUtils.getRecipients(m.getCc()));
+        message.setRecipients(RecipientType.BCC, MessageUtils.getRecipients(m.getBcc()));
         message.setSubject(m.getSubject());
         return message;
     }

Modified: 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=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockSMTPTransport.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/mock/MockSMTPTransport.java Tue Dec  1 15:05:00 2009
@@ -19,6 +19,9 @@
 
 package org.apache.hupa.server.mock;
 
+import java.io.IOException;
+import java.io.OutputStream;
+
 import javax.mail.Address;
 import javax.mail.Message;
 import javax.mail.MessagingException;
@@ -28,21 +31,25 @@
 
 import org.apache.hupa.server.guice.DemoModeConstants;
 
-
 public class MockSMTPTransport extends Transport {
 
     static final URLName demoUrl = new URLName(null, DemoModeConstants.DEMO_MODE, 143, null, null, null);
-    
+
     public MockSMTPTransport(Session session) {
         super(session, demoUrl);
     }
 
     @Override
     public void sendMessage(Message msg, Address[] addresses) throws MessagingException {
+        try {
+            msg.writeTo(new OutputStream() {
+                public void write(int b) throws IOException {}
+            });
+        } catch (IOException e) {}
     }
-    
+
     @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=885783&r1=885782&r2=885783&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 Tue Dec  1 15:05:00 2009
@@ -26,10 +26,8 @@
 import javax.mail.Folder;
 import javax.mail.Message;
 import javax.mail.MessagingException;
-import javax.mail.Multipart;
 import javax.mail.Part;
 import javax.mail.Store;
-import javax.mail.internet.MimeUtility;
 import javax.servlet.ServletException;
 import javax.servlet.http.HttpServlet;
 import javax.servlet.http.HttpServletRequest;
@@ -38,6 +36,7 @@
 import org.apache.commons.io.IOUtils;
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.InMemoryIMAPStoreCache;
+import org.apache.hupa.server.utils.MessageUtils;
 import org.apache.hupa.shared.SConsts;
 import org.apache.hupa.shared.data.User;
 
@@ -99,7 +98,7 @@
             Message m = folder.getMessageByUID(Long.parseLong(message_uuid));
 
             Object content = m.getContent();
-            Part part  = handleMultiPart(logger, content, attachmentName);
+            Part part  = MessageUtils.handleMultiPart(logger, content, attachmentName);
             if (part.getContentType()!=null)
                 response.setContentType(part.getContentType());
             else
@@ -139,49 +138,4 @@
         }
     }
 
-    /**
-     * Loop over MuliPart and write the content to the Outputstream if a
-     * attachment with the given name was found.
-     *
-     * @param out
-     *            Outputstream to write the content to
-     * @param content
-     *            Content which should checked for attachments
-     * @param attachmentName
-     *            The attachmentname or the unique id for the searched attachment
-     * @throws MessagingException
-     * @throws IOException
-     */
-    static protected Part handleMultiPart(Log logger, Object content, String attachmentName)
-            throws MessagingException, IOException {
-        if (content instanceof Multipart) {
-            Multipart part = (Multipart) content;
-            for (int i = 0; i < part.getCount(); i++) {
-                Part bodyPart = part.getBodyPart(i);
-                String fileName = bodyPart.getFileName();
-                String[] contentId = bodyPart.getHeader("Content-ID");
-                if (bodyPart.isMimeType("multipart/*")) {
-                    Part p = handleMultiPart(logger, 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 {
-            logger.error("Unknown content: " + content.getClass().getName());
-        }
-        return null;
-    }
-
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/UploadAttachmentServlet.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/UploadAttachmentServlet.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/UploadAttachmentServlet.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/servlet/UploadAttachmentServlet.java Tue Dec  1 15:05:00 2009
@@ -27,6 +27,7 @@
 import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.fileupload.FileItem;
+import org.apache.commons.logging.Log;
 import org.apache.hupa.server.FileItemRegistry;
 
 import com.google.inject.Inject;
@@ -40,19 +41,33 @@
 public class UploadAttachmentServlet extends UploadAction{
 
     private static final long serialVersionUID = 4936687307133529124L;
-    private FileItemRegistry registry;
+    
+    
+
+    private Log logger;
     
     @Inject
-    public UploadAttachmentServlet(FileItemRegistry registry) {
-        this.registry = registry;
+    public UploadAttachmentServlet(Log logger) {
+        this.logger = logger;
+    }
+    
+    private FileItemRegistry getSessionRegistry(HttpServletRequest request) {
+        FileItemRegistry registry = (FileItemRegistry)request.getSession().getAttribute("registry");
+        if (registry == null) {
+            registry = new FileItemRegistry(logger);
+            request.getSession().setAttribute("registry", registry);
+        }
+        return registry;
     }
     
     @Override
     public String executeAction(HttpServletRequest request, List<FileItem> sessionFiles) throws UploadActionException {
-        logger.info("Executing Action, files in session: " + sessionFiles.size() + " files in registry: " + registry.size());
-        // save file items in the registry
+
+        logger.info("Executing Action, files in session: " + sessionFiles.size() + " previous files in registry: " + getSessionRegistry(request).size());
+        // save file items in the user session's registry
         for(FileItem item: sessionFiles) 
-            registry.add(item);
+            getSessionRegistry(request).add(item);
+
         
         // remove items from session but not remove the data from disk or memory
         removeSessionFileItems(request, false);
@@ -61,6 +76,6 @@
     
     @Override
     public void removeItem(HttpServletRequest request, FileItem item)  throws UploadActionException {
-       registry.remove(item);
+       getSessionRegistry(request).remove(item);
     }
 }

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/MessageUtils.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/MessageUtils.java?rev=885783&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/MessageUtils.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/MessageUtils.java Tue Dec  1 15:05:00 2009
@@ -0,0 +1,161 @@
+/****************************************************************
+ * 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.utils;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import javax.mail.Address;
+import javax.mail.BodyPart;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Part;
+import javax.mail.internet.AddressException;
+import javax.mail.internet.InternetAddress;
+import javax.mail.internet.MimeUtility;
+import javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.FileItemRegistry;
+
+
+
+/**
+ * Utility methods in server side
+ */
+public class MessageUtils {
+
+    /**
+     * Get a Address array for a set of address passed as arguments 
+     * 
+     * @param addresses
+     * @return Address array
+     * @throws AddressException
+     */
+    public static Address[] getRecipients(String... addresses) throws AddressException {
+        return getRecipients(Arrays.asList(addresses));
+    }
+
+    /**
+     * Get a Address array for the given ArrayList 
+     * 
+     * @param recipients
+     * @return addressArray
+     * @throws AddressException
+     */
+    public static Address[] getRecipients(List<String> recipients) throws AddressException {
+        if (recipients == null) {
+            return new InternetAddress[]{};
+        }
+        Address[] array = new Address[recipients.size()];
+        for (int i = 0; i < recipients.size(); i++) {
+            array[i] = new InternetAddress(recipients.get(i));
+        }
+        return array;
+    }
+
+    /**
+     * Extract the attachments present in a mime message
+     * 
+     * @param logger
+     * @param content
+     * @return
+     * @throws MessagingException
+     * @throws IOException
+     */
+    static public List<BodyPart> extractMessageAttachments(Log logger, Object content) throws MessagingException, IOException {
+        ArrayList<BodyPart> ret = new ArrayList<BodyPart>();
+        if (content instanceof Multipart) {
+            Multipart part = (Multipart) content;
+            for (int i = 0; i < part.getCount(); i++) {
+                BodyPart bodyPart = part.getBodyPart(i);
+                String fileName = bodyPart.getFileName();
+                String[] contentId = bodyPart.getHeader("Content-ID");
+                if (bodyPart.isMimeType("multipart/*")) {
+                    ret.addAll(extractMessageAttachments(logger, bodyPart.getContent()));
+                } else {
+                    if (contentId != null || fileName != null) {
+                        ret.add(bodyPart);
+                    }
+                }
+            }
+        } else {
+            logger.error("Unknown content: " + content.getClass().getName());
+        }
+        return ret;
+    }
+
+    public static FileItemRegistry getSessionRegistry(HttpSession session, Log logger) {
+        FileItemRegistry registry = (FileItemRegistry)session.getAttribute("registry");
+        if (registry == null) {
+            registry = new FileItemRegistry(logger);
+            session.setAttribute("registry", registry);
+        }
+        return registry;
+    }
+
+    /**
+     * Loop over MuliPart and write the content to the Outputstream if a
+     * attachment with the given name was found.
+     *
+     * @param out
+     *            Outputstream to write the content to
+     * @param content
+     *            Content which should checked for attachments
+     * @param attachmentName
+     *            The attachmentname or the unique id for the searched attachment
+     * @throws MessagingException
+     * @throws IOException
+     */
+    public static Part handleMultiPart(Log logger, Object content, String attachmentName)
+            throws MessagingException, IOException {
+        if (content instanceof Multipart) {
+            Multipart part = (Multipart) content;
+            for (int i = 0; i < part.getCount(); i++) {
+                Part bodyPart = part.getBodyPart(i);
+                String fileName = bodyPart.getFileName();
+                String[] contentId = bodyPart.getHeader("Content-ID");
+                if (bodyPart.isMimeType("multipart/*")) {
+                    Part p = handleMultiPart(logger, 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 {
+            logger.error("Unknown content: " + content.getClass().getName());
+        }
+        return null;
+    }
+    
+}
\ No newline at end of file

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/RegexPatterns.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/RegexPatterns.java?rev=885783&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/RegexPatterns.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/RegexPatterns.java Tue Dec  1 15:05:00 2009
@@ -0,0 +1,102 @@
+/****************************************************************
+ * 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.utils;
+
+import java.util.regex.Pattern;
+
+import org.apache.hupa.shared.SConsts;
+
+/**
+ * A place where we centralize all compiled regular expressions which will be used in 
+ * server side for html and text transformations.
+ */
+public class RegexPatterns {
+    
+    public static final Pattern regex_lt = Pattern.compile("<");
+    public static final String repl_lt = "&lt;";
+    
+    public static final Pattern regex_gt = Pattern.compile(">");
+    public static final String repl_gt = "&lt;";
+
+    public static final Pattern regex_nl = Pattern.compile("\n");
+    public static final String repl_nl = "<br/>";
+
+    public static final String HTML_LINK_REGEXP =  "\\b?(https?://[\\w\\d:#@%/;$\\(\\)~_\\?\\+\\-=\\\\.&]*)\\b?";
+    public static final Pattern regex_htmllink = Pattern.compile(HTML_LINK_REGEXP);
+    public static final String repl_htmllink = "<a href=\"$1\">$1</a>";
+    
+    public static final String EMAIL_REGEXP =  "\\b(?<![A-z0-9._%\\+\\-=])([A-z][A-z0-9._%\\+\\-]+@[A-z0-9\\.\\-]+\\.[A-z]{2,4})";
+    public static final Pattern regex_email = Pattern.compile("\\b"+ EMAIL_REGEXP);
+    public static final String repl_email = "<a href=\"mailto:$1\">$1</a>";
+    
+    public static final Pattern regex_inlineImg = Pattern.compile("(?si)(<\\s*img\\s+.*?src=)[\"']?cid:([^\"']+)[\"']?");
+    public static final String repl_inlineImg = "$1'" + SConsts.HUPA + SConsts.SERVLET_DOWNLOAD 
+                                        + "?" + SConsts.PARAM_FOLDER + "=%%FOLDER%%" 
+                                        + "&" + SConsts.PARAM_UID + "=%%UID%%" 
+                                        + "&" + SConsts.PARAM_NAME + "=$2' name='cid:$2'";
+    
+    public static final Pattern regex_revertInlineImg = Pattern.compile("(?si)(<img\\s[^>]*src=)[^>]+name=([\"']cid:[^\"']+[\"'])");
+    public static final String repl_revertInlineImg = "$1$2";
+    
+    public static final Pattern regex_badTags = Pattern.compile("(?si)<(script|style|head).*?</\\1\\s*>");
+    public static final String repl_badTags = "";
+    
+    public static final Pattern regex_unneededTags = Pattern.compile("(?si)(</?(html|body)[^>]*?>)");
+    public static final String repl_unneededTags = "";
+    
+    public static final String EVENT_ATTR_REGEX = "(?:on[dbl]*click)|(?:onmouse[a-z]+)|(?:onkey[a-z]+)";
+    public static final Pattern regex_badAttrs = Pattern.compile("(?si)(<\\w+[^<>]*)\\s+("+ EVENT_ATTR_REGEX + ")=[\"']?([^\\s<>]+?)[\"']?([\\s>])");
+    public static final String repl_badAttrs = "$1$4";
+    
+    public static final Pattern regex_orphandHttpLinks = Pattern.compile("(?si)(?!.*<a\\s?[^>]*?>.+</a\\s*>.*)(<[^<]*?>[^<>]*)" + HTML_LINK_REGEXP + "([^<>]*<[^>]*?>)");
+    public static final String repl_orphandHttpLinks = "$1<a href=\"$2\">$2</a>$3";
+    
+    public static final Pattern regex_existingHttpLinks = Pattern.compile("(?si)<a\\s[^>]*?href=[\"']?" + HTML_LINK_REGEXP + "[\"']?");
+    public static final String repl_existingHttpLinks = "<a onClick=\"openLink('$1');return false;\" href=\"$1\"";
+    
+    public static final Pattern regex_orphandEmailLinks = Pattern.compile("(?si)(?!.*<a\\s?[^>]*?>.+</a\\s*>.*)(<[^<]*?>[^<>]*)" + EMAIL_REGEXP + "([^<>]*<[^>]*?>)");
+    public static final String repl_orphandEmailLinks = "$1<a href=\"mailto:$2\">$2</a>$3";
+    
+    public static final Pattern regex_existingEmailLinks = Pattern.compile("(?si)<a\\s[^>]*?href=[\"']*mailto:[\"']?([^\"]+)[\"']?");
+    public static final String repl_existngEmailLinks = "<a onClick=\"mailTo('$1');return false;\" href=\"mailto:$1\"";
+    
+    public static String replaceAll(String txt, Pattern pattern, String replacement) {
+        return pattern.matcher(txt).replaceAll(replacement);
+    }
+    
+    public static String replaceAllRecursive(String txt, Pattern pattern, String replacement) {
+        while (pattern.matcher(txt).find())
+            txt = pattern.matcher(txt).replaceAll(replacement);
+        return txt;
+    }
+    
+    public static final Pattern regex_nl_tags = Pattern.compile("(?si)(<br\\s*?/?>)|(</div\\s*?>)");
+    public static final Pattern regex_any_tag = Pattern.compile("(\\w)<.*?>(\\w)");
+    public static final String repl_any_tag = "$1 $2";
+    
+//    s=s.replaceAll("\n", " ");
+//    s=s.replaceAll("(?si)<br\\s*?/?>", "\n");
+//    s=s.replaceAll("(?si)</div\\s*?>", "\n");
+//    s=s.replaceAll("(\\w)<.*?>(\\w)", "$1 $2");
+//    s=s.replaceAll("<.*?>", "");
+//    s=s.replaceAll("[ \t]+", " ");
+
+    
+}
\ No newline at end of file

Added: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaTestCase.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaTestCase.java?rev=885783&view=auto
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaTestCase.java (added)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaTestCase.java Tue Dec  1 15:05:00 2009
@@ -0,0 +1,52 @@
+/****************************************************************
+ * 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;
+
+import javax.mail.Session;
+
+import junit.framework.TestCase;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.guice.GuiceTestModule;
+import org.apache.hupa.server.handler.AbstractSendMessageHandler;
+import org.apache.hupa.server.handler.ForwardMessageHandler;
+import org.apache.hupa.server.handler.GetMessageDetailsHandler;
+import org.apache.hupa.shared.rpc.SendMessage;
+
+import com.google.inject.Injector;
+
+public abstract class HupaTestCase extends TestCase{
+
+    protected GuiceTestModule module = new GuiceTestModule();
+    protected Injector injector = module.getInjector();
+    
+    protected Session session = injector.getInstance(Session.class);
+    protected Log logger = injector.getInstance(Log.class);
+    protected IMAPStoreCache storeCache = injector.getInstance(IMAPStoreCache.class);
+    
+    @SuppressWarnings("unchecked")
+    protected AbstractSendMessageHandler<SendMessage> abstSendMsgHndl = injector.getInstance(AbstractSendMessageHandler.class);
+    
+    protected ForwardMessageHandler fwdMsgHndl = injector.getInstance(ForwardMessageHandler.class);
+    
+    protected GetMessageDetailsHandler getDetailsMsgHndl = injector.getInstance(GetMessageDetailsHandler.class);
+    
+}

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceTestModule.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceTestModule.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceTestModule.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceTestModule.java Tue Dec  1 15:05:00 2009
@@ -23,7 +23,6 @@
 import javax.servlet.http.HttpSession;
 
 import org.apache.commons.logging.Log;
-import org.apache.hupa.server.FileItemRegistry;
 import org.apache.hupa.server.IMAPStoreCache;
 import org.apache.hupa.server.handler.AbstractSendMessageHandler;
 import org.apache.hupa.server.handler.ForwardMessageHandler;
@@ -50,7 +49,6 @@
         Names.bindProperties(binder(), DemoModeConstants.demoProperties);
 
         bind(Log.class).toProvider(MockLogProvider.class).in(Singleton.class);
-        bind(FileItemRegistry.class).in(Singleton.class);
         bind(Session.class).toProvider(SessionProvider.class);
         bind(HttpSession.class).to(MockHttpSession.class).in(Singleton.class);
 

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbstractHandlerTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbstractHandlerTest.java?rev=885783&r1=885782&r2=885783&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbstractHandlerTest.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbstractHandlerTest.java Tue Dec  1 15:05:00 2009
@@ -20,12 +20,9 @@
 
 package org.apache.hupa.server.handler;
 
-import java.io.FileInputStream;
-import java.net.URL;
 import java.util.Properties;
 
 import javax.mail.Session;
-import javax.mail.internet.MimeMessage;
 import javax.servlet.http.HttpSession;
 
 import junit.framework.TestCase;
@@ -93,15 +90,6 @@
         user.setSettings(new Settings());
         return user;
     }
-    
-    protected MimeMessage loadMessage(String msgFile) throws Exception {
-        msgFile = DemoModeConstants.DEMO_MODE_MESSAGES_LOCATION + msgFile;
-        URL url = Thread.currentThread().getContextClassLoader().getResource(msgFile);
-        assertNotNull("Check that the file " + msgFile + " is in the classpath", url);
-    
-        FileInputStream is = new FileInputStream(url.getFile());
-        return new MimeMessage(session, is);
-    }
 
 
 }



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