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 2014/03/02 13:12:27 UTC

svn commit: r1573291 [7/8] - in /james/hupa/trunk: ./ client/ client/src/main/java/org/apache/hupa/ client/src/main/java/org/apache/hupa/client/ client/src/main/java/org/apache/hupa/client/activity/ client/src/main/java/org/apache/hupa/client/ioc/ clie...

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/FetchMessagesServiceImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/FetchMessagesServiceImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/FetchMessagesServiceImpl.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/FetchMessagesServiceImpl.java Sun Mar  2 12:12:22 2014
@@ -53,239 +53,254 @@ import com.google.inject.Inject;
 import com.sun.mail.imap.IMAPFolder;
 import com.sun.mail.imap.IMAPStore;
 
-public class FetchMessagesServiceImpl extends AbstractService implements FetchMessagesService{
+public class FetchMessagesServiceImpl extends AbstractService implements FetchMessagesService {
 
+	@Inject protected UserPreferencesStorage userPreferences;
 
-    @Inject protected UserPreferencesStorage userPreferences;
-    
-    public FetchMessagesResult fetch(FetchMessagesAction action) throws HupaException{
-        User user = getUser();
-//        ImapFolder folder = action.getFolder();
-        if (action.getFolder() == null) {
-//            folder = new ImapFolderImpl(user.getSettings().getInboxFolderName());
-        	throw new IllegalArgumentException("why you want to ask us for messages in a null folder");
-        }
-        com.sun.mail.imap.IMAPFolder f = null;
-        int start = action.getStart();
-        int offset = action.getOffset();
-        try {
-            IMAPStore store = cache.get(user);
-            
-            f =  (com.sun.mail.imap.IMAPFolder)store.getFolder(action.getFolder().getFullName());
-
-             // check if the folder is open, if not open it read only
-            if (f.isOpen() == false) {
-                f.open(com.sun.mail.imap.IMAPFolder.READ_ONLY);
+	public FetchMessagesResult fetch(FetchMessagesAction action) throws HupaException {
+		User user = getUser();
+		// ImapFolder folder = action.getFolder();
+		if (action.getFolder() == null || action.getFolder().getFullName() == null) {
+			// folder = new
+			// ImapFolderImpl(user.getSettings().getInboxFolderName());
+			throw new IllegalArgumentException("why you want to ask us for messages in a null folder");
+		}
+		com.sun.mail.imap.IMAPFolder f = null;
+		int start = action.getStart();
+		int offset = action.getOffset();
+		try {
+			IMAPStore store = cache.get(user);
+
+			f = (com.sun.mail.imap.IMAPFolder) store.getFolder(action.getFolder().getFullName());
+
+			// check if the folder is open, if not open it read only
+			if (f.isOpen() == false) {
+				f.open(com.sun.mail.imap.IMAPFolder.READ_ONLY);
+			}
+
+			// if the folder is empty we have no need to process
+			int exists = f.getMessageCount();
+			if (exists == 0) {
+				return new FetchMessagesResultImpl(new ArrayList<org.apache.hupa.shared.domain.Message>(), start,
+						offset, 0, 0);
+			}
+
+			MessageConvertArray convArray = getMessagesToConvert(f, action);
+			return new FetchMessagesResultImpl(convert(offset, f, convArray.getMesssages()), start, offset,
+					convArray.getRealCount(), f.getUnreadMessageCount());
+		} catch (MessagingException e) {
+			logger.info("Error fetching messages in folder: " + action.getFolder().getFullName() + " " + e.getMessage());
+			// Folder can not contain messages
+			return new FetchMessagesResultImpl(new ArrayList<org.apache.hupa.shared.domain.Message>(), start, offset,
+					0, 0);
+		} finally {
+			if (f != null && f.isOpen()) {
+				try {
+					f.close(false);
+				} catch (MessagingException e) {
+					// we don't care to much about an exception on close here...
+				}
+			}
+		}
+	}
+
+	protected MessageConvertArray getMessagesToConvert(IMAPFolder f, FetchMessagesAction action)
+			throws MessagingException, HupaException {
+
+		String searchString = action.getSearchString();
+		int start = action.getStart();
+		int offset = action.getOffset();
+		int end = start + offset;
+		Message[] messages;
+		int exists;
+		// check if a searchString was given, and if so use it
+		if (searchString == null) {
+			exists = f.getMessageCount();
+
+			if (end > exists) {
+				end = exists;
+			}
+
+			int firstIndex = exists - end + 1;
+			if (firstIndex < 1) {
+				firstIndex = 1;
+			}
+			int lastIndex = exists - start;
+
+			messages = f.getMessages(firstIndex, lastIndex);
+		} else {
+			SearchTerm subjectTerm = new SubjectTerm(searchString);
+			SearchTerm fromTerm = new FromStringTerm(searchString);
+			SearchTerm bodyTerm = new BodyTerm(searchString);
+			SearchTerm orTerm = new OrTerm(new SearchTerm[] { subjectTerm, fromTerm, bodyTerm });
+			Message[] tmpMessages = f.search(orTerm);
+			if (end > tmpMessages.length) {
+				end = tmpMessages.length;
+			}
+			exists = tmpMessages.length;
+
+			int firstIndex = exists - end;
+
+			if (tmpMessages.length > firstIndex) {
+				List<Message> mList = new ArrayList<Message>();
+				for (int i = firstIndex; i < tmpMessages.length; i++) {
+					if (i == end)
+						break;
+					mList.add(tmpMessages[i]);
+				}
+				messages = mList.toArray(new Message[mList.size()]);
+			} else {
+				messages = new Message[0];
+			}
+
+		}
+		logger.debug("Fetching messages for user: " + getUser() + " returns: " + messages.length + " messages in "
+				+ f.getFullName());
+
+		return new MessageConvertArray(exists, messages);
+	}
+	
+
+	public List<org.apache.hupa.shared.domain.Message> convert(int offset, com.sun.mail.imap.IMAPFolder folder,
+			Message[] messages) throws MessagingException {
+		List<org.apache.hupa.shared.domain.Message> mList = new ArrayList<org.apache.hupa.shared.domain.Message>();
+		
+		// Setup fetchprofile to limit the stuff which is fetched
+		FetchProfile fp = getFetchProfile();
+		folder.fetch(messages, fp);
+		
+		// loop over the fetched messages
+		for (int i = 0; i < messages.length && i < offset; i++) {
+			org.apache.hupa.shared.domain.Message msg = new org.apache.hupa.shared.data.MessageImpl();
+			Message message = messages[i];
+
+			String from = null;
+            if (message.getFrom() != null && message.getFrom().length > 0) {
+                from = MessageUtils.decodeText(message.getFrom()[0].toString());
             }
+            msg.setFrom(from);
 
-            // if the folder is empty we have no need to process 
-            int exists = f.getMessageCount();
-            if (exists == 0) {
-                 return new FetchMessagesResultImpl(new ArrayList<org.apache.hupa.shared.domain.Message>(), start, offset, 0, 0);
-            }        
-            
-            MessageConvertArray convArray = getMessagesToConvert(f,action);
-            return new FetchMessagesResultImpl(convert(offset, f, convArray.getMesssages()),start, offset,convArray.getRealCount(),f.getUnreadMessageCount());
-        } catch (MessagingException e) {
-            logger.info("Error fetching messages in folder: " + action.getFolder().getFullName() + " " + e.getMessage());
-            // Folder can not contain messages
-            return new FetchMessagesResultImpl(new ArrayList<org.apache.hupa.shared.domain.Message>(), start, offset, 0, 0);
-        } finally {
-            if (f != null && f.isOpen()) {
-                try {
-                    f.close(false);
-                } catch (MessagingException e) {
-                    // we don't care to much about an exception on close here...
-                }
-            }
-        }
-    }
-
-
-    protected MessageConvertArray getMessagesToConvert(IMAPFolder f, FetchMessagesAction action) throws MessagingException, HupaException {
-        
-        String searchString = action.getSearchString();
-        int start = action.getStart();
-        int offset = action.getOffset();
-        int end = start + offset;
-        Message[] messages;
-        int exists;
-        // check if a searchString was given, and if so use it
-        if (searchString == null) {
-            exists = f.getMessageCount();
-
-            if (end > exists) {
-                end = exists;
-            }
-
-            int firstIndex = exists - end + 1;
-            if (firstIndex < 1) {
-                firstIndex = 1;
-            }
-            int lastIndex = exists - start;
-            
-            messages = f.getMessages(firstIndex, lastIndex);
-        } else {
-            SearchTerm subjectTerm = new SubjectTerm(searchString);
-            SearchTerm fromTerm = new FromStringTerm(searchString);
-            SearchTerm bodyTerm = new BodyTerm(searchString);
-            SearchTerm orTerm = new OrTerm(new SearchTerm[] { subjectTerm,
-                    fromTerm, bodyTerm });
-            Message[] tmpMessages = f.search(orTerm);
-            if (end > tmpMessages.length) {
-                end = tmpMessages.length;
-            }
-            exists = tmpMessages.length;
-
-            int firstIndex = exists - end;        
-            
-            if (tmpMessages.length > firstIndex) {
-                List<Message> mList = new ArrayList<Message>();
-                for (int i = firstIndex; i < tmpMessages.length; i++) {
-                    if (i == end) break;
-                    mList.add(tmpMessages[i]);
-                }
-                messages = mList.toArray(new Message[mList.size()]);
-            } else {
-                messages = new Message[0];
-            }
-          
-        }
-        logger.debug("Fetching messages for user: " + getUser() + " returns: " + messages.length + " messages in " + f.getFullName());
-
-        return new MessageConvertArray(exists, messages);
-    }
+			String replyto = null;
+			if (message.getReplyTo() != null && message.getReplyTo().length > 0) {
+				replyto = MessageUtils.decodeText(message.getReplyTo()[0].toString());
+			}
+			msg.setReplyto(replyto);
+
+			ArrayList<String> to = new ArrayList<String>();
+			// Add to addresses
+			Address[] toArray = message.getRecipients(RecipientType.TO);
+			if (toArray != null) {
+				for (Address addr : toArray) {
+					String mailTo = MessageUtils.decodeText(addr.toString());
+					to.add(mailTo);
+				}
+			}
+			msg.setTo(to);
+
+			// Check if a subject exist and if so decode it
+			String subject = message.getSubject();
+			if (subject != null) {
+				subject = MessageUtils.decodeText(subject);
+			}
+			msg.setSubject(subject);
+
+			// Add cc addresses
+			Address[] ccArray = message.getRecipients(RecipientType.CC);
+			ArrayList<String> cc = new ArrayList<String>();
+			if (ccArray != null) {
+				for (Address addr : ccArray) {
+					String mailCc = MessageUtils.decodeText(addr.toString());
+					cc.add(mailCc);
+				}
+			}
+			msg.setCc(cc);
+
+			userPreferences.addContact(from);
+			userPreferences.addContact(to);
+			userPreferences.addContact(replyto);
+			userPreferences.addContact(cc);
+
+			// Using sentDate since received date is not useful in the view when
+			// using fetchmail
+			msg.setReceivedDate(message.getSentDate());
+
+			// Add flags
+			ArrayList<IMAPFlag> iFlags = JavamailUtil.convert(message.getFlags());
+
+			ArrayList<Tag> tags = new ArrayList<Tag>();
+			for (String flag : message.getFlags().getUserFlags()) {
+				if (flag.startsWith(TagImpl.PREFIX)) {
+					tags.add(new TagImpl(flag.substring(TagImpl.PREFIX.length())));
+				}
+			}
+
+			msg.setUid(folder.getUID(message));
+			msg.setFlags(iFlags);
+			msg.setTags(tags);
+			try {
+				msg.setHasAttachments(hasAttachment(message));
+			} catch (MessagingException e) {
+				logger.debug("Unable to identify attachments in message UID:" + msg.getUid() + " subject:"
+						+ msg.getSubject() + " cause:" + e.getMessage());
+				logger.info("");
+			}
+			mList.add(0, msg);
+
+		}
+		return mList;
+	}
 
-    public List<org.apache.hupa.shared.domain.Message> convert(int offset, com.sun.mail.imap.IMAPFolder folder, Message[] messages) throws MessagingException {
-        List<org.apache.hupa.shared.domain.Message> mList = new ArrayList<org.apache.hupa.shared.domain.Message>();
-        // Setup fetchprofile to limit the stuff which is fetched 
+    protected FetchProfile getFetchProfile() {
         FetchProfile fp = new FetchProfile();
         fp.add(FetchProfile.Item.ENVELOPE);
-        fp.add(FetchProfile.Item.FLAGS);
-        fp.add(FetchProfile.Item.CONTENT_INFO);
-        fp.add(UIDFolder.FetchProfileItem.UID);
-        folder.fetch(messages, fp);
-        
-        // loop over the fetched messages
-        for (int i = 0; i < messages.length && i < offset; i++) {
-            org.apache.hupa.shared.domain.Message msg = new org.apache.hupa.shared.data.MessageImpl();
-            Message m = messages[i];                
-            String from = null;
-            if (m.getFrom() != null && m.getFrom().length >0 ) {
-                from = MessageUtils.decodeText(m.getFrom()[0].toString());
-            }
-            msg.setFrom(from);
-
-            String replyto = null;
-            if (m.getReplyTo() != null && m.getReplyTo().length >0 ) {
-                replyto = MessageUtils.decodeText(m.getReplyTo()[0].toString());
-            }
-            msg.setReplyto(replyto);
-            
-            ArrayList<String> to = new ArrayList<String>();
-            // Add to addresses
-            Address[] toArray = m.getRecipients(RecipientType.TO);
-            if (toArray != null) {
-                for (Address addr : toArray) {
-                    String mailTo = MessageUtils.decodeText(addr.toString());
-                    to.add(mailTo);
-                }
-            }
-            msg.setTo(to);
-            
-            // Check if a subject exist and if so decode it
-            String subject = m.getSubject();
-            if (subject != null) {
-                subject = MessageUtils.decodeText(subject);
-            }
-            msg.setSubject(subject);
-            
-            // Add cc addresses
-            Address[] ccArray = m.getRecipients(RecipientType.CC);
-            ArrayList<String> cc = new ArrayList<String>();
-            if (ccArray != null) {
-                for (Address addr : ccArray) {
-                    String mailCc = MessageUtils.decodeText(addr.toString());
-                    cc.add(mailCc);
-                }            	
-            }
-            msg.setCc(cc);
-
-            userPreferences.addContact(from);
-            userPreferences.addContact(to);
-            userPreferences.addContact(replyto);
-            userPreferences.addContact(cc);
-
-            // Using sentDate since received date is not useful in the view when using fetchmail
-            msg.setReceivedDate(m.getSentDate());
-
-            // Add flags
-            ArrayList<IMAPFlag> iFlags = JavamailUtil.convert(m.getFlags());
-          
-            ArrayList<Tag> tags = new ArrayList<Tag>();
-            for (String flag : m.getFlags().getUserFlags()) {
-                if (flag.startsWith(TagImpl.PREFIX)) {
-                    tags.add(new TagImpl(flag.substring(TagImpl.PREFIX.length())));
-                }
-            }
-            
-            msg.setUid(folder.getUID(m));
-            msg.setFlags(iFlags);
-            msg.setTags(tags);
-            try {
-                msg.setHasAttachments(hasAttachment(m));
-            } catch (MessagingException e) {
-                logger.debug("Unable to identify attachments in message UID:" + msg.getUid() + " subject:" + msg.getSubject() + " cause:" + e.getMessage());
-                logger.info("");
-            }
-            mList.add(0, msg);
-            
-        }
-        return mList;
+		fp.add(FetchProfile.Item.FLAGS);
+		fp.add(FetchProfile.Item.CONTENT_INFO);
+		fp.add(UIDFolder.FetchProfileItem.UID);
+		return fp;
     }
 
-    private boolean hasAttachment(Message message) throws MessagingException {
-        if (message.getContentType().startsWith("multipart/")) {
-            try {
-                Object content;
-
-                content = message.getContent();
-
-                if (content instanceof Multipart) {
-                    Multipart mp = (Multipart) content;
-                    if (mp.getCount() > 1) {
-                        for (int i = 0; i < mp.getCount(); i++) {
-                            String disp = mp.getBodyPart(i).getDisposition();
-                            if (disp != null
-                                    && disp.equalsIgnoreCase(Part.ATTACHMENT)) {
-                                return true;
-                            }
-                        }
-                    }
-
-                }
-            } catch (IOException e) {
-                logger.error("Error while get content of message " + message.getMessageNumber());
-            }
-            
-        }
-        return false;
-    }   
-    protected final class MessageConvertArray {
-        private Message[] messages;
-        private int realCount;
-
-        public MessageConvertArray(int realCount, Message[] messages) {
-            this.messages = messages;
-            this.realCount = realCount;
-        }
-        
-        public int getRealCount() {
-            return realCount;
-        }
-        
-        public Message[] getMesssages() {
-            return messages;
-        }
-    }
+	private boolean hasAttachment(Message message) throws MessagingException {
+		if (message.getContentType().startsWith("multipart/")) {
+			try {
+				Object content;
+
+				content = message.getContent();
+
+				if (content instanceof Multipart) {
+					Multipart mp = (Multipart) content;
+					if (mp.getCount() > 1) {
+						for (int i = 0; i < mp.getCount(); i++) {
+							String disp = mp.getBodyPart(i).getDisposition();
+							if (disp != null && disp.equalsIgnoreCase(Part.ATTACHMENT)) {
+								return true;
+							}
+						}
+					}
+
+				}
+			} catch (IOException e) {
+				logger.error("Error while get content of message " + message.getMessageNumber());
+			}
+
+		}
+		return false;
+	}
+
+	protected final class MessageConvertArray {
+		private Message[] messages;
+		private int realCount;
+
+		public MessageConvertArray(int realCount, Message[] messages) {
+			this.messages = messages;
+			this.realCount = realCount;
+		}
+
+		public int getRealCount() {
+			return realCount;
+		}
+
+		public Message[] getMesssages() {
+			return messages;
+		}
+	}
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/GetMessageDetailsServiceImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/GetMessageDetailsServiceImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/GetMessageDetailsServiceImpl.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/GetMessageDetailsServiceImpl.java Sun Mar  2 12:12:22 2014
@@ -59,6 +59,13 @@ import javax.mail.internet.MimeMessage;
 import org.apache.hupa.server.utils.MessageUtils;
 import org.apache.hupa.shared.data.GetMessageDetailsResultImpl;
 import org.apache.hupa.shared.data.MailHeaderImpl;
+import javax.mail.Multipart;
+import javax.mail.Part;
+import javax.mail.internet.MimeMessage;
+
+import org.apache.hupa.server.utils.MessageUtils;
+import org.apache.hupa.shared.data.GetMessageDetailsResultImpl;
+import org.apache.hupa.shared.data.MailHeaderImpl;
 import org.apache.hupa.shared.data.MessageDetailsImpl;
 import org.apache.hupa.shared.domain.GetMessageDetailsAction;
 import org.apache.hupa.shared.domain.GetMessageDetailsResult;
@@ -89,7 +96,7 @@ public class GetMessageDetailsServiceImp
 
 			MimeMessage message = (MimeMessage) f.getMessageByUID(uid);
 
-			MessageDetails mDetails = mimeToDetails(message, f.getFullName(), uid);
+			MessageDetails mDetails = mimeToDetails(message, f.getFullName(), uid, user);
 
 			mDetails.setUid(uid);
 
@@ -111,7 +118,7 @@ public class GetMessageDetailsServiceImp
 		}
 	}
 
-	protected MessageDetails mimeToDetails(MimeMessage message, String folderName, long uid) throws IOException,
+	protected MessageDetails mimeToDetails(MimeMessage message, String folderName, long uid, User user) throws IOException,
 	        MessagingException, UnsupportedEncodingException {
 		MessageDetails mDetails = new MessageDetailsImpl();
 
@@ -132,7 +139,9 @@ public class GetMessageDetailsServiceImp
 
 		for (@SuppressWarnings("unchecked") Enumeration<Header> en = message.getAllHeaders(); en.hasMoreElements();) {
 			Header header = en.nextElement();
-			mDetails.setMailHeader(new MailHeaderImpl(header.getName(), header.getValue()));
+			if (header.getName().toLowerCase().matches("^(x-.*|date|from|to|subject)$")) {
+	            mDetails.getMailHeaders().add(new MailHeaderImpl(header.getName(), header.getValue()));
+			}
 		}
 
 		return mDetails;

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserService.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserService.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserService.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserService.java Sun Mar  2 12:12:22 2014
@@ -21,9 +21,11 @@ package org.apache.hupa.server.service;
 
 import javax.mail.MessagingException;
 
+import org.apache.hupa.shared.domain.Settings;
 import org.apache.hupa.shared.domain.User;
 import org.apache.hupa.shared.exception.HupaException;
 
 public interface LoginUserService {
-	public User login(String username, String password) throws HupaException, MessagingException;
+	User login(String username, String password, Settings settings) throws HupaException, MessagingException;
+	Settings getSettings(String email);
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserServiceImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserServiceImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserServiceImpl.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/LoginUserServiceImpl.java Sun Mar  2 12:12:22 2014
@@ -23,6 +23,7 @@ import javax.mail.MessagingException;
 import javax.servlet.http.HttpSession;
 
 import org.apache.hupa.server.utils.SessionUtils;
+import org.apache.hupa.server.utils.SettingsDiscoverer;
 import org.apache.hupa.shared.SConsts;
 import org.apache.hupa.shared.data.UserImpl;
 import org.apache.hupa.shared.domain.Settings;
@@ -35,18 +36,58 @@ import com.google.inject.Provider;
 public class LoginUserServiceImpl extends AbstractService implements LoginUserService {
 
 	@Inject private Provider<Settings> settingsProvider;
+	@Inject private SettingsDiscoverer settingsDiscoverer;
 
-	public User login(String username, String password) throws HupaException, MessagingException {
-		HttpSession httpSession = httpSessionProvider.get();
-        SessionUtils.cleanSessionAttributes(httpSession);
-		User user = new UserImpl();
-		user.setName(username);
-		user.setPassword(password);
-		cache.get(user);
-		user.setAuthenticated(true);
-		user.setSettings(settingsProvider.get());
-		httpSession.setAttribute(SConsts.USER_SESS_ATTR, user);
-		logger.debug("Logged user: " + username);
-		return user;
+	public User login(String username, String password, Settings settings) throws HupaException, MessagingException {
+	    logger.debug("Login user: " + username + " " + password);
+	    try {
+	        HttpSession httpSession = httpSessionProvider.get();
+	        SessionUtils.cleanSessionAttributes(httpSession);
+	        User user = new UserImpl();
+	        user.setName(username);
+	        user.setPassword(password);
+	        user.setSettings(fix(settings));
+	        cache.get(user);
+	        user.setAuthenticated(true);
+	        httpSession.setAttribute(SConsts.USER_SESS_ATTR, user);
+	        logger.debug("Logged user: " + username);
+	        settingsDiscoverer.setValidSettings(user);
+	        return user;
+        } catch (Exception e) {
+            e.printStackTrace();
+            throw new RuntimeException(e);
+        }
 	}
+	
+	private Settings fix(Settings a) {
+	    if (settingsProvider != null) {
+    	    Settings b = settingsProvider.get();
+    	    if (a == null) {
+    	        return b;
+    	    }
+    	    a.setImapServer(or(a.getImapServer(), b.getImapServer()));
+            a.setImapPort(or(a.getImapPort(), b.getImapPort()));
+            a.setSmtpServer((or(a.getSmtpServer(), b.getSmtpServer())));
+            a.setSmtpPort(or(a.getSmtpPort(), b.getSmtpPort()));
+            
+            a.setInboxFolderName(or(a.getInboxFolderName(), b.getInboxFolderName()));
+            a.setSentFolderName(or(a.getSentFolderName(), b.getSentFolderName()));
+            a.setTrashFolderName(or(a.getTrashFolderName(), b.getTrashFolderName()));
+            a.setDraftsFolderName(or(a.getDraftsFolderName(), b.getDraftsFolderName()));
+	    }
+	    return a;
+	}
+	
+	private <T> T or (T a, T b) {
+	    return a == null ? b : a;
+	}
+
+    @Override
+    public Settings getSettings(String email) {
+        if (settingsDiscoverer == null) {
+            settingsDiscoverer = new SettingsDiscoverer();
+        }
+        return settingsDiscoverer.discoverSettings(email);
+    }
+
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendForwardMessageServiceImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendForwardMessageServiceImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendForwardMessageServiceImpl.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendForwardMessageServiceImpl.java Sun Mar  2 12:12:22 2014
@@ -35,16 +35,14 @@ import org.apache.hupa.shared.domain.Sen
 import org.apache.hupa.shared.exception.HupaException;
 
 import com.google.inject.Inject;
-import com.google.inject.name.Named;
 import com.sun.mail.imap.IMAPFolder;
 import com.sun.mail.imap.IMAPStore;
 
-public class SendForwardMessageServiceImpl extends SendMessageBaseServiceImpl implements SendForwardMessageService{
+public class SendForwardMessageServiceImpl extends SendMessageBaseServiceImpl implements SendForwardMessageService {
 
 	@Inject
-	public SendForwardMessageServiceImpl(UserPreferencesStorage preferences, @Named("SMTPServerAddress") String address,
-	        @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL, IMAPStoreCache cache) {
-	    super(preferences, address, port, auth, useSSL,cache);
+	public SendForwardMessageServiceImpl(UserPreferencesStorage preferences, IMAPStoreCache cache) {
+	    super(preferences, cache);
     }
 
     @Override

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendMessageBaseServiceImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendMessageBaseServiceImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendMessageBaseServiceImpl.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendMessageBaseServiceImpl.java Sun Mar  2 12:12:22 2014
@@ -24,10 +24,10 @@ import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
+import java.util.Date;
 import java.util.List;
 
 import javax.activation.DataSource;
-import javax.mail.Address;
 import javax.mail.AuthenticationFailedException;
 import javax.mail.BodyPart;
 import javax.mail.Flags.Flag;
@@ -36,13 +36,13 @@ import javax.mail.Message;
 import javax.mail.MessagingException;
 import javax.mail.Multipart;
 import javax.mail.Session;
-import javax.mail.Transport;
 import javax.mail.internet.AddressException;
 import javax.mail.internet.InternetAddress;
 import javax.mail.internet.MimeBodyPart;
 import javax.mail.internet.MimeMessage;
 import javax.mail.internet.MimeMessage.RecipientType;
 import javax.mail.internet.MimeMultipart;
+import javax.servlet.http.HttpServletRequest;
 
 import org.apache.commons.fileupload.FileItem;
 import org.apache.hupa.server.FileItemRegistry;
@@ -61,45 +61,31 @@ import org.apache.hupa.shared.domain.Use
 import org.apache.hupa.shared.exception.HupaException;
 
 import com.google.inject.Inject;
-import com.google.inject.name.Named;
+import com.google.web.bindery.requestfactory.server.RequestFactoryServlet;
 import com.sun.mail.imap.IMAPFolder;
 import com.sun.mail.imap.IMAPStore;
 
-public class SendMessageBaseServiceImpl extends AbstractService implements SendMessageService{
+public class SendMessageBaseServiceImpl extends AbstractService implements SendMessageService {
 
-	private final boolean auth;
-	private final String address;
-	private final int port;
-	private boolean useSSL = false;
 	UserPreferencesStorage userPreferences;
-	Session session;
 
 	@Inject
-	public SendMessageBaseServiceImpl(UserPreferencesStorage preferences, @Named("SMTPServerAddress") String address,
-	        @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL, IMAPStoreCache cache) {
+	public SendMessageBaseServiceImpl(UserPreferencesStorage preferences, IMAPStoreCache cache) {
 		this.cache = cache;
-		this.auth = auth;
-		this.address = address;
-		this.port = port;
-		this.useSSL = useSSL;
 		this.userPreferences = preferences;
-		this.session = cache.getMailSession();
-		session.getProperties().put("mail.smtp.auth", auth);
 	}
 	
-
-
     public GenericResult send(SendMessageAction action)
             throws Exception {
         GenericResult result = new GenericResultImpl();
         try {
-
-            Message message = createMessage(session, action);
+            User user = getUser();
+            Message message = createMessage(cache.getMailSession(user), action);
             message = fillBody(message,action);
-
             sendMessage(getUser(), message);
-            saveSentMessage(getUser(), message);
-        
+            if (!user.getSettings().getSmtpServer().contains("gmail.com")) {
+                saveSentMessage(getUser(), message);
+            }
             resetAttachments(action);
         
             // TODO: notify the user more accurately where the error is
@@ -129,7 +115,7 @@ public class SendMessageBaseServiceImpl 
      * @throws AddressException
      * @throws MessagingException
      */
-    protected Message createMessage(Session session, SendMessageAction action) throws AddressException, MessagingException {
+    public Message createMessage(Session session, SendMessageAction action) throws AddressException, MessagingException {
         MimeMessage message = new MimeMessage(session);
         SmtpMessage m = action.getMessage();
         message.setFrom(new InternetAddress(m.getFrom()));
@@ -141,13 +127,39 @@ public class SendMessageBaseServiceImpl 
         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(MessageUtils.encodeTexts(m.getSubject()));
+        message.setSentDate(new Date());
+        message.addHeader("User-Agent:", "HUPA, The Apache JAMES webmail client.");
+        message.addHeader("X-Originating-IP", getClientIpAddr());
         message.setSubject(m.getSubject(), "utf-8");
         updateHeaders(message, action);
         message.saveChanges();
         return message;
     }
     
+    public static String getClientIpAddr() {
+        HttpServletRequest request = RequestFactoryServlet.getThreadLocalRequest();
+        String ip = "unknown";
+        if (request != null) {
+            ip = request.getHeader("X-Forwarded-For");  
+            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
+                ip = request.getHeader("Proxy-Client-IP");  
+            }  
+            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
+                ip = request.getHeader("WL-Proxy-Client-IP");  
+            }  
+            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
+                ip = request.getHeader("HTTP_CLIENT_IP");  
+            }  
+            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
+                ip = request.getHeader("HTTP_X_FORWARDED_FOR");  
+            }  
+            if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {  
+                ip = request.getRemoteAddr();  
+            }  
+        }
+        return ip;
+    }  
+    
     protected void updateHeaders(MimeMessage message, SendMessageAction action) {
         if (action.getInReplyTo() != null) {
             try {
@@ -175,7 +187,7 @@ public class SendMessageBaseServiceImpl 
      * @throws IOException 
 	 * @throws HupaException 
      */
-    protected Message fillBody(Message message, SendMessageAction action) throws MessagingException, IOException, HupaException {
+    public Message fillBody(Message message, SendMessageAction action) throws MessagingException, IOException, HupaException {
 
         String html = restoreInlineLinks(action.getMessage().getText());
         
@@ -255,26 +267,8 @@ public class SendMessageBaseServiceImpl 
      * @throws MessagingException
      */
     protected void sendMessage(User user, Message message) throws MessagingException {
-        
-        Transport transport = cache.getMailTransport(useSSL);
-    
-        if (auth) {
-            logger.debug("Use auth for smtp connection");
-            transport.connect(address,port,user.getName(), user.getPassword());
-        } else {
-            transport.connect(address, port, null,null);
-        }
-        
-        Address[] recips = message.getAllRecipients();
-        StringBuffer sb = new StringBuffer();
-        for (int i = 0; i < recips.length; i++) {
-            sb.append(recips[i]);
-            if (i != recips.length -1) {
-                sb.append(", ");
-            }
-        }
-        logger.info("Send message from " + message.getFrom()[0].toString()+ " to " + sb.toString());
-        transport.sendMessage(message, recips);
+        cache.sendMessage(message);
+        logger.info("Send message from " + message.getFrom()[0].toString());
     }
 
     /**

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendReplyMessageServiceImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendReplyMessageServiceImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendReplyMessageServiceImpl.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/service/SendReplyMessageServiceImpl.java Sun Mar  2 12:12:22 2014
@@ -35,16 +35,14 @@ import org.apache.hupa.shared.domain.Sen
 import org.apache.hupa.shared.exception.HupaException;
 
 import com.google.inject.Inject;
-import com.google.inject.name.Named;
 import com.sun.mail.imap.IMAPFolder;
 import com.sun.mail.imap.IMAPStore;
 
 public class SendReplyMessageServiceImpl extends SendMessageBaseServiceImpl implements SendReplyMessageService{
 
 	@Inject
-	public SendReplyMessageServiceImpl(UserPreferencesStorage preferences, @Named("SMTPServerAddress") String address,
-	        @Named("SMTPServerPort") int port, @Named("SMTPAuth") boolean auth, @Named("SMTPS") boolean useSSL, IMAPStoreCache cache) {
-	    super(preferences, address, port, auth, useSSL,cache);
+	public SendReplyMessageServiceImpl(UserPreferencesStorage preferences, IMAPStoreCache cache) {
+	    super(preferences, cache);
     }
 
     @Override

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=1573291&r1=1573290&r2=1573291&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 Sun Mar  2 12:12:22 2014
@@ -99,25 +99,14 @@ public class DownloadAttachmentServlet e
 
             Object content = m.getContent();
             Part part  = MessageUtils.handleMultiPart(logger, content, attachmentName);
-            if (part.getContentType()!=null)
+            if (part.getContentType()!=null) {
                 response.setContentType(part.getContentType());
-            else
-                response.setContentType("application/download");
-
-            in = part.getInputStream();
-            if (in != null) {
-                // FIXME: for some reason Chrome does not display inline images when they have the content-length
-                // it's like the size reported in server is different than the received bytes.
-                if (!inline) {
-                    response.setContentLength(part.getSize());
-                }
-                IOUtils.copy(in, out);
             } else {
-                response.setContentLength(0);
+                response.setContentType("application/download");
             }
-
-            out.flush();
-
+            
+            handleAttachmentData(request, m, attachmentName, part.getInputStream(), out);
+            return;
         } catch (Exception e) {
             logger.error("Error while downloading attachment "
                     + attachmentName + " of message " + message_uuid
@@ -129,11 +118,17 @@ public class DownloadAttachmentServlet e
                 try {
                     folder.close(false);
                 } catch (MessagingException e) {
-                    // ignore on close
                 }
             }
-
         }
     }
 
+    /**
+     * Override this to create customized servlets
+     */
+    protected void handleAttachmentData(HttpServletRequest req, Message message,
+            String attachmentName, InputStream is, OutputStream os) throws Exception {
+        IOUtils.copy(is, os);
+        IOUtils.closeQuietly(os);
+    }
 }

Modified: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/ConfigurationProperties.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/ConfigurationProperties.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/ConfigurationProperties.java (original)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/ConfigurationProperties.java Sun Mar  2 12:12:22 2014
@@ -50,6 +50,7 @@ public enum ConfigurationProperties {
     SESSION_DEBUG("SessionDebug", false, "false"),
     SMTP_AUTH("SMTPAuth", false, "true"),
     SMTPS("SMTPS", false, "false"),
+    TRUST_SSL("TrustSSL", false, "false"),
 
     // Used only in demo mode
     USERNAME("Username", false, null),
@@ -119,8 +120,7 @@ public enum ConfigurationProperties {
 
         // Test for mandatory and complete properties with default values when
         // missing
-        for (ConfigurationProperties confProps : ConfigurationProperties
-                .values()) {
+        for (ConfigurationProperties confProps : ConfigurationProperties.values()) {
             String propName = confProps.getProperty();
             String propValue = confProps.getPropValue();
             Object value = properties.get(propName);
@@ -142,7 +142,7 @@ public enum ConfigurationProperties {
             }
         }
         if (!errors.isEmpty()) {
-            throw new IllegalArgumentException("Error validating configuration: \n" + properties + "\n" +  errors.toString());
+            throw new IllegalArgumentException("Error validating configuration : \n" + properties + "\n" +  errors.toString());
         }
     }
     

Added: james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SettingsDiscoverer.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SettingsDiscoverer.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SettingsDiscoverer.java (added)
+++ james/hupa/trunk/server/src/main/java/org/apache/hupa/server/utils/SettingsDiscoverer.java Sun Mar  2 12:12:22 2014
@@ -0,0 +1,229 @@
+package org.apache.hupa.server.utils;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
+import javax.naming.NamingException;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.InitialDirContext;
+
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.hupa.shared.data.SettingsImpl;
+import org.apache.hupa.shared.domain.Settings;
+import org.apache.hupa.shared.domain.User;
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+public class SettingsDiscoverer {
+    
+    private static HashMap<String, Settings> validConfigs = new HashMap<String, Settings>();
+    
+    @Inject private Provider<Settings> settingsProvider;
+
+    public Settings discoverSettings(String email) {
+        String domain = email.replaceFirst("^.*@", "");
+        Settings s = validConfigs.get(domain);
+        if (s != null) {
+            return s;
+        }
+        
+        String [] mxHosts = null;
+        try {
+            mxHosts = lookupMailHosts(domain);
+        } catch (Exception e) {
+            mxHosts = new String[0];
+        }
+        
+        s = settingsProvider != null ? settingsProvider.get() : new SettingsImpl();
+        
+        if (email.matches(".*@gmail.com") || isValidMx(".*google.*.com", mxHosts)) {
+            s.setImapServer("imap.gmail.com");
+            s.setImapPort(993);
+            s.setImapSecure(true);
+            s.setSmtpServer("smtp.gmail.com");
+            s.setSmtpPort(587); //465
+            s.setSmtpSecure(true);
+            s.setSmtpAuth(true);
+            s.setInboxFolderName("INBOX");
+            s.setSentFolderName("[Gmail]/Sent");
+            s.setTrashFolderName("[Gmail]/Trash");
+            s.setDraftsFolderName("[Gmail]/Drafts");
+        } else if (email.matches(".*@(yahoo|ymail)\\....?") || isValidMx(".*google.*\\....?", mxHosts)) {
+            s.setImapServer("imap.mail.yahoo.com");
+            s.setImapPort(993);
+            s.setImapSecure(true);
+            s.setSmtpServer("smtp.mail.yahoo.com");
+            s.setSmtpPort(465);
+            s.setSmtpSecure(true);
+            s.setSmtpAuth(true);
+            s.setInboxFolderName("INBOX");
+            s.setSentFolderName("Sent");
+            s.setTrashFolderName("Trash");
+            s.setDraftsFolderName("Templates");
+        } else if (email.matches(".*@(hotmail|outlook|live).com")) {
+            s.setImapServer("imap-mail.outlook.com");
+            s.setImapPort(993);
+            s.setImapSecure(true);
+            s.setSmtpServer("smtp-mail.outlook.com");
+            s.setSmtpPort(587);
+            s.setSmtpSecure(true);
+            s.setSmtpAuth(true);
+            s.setInboxFolderName("INBOX");
+            s.setSentFolderName("Sent");
+            s.setTrashFolderName("Trash");
+            s.setDraftsFolderName("Templates");
+        } else {
+            String[] hostNames = new String[]{"imap." + domain, "smtp." + domain, "www." + domain, "mail." + domain, domain};
+            String[] hosts = (String[])ArrayUtils.addAll(hostNames, mxHosts);
+            
+            Integer[] imapPorts = new Integer[]{993, 585, 143};
+            Integer[] smtpPorts = new Integer[]{465, 587, 25};
+            Integer[] ports = (Integer[])ArrayUtils.addAll(imapPorts, smtpPorts);
+            
+            final List<String> validPorts = new ArrayList<String>();
+            ExecutorService es = Executors.newCachedThreadPool();
+            for (final String h : hosts) {
+                if (isValidHostName(h)) {
+                    for (final Integer p : ports) {
+                        es.execute(new Runnable() {
+                            public void run() {
+                                if (isValidPort(h, p)) {
+                                    validPorts.add(h + ":" + p);
+                                }
+                            } 
+                        });
+                    }
+                }
+            }
+            
+            try {
+                es.awaitTermination(1500, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                e.printStackTrace();
+            }
+            System.out.println("ValidPorts: " + domain + " -> "+ validPorts);
+            
+            boolean imapdone = false;
+            loop: for (final String h : hosts) {
+                for (final Integer p : imapPorts) {
+                    if (validPorts.contains(h + ":" + p)) {
+                        s.setImapServer(h);
+                        s.setImapPort(p);
+                        s.setImapSecure(p != 143);
+                        imapdone = true;
+                        break loop;
+                    }
+               }
+            }
+            if (!imapdone) {
+                s.setImapServer("");
+                s.setImapPort(0);
+                s.setImapSecure(false);
+            }
+
+            boolean smtpdone = false;
+            loop: for (final String h : hosts) {
+                for (final Integer p : smtpPorts) {
+                    if (validPorts.contains(h + ":" + p)) {
+                        s.setSmtpServer(h);
+                        s.setSmtpPort(p);
+                        s.setSmtpSecure(p != 25);
+                        smtpdone = true;
+                        break loop;
+                    }
+               }
+            }
+            if (!smtpdone) {
+                s.setSmtpServer("");
+                s.setSmtpPort(0);
+                s.setSmtpSecure(false);
+            }
+            
+            s.setSmtpAuth(true);
+            s.setInboxFolderName("INBOX");
+            s.setSentFolderName("Sent");
+            s.setTrashFolderName("Trash");
+            s.setDraftsFolderName("Drafts");  
+            System.out.println("Returning config: \n" + s);
+        }
+        return s;
+    }
+    
+    static boolean isValidMx(String regexp, String[] mailhosts) {
+        if (mailhosts != null) for (String h : mailhosts) {
+            if (h.toLowerCase().matches(regexp)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    static boolean isValidHostName(String name) {
+        try {
+            InetAddress.getByName(name);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+    
+    static boolean isValidPort(String hostname, int port) {
+        try {
+            Socket socket = new Socket();
+            socket.setSoTimeout(1500);
+            socket.connect(new InetSocketAddress(hostname, port), 1500);
+            socket.close();
+            return true;
+          } catch (Exception ex) {
+            return false;
+          }
+    }
+    
+    static String[] lookupMailHosts(String domainName) throws NamingException {
+        InitialDirContext iDirC = new InitialDirContext();
+        Attributes attributes = iDirC.getAttributes("dns:/" + domainName,
+                new String[] { "MX" });
+        Attribute attributeMX = attributes.get("MX");
+        if (attributeMX == null) {
+            return (new String[] { domainName });
+        }
+
+        // split MX RRs into Preference Values(pvhn[0]) and Host Names(pvhn[1])
+        String[][] pvhn = new String[attributeMX.size()][2];
+        for (int i = 0; i < attributeMX.size(); i++) {
+            pvhn[i] = ("" + attributeMX.get(i)).split("\\s+");
+        }
+
+        // sort the MX RRs by RR value (lower is preferred)
+        Arrays.sort(pvhn, new Comparator<String[]>() {
+            public int compare(String[] o1, String[] o2) {
+                return (Integer.parseInt(o1[0]) - Integer.parseInt(o2[0]));
+            }
+        });
+
+        // put sorted host names in an array, get rid of any trailing '.'
+        String[] sortedHostNames = new String[pvhn.length];
+        for (int i = 0; i < pvhn.length; i++) {
+            sortedHostNames[i] = pvhn[i][1].endsWith(".") ? pvhn[i][1]
+                    .substring(0, pvhn[i][1].length() - 1) : pvhn[i][1];
+        }
+        return sortedHostNames;
+    }
+
+    public void setValidSettings(User user) {
+        String domain = user.getName().replaceFirst("^.*@", "");
+        validConfigs.put(domain, user.getSettings());
+    }
+    
+}

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=1573291&r1=1573290&r2=1573291&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 Sun Mar  2 12:12:22 2014
@@ -36,12 +36,11 @@ import org.apache.hupa.server.service.Fe
 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.SendMessageBaseServiceImpl;
 import org.apache.hupa.server.service.SendReplyMessageServiceImpl;
 import org.apache.hupa.server.utils.SessionUtils;
 import org.apache.hupa.shared.SConsts;
@@ -53,7 +52,7 @@ import com.google.inject.Injector;
 import com.google.inject.Module;
 import com.sun.mail.imap.IMAPStore;
 
-public class HupaGuiceTestCase{
+public class HupaGuiceTestCase {
 
     protected Injector injector = Guice.createInjector(getModules());
     
@@ -63,10 +62,10 @@ public class HupaGuiceTestCase{
 	protected DeleteFolderService deleteFolderService;
 	protected DeleteMessageByUidService deleteMessageByUidService;
 	protected GetMessageDetailsServiceImpl  getMessageDetailsService;
-	protected IdleService idleService;
 	protected LoginUserService loginUserService;
 	protected LogoutUserService logoutUserService;
 	protected SendReplyMessageServiceImpl sendReplyMessageService;
+	protected SendMessageBaseServiceImpl sendMessageService;
 	
 	protected Log logger;
     protected IMAPStoreCache storeCache;
@@ -79,6 +78,8 @@ public class HupaGuiceTestCase{
         return new Module[]{new GuiceServerTestModule()};
     }
     
+    protected FileItemRegistry registry;
+    
 
     @Before
     public void setUp(){
@@ -90,13 +91,12 @@ public class HupaGuiceTestCase{
         	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);
+        	sendMessageService = injector.getInstance(SendMessageBaseServiceImpl.class);
         	
         	logger = injector.getInstance(Log.class);
-            session = injector.getInstance(Session.class);
             storeCache = injector.getInstance(IMAPStoreCache.class);
             userPreferences = injector.getInstance(UserPreferencesStorage.class);
 
@@ -105,7 +105,10 @@ public class HupaGuiceTestCase{
             testUser = injector.getInstance(User.class);
             store = storeCache.get(testUser);
             httpSession.setAttribute(SConsts.USER_SESS_ATTR, testUser);
-        }catch (Exception e) {
+            session = storeCache.getMailSession(testUser);
+
+            registry = SessionUtils.getSessionRegistry(logger, httpSession);
+        } catch (Exception e) {
         	e.printStackTrace();
         }
     }

Added: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceJunitRunner.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceJunitRunner.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceJunitRunner.java (added)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceJunitRunner.java Sun Mar  2 12:12:22 2014
@@ -0,0 +1,50 @@
+package org.apache.hupa.server.guice;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+import com.google.inject.Guice;
+import com.google.inject.Injector;
+import com.google.inject.Module;
+
+/**
+ * Customized Junit Runner able to inject components with guice
+ */
+public class GuiceJunitRunner extends BlockJUnit4ClassRunner {
+
+  @Target(ElementType.TYPE)
+  @Retention(RetentionPolicy.RUNTIME)
+  @Inherited
+  public @interface GuiceModules {
+    Class<?>[] value();
+  }
+
+  private Module[] guiceModules;
+
+  @Override
+  public Object createTest() throws Exception {
+    Injector injector = Guice.createInjector(guiceModules);
+    return injector.getInstance(getTestClass().getJavaClass());
+  }
+
+  public GuiceJunitRunner(Class<?> clz) throws Exception {
+    super(clz);
+
+    GuiceModules ann = clz.getAnnotation(GuiceModules.class);
+    if (ann == null) {
+      throw new InitializationError("No @GuiceModules annotation for  '" + clz.getName() + "'");
+    }
+
+    Class<?>[] classes = ann.value();
+    guiceModules = new Module[classes.length];
+    for (int i = 0; i < classes.length; i++) {
+      guiceModules[i] = (Module) (classes[i]).newInstance();
+    }
+  }
+}
\ No newline at end of file

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceServerTestModule.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceServerTestModule.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceServerTestModule.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/guice/GuiceServerTestModule.java Sun Mar  2 12:12:22 2014
@@ -21,14 +21,12 @@ package org.apache.hupa.server.guice;
 
 import java.util.Properties;
 
-import javax.mail.Session;
 import javax.servlet.http.HttpSession;
 
 import org.apache.commons.logging.Log;
 import org.apache.hupa.server.IMAPStoreCache;
 import org.apache.hupa.server.InMemoryIMAPStoreCache;
 import org.apache.hupa.server.guice.providers.DefaultUserSettingsProvider;
-import org.apache.hupa.server.guice.providers.JavaMailSessionProvider;
 import org.apache.hupa.server.ioc.demo.DemoGuiceServerModule.DemoIMAPStoreCache;
 import org.apache.hupa.server.mock.MockConstants;
 import org.apache.hupa.server.mock.MockHttpSessionProvider;
@@ -41,11 +39,11 @@ import org.apache.hupa.server.service.Cr
 import org.apache.hupa.server.service.DeleteFolderServiceImpl;
 import org.apache.hupa.server.service.DeleteMessageAllServiceImpl;
 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.FetchMessagesServiceImpl;
 import org.apache.hupa.server.service.GetMessageDetailsServiceImpl;
 import org.apache.hupa.server.service.GetMessageRawServiceImpl;
-import org.apache.hupa.server.service.IdleServiceImpl;
 import org.apache.hupa.server.service.ImapFolderServiceImpl;
 import org.apache.hupa.server.service.LoginUserServiceImpl;
 import org.apache.hupa.server.service.LogoutUserServiceImpl;
@@ -70,8 +68,6 @@ import org.apache.hupa.shared.data.GetMe
 import org.apache.hupa.shared.data.GetMessageDetailsResultImpl;
 import org.apache.hupa.shared.data.GetMessageRawActionImpl;
 import org.apache.hupa.shared.data.GetMessageRawResultImpl;
-import org.apache.hupa.shared.data.IdleActionImpl;
-import org.apache.hupa.shared.data.IdleResultImpl;
 import org.apache.hupa.shared.data.ImapFolderImpl;
 import org.apache.hupa.shared.data.LogoutUserActionImpl;
 import org.apache.hupa.shared.data.MailHeaderImpl;
@@ -92,6 +88,7 @@ import org.apache.hupa.shared.domain.Set
 import org.apache.hupa.shared.domain.User;
 
 import com.google.inject.Provider;
+import com.google.inject.Provides;
 import com.google.inject.Singleton;
 import com.google.inject.name.Names;
 import com.sun.mail.imap.IMAPStore;
@@ -107,17 +104,15 @@ public class GuiceServerTestModule exten
         ConfigurationProperties.validateProperties(properties);
         Names.bindProperties(binder(), properties);
 
-        bind(Session.class).toProvider(JavaMailSessionProvider.class);
         bind(HttpSession.class).toProvider(MockHttpSessionProvider.class);
-        bind(Settings.class).toProvider(DefaultUserSettingsProvider.class).in(
-                Singleton.class);
+        bind(Settings.class).toProvider(DefaultUserSettingsProvider.class);
         bind(Log.class).toProvider(logProviderClass).in(Singleton.class);
 
-        bind(IMAPStore.class).to(MockIMAPStore.class);
         
         if (properties == MockConstants.mockProperties) {
             bind(IMAPStoreCache.class).to(DemoIMAPStoreCache.class).in(
                     Singleton.class);
+            bind(IMAPStore.class).to(MockIMAPStore.class);
         } else {
             bind(IMAPStoreCache.class).to(InMemoryIMAPStoreCache.class).in(
                     Singleton.class);
@@ -149,8 +144,6 @@ public class GuiceServerTestModule exten
 		bind(SendReplyMessageActionImpl.class);
 		bind(GetMessageRawActionImpl.class);
 		bind(GetMessageRawResultImpl.class);
-		bind(IdleActionImpl.class);
-		bind(IdleResultImpl.class);
 		bind(LogoutUserActionImpl.class);
 		bind(MoveMessageActionImpl.class);
 		bind(SetFlagActionImpl.class);
@@ -172,10 +165,12 @@ public class GuiceServerTestModule exten
 		bind(SendForwardMessageServiceImpl.class);
 		bind(SendReplyMessageServiceImpl.class);
 		bind(GetMessageRawServiceImpl.class);
-		bind(IdleServiceImpl.class);
 		bind(LogoutUserServiceImpl.class);
 		bind(MoveMessageServiceImpl.class);
 		bind(SetFlagServiceImpl.class);
+		
+        bind(FetchFoldersService.class).to(FetchFoldersServiceImpl.class);
+
 
         bind(DownloadAttachmentServlet.class).in(Singleton.class);
         bind(UploadAttachmentServlet.class).in(Singleton.class);
@@ -183,8 +178,13 @@ public class GuiceServerTestModule exten
         
         bind(UserPreferencesStorage.class).to(userPreferencesStorageClass);
         bind(User.class).to(TestUser.class).in(Singleton.class);
-        bind(Properties.class).toInstance(properties);
 		
 	}
+	
+   @Provides
+    protected Properties getProperties() {
+        System.out.println("getProperties");
+        return (Properties)properties.clone();
+    }
 
 }

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/integration/StoreBugTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/integration/StoreBugTest.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/integration/StoreBugTest.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/integration/StoreBugTest.java Sun Mar  2 12:12:22 2014
@@ -30,7 +30,6 @@ import javax.mail.Session;
 import junit.framework.Assert;
 
 import org.apache.hupa.server.InMemoryIMAPStoreCache;
-import org.apache.hupa.server.guice.providers.JavaMailSessionProvider;
 import org.apache.hupa.server.mock.MockIMAPStore;
 import org.apache.hupa.server.mock.MockLog;
 import org.apache.hupa.shared.data.UserImpl;
@@ -55,8 +54,7 @@ public class StoreBugTest {
     static int threadTimeout = 15000;
     
     Session session = Session.getDefaultInstance(new Properties(), null);
-    static InMemoryIMAPStoreCache cache = new InMemoryIMAPStoreCache(new MockLog(), imapServer, imapPort, isSSl, 2, 60000, false,
-        truststore, truststorePassword, new JavaMailSessionProvider().get());
+    static InMemoryIMAPStoreCache cache = new InMemoryIMAPStoreCache(new MockLog(), 2, 60000, false, truststore, truststorePassword, false);
     static User user = new UserImpl() {
        {setName(imapUser); setPassword(imapPass);}
     };

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/GetMessageDetailServiceTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/GetMessageDetailServiceTest.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/GetMessageDetailServiceTest.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/GetMessageDetailServiceTest.java Sun Mar  2 12:12:22 2014
@@ -132,7 +132,7 @@ public class GetMessageDetailServiceTest
     }
     
     private MessageDetails loadMessageDetails(String msgFile) throws Exception {
-        return getMessageDetailsService.mimeToDetails(TestUtils.loadMessageFromFile(session,msgFile), "theFolder", 9999l);
+        return getMessageDetailsService.mimeToDetails(TestUtils.loadMessageFromFile(session,msgFile), "theFolder", 9999l, testUser);
     }
     
     @Test public void testMessageDetails_textPlain() throws Exception {
@@ -212,5 +212,10 @@ public class GetMessageDetailServiceTest
         assertTrue(html.contains("<a onClick=\"openLink('http://code.google.com/intl/es/webtoolkit/');return false;\" href=\"http://code.google.com/intl/es/webtoolkit/\""));
         assertTrue(html.contains("<a onClick=\"mailTo('donald@example.com');return false;\" href=\"mailto:donald@example.com\""));
     }
+    
+    @Test public void testMessageDetails_ecs_crypt() throws Exception {
+        MessageDetails details = loadMessageDetails("12.msg");
+        assertEquals("Secure Hello world<br>", details.getText());
+    }
 
 }

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/LoginUserServiceTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/LoginUserServiceTest.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/LoginUserServiceTest.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/LoginUserServiceTest.java Sun Mar  2 12:12:22 2014
@@ -36,7 +36,7 @@ public class LoginUserServiceTest extend
     @Test public void invalidLogin() throws MessagingException {
         httpSession.setAttribute("Attribute", "Value");
         try {
-            loginUserService.login("invalid","invalid");
+            loginUserService.login("invalid", "invalid", null);
             fail("Should throw an exception");
         } catch (Throwable t) {
         }
@@ -46,7 +46,8 @@ public class LoginUserServiceTest extend
     
     @Test public void validLogin() throws MessagingException {
         try {
-            User u = loginUserService.login(testUser.getName(), testUser.getPassword());
+            System.out.println(testUser.getName() + " " + testUser.getPassword());
+            User u = loginUserService.login(testUser.getName(), testUser.getPassword(), null);
             assertEquals("Authenticated", true, u.getAuthenticated());
             assertEquals("Authenticated", testUser.getName(), u.getName());
             assertEquals("Authenticated", testUser.getPassword(), u.getPassword());

Added: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/SendMessageServiceTest.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/SendMessageServiceTest.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/SendMessageServiceTest.java (added)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/service/SendMessageServiceTest.java Sun Mar  2 12:12:22 2014
@@ -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.service;
+
+import java.util.Arrays;
+
+import javax.mail.Folder;
+import javax.mail.Message;
+
+import junit.framework.Assert;
+
+import org.apache.hupa.server.FileItemRegistry;
+import org.apache.hupa.server.HupaGuiceTestCase;
+import org.apache.hupa.server.guice.AbstractGuiceTestModule;
+import org.apache.hupa.server.guice.GuiceServerTestModule;
+import org.apache.hupa.server.utils.SessionUtils;
+import org.apache.hupa.server.utils.TestUtils;
+import org.apache.hupa.shared.data.SendMessageActionImpl;
+import org.apache.hupa.shared.domain.SmtpMessage;
+import org.junit.Test;
+
+import com.google.inject.Module;
+import com.sun.mail.imap.IMAPFolder;
+
+public class SendMessageServiceTest extends HupaGuiceTestCase {
+    
+    static final String imapUser = "mcdodot@gmail.com";
+    static final String imapPass = "5234manolito";
+    final private boolean useMock = true;
+    
+    @Override
+    protected Module[] getModules() {
+        if (useMock ) {
+            return super.getModules();
+        } else {
+            return new Module[]{new GuiceServerTestModule(){{
+                properties = AbstractGuiceTestModule.gmailProperties;
+                properties.setProperty("Username", imapUser);
+                properties.setProperty("Password", imapPass);
+            }}};
+        }
+    }
+    
+    @Test
+    public void testSendMessage() throws Exception {
+        IMAPFolder folder = (IMAPFolder) store.getFolder(testUser.getSettings().getSentFolderName());
+        folder.open(Folder.READ_ONLY);
+        long count = folder.getMessageCount();
+        
+        FileItemRegistry registry = SessionUtils.getSessionRegistry(logger, httpSession);
+        
+        // Create a reply user action with an uploaded message
+        SmtpMessage smtpmsg = TestUtils.createMockSMTPMessage(registry, 1);
+        SendMessageActionImpl action = new SendMessageActionImpl(smtpmsg);
+        String subject = "Test Message: " + System.currentTimeMillis();
+        smtpmsg.setTo(Arrays.asList("manolo@alcala.org"));
+        smtpmsg.setCc(Arrays.<String>asList());
+        smtpmsg.setBcc(Arrays.<String>asList());
+        smtpmsg.setFrom(imapUser);
+        smtpmsg.setSubject(subject);
+        
+        Message message = sendMessageService.createMessage(session, action);
+        message = sendMessageService.fillBody(message, action);
+        
+        sendMessageService.send(action);
+        
+        Assert.assertTrue(count < folder.getMessageCount());
+    }
+    
+    
+}

Modified: james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/TestUtils.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/TestUtils.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/TestUtils.java (original)
+++ james/hupa/trunk/server/src/test/java/org/apache/hupa/server/utils/TestUtils.java Sun Mar  2 12:12:22 2014
@@ -24,6 +24,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.List;
 
 import javax.mail.BodyPart;
 import javax.mail.Folder;
@@ -195,9 +196,9 @@ public class TestUtils extends TestCase 
 
         SmtpMessage smtpMessage = new SmtpMessageImpl();
         smtpMessage.setFrom("Test user <fr...@dom.com>");
-        smtpMessage.setTo(new ArrayList<String>(Arrays.asList("to@dom.com")));
-        smtpMessage.setCc(new ArrayList<String>(Arrays.asList("cc@dom.com")));
-        smtpMessage.setBcc(new ArrayList<String>(Arrays.asList("bcc@dom.com")));
+        smtpMessage.setTo(Arrays.asList("to@dom.com"));
+        smtpMessage.setCc(Arrays.asList("cc@dom.com"));
+        smtpMessage.setBcc(Arrays.asList("bcc@dom.com"));
         smtpMessage.setSubject("Subject");
         smtpMessage.setText("<div>Body</div>");
         smtpMessage.setMessageAttachments(attachments);

Added: james/hupa/trunk/server/src/test/resources/testimage.jpg
URL: http://svn.apache.org/viewvc/james/hupa/trunk/server/src/test/resources/testimage.jpg?rev=1573291&view=auto
==============================================================================
Binary file - no diff available.

Propchange: james/hupa/trunk/server/src/test/resources/testimage.jpg
------------------------------------------------------------------------------
    svn:mime-type = application/octet-stream

Modified: james/hupa/trunk/shared/pom.xml
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/pom.xml?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/shared/pom.xml (original)
+++ james/hupa/trunk/shared/pom.xml Sun Mar  2 12:12:22 2014
@@ -35,6 +35,10 @@
             <artifactId>gwt-user</artifactId>
         </dependency>
         <dependency>
+            <groupId>com.google.code.guice</groupId>
+            <artifactId>guice</artifactId>
+        </dependency>        
+        <dependency>
             <groupId>junit</groupId>
             <artifactId>junit</artifactId>
             <scope>test</scope>

Added: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/B64.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/B64.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/B64.java (added)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/B64.java Sun Mar  2 12:12:22 2014
@@ -0,0 +1,195 @@
+package org.apache.hupa.shared.algorithms;
+
+/**
+ * A utility to decode and encode byte arrays as Strings, using only "safe"
+ * characters.
+ */
+public class B64 {
+
+    /**
+     * An array mapping size but values to the characters that will be used to
+     * represent them. Note that this is not identical to the set of characters
+     * used by MIME-Base64.
+     */
+    private static final char[] base64Chars = new char[] { 'A', 'B', 'C', 'D',
+            'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q',
+            'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
+            'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q',
+            'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3',
+            '4', '5', '6', '7', '8', '9', '$', '_' };
+
+    /**
+     * An array mapping legal base 64 characters [a-zA-Z0-9$_] to their
+     * associated 6-bit values. The source indices will be given by 7-bit ASCII
+     * characters, thus the array size needs to be 128 (actually 123 would
+     * suffice for the given set of characters in use).
+     */
+    private static final byte[] base64Values = new byte[128];
+
+    /**
+     * Initialize the base 64 encoder values.
+     */
+    static {
+        // Invert the mapping (i -> base64Chars[i])
+        for (int i = 0; i < base64Chars.length; i++) {
+            base64Values[base64Chars[i]] = (byte) i;
+        }
+    }
+
+    /**
+     * Decode a base64 string into a byte array.
+     * 
+     * @param data
+     *            the encoded data.
+     * @return a byte array.
+     * @see #fromBase64(String)
+     */
+    public static byte[] fromBase64(String data) {
+        if (data == null) {
+            return null;
+        }
+
+        int len = data.length();
+        assert (len % 4) == 0;
+
+        if (len == 0) {
+            return new byte[0];
+        }
+
+        char[] chars = new char[len];
+        data.getChars(0, len, chars, 0);
+
+        int olen = 3 * (len / 4);
+        if (chars[len - 2] == '=') {
+            --olen;
+        }
+        if (chars[len - 1] == '=') {
+            --olen;
+        }
+
+        byte[] bytes = new byte[olen];
+
+        int iidx = 0;
+        int oidx = 0;
+        while (iidx < len) {
+            int c0 = base64Values[chars[iidx++] & 0xff];
+            int c1 = base64Values[chars[iidx++] & 0xff];
+            int c2 = base64Values[chars[iidx++] & 0xff];
+            int c3 = base64Values[chars[iidx++] & 0xff];
+            int c24 = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3;
+
+            bytes[oidx++] = (byte) (c24 >> 16);
+            if (oidx == olen) {
+                break;
+            }
+            bytes[oidx++] = (byte) (c24 >> 8);
+            if (oidx == olen) {
+                break;
+            }
+            bytes[oidx++] = (byte) c24;
+        }
+
+        return bytes;
+    }
+
+    /**
+     * Decode a base64 string into a long value.
+     */
+    public static long longFromBase64(String value) {
+        int pos = 0;
+        long longVal = base64Values[value.charAt(pos++)];
+        int len = value.length();
+        while (pos < len) {
+            longVal <<= 6;
+            longVal |= base64Values[value.charAt(pos++)];
+        }
+        return longVal;
+    }
+
+    /**
+     * Converts a byte array into a base 64 encoded string. Null is encoded as
+     * null, and an empty array is encoded as an empty string. Otherwise, the
+     * byte data is read 3 bytes at a time, with bytes off the end of the array
+     * padded with zeros. Each 24-bit chunk is encoded as 4 characters from the
+     * sequence [A-Za-z0-9$_]. If one of the source positions consists entirely
+     * of padding zeros, an '=' character is used instead.
+     * 
+     * @param data
+     *            a byte array, which may be null or empty
+     * @return a String
+     */
+    public static String toBase64(byte[] data) {
+        if (data == null) {
+            return null;
+        }
+
+        int len = data.length;
+        if (len == 0) {
+            return "";
+        }
+
+        int olen = 4 * ((len + 2) / 3);
+        char[] chars = new char[olen];
+
+        int iidx = 0;
+        int oidx = 0;
+        int charsLeft = len;
+        while (charsLeft > 0) {
+            int b0 = data[iidx++] & 0xff;
+            int b1 = (charsLeft > 1) ? data[iidx++] & 0xff : 0;
+            int b2 = (charsLeft > 2) ? data[iidx++] & 0xff : 0;
+            int b24 = (b0 << 16) | (b1 << 8) | b2;
+
+            int c0 = (b24 >> 18) & 0x3f;
+            int c1 = (b24 >> 12) & 0x3f;
+            int c2 = (b24 >> 6) & 0x3f;
+            int c3 = b24 & 0x3f;
+
+            chars[oidx++] = base64Chars[c0];
+            chars[oidx++] = base64Chars[c1];
+            chars[oidx++] = (charsLeft > 1) ? base64Chars[c2] : '=';
+            chars[oidx++] = (charsLeft > 2) ? base64Chars[c3] : '=';
+
+            charsLeft -= 3;
+        }
+
+        return new String(chars);
+    }
+
+    /**
+     * Return a string containing a base-64 encoded version of the given long
+     * value. Leading groups of all zero bits are omitted.
+     */
+    public static String toBase64(long value) {
+        // Convert to ints early to avoid need for long ops
+        int low = (int) (value & 0xffffffff);
+        int high = (int) (value >> 32);
+
+        StringBuilder sb = new StringBuilder();
+        boolean haveNonZero = base64Append(sb, (high >> 28) & 0xf, false);
+        haveNonZero = base64Append(sb, (high >> 22) & 0x3f, haveNonZero);
+        haveNonZero = base64Append(sb, (high >> 16) & 0x3f, haveNonZero);
+        haveNonZero = base64Append(sb, (high >> 10) & 0x3f, haveNonZero);
+        haveNonZero = base64Append(sb, (high >> 4) & 0x3f, haveNonZero);
+        int v = ((high & 0xf) << 2) | ((low >> 30) & 0x3);
+        haveNonZero = base64Append(sb, v, haveNonZero);
+        haveNonZero = base64Append(sb, (low >> 24) & 0x3f, haveNonZero);
+        haveNonZero = base64Append(sb, (low >> 18) & 0x3f, haveNonZero);
+        haveNonZero = base64Append(sb, (low >> 12) & 0x3f, haveNonZero);
+        base64Append(sb, (low >> 6) & 0x3f, haveNonZero);
+        base64Append(sb, low & 0x3f, true);
+
+        return sb.toString();
+    }
+
+    private static boolean base64Append(StringBuilder sb, int digit,
+            boolean haveNonZero) {
+        if (digit > 0) {
+            haveNonZero = true;
+        }
+        if (haveNonZero) {
+            sb.append(base64Chars[digit]);
+        }
+        return haveNonZero;
+    }
+}

Added: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/Md5.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/Md5.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/Md5.java (added)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/Md5.java Sun Mar  2 12:12:22 2014
@@ -0,0 +1,23 @@
+package org.apache.hupa.shared.algorithms;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+public class Md5 {
+    public static String md5Hex(String input) {
+        try {
+            MessageDigest md5 = MessageDigest.getInstance("MD5");
+            md5.reset();
+            md5.update(input.getBytes());
+            byte messageDigest[] = md5.digest();
+            String ret = "";
+            for (byte b : messageDigest) {
+                ret += Integer.toHexString((int)b & 0xff | 0x100).substring(1);
+            }
+            return ret;
+        } catch (NoSuchAlgorithmException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+}

Added: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/RC4.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/RC4.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/RC4.java (added)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/algorithms/RC4.java Sun Mar  2 12:12:22 2014
@@ -0,0 +1,65 @@
+package org.apache.hupa.shared.algorithms;
+
+public class RC4 {
+    private byte state[] = new byte[256];
+
+    public RC4(String key) throws NullPointerException {
+        this(key.getBytes());
+    }
+
+    public RC4(byte[] key) throws NullPointerException {
+        for (int i = 0; i < 256; i++) {
+            state[i] = (byte) i;
+        }
+
+        int index1 = 0, index2 = 0;
+
+        byte tmp;
+        if (key == null || key.length == 0) {
+            throw new NullPointerException();
+        }
+
+        for (int i = 0; i < 256; i++) {
+            index2 = ((key[index1] & 0xff) + (state[i] & 0xff) + index2) & 0xff;
+
+            tmp = state[i];
+            state[i] = state[index2];
+            state[index2] = tmp;
+
+            index1 = (index1 + 1) % key.length;
+        }
+    }
+
+    public byte[] rc4(String data) {
+        return data == null ? null : this.rc4(data.getBytes());
+    }
+
+    public byte[] rc4(byte[] buf) {
+        int xorIndex;
+        byte tmp;
+        int x = 0, y = 0;
+
+        if (buf == null) {
+            return null;
+        }
+
+        byte[] result = new byte[buf.length];
+
+        for (int i = 0; i < buf.length; i++) {
+            x = (x + 1) & 0xff;
+            y = ((state[x] & 0xff) + y) & 0xff;
+
+            tmp = state[x];
+            state[x] = state[y];
+            state[y] = tmp;
+
+            xorIndex = ((state[x] & 0xff) + (state[y] & 0xff)) & 0xff;
+            result[i] = (byte) (buf[i] ^ state[xorIndex]);
+            // System.out.printf("%02d %03d %03d %c %03d %03d %03d %03d\n", i ,
+            // (buf[i] & 0xFF), (result[i] & 0xFF), buf[i], x, (state[x] &
+            // 0xFF), y, (state[y] & 0xFF));
+        }
+
+        return result;
+    }
+}

Modified: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/FetchMessagesActionImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/FetchMessagesActionImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/FetchMessagesActionImpl.java (original)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/FetchMessagesActionImpl.java Sun Mar  2 12:12:22 2014
@@ -31,6 +31,11 @@ public class FetchMessagesActionImpl imp
 
 	public FetchMessagesActionImpl() {
 	}
+	
+	@Override
+	public String toString() {
+	    return "[" + folder.getFullName() + "," + start + "," + offset + "," + searchString + "]";
+	}
 
 	public FetchMessagesActionImpl(ImapFolder folder, int start, int offset, String searchString) {
 		this.folder = folder;

Added: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasFullName.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasFullName.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasFullName.java (added)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasFullName.java Sun Mar  2 12:12:22 2014
@@ -0,0 +1,6 @@
+package org.apache.hupa.shared.data;
+
+public interface HasFullName {
+   String getFullName();
+   void setFullName(String name);
+}

Added: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasId.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasId.java?rev=1573291&view=auto
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasId.java (added)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/HasId.java Sun Mar  2 12:12:22 2014
@@ -0,0 +1,5 @@
+package org.apache.hupa.shared.data;
+
+public interface HasId {
+   String getId();
+}

Modified: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/ImapFolderImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/ImapFolderImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/ImapFolderImpl.java (original)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/ImapFolderImpl.java Sun Mar  2 12:12:22 2014
@@ -213,6 +213,4 @@ public class ImapFolderImpl implements I
 	public void setHasChildren(boolean hasChildren){
 		this.hasChildren = hasChildren;
 	}
-
-    
 }

Modified: james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/MailHeaderImpl.java
URL: http://svn.apache.org/viewvc/james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/MailHeaderImpl.java?rev=1573291&r1=1573290&r2=1573291&view=diff
==============================================================================
--- james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/MailHeaderImpl.java (original)
+++ james/hupa/trunk/shared/src/main/java/org/apache/hupa/shared/data/MailHeaderImpl.java Sun Mar  2 12:12:22 2014
@@ -44,4 +44,13 @@ public class MailHeaderImpl implements M
 		return value;
 	}
 
+    @Override
+    public void setName(String s) {
+        name = s;
+    }
+
+    @Override
+    public void setValue(String s) {
+        value = s;
+    }
 }



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