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 do...@apache.org on 2013/08/21 18:35:18 UTC

svn commit: r1516205 [6/9] - in /james/hupa/trunk: ./ client/src/main/java/org/apache/hupa/ client/src/main/java/org/apache/hupa/client/ client/src/main/java/org/apache/hupa/client/gin/ client/src/main/java/org/apache/hupa/client/mvp/ client/src/main/j...

Added: 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=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetMessageDetailsHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetMessageDetailsHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,297 @@
+/****************************************************************
+ * 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.handler;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.ArrayList;
+
+import javax.mail.Flags;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Multipart;
+import javax.mail.Part;
+import javax.mail.Flags.Flag;
+import javax.mail.internet.MimeMessage;
+import javax.mail.internet.MimeUtility;
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+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;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.GetMessageDetails;
+import org.apache.hupa.shared.rpc.GetMessageDetailsResult;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPStore;
+
+public class GetMessageDetailsHandler extends
+        AbstractSessionHandler<GetMessageDetails, GetMessageDetailsResult> {
+
+    @Inject
+    public GetMessageDetailsHandler(IMAPStoreCache cache, Log logger,
+            Provider<HttpSession> sProvider) {
+        super(cache, logger, sProvider);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.hupa.server.handler.AbstractSessionHandler#executeInternal
+     * (org.apache.hupa.shared.rpc.Session,
+     * net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    public GetMessageDetailsResult executeInternal(GetMessageDetails action,
+            ExecutionContext arg1) throws ActionException {
+        return new GetMessageDetailsResult(exposeMessage(getUser(), action.getFolder(), action.getUid()));
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<GetMessageDetails> getActionType() {
+        return GetMessageDetails.class;
+    }
+
+    protected MessageDetails exposeMessage(User user, IMAPFolder folder,
+            long uid) throws ActionException {
+        IMAPStore store = null;
+        com.sun.mail.imap.IMAPFolder f = null;
+        try {
+            store = cache.get(user);
+
+            f = (com.sun.mail.imap.IMAPFolder) store
+                    .getFolder(folder.getFullName());
+
+            if (f.isOpen() == false) {
+                f.open(com.sun.mail.imap.IMAPFolder.READ_WRITE);
+            }
+            
+            MimeMessage message = (MimeMessage) f.getMessageByUID(uid);
+
+            MessageDetails mDetails = mimeToDetails(message, f.getFullName(), uid);
+
+            mDetails.setUid(uid);
+            
+            f.setFlags(new Message[] { message }, new Flags(Flag.SEEN), true);
+            
+            return mDetails;
+        } catch (Exception e) {
+            logger.error("Unable to expose msg for user " + user
+                    + " in folder " + folder + " with uid " + uid, e);
+            throw new ActionException("Unable to expose msg for user " + user
+                    + " in folder " + folder + " with uid " + uid);
+
+        } finally {
+            if (f != null && f.isOpen()) {
+                try {
+                    f.close(false);
+                } catch (MessagingException e) {
+                    // ignore on close
+                }
+            }
+        }
+    }
+
+    protected MessageDetails mimeToDetails(MimeMessage message, String folderName, long uid)
+            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);
+        
+        System.out.println(isHTML);
+        
+        if (isHTML) {
+            mDetails.setText(filterHtmlDocument(sbPlain.toString(), folderName, uid));
+        } else {
+            mDetails.setText(txtDocumentToHtml(sbPlain.toString(), folderName, uid));
+        }
+
+        mDetails.setMessageAttachments(attachmentList);
+
+        mDetails.setRawHeader(message.getAllHeaders().toString());
+        
+        return mDetails;
+    }
+
+    /**
+     * 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 attachmentList ArrayList with attachments
+     * @throws UnsupportedEncodingException
+     * @throws MessagingException
+     * @throws IOException
+     */
+    protected boolean handleParts(MimeMessage message, Object con,
+            StringBuffer sbPlain,
+            ArrayList<MessageAttachment> attachmentList)
+            throws UnsupportedEncodingException, MessagingException,
+            IOException {
+        boolean isHTML = false;
+        if (con instanceof String) {
+            if (message.getContentType().startsWith("text/html")) {
+                isHTML = true;
+            } else {
+                isHTML = false;
+            }
+            sbPlain.append((String) con);
+
+        } else if (con instanceof Multipart) {
+
+            Multipart mp = (Multipart) con;
+            String multipartContentType = mp.getContentType().toLowerCase();
+            
+            String text = null;
+
+            if (multipartContentType.startsWith("multipart/alternative")) {
+                isHTML = handleMultiPartAlternative(mp, sbPlain);
+            } else {
+                for (int i = 0; i < mp.getCount(); i++) {
+                    Part part = mp.getBodyPart(i);
+
+                    String contentType = part.getContentType().toLowerCase();
+                    
+                    Boolean bodyRead = sbPlain.length() > 0;
+
+                    if (!bodyRead && contentType.startsWith("text/plain") ) {
+                        isHTML = false;
+                        text = (String)part.getContent();
+                    } else if (!bodyRead && contentType.startsWith("text/html")) {
+                        isHTML = true;
+                        text = (String)part.getContent();
+                    } else if (!bodyRead && contentType.startsWith("message/rfc822")) {
+                        // Extract the message and pass it
+                        MimeMessage msg = (MimeMessage) part.getDataHandler().getContent();
+                        isHTML =  handleParts(msg, msg.getContent(), sbPlain, attachmentList);
+                    } else {
+                        if (part.getFileName() != null) {
+                            // 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);
+                        }
+                    }
+
+                }
+                if (text != null)
+                    sbPlain.append(text);
+            }
+
+        }
+        return isHTML;
+    }
+    
+    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();
+
+            // we prefer html
+            if (text == null && contentType.startsWith("text/plain")) {
+                isHTML = false;
+                text = (String) part.getContent();
+            } else if (contentType.startsWith("text/html")) {
+                isHTML = true;
+                text = (String) part.getContent();
+            } 
+        }
+        sbPlain.append(text);
+        return isHTML;
+    }
+    
+    protected String txtDocumentToHtml(String txt, String folderName, long uuid) {
+        
+        if (txt == null || txt.length()==0)
+            return txt;
+
+        // escape html tags symbols 
+        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_htmllink, repl_htmllink);
+        txt = replaceAll(txt, regex_email, repl_email);
+        
+        // put break lines
+        txt = replaceAll(txt, regex_nl, repl_nl);
+        
+        txt = filterHtmlDocument(txt, folderName, uuid);
+
+        return txt;
+    }
+    
+    protected String filterHtmlDocument(String html, String folderName, long uuid) {
+        
+        if (html == null || html.length()==0)
+            return html;
+
+        // Replace in-line images links to use Hupa's download servlet
+        html = replaceAll(html, regex_inlineImg, repl_inlineImg).replaceAll("%%FOLDER%%",folderName).replaceAll("%%UID%%", String.valueOf(uuid));
+        // Remove head, script and style tags to avoid interferences with Hupa
+        html = replaceAll(html, regex_badTags, repl_badTags);
+        // Remove body and html tags
+        html = replaceAll(html, regex_unneededTags, repl_unneededTags);
+        // Remove all onClick attributes 
+        html = replaceAllRecursive(html, regex_badAttrs, repl_badAttrs);
+        html = replaceAll(html, regex_existingHttpLinks, repl_existingHttpLinks);
+
+        //FIXME: These have serious performance problems (see testMessageDetails_Base64Image_Performance)
+        // Add <a> tags to links which are not already into <a>
+        // html = replaceAll(html, regex_orphandHttpLinks, repl_orphandHttpLinks);
+        // Add javascript method to <a> in order to open links in a different window
+        // Add <a> tags to emails which are not already into <a>
+        // html = replaceAll(html, regex_orphandEmailLinks, repl_orphandEmailLinks);
+        // Add a js method to mailto links in order to compose new mails inside hupa
+        html = replaceAll(html, regex_existingEmailLinks, repl_existngEmailLinks);
+        
+        return html;
+    }
+    
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetRawMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetRawMessageHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetRawMessageHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/GetRawMessageHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,87 @@
+/****************************************************************
+ * 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.handler;
+
+import java.io.ByteArrayOutputStream;
+
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.RawMessage;
+import org.apache.hupa.shared.rpc.RawMessageResult;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPFolder;
+import com.sun.mail.imap.IMAPStore;
+
+public class GetRawMessageHandler extends AbstractSessionHandler<RawMessage, RawMessageResult>{
+
+    @Inject
+    public GetRawMessageHandler(IMAPStoreCache cache, Log logger,
+            Provider<HttpSession> sessionProvider) {
+        super(cache, logger, sessionProvider);
+    }
+
+    @Override
+    protected RawMessageResult executeInternal(RawMessage action,
+            ExecutionContext context) throws ActionException {
+        User user = getUser();
+        long uid = action.getUid();
+        org.apache.hupa.shared.data.IMAPFolder folder = action.getFolder();
+        try {
+            IMAPStore store = cache.get(user);
+            IMAPFolder f = (IMAPFolder) store.getFolder(folder.getFullName());
+            if (f.isOpen() == false) {
+                f.open(Folder.READ_ONLY);
+            }
+             Message m = f.getMessageByUID(action.getUid());
+            
+            ByteArrayOutputStream out = new ByteArrayOutputStream();
+            m.writeTo(out);
+            if (f.isOpen()) {
+                f.close(false);
+            }
+            return new RawMessageResult(out.toString());
+        } catch (Exception e) {
+            logger.error("Unable to get raw content of msg for user " + user
+                    + " in folder " + folder + " with uid " + uid, e);
+            throw new ActionException("Unable to et raw content of msg for user " + user
+                    + " in folder " + folder + " with uid " + uid);
+        }
+        
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<RawMessage> getActionType() {
+        return RawMessage.class;
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/IdleHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/IdleHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/IdleHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/IdleHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,81 @@
+/****************************************************************
+ * 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.handler;
+
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.rpc.Idle;
+import org.apache.hupa.shared.rpc.IdleResult;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPStore;
+
+/**
+ * Handle Noops
+ * 
+ *
+ */
+public class IdleHandler extends AbstractSessionHandler<Idle, IdleResult>{
+
+
+    @Inject
+    public IdleHandler(IMAPStoreCache cache, Log logger, Provider<HttpSession> provider) {
+        super(cache,logger,provider);
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.hupa.server.handler.AbstractSessionHandler#executeInternal(org.apache.hupa.shared.rpc.Session, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    public IdleResult executeInternal(Idle action, ExecutionContext context)
+            throws ActionException {
+        try {
+            IMAPStore store = cache.get(getUser());
+            
+            if (store.getURLName() != null ) {
+                // check if the store supports the IDLE command
+                if (store.hasCapability("IDLE")) {
+                    // just send a noop to keep the connection alive
+                    store.idle();
+                } else {
+                    return new IdleResult(false);
+                }
+            }
+            return new IdleResult(true);
+        } catch (Exception e) {
+            throw new ActionException("Unable to send NOOP " + e.getMessage());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<Idle> getActionType() {
+        return Idle.class;
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LoginUserHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,112 @@
+/****************************************************************
+ * 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.handler;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import net.customware.gwt.dispatch.server.ActionHandler;
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.utils.SessionUtils;
+import org.apache.hupa.shared.SConsts;
+import org.apache.hupa.shared.data.Settings;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.LoginUser;
+import org.apache.hupa.shared.rpc.LoginUserResult;
+
+
+import javax.servlet.http.HttpSession;
+
+/**
+ * Handler for login a user via username and password
+ * 
+ */
+public class LoginUserHandler implements
+        ActionHandler<LoginUser, LoginUserResult> {
+
+    private final IMAPStoreCache cache;
+    private final Log logger;
+    private final Provider<HttpSession> sessionProvider;
+    private final Provider<Settings> settingsProvider;
+
+    @Inject
+    public LoginUserHandler(IMAPStoreCache cache, Log logger, Provider<HttpSession> sessionProvider, Provider<Settings> settingsProvider) {
+        this.cache = cache;
+        this.logger = logger;
+        this.sessionProvider = sessionProvider;
+        this.settingsProvider = settingsProvider;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#execute(net.customware.gwt.dispatch.shared.Action, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    public LoginUserResult execute(LoginUser action, ExecutionContext context) throws ActionException {
+        HttpSession session = sessionProvider.get();
+        SessionUtils.cleanSessionAttributes(session);
+        
+        String username = action.getUserName();
+        String password = action.getPassword();
+        try {
+            
+            // construct a new user
+            User user = new User();
+            user.setName(username);
+            user.setPassword(password);
+            
+            // login
+            cache.get(user);
+            
+            user.setAuthenticated(true);
+            user.setSettings(settingsProvider.get());
+            
+            // store the session id for later usage
+            session.setAttribute(SConsts.USER_SESS_ATTR, user);
+            
+            logger.debug("Logged user: " + username);
+            return new LoginUserResult(user);
+
+        } catch (Exception e) {
+            logger.error("Unable to authenticate user: " + username, e);
+            throw new ActionException(e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#rollback(net.customware.gwt.dispatch.shared.Action, net.customware.gwt.dispatch.shared.Result, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    public void rollback(LoginUser user, LoginUserResult result,
+            ExecutionContext context) throws ActionException {
+        // Nothing todo here
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<LoginUser> getActionType() {
+        return LoginUser.class;
+    }
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/LogoutUserHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,85 @@
+/****************************************************************
+ * 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.handler;
+
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.utils.SessionUtils;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.LogoutUser;
+import org.apache.hupa.shared.rpc.LogoutUserResult;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+/**
+ * Handler for handle logout requests
+ * 
+ */
+public class LogoutUserHandler extends AbstractSessionHandler<LogoutUser, LogoutUserResult> {
+    
+    
+    @Inject
+    public LogoutUserHandler(IMAPStoreCache cache, Log logger,Provider<HttpSession> provider) {
+        super(cache,logger,provider);
+    }
+
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.hupa.server.handler.AbstractSessionHandler#executeInternal(org.apache.hupa.shared.rpc.Session, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    public LogoutUserResult executeInternal(LogoutUser action, ExecutionContext arg1)
+            throws ActionException {
+        User user = getUser();
+        user.setAuthenticated(false);
+        
+        // delete cached store
+        cache.delete(user);
+        
+        // remove user attributes from session
+        SessionUtils.cleanSessionAttributes(httpSessionProvider.get());
+        
+        return new LogoutUserResult(user);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<LogoutUser> getActionType() {
+        return LogoutUser.class;
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#rollback(net.customware.gwt.dispatch.shared.Action, net.customware.gwt.dispatch.shared.Result, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    public void rollback(LogoutUser arg0, LogoutUserResult arg1,
+            ExecutionContext arg2) throws ActionException {
+        // not implemented
+    }
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/MoveMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/MoveMessageHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/MoveMessageHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/MoveMessageHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,93 @@
+/****************************************************************
+ * 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.handler;
+
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.MoveMessage;
+import org.apache.hupa.shared.rpc.MoveMessageResult;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPFolder;
+import com.sun.mail.imap.IMAPStore;
+
+/**
+ * Handler which handle moving of messages
+ *
+ */
+public class MoveMessageHandler extends AbstractSessionHandler<MoveMessage, MoveMessageResult>{
+
+    @Inject
+    public MoveMessageHandler(IMAPStoreCache cache, Log logger,
+            Provider<HttpSession> sessionProvider) {
+        super(cache, logger, sessionProvider);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.hupa.server.handler.AbstractSessionHandler#executeInternal(org.apache.hupa.shared.rpc.Session, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    protected MoveMessageResult executeInternal(MoveMessage action,
+            ExecutionContext context) throws ActionException {
+        User user = getUser();
+        try {
+            IMAPStore store = cache.get(user);
+            IMAPFolder folder = (IMAPFolder)store.getFolder(action.getOldFolder().getFullName());
+            if (folder.isOpen() == false) {
+                folder.open(Folder.READ_WRITE);
+            }
+            Message m = folder.getMessageByUID(action.getMessageUid());
+            Message[] mArray = new Message[] {m};
+            folder.copyMessages(mArray, store.getFolder(action.getNewFolder().getFullName()));
+            folder.setFlags(mArray, new Flags(Flags.Flag.DELETED), true);
+            try {
+                folder.expunge(mArray);
+                folder.close(false);
+            } catch (MessagingException e) {
+                // prolly UID expunge is not supported
+                folder.close(true);
+            }
+            return new MoveMessageResult();
+        } catch (MessagingException e) {
+            logger.error("Error while moving message " + action.getMessageUid() + " from folder " + action.getOldFolder() + " to " + action.getNewFolder(),e);
+            throw new ActionException(e);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<MoveMessage> getActionType() {
+        return MoveMessage.class;
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/PrepareNewMessageHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/PrepareNewMessageHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/PrepareNewMessageHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/PrepareNewMessageHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,75 @@
+/****************************************************************
+ * 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.handler;
+
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.rpc.Idle;
+import org.apache.hupa.shared.rpc.IdleResult;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPStore;
+
+/**
+ * Handle Noops
+ * 
+ *
+ */
+public class PrepareNewMessageHandler extends AbstractSessionHandler<Idle, IdleResult>{
+
+
+    @Inject
+    public PrepareNewMessageHandler(IMAPStoreCache cache, Log logger, Provider<HttpSession> provider) {
+        super(cache,logger,provider);
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see org.apache.hupa.server.handler.AbstractSessionHandler#executeInternal(org.apache.hupa.shared.rpc.Session, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    public IdleResult executeInternal(Idle action, ExecutionContext context)
+            throws ActionException {
+        try {
+            IMAPStore store = cache.get(getUser());
+            if (store.getURLName() != null) {
+                // just send a noop to keep the connection alive
+                store.idle();
+            }
+            return new IdleResult(false);
+        } catch (Exception e) {
+            throw new ActionException("Unable to send NOOP " + e.getMessage());
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<Idle> getActionType() {
+        return Idle.class;
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/RenameFolderHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/RenameFolderHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/RenameFolderHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/RenameFolderHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,88 @@
+/****************************************************************
+ * 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.handler;
+
+import javax.mail.Folder;
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.data.IMAPFolder;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.GenericResult;
+import org.apache.hupa.shared.rpc.RenameFolder;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPStore;
+
+/**
+ * Handler which handle renaming of folders
+ *
+ */
+public class RenameFolderHandler extends AbstractSessionHandler<RenameFolder, GenericResult>{
+
+    @Inject
+    public RenameFolderHandler(IMAPStoreCache cache, Log logger,
+            Provider<HttpSession> sessionProvider) {
+        super(cache, logger, sessionProvider);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.hupa.server.handler.AbstractSessionHandler#executeInternal(org.apache.hupa.shared.rpc.Session, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    protected GenericResult executeInternal(RenameFolder action,
+            ExecutionContext context) throws ActionException {
+        User user = getUser();
+        IMAPFolder folder = action.getFolder();
+        String newName = action.getNewName();
+        try {
+            IMAPStore store = cache.get(user);
+            com.sun.mail.imap.IMAPFolder iFolder = (com.sun.mail.imap.IMAPFolder) store.getFolder(folder.getFullName());
+            Folder newFolder = store.getFolder(newName);
+            
+            if (iFolder.isOpen()) {
+                iFolder.close(false);
+            }
+            if (iFolder.renameTo(newFolder)) {
+                return new GenericResult();
+            }
+            throw new ActionException("Unable to rename Folder " + folder.getFullName() + " to " + newName + " for user " + user);
+
+        } catch (Exception e) {
+            logger.error("Error while renaming Folder " + folder.getFullName() + " to " + newName + " for user " + user,e);
+            throw new ActionException("Error while renaming Folder " + folder.getFullName() + " to " + newName + " for user " + user,e);
+        }
+
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<RenameFolder> getActionType() {
+        return RenameFolder.class;
+    }
+
+}

Added: 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=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ReplyMessageHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/ReplyMessageHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,94 @@
+/****************************************************************
+ * 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.handler;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.preferences.UserPreferencesStorage;
+import org.apache.hupa.server.utils.MessageUtils;
+import org.apache.hupa.shared.rpc.ReplyMessage;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.name.Named;
+import com.sun.mail.imap.IMAPFolder;
+import com.sun.mail.imap.IMAPStore;
+
+/**
+ * Handler which handle replies to a message
+ * 
+ *
+ */
+public class ReplyMessageHandler extends AbstractSendMessageHandler<ReplyMessage> {
+
+    @Inject
+    public ReplyMessageHandler(Log logger, IMAPStoreCache store, Provider<HttpSession> provider, UserPreferencesStorage preferences,
+            @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
+        super(logger, store, provider, preferences, address, port, auth, useSSL);
+    }
+
+    @Override
+    @SuppressWarnings({ "rawtypes", "unchecked" })
+    protected List getAttachments(ReplyMessage action) throws MessagingException, ActionException {
+        List<?> items = new ArrayList();
+        IMAPStore store = cache.get(getUser());
+
+        IMAPFolder folder = (IMAPFolder) store.getFolder(action.getFolder().getFullName());
+        if (folder.isOpen() == false) {
+            folder.open(Folder.READ_ONLY);
+        }
+
+        // Only original inline images have to be added to the list 
+        Message msg = folder.getMessageByUID(action.getReplyMessageUid());
+        try {
+            items = MessageUtils.extractInlineImages(logger, msg.getContent());
+            if (items.size() > 0)
+                logger.debug("Replying a message, extracted: " + items.size() + " inline image from");
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+        
+        // Put into 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<ReplyMessage> getActionType() {
+        return ReplyMessage.class;
+    }
+
+}

Copied: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java (from r1516164, james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/exception/InvalidSessionException.java)
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java?p2=james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java&p1=james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/exception/InvalidSessionException.java&r1=1516164&r2=1516205&rev=1516205&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/exception/InvalidSessionException.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SendMessageHandler.java Wed Aug 21 16:35:16 2013
@@ -17,13 +17,38 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.hupa.shared.exception;
+package org.apache.hupa.server.handler;
 
-public class InvalidSessionException extends HupaException{
+import javax.servlet.http.HttpSession;
 
-	private static final long serialVersionUID = 995112620968798947L;
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.server.preferences.UserPreferencesStorage;
+import org.apache.hupa.shared.rpc.SendMessage;
 
-	public InvalidSessionException(String message) {
-        super(message);
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.google.inject.name.Named;
+
+/**
+ * Handler which handle sending of new messages
+ * 
+ *
+ */
+public class SendMessageHandler extends AbstractSendMessageHandler<SendMessage> {
+
+    @Inject
+    public SendMessageHandler(Log logger, IMAPStoreCache store, Provider<HttpSession> provider, UserPreferencesStorage preferences,
+            @Named("SMTPServerAddress") String address, @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL) {
+        super(logger, store, provider, preferences, address, port, auth,useSSL);
     }
+
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<SendMessage> getActionType() {
+        return SendMessage.class;
+    }
+
 }

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SetFlagsHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SetFlagsHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SetFlagsHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/SetFlagsHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,101 @@
+/****************************************************************
+ * 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.handler;
+
+import java.util.ArrayList;
+
+import javax.mail.Flags;
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.mail.Flags.Flag;
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.data.IMAPFolder;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.GenericResult;
+import org.apache.hupa.shared.rpc.SetFlag;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPStore;
+
+public class SetFlagsHandler extends AbstractSessionHandler<SetFlag, GenericResult>{
+
+    @Inject
+    public SetFlagsHandler(IMAPStoreCache cache, Log logger,
+            Provider<HttpSession> sessionProvider) {
+        super(cache, logger, sessionProvider);
+    }
+
+    @Override
+    protected GenericResult executeInternal(SetFlag action,
+            ExecutionContext context) throws ActionException {
+        User user = getUser();
+        IMAPFolder folder = action.getFolder();
+        ArrayList<Long> uids = action.getUids();
+        com.sun.mail.imap.IMAPFolder f = null;
+        try {
+            IMAPStore store = cache.get(user);
+
+            f = (com.sun.mail.imap.IMAPFolder) store.getFolder(folder.getFullName());
+            if (f.isOpen() == false) {
+                f.open(Folder.READ_WRITE);
+            }
+            Message[] msgs = f.getMessagesByUID(toArray(uids));
+            Flag flag = JavamailUtil.convert(action.getFlag());
+            Flags flags = new Flags();
+            flags.add(flag);
+            
+            f.setFlags(msgs, flags, action.getValue());
+            return new GenericResult();
+        } catch (MessagingException e) {
+            String errorMsg = "Error while setting flags of messages with uids " + uids + " for user " + user;
+            logger.error(errorMsg,e);
+            throw new ActionException(errorMsg,e);
+        } finally {
+            if (f != null && f.isOpen()) {
+                try {
+                    f.close(false);
+                } catch (MessagingException e) {
+                    // ignore on close
+                }
+            }
+        }
+    }
+
+    public Class<SetFlag> getActionType() {
+        return SetFlag.class;
+    }
+    
+    private long[] toArray(ArrayList<Long> uids) {
+        long[] array = new long[uids.size()];
+        for (int i = 0; i < uids.size(); i++) {
+            array[i] = uids.get(i);
+        }
+        return array;
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/TagMessagesHandler.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/TagMessagesHandler.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/TagMessagesHandler.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/handler/TagMessagesHandler.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,104 @@
+/****************************************************************
+ * 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.handler;
+
+import java.util.ArrayList;
+
+import javax.mail.Folder;
+import javax.mail.Message;
+import javax.mail.MessagingException;
+import javax.servlet.http.HttpSession;
+
+import net.customware.gwt.dispatch.server.ExecutionContext;
+import net.customware.gwt.dispatch.shared.ActionException;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.IMAPStoreCache;
+import org.apache.hupa.shared.data.Tag;
+import org.apache.hupa.shared.data.User;
+import org.apache.hupa.shared.rpc.GenericResult;
+import org.apache.hupa.shared.rpc.TagMessage;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+import com.sun.mail.imap.IMAPFolder;
+import com.sun.mail.imap.IMAPStore;
+
+/**
+ * Handler which use user flags for supporting tagging of messages
+ *
+ */
+public class TagMessagesHandler extends AbstractSessionHandler<TagMessage, GenericResult>{
+
+    @Inject
+    public TagMessagesHandler(IMAPStoreCache cache, Log logger,
+            Provider<HttpSession> sessionProvider) {
+        super(cache, logger, sessionProvider);
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see org.apache.hupa.server.handler.AbstractSessionHandler#executeInternal(org.apache.hupa.shared.rpc.Session, net.customware.gwt.dispatch.server.ExecutionContext)
+     */
+    protected GenericResult executeInternal(TagMessage action,
+            ExecutionContext context) throws ActionException {
+        User user = getUser();
+        ArrayList<Long> uids = action.getMessageUids();
+        Tag tag = action.getTag();
+        IMAPFolder folder = null;
+        try {
+            IMAPStore store = cache.get(user);
+            folder = (IMAPFolder) store.getFolder(action.getFolder().getFullName());
+            if (folder.isOpen() == false) {
+                folder.open(Folder.READ_WRITE);
+            }
+            for (Message m :folder.getMessagesByUID(copyUids(uids))) {
+                m.getFlags().add(tag.toString());
+            }
+            return new GenericResult();
+        } catch (MessagingException e) {
+            logger.error("Error while tag messages " + uids.toString() + " for user " + user + " of folder" + action.getFolder(), e);
+            throw new ActionException(e);
+        } finally {
+            try {
+                folder.close(false);
+            } catch (MessagingException e) {
+                // ignore on close
+            }
+        }
+    }
+
+    private long[] copyUids(ArrayList<Long> uids) {
+        long[] lArray = new long[uids.size()];
+        for (int i = 0; i < uids.size(); i++) {
+            lArray[i] = uids.get(i);
+        }
+        return lArray;
+    }
+    
+    /*
+     * (non-Javadoc)
+     * @see net.customware.gwt.dispatch.server.ActionHandler#getActionType()
+     */
+    public Class<TagMessage> getActionType() {
+        return TagMessage.class;
+    }
+
+}

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/rf/Subject.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/rf/Subject.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/rf/Subject.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/rf/Subject.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,87 @@
+/****************************************************************
+ * 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.rf;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+public class Subject {
+
+    public static HashMap<Long, Subject> subjects = new HashMap<Long, Subject>();
+
+    private static long cont = 0;
+    private Integer version = 0;
+    private Long id = cont++;
+    private String title;
+
+    public Long getId() {
+        return id;
+    }
+
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    public Integer getVersion() {
+        return version;
+    }
+
+    public void setVersion(Integer version) {
+        this.version = version;
+    }
+
+    public void flush() {
+    }
+
+    public void persist() {
+        version++;
+        subjects.put(getId(), this);
+    }
+
+    public void remove() {
+        subjects.remove(getId());
+    }
+
+    public static List<Subject> findAllSubjects() {
+        return new ArrayList<Subject>(subjects.values());
+    }
+
+    public static long countSubjects() {
+        return subjects.size();
+    }
+
+    public static Subject findSubject(Long id) {
+        return subjects.get(id);
+    }
+
+    public String getTitle() {
+        return title;
+    }
+
+    public void setTitle(String title) {
+        this.title = title;
+    }
+
+    public static String echo(Subject subject, String from, String to) {
+        String msg = "In server side: " + subject.getTitle() + ",from: " + from
+                + " To: " + to;
+        return msg;
+    }
+}

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=1516205&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 Wed Aug 21 16:35:16 2013
@@ -0,0 +1,69 @@
+/****************************************************************
+ * 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.guice.GuiceStandardDispatchServlet;
+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 GuiceStandardDispatchServlet {
+    
+    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("^.*\\.",""));
+            Result res = super.execute(action);
+            logger.info("HupaDispatchServlet: finished: " + action.getClass().getName().replaceAll("^.*\\.",""));
+            return res;
+        } 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;
+
+}

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java?rev=1516205&r1=1516204&r2=1516205&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/HupaGuiceTestCase.java Wed Aug 21 16:35:16 2013
@@ -1,112 +1,112 @@
-/****************************************************************
- * 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 javax.servlet.http.HttpSession;
-
-import org.apache.commons.logging.Log;
-import org.apache.hupa.server.guice.GuiceServerTestModule;
-import org.apache.hupa.server.preferences.UserPreferencesStorage;
-import org.apache.hupa.server.service.CreateFolderService;
-import org.apache.hupa.server.service.CreateFolderServiceImpl;
-import org.apache.hupa.server.service.DeleteFolderService;
-import org.apache.hupa.server.service.DeleteFolderServiceImpl;
-import org.apache.hupa.server.service.DeleteMessageByUidService;
-import org.apache.hupa.server.service.DeleteMessageByUidServiceImpl;
-import org.apache.hupa.server.service.FetchFoldersService;
-import org.apache.hupa.server.service.FetchFoldersServiceImpl;
-import org.apache.hupa.server.service.FetchMessagesService;
-import org.apache.hupa.server.service.FetchMessagesServiceImpl;
-import org.apache.hupa.server.service.GetMessageDetailsServiceImpl;
-import org.apache.hupa.server.service.IdleService;
-import org.apache.hupa.server.service.IdleServiceImpl;
-import org.apache.hupa.server.service.LoginUserService;
-import org.apache.hupa.server.service.LoginUserServiceImpl;
-import org.apache.hupa.server.service.LogoutUserService;
-import org.apache.hupa.server.service.LogoutUserServiceImpl;
-import org.apache.hupa.server.service.SendReplyMessageServiceImpl;
-import org.apache.hupa.server.utils.SessionUtils;
-import org.apache.hupa.shared.SConsts;
-import org.apache.hupa.shared.domain.User;
-import org.junit.Before;
-
-import com.google.inject.Guice;
-import com.google.inject.Injector;
-import com.google.inject.Module;
-import com.sun.mail.imap.IMAPStore;
-
-public class HupaGuiceTestCase{
-
-    protected Injector injector = Guice.createInjector(getModules());
-    
-	protected CreateFolderService createFolderService;
-	protected FetchFoldersService fetchFoldersService;
-	protected FetchMessagesService fetchMessagesService;
-	protected DeleteFolderService deleteFolderService;
-	protected DeleteMessageByUidService deleteMessageByUidService;
-	protected GetMessageDetailsServiceImpl  getMessageDetailsService;
-	protected IdleService idleService;
-	protected LoginUserService loginUserService;
-	protected LogoutUserService logoutUserService;
-	protected SendReplyMessageServiceImpl sendReplyMessageService;
-	
-	protected Log logger;
-    protected IMAPStoreCache storeCache;
-    protected User testUser;
-    protected UserPreferencesStorage userPreferences;
-    protected IMAPStore store;
-    protected HttpSession httpSession;
-    protected Session session;
-    protected Module[] getModules() {
-        return new Module[]{new GuiceServerTestModule()};
-    }
-    
-
-    @Before
-    public void setUp(){
-
-        try {
-        	createFolderService = injector.getInstance(CreateFolderServiceImpl.class);
-        	fetchFoldersService = injector.getInstance(FetchFoldersServiceImpl.class);
-        	fetchMessagesService = injector.getInstance(FetchMessagesServiceImpl.class);
-        	deleteFolderService = injector.getInstance(DeleteFolderServiceImpl.class);
-        	deleteMessageByUidService = injector.getInstance(DeleteMessageByUidServiceImpl.class);
-        	getMessageDetailsService = injector.getInstance(GetMessageDetailsServiceImpl.class);
-        	idleService = injector.getInstance(IdleServiceImpl.class);
-        	loginUserService = injector.getInstance(LoginUserServiceImpl.class);
-        	logoutUserService = injector.getInstance(LogoutUserServiceImpl.class);
-        	sendReplyMessageService = injector.getInstance(SendReplyMessageServiceImpl.class);
-        	
-        	logger = injector.getInstance(Log.class);
-            session = injector.getInstance(Session.class);
-            storeCache = injector.getInstance(IMAPStoreCache.class);
-            userPreferences = injector.getInstance(UserPreferencesStorage.class);
-
-            httpSession = injector.getInstance(HttpSession.class);
-            SessionUtils.cleanSessionAttributes(httpSession);
-            testUser = injector.getInstance(User.class);
-            store = storeCache.get(testUser);
-            httpSession.setAttribute(SConsts.USER_SESS_ATTR, testUser);
-        }catch (Exception e) {
-        	e.printStackTrace();
-        }
-    }
-}
+/****************************************************************
+ * 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 javax.servlet.http.HttpSession;
+
+import org.apache.commons.logging.Log;
+import org.apache.hupa.server.guice.GuiceServerTestModule;
+import org.apache.hupa.server.preferences.UserPreferencesStorage;
+import org.apache.hupa.server.service.CreateFolderService;
+import org.apache.hupa.server.service.CreateFolderServiceImpl;
+import org.apache.hupa.server.service.DeleteFolderService;
+import org.apache.hupa.server.service.DeleteFolderServiceImpl;
+import org.apache.hupa.server.service.DeleteMessageByUidService;
+import org.apache.hupa.server.service.DeleteMessageByUidServiceImpl;
+import org.apache.hupa.server.service.FetchFoldersService;
+import org.apache.hupa.server.service.FetchFoldersServiceImpl;
+import org.apache.hupa.server.service.FetchMessagesService;
+import org.apache.hupa.server.service.FetchMessagesServiceImpl;
+import org.apache.hupa.server.service.GetMessageDetailsServiceImpl;
+import org.apache.hupa.server.service.IdleService;
+import org.apache.hupa.server.service.IdleServiceImpl;
+import org.apache.hupa.server.service.LoginUserService;
+import org.apache.hupa.server.service.LoginUserServiceImpl;
+import org.apache.hupa.server.service.LogoutUserService;
+import org.apache.hupa.server.service.LogoutUserServiceImpl;
+import org.apache.hupa.server.service.SendReplyMessageServiceImpl;
+import org.apache.hupa.server.utils.SessionUtils;
+import org.apache.hupa.shared.SConsts;
+import org.apache.hupa.shared.domain.User;
+import org.junit.Before;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+import com.sun.mail.imap.IMAPStore;
+
+public class HupaGuiceTestCase{
+
+    protected Injector injector = Guice.createInjector(getModules());
+    
+	protected CreateFolderService createFolderService;
+	protected FetchFoldersService fetchFoldersService;
+	protected FetchMessagesService fetchMessagesService;
+	protected DeleteFolderService deleteFolderService;
+	protected DeleteMessageByUidService deleteMessageByUidService;
+	protected GetMessageDetailsServiceImpl  getMessageDetailsService;
+	protected IdleService idleService;
+	protected LoginUserService loginUserService;
+	protected LogoutUserService logoutUserService;
+	protected SendReplyMessageServiceImpl sendReplyMessageService;
+	
+	protected Log logger;
+    protected IMAPStoreCache storeCache;
+    protected User testUser;
+    protected UserPreferencesStorage userPreferences;
+    protected IMAPStore store;
+    protected HttpSession httpSession;
+    protected Session session;
+    protected Module[] getModules() {
+        return new Module[]{new GuiceServerTestModule()};
+    }
+    
+
+    @Before
+    public void setUp(){
+
+        try {
+        	createFolderService = injector.getInstance(CreateFolderServiceImpl.class);
+        	fetchFoldersService = injector.getInstance(FetchFoldersServiceImpl.class);
+        	fetchMessagesService = injector.getInstance(FetchMessagesServiceImpl.class);
+        	deleteFolderService = injector.getInstance(DeleteFolderServiceImpl.class);
+        	deleteMessageByUidService = injector.getInstance(DeleteMessageByUidServiceImpl.class);
+        	getMessageDetailsService = injector.getInstance(GetMessageDetailsServiceImpl.class);
+        	idleService = injector.getInstance(IdleServiceImpl.class);
+        	loginUserService = injector.getInstance(LoginUserServiceImpl.class);
+        	logoutUserService = injector.getInstance(LogoutUserServiceImpl.class);
+        	sendReplyMessageService = injector.getInstance(SendReplyMessageServiceImpl.class);
+        	
+        	logger = injector.getInstance(Log.class);
+            session = injector.getInstance(Session.class);
+            storeCache = injector.getInstance(IMAPStoreCache.class);
+            userPreferences = injector.getInstance(UserPreferencesStorage.class);
+
+            httpSession = injector.getInstance(HttpSession.class);
+            SessionUtils.cleanSessionAttributes(httpSession);
+            testUser = injector.getInstance(User.class);
+            store = storeCache.get(testUser);
+            httpSession.setAttribute(SConsts.USER_SESS_ATTR, testUser);
+        }catch (Exception e) {
+        	e.printStackTrace();
+        }
+    }
+}

Added: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbtractSendMessageHandlerTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbtractSendMessageHandlerTest.java?rev=1516205&view=auto
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbtractSendMessageHandlerTest.java (added)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/AbtractSendMessageHandlerTest.java Wed Aug 21 16:35:16 2013
@@ -0,0 +1,145 @@
+/****************************************************************
+ * 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.handler;
+
+
+import javax.mail.Message;
+import javax.mail.Part;
+
+import org.apache.hupa.server.HupaGuiceTestCase;
+import org.apache.hupa.server.mock.MockIMAPFolder;
+import org.apache.hupa.server.mock.MockIMAPStore;
+import org.apache.hupa.server.utils.MessageUtils;
+import org.apache.hupa.server.utils.SessionUtils;
+import org.apache.hupa.server.utils.TestUtils;
+import org.apache.hupa.shared.data.SMTPMessage;
+import org.apache.hupa.shared.rpc.SendMessage;
+
+import com.sun.mail.imap.IMAPStore;
+
+public class AbtractSendMessageHandlerTest extends HupaGuiceTestCase {
+
+    String contentTwoAttach = "multipart/mixed\n"
+                            + " multipart/alternative\n"
+                            + "  text/plain\n"
+                            + "  text/html\n"
+                            + " mock/attachment => uploadedFile_1.bin\n"
+                            + " mock/attachment => uploadedFile_2.bin\n";
+
+    public void testComposeMessage() throws Exception{
+        Message msg = TestUtils.createMockMimeMessage(session, "body", null, -1);
+        String exp = "text/plain\n";
+        assertEquals(exp, TestUtils.summaryzeContent(msg).toString());
+        
+        msg = TestUtils.createMockMimeMessage(session, "body", null, 0);
+        exp = "text/plain\n";
+        assertEquals(exp, TestUtils.summaryzeContent(msg).toString());
+
+        msg = TestUtils.createMockMimeMessage(session, null, "html", 0);
+        exp = "text/html\n";
+        assertEquals(exp, TestUtils.summaryzeContent(msg).toString());
+
+        msg = TestUtils.createMockMimeMessage(session, 0);
+        exp = "multipart/alternative\n" +
+              " text/plain\n" +
+              " text/html\n";
+        assertEquals(exp, TestUtils.summaryzeContent(msg).toString());
+        
+        msg = TestUtils.createMockMimeMessage(session, 1);
+        exp = "multipart/mixed\n" +
+              " multipart/alternative\n" +
+              "  text/plain\n" +
+              "  text/html\n" +
+              " mock/attachment => file_1.bin\n";
+        assertEquals(exp, TestUtils.summaryzeContent(msg).toString());
+        
+        msg = TestUtils.createMockMimeMessage(session, 3);
+        exp = "multipart/mixed\n" +
+              " multipart/alternative\n" +
+              "  text/plain\n" +
+              "  text/html\n" +
+              " mock/attachment => file_1.bin\n" +
+              " mock/attachment => file_2.bin\n" +
+              " mock/attachment => file_3.bin\n";
+        assertEquals(exp, TestUtils.summaryzeContent(msg).toString());
+    }
+    
+    public void testRestoreInlineLinks() {
+        String txt, res;
+        txt = ".. <img\nsrc='...&name=abcd' name='cid:abcd'\nwhatever=/> ..";
+        res = sendMessageHandler.restoreInlineLinks(txt);
+        assertEquals(".. <img\nsrc='cid:abcd'\nwhatever=/> ..", res);
+    }
+
+    public void testHtmlmessageToText() {
+        String txt, res;
+        txt = "<div>Hola:</div>Como \n estas<br/>Adios\n\n";
+        res = sendMessageHandler.htmlToText(txt);
+        assertEquals("Hola:\nComo estas\nAdios ", res);
+    }
+    
+    public void testSendEmailWithAttachments() throws Exception {
+        IMAPStore store = storeCache.get(testUser);
+        MockIMAPFolder sentbox = (MockIMAPFolder) store.getFolder(MockIMAPStore.MOCK_SENT_FOLDER);
+        
+        SMTPMessage smtpmsg = TestUtils.createMockSMTPMessage(SessionUtils.getSessionRegistry(logger, httpSession), 2);
+        SendMessage action = new SendMessage(smtpmsg);
+        
+        Message message = sendMessageHandler.createMessage(session, action);
+        message =  sendMessageHandler.fillBody(message, action);
+        
+        assertEquals(contentTwoAttach, TestUtils.summaryzeContent(message).toString());
+
+        sendMessageHandler.sendMessage(testUser, message);
+        
+        // The reported size is wrong before the message has been saved
+        Part part = MessageUtils.handleMultiPart(logger, message.getContent(), "uploadedFile_1.bin");
+        assertTrue(part.getSize() < 0);
+
+        assertTrue(sentbox.getMessages().length == 0);
+        sendMessageHandler.saveSentMessage(testUser, message);
+        assertTrue(sentbox.getMessages().length == 1);
+        
+        message = sentbox.getMessage(0);
+        assertNotNull(message);
+        assertEquals(contentTwoAttach, TestUtils.summaryzeContent(message).toString());
+
+        // After saving the message, the reported size has to be OK
+        part = MessageUtils.handleMultiPart(logger, message.getContent(), "uploadedFile_1.bin");
+        assertTrue(part.getSize() > 0);
+    }
+
+    public void testExecute() throws Exception {
+        IMAPStore store = storeCache.get(testUser);
+        MockIMAPFolder sentbox = (MockIMAPFolder) store.getFolder(MockIMAPStore.MOCK_SENT_FOLDER);
+        
+        SMTPMessage smtpmsg = TestUtils.createMockSMTPMessage(SessionUtils.getSessionRegistry(logger, httpSession), 2);
+        SendMessage action = new SendMessage(smtpmsg);
+        
+        assertTrue(sentbox.getMessages().length == 0);
+        sendMessageHandler.execute(action, null);
+        Message message = sentbox.getMessage(0);
+        assertNotNull(message);
+        assertEquals(contentTwoAttach, TestUtils.summaryzeContent(message).toString());
+        
+        Part part = MessageUtils.handleMultiPart(logger, message.getContent(), "uploadedFile_1.bin");
+        assertTrue(part.getSize() > 0);
+    }
+}

Copied: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/ContactsHandlerTest.java (from r1516164, james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/exception/InvalidSessionException.java)
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/ContactsHandlerTest.java?p2=james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/ContactsHandlerTest.java&p1=james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/exception/InvalidSessionException.java&r1=1516164&r2=1516205&rev=1516205&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/exception/InvalidSessionException.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/handler/ContactsHandlerTest.java Wed Aug 21 16:35:16 2013
@@ -17,13 +17,20 @@
  * under the License.                                           *
  ****************************************************************/
 
-package org.apache.hupa.shared.exception;
+package org.apache.hupa.server.handler;
 
-public class InvalidSessionException extends HupaException{
+import junit.framework.Assert;
 
-	private static final long serialVersionUID = 995112620968798947L;
+import org.apache.hupa.server.HupaGuiceTestCase;
+import org.apache.hupa.shared.rpc.Contacts;
 
-	public InvalidSessionException(String message) {
-        super(message);
+public class ContactsHandlerTest extends HupaGuiceTestCase {
+    
+    public void testContactsHandler() throws Exception {
+        Assert.assertEquals(0, contactsHandler.execute(new Contacts(), null).getContacts().length);
+        userPreferences.addContact("Somebody <so...@foo.com>");
+        userPreferences.addContact(" Some.body   <so...@foo.com>  ");
+        Assert.assertEquals(1, contactsHandler.execute(new Contacts(), null).getContacts().length);
     }
+    
 }



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