| /**************************************************************** |
| * Licensed to the Apache Software Foundation (ASF) under one * |
| * or more contributor license agreements. See the NOTICE file * |
| * distributed with this work for additional information * |
| * regarding copyright ownership. The ASF licenses this file * |
| * to you under the Apache License, Version 2.0 (the * |
| * "License"); you may not use this file except in compliance * |
| * with the License. You may obtain a copy of the License at * |
| * * |
| * http://www.apache.org/licenses/LICENSE-2.0 * |
| * * |
| * Unless required by applicable law or agreed to in writing, * |
| * software distributed under the License is distributed on an * |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * |
| * KIND, either express or implied. See the License for the * |
| * specific language governing permissions and limitations * |
| * under the License. * |
| ****************************************************************/ |
| |
| package org.apache.hupa.client.activity; |
| |
| import gwtupload.client.IUploadStatus.Status; |
| import gwtupload.client.IUploader; |
| import gwtupload.client.IUploader.OnCancelUploaderHandler; |
| import gwtupload.client.IUploader.OnFinishUploaderHandler; |
| import gwtupload.client.IUploader.OnStatusChangedHandler; |
| import gwtupload.client.IUploader.UploadedInfo; |
| |
| import java.util.ArrayList; |
| import java.util.Iterator; |
| import java.util.List; |
| |
| import org.apache.hupa.client.HupaController; |
| import org.apache.hupa.client.place.ComposePlace; |
| import org.apache.hupa.client.rf.SendForwardMessageRequest; |
| import org.apache.hupa.client.rf.SendMessageRequest; |
| import org.apache.hupa.client.rf.SendReplyMessageRequest; |
| import org.apache.hupa.client.validation.EmailListValidator; |
| import org.apache.hupa.shared.Util; |
| import org.apache.hupa.shared.data.MessageAttachmentImpl; |
| import org.apache.hupa.shared.domain.GenericResult; |
| import org.apache.hupa.shared.domain.ImapFolder; |
| import org.apache.hupa.shared.domain.Message; |
| import org.apache.hupa.shared.domain.MessageAttachment; |
| import org.apache.hupa.shared.domain.MessageDetails; |
| import org.apache.hupa.shared.domain.SendForwardMessageAction; |
| import org.apache.hupa.shared.domain.SendMessageAction; |
| import org.apache.hupa.shared.domain.SendReplyMessageAction; |
| import org.apache.hupa.shared.domain.SmtpMessage; |
| import org.apache.hupa.shared.domain.User; |
| import org.apache.hupa.shared.events.AddressClickEvent; |
| import org.apache.hupa.shared.events.AddressClickEventHandler; |
| import org.apache.hupa.shared.events.AttachClickEvent; |
| import org.apache.hupa.shared.events.AttachClickEventHandler; |
| import org.apache.hupa.shared.events.LoginEvent; |
| import org.apache.hupa.shared.events.LoginEventHandler; |
| import org.apache.hupa.shared.events.MailToEvent; |
| import org.apache.hupa.shared.events.MailToEventHandler; |
| import org.apache.hupa.shared.events.SendClickEvent; |
| import org.apache.hupa.shared.events.SendClickEventHandler; |
| |
| import com.google.gwt.activity.shared.Activity; |
| import com.google.gwt.event.dom.client.ClickEvent; |
| import com.google.gwt.event.dom.client.ClickHandler; |
| import com.google.gwt.event.dom.client.HasClickHandlers; |
| import com.google.gwt.event.dom.client.HasFocusHandlers; |
| import com.google.gwt.event.shared.EventBus; |
| import com.google.gwt.storage.client.Storage; |
| import com.google.gwt.user.client.History; |
| import com.google.gwt.user.client.ui.AcceptsOneWidget; |
| import com.google.gwt.user.client.ui.HasEnabled; |
| import com.google.gwt.user.client.ui.HasHTML; |
| import com.google.gwt.user.client.ui.HasText; |
| import com.google.gwt.user.client.ui.IsWidget; |
| import com.google.gwt.user.client.ui.ListBox; |
| import com.google.inject.Inject; |
| import com.google.web.bindery.requestfactory.shared.Receiver; |
| import com.google.web.bindery.requestfactory.shared.RequestContext; |
| |
| public class ComposeActivity extends AppBaseActivity { |
| @Inject private Displayable display; |
| @Inject private HupaController hupaController; |
| private List<MessageAttachment> attachments = new ArrayList<MessageAttachment>(); |
| protected ComposePlace place; |
| private User user; |
| |
| public Activity with(ComposePlace place) { |
| this.place = place; |
| return this; |
| } |
| |
| @Override |
| public void start(AcceptsOneWidget container, EventBus eventBus) { |
| container.setWidget(display.asWidget()); |
| bindTo(eventBus); |
| fillHeader(); |
| } |
| |
| @Override |
| public String mayStop() { |
| super.mayStop(); |
| if (noContent()) { |
| return null; |
| } |
| return null; |
| // return "Do you want to leave this page?"; TODO |
| } |
| |
| @Override |
| public void onStop() { |
| super.onStop(); |
| } |
| |
| private boolean noContent() { |
| return "".equals(display.getMessage().getText()) && "".equals(display.getSubject().getText()); |
| } |
| |
| @Override |
| public void onCancel() { |
| |
| } |
| |
| protected void fillHeader() { |
| if (place == null || place.getParameters() == null) |
| return; |
| if (user == null) { |
| user = place.getParameters().getUser(); |
| } |
| if (user == null) { |
| user = HupaController.user; |
| } |
| display.getFromList().addItem(user.getName()); |
| display.getUploader().reset(); |
| if ("new".equals(place.getToken())) { |
| display.getTo().setText(""); |
| display.getCc().setText(""); |
| display.getBcc().setText(""); |
| display.getSubject().setText(place.getSubject() == null ? "" : place.getSubject()); |
| display.getMessageHTML().setHTML(place.getBody() == null ? "" : place.getBody()); |
| attachments.clear(); |
| return; |
| } |
| Message oldMessage = place.getParameters().getOldmessage(); |
| display.getMessageHTML().setHTML( |
| wrapMessage(oldMessage, place.getParameters().getOldDetails(), place.getToken())); |
| if ("forward".equals(place.getToken())) { |
| String subject = oldMessage.getSubject() != null ? oldMessage.getSubject().trim() : ""; |
| if (!subject.toLowerCase().startsWith("fwd:")) { |
| subject = "Fwd: " + subject; |
| } |
| display.getSubject().setText(subject); |
| } else if ("reply".equals(place.getToken()) || "replyAll".equals(place.getToken())) { |
| |
| String subject = oldMessage.getSubject() != null ? oldMessage.getSubject().trim() : ""; |
| if (!subject.toLowerCase().startsWith("re:")) { |
| subject = "Re: " + subject; |
| } |
| if ("reply".equals(place.getToken())) { |
| display.getSubject().setText(subject); |
| if (oldMessage.getReplyto() != null && !oldMessage.getFrom().contains(oldMessage.getReplyto())) { |
| display.getTo().setText(oldMessage.getReplyto()); |
| } else { |
| display.getTo().setText(oldMessage.getFrom()); |
| } |
| } else if ("replyAll".equals(place.getToken())) { |
| ArrayList<String> list = new ArrayList<String>(); |
| if (oldMessage.getReplyto() != null && !oldMessage.getFrom().contains(oldMessage.getReplyto())) |
| list.add(oldMessage.getReplyto()); |
| if (oldMessage.getTo() != null) |
| list.addAll(oldMessage.getTo()); |
| if (oldMessage.getCc() != null) |
| list.addAll(oldMessage.getCc()); |
| list = removeEmailFromList(list, user.getName()); |
| display.getCc().setText(Util.listToString(list)); |
| if (oldMessage.getTo() != null) { |
| oldMessage.getTo().remove(user.getName()); |
| } |
| display.getTo().setText(oldMessage.getFrom()); |
| } |
| } |
| } |
| |
| protected ArrayList<String> removeEmailFromList(List<String> list, String email) { |
| ArrayList<String> ret = new ArrayList<String>(); |
| String regex = ".*<?\\s*" + email.trim() + "\\s*>?\\s*"; |
| for (String e : list) { |
| if (!e.matches(regex)) { |
| ret.add(e); |
| } |
| } |
| return ret; |
| } |
| private static String generateHeader(Message message, String type) { |
| String ret = "<br>"; |
| if (message != null) { |
| if (type.equals("forward")) { |
| ret += "--------- Forwarded message --------- <br>"; |
| ret += "From: " + message.getFrom().replaceAll("<", "<").replaceAll(">", ">") + "<br>"; |
| ret += "Date: " + message.getReceivedDate() + "<br>"; |
| ret += "Subject: " + message.getSubject() + "<br>"; |
| ArrayList<String> to = new ArrayList<String>(); |
| to.addAll(message.getTo()); |
| to.addAll(message.getCc()); |
| ret += "To: " + Util.listToString(to).replaceAll("<", "<").replaceAll(">", ">") + "<br>"; |
| } else if (type.equals("reply") || type.equals("replyAll")) { |
| ret += "On " + message.getReceivedDate(); |
| ret += ", " + message.getFrom().replaceAll("<", "<").replaceAll(">", ">"); |
| ret += ". wrote:<br>"; |
| } |
| } |
| return ret + "<br>"; |
| } |
| public static String wrapMessage(Message message, MessageDetails details, String type) { |
| String ret = ""; |
| if (message != null) { |
| ret += generateHeader(message, type); |
| } |
| if (details != null && details.getText() != null && details.getText().length() > 0) { |
| ret += "<blockquote style='border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;'>"; |
| ret += details.getText(); |
| ret += "</blockquote>"; |
| } |
| return ret; |
| } |
| protected void bindTo(EventBus eventBus) { |
| eventBus.addHandler(AddressClickEvent.TYPE, new AddressClickEventHandler() { |
| @Override |
| public void onClick(AddressClickEvent event) { |
| String to = display.getTo().getText(); |
| if(to != null && to.trim().length() > 0){ |
| display.getTo().setText(to + ";" + event.getEmail()); |
| }else { |
| display.getTo().setText(event.getEmail()); |
| } |
| } |
| }); |
| eventBus.addHandler(SendClickEvent.TYPE, new SendClickEventHandler() { |
| public void onSendClick(SendClickEvent event) { |
| send(); |
| } |
| }); |
| eventBus.addHandler(LoginEvent.TYPE, new LoginEventHandler() { |
| public void onLogin(LoginEvent event) { |
| user = event.getUser(); |
| } |
| }); |
| eventBus.addHandler(AttachClickEvent.TYPE, new AttachClickEventHandler() { |
| public void onAttachClick(AttachClickEvent event) { |
| display.getAttachButton().fireEvent(new ClickEvent() { |
| }); |
| } |
| }); |
| registerHandler(display.getSendClick().addClickHandler(sendClickHandler)); |
| registerHandler(display.getCancelClick().addClickHandler(cancelClickHandler)); |
| |
| registerHandler(display.getCcClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.showCc(); |
| } |
| })); |
| registerHandler(display.get_CcClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.hideCc(); |
| } |
| })); |
| registerHandler(display.getBccClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.showBcc(); |
| } |
| })); |
| registerHandler(display.get_BccClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.hideBcc(); |
| } |
| })); |
| registerHandler(display.getReplyClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.showReply(); |
| } |
| })); |
| registerHandler(display.get_ReplyClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.hideReply(); |
| } |
| })); |
| registerHandler(display.getFollowupClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.showFollowup(); |
| } |
| })); |
| registerHandler(display.get_FollowupClick().addClickHandler(new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| display.hideFollowup(); |
| } |
| })); |
| registerHandler(display.getUploader().addOnStatusChangedHandler(onStatusChangedHandler)); |
| registerHandler(display.getUploader().addOnFinishUploadHandler(onFinishUploadHandler)); |
| registerHandler(display.getUploader().addOnCancelUploadHandler(onCancelUploadHandler)); |
| |
| eventBus.addHandler(MailToEvent.TYPE, new MailToEventHandler() { |
| @Override |
| public void onMailTo(MailToEvent event) { |
| display.getTo().setText(event.getMailto()); |
| } |
| }); |
| |
| fillSuggestList(); |
| |
| } |
| |
| private void fillSuggestList() { |
| // TODO move this to hupaStorage |
| Storage contactStore = Storage.getLocalStorageIfSupported(); |
| if (contactStore != null) { |
| String contactsString = contactStore.getItem(MessageListActivity.CONTACTS_STORE); |
| if (contactsString != null) { |
| display.fillContactList(contactsString.replace("[", "").replace("]", "").trim().split(",")); |
| } |
| } |
| } |
| |
| private OnFinishUploaderHandler onFinishUploadHandler = new OnFinishUploaderHandler() { |
| public void onFinish(IUploader uploader) { |
| if (uploader.getStatus() == Status.SUCCESS) { |
| // We use the fileInputName (unique) instead of the fileName so |
| // as we |
| // can find the item in the registry. |
| for (UploadedInfo info : uploader.getServerMessage().getUploadedInfos()) { |
| MessageAttachment attachment = new MessageAttachmentImpl(); |
| attachment.setName(info.getField()); |
| attachment.setContentType(info.getCtype()); |
| attachment.setSize(info.getSize()); |
| attachments.add(attachment); |
| } |
| } |
| } |
| }; |
| |
| private OnStatusChangedHandler onStatusChangedHandler = new OnStatusChangedHandler() { |
| public void onStatusChanged(IUploader uploader) { |
| Status stat = display.getUploader().getStatus(); |
| ((HasEnabled) display.getSendClick()).setEnabled(stat != Status.INPROGRESS); |
| } |
| }; |
| |
| private OnCancelUploaderHandler onCancelUploadHandler = new OnCancelUploaderHandler() { |
| public void onCancel(IUploader uploader) { |
| for (Iterator<MessageAttachment> i = attachments.iterator(); i.hasNext();) { |
| MessageAttachment attachment = i.next(); |
| if (attachment.getName().equals(uploader.getInputName())) |
| i.remove(); |
| } |
| } |
| }; |
| |
| private ClickHandler cancelClickHandler = new ClickHandler() { |
| @Override |
| public void onClick(ClickEvent event) { |
| History.back(); |
| } |
| |
| }; |
| |
| protected ClickHandler sendClickHandler = new ClickHandler() { |
| public void onClick(ClickEvent event) { |
| send(); |
| } |
| }; |
| |
| protected void send() { |
| if (!validate()) |
| return; |
| hupaController.showTopLoading("Sending..."); |
| |
| MessageDetails oldDetails = place.getParameters().getOldDetails(); |
| |
| if ("new".equals(place.getToken())) { |
| SendMessageRequest sendReq = rf.sendMessageRequest(); |
| SendMessageAction sendAction = sendReq.create(SendMessageAction.class); |
| sendAction.setMessage(parseMessage(sendReq)); |
| sendReq.send(sendAction).fire(new Receiver<GenericResult>() { |
| @Override |
| public void onSuccess(GenericResult response) { |
| afterSend(response); |
| } |
| }); |
| } else if ("forward".equals(place.getToken())) { |
| // FIXME will get a NullPointerException given accessing |
| // directly from some URL like #/compose:forward |
| SendForwardMessageRequest req = rf.sendForwardMessageRequest(); |
| SendForwardMessageAction action = req.create(SendForwardMessageAction.class); |
| action.setReferences(oldDetails.getReferences()); |
| |
| action.setMessage(parseMessage(req)); |
| ImapFolder f = req.create(ImapFolder.class); |
| f.setFullName(place.getParameters().getFolderName()); |
| action.setFolder(f); |
| action.setUid(place.getParameters().getOldmessage().getUid()); |
| req.send(action).fire(new Receiver<GenericResult>() { |
| @Override |
| public void onSuccess(GenericResult response) { |
| afterSend(response); |
| } |
| }); |
| } else { |
| SendReplyMessageRequest replyReq = rf.sendReplyMessageRequest(); |
| SendReplyMessageAction action = replyReq.create(SendReplyMessageAction.class); |
| action.setReferences(oldDetails.getReferences()); |
| action.setMessage(parseMessage(replyReq)); |
| ImapFolder folder = replyReq.create(ImapFolder.class); |
| folder.setFullName(place.getParameters().getFolderName()); |
| action.setFolder(folder); |
| action.setUid(place.getParameters().getOldmessage().getUid()); |
| replyReq.send(action).fire(new Receiver<GenericResult>() { |
| @Override |
| public void onSuccess(GenericResult response) { |
| afterSend(response); |
| } |
| }); |
| } |
| } |
| private boolean validate() { |
| // Don't trust only in view validation |
| return display.validate() && display.getTo().getText().trim().length() > 0 |
| && EmailListValidator.isValidAddressList(display.getTo().getText()) |
| && EmailListValidator.isValidAddressList(display.getCc().getText()) |
| && EmailListValidator.isValidAddressList(display.getBcc().getText()); |
| } |
| |
| protected SmtpMessage parseMessage(RequestContext rc) { |
| SmtpMessage message = rc.create(SmtpMessage.class); |
| List<MessageAttachment> attaches = new ArrayList<MessageAttachment>(); |
| for (MessageAttachment attach : attachments) { |
| MessageAttachment attachMent = rc.create(MessageAttachment.class); |
| attachMent.setName(attach.getName()); |
| attachMent.setSize(attach.getSize()); |
| attachMent.setContentType(attach.getContentType()); |
| attaches.add(attachMent); |
| } |
| message.setFrom(display.getFromText()); |
| message.setSubject(display.getSubject().getText()); |
| message.setText(display.getMessageHTML().getHTML()); |
| message.setMessageAttachments(attaches); |
| message.setTo(emailTextToArray(display.getTo().getText())); |
| message.setCc(emailTextToArray(display.getCc().getText())); |
| message.setBcc(emailTextToArray(display.getBcc().getText())); |
| return message; |
| } |
| |
| private List<String> emailTextToArray(String emails) { |
| List<String> cc = new ArrayList<String>(); |
| for (String ccRaw : emails.split("[,;]+")) { |
| String ccRecip = ccRaw.trim(); |
| if (ccRecip.length() > 0) { |
| cc.add(ccRaw.trim()); |
| } |
| } |
| return cc; |
| } |
| |
| private void afterSend(GenericResult response) { |
| hupaController.hideTopLoading(); |
| hupaController.showNotice("Your mail has been sent.", 10000); |
| History.back(); |
| } |
| |
| public interface Displayable extends IsWidget { |
| String getFromText(); |
| void showCc(); |
| void hideCc(); |
| void showBcc(); |
| void hideBcc(); |
| void showReply(); |
| void hideReply(); |
| void showFollowup(); |
| void hideFollowup(); |
| HasText getTo(); |
| HasText getCc(); |
| HasText getBcc(); |
| HasText getSubject(); |
| HasClickHandlers getSendClick(); |
| HasClickHandlers getCancelClick(); |
| HasClickHandlers getCcClick(); |
| HasClickHandlers get_CcClick(); |
| HasClickHandlers getBccClick(); |
| HasClickHandlers get_BccClick(); |
| HasClickHandlers getReplyClick(); |
| HasClickHandlers get_ReplyClick(); |
| HasClickHandlers getFollowupClick(); |
| HasClickHandlers get_FollowupClick(); |
| boolean validate(); |
| HasText getMessage(); |
| HasHTML getMessageHTML(); |
| ListBox getFromList(); |
| IUploader getUploader(); |
| void fillContactList(String[] contacts); |
| HasFocusHandlers getAttachButton(); |
| } |
| } |