001    package de.deepamehta.plugins.mail;
002    
003    import static de.deepamehta.plugins.mail.MailPlugin.*;
004    
005    import java.io.UnsupportedEncodingException;
006    import java.util.Date;
007    import java.util.HashSet;
008    import java.util.List;
009    import java.util.Set;
010    
011    import javax.mail.internet.AddressException;
012    import javax.mail.internet.InternetAddress;
013    
014    import de.deepamehta.core.Association;
015    import de.deepamehta.core.CompositeValue;
016    import de.deepamehta.core.RelatedTopic;
017    import de.deepamehta.core.Topic;
018    import de.deepamehta.core.service.ClientState;
019    import de.deepamehta.core.service.DeepaMehtaService;
020    import de.deepamehta.core.service.Directives;
021    import de.deepamehta.core.storage.spi.DeepaMehtaTransaction;
022    
023    /**
024     * Model class that wraps the mail composite access.
025     */
026    public class Mail {
027    
028        private final DeepaMehtaService dms;
029    
030        private final Topic topic;
031    
032        public Mail(long topicId, DeepaMehtaService dms) {
033            this.dms = dms;
034            this.topic = dms.getTopic(topicId, true);
035        }
036    
037        public String getBody() throws Exception {
038            String body = topic.getCompositeValue().getTopic(BODY).getSimpleValue().toString();
039            if (body.isEmpty()) {
040                throw new IllegalArgumentException("Body of mail is empty");
041            }
042    
043            if (topic.getCompositeValue().has(SIGNATURE) == false) {
044                throw new IllegalArgumentException("Signature of mail not found");
045            } else {
046                List<Topic> signature = topic.getCompositeValue().getTopics(SIGNATURE);
047                CompositeValue value = signature.get(0).getCompositeValue();
048                if (value.has(BODY) == false) {
049                    throw new IllegalArgumentException("Signature of mail is empty");
050                } else {
051                    String sigBody = value.getTopic(BODY).getSimpleValue().toString();
052                    if (sigBody.isEmpty()) {
053                        throw new IllegalArgumentException("Signature of mail is empty");
054                    }
055                    return body + sigBody;
056                }
057            }
058        }
059    
060        public RecipientsByType getRecipients() throws InvalidRecipients {
061            Set<String> invalid = new HashSet<String>();
062            RecipientsByType results = new RecipientsByType();
063    
064            for (RelatedTopic recipient : topic.getRelatedTopics(RECIPIENT, PARENT, CHILD, null, false, false, 0)) {
065                String personal = recipient.getSimpleValue().toString();
066    
067                for (Association association : dms.getAssociations(topic.getId(), recipient.getId())) {
068                    if (association.getTypeUri().equals(RECIPIENT) == false) {
069                        continue; // sender or something else found
070                    }
071    
072                    // get and validate recipient association
073                    CompositeValue value = dms.getAssociation(association.getId(),//
074                            true).getCompositeValue(); // re-fetch with value
075                    if (value.has(RECIPIENT_TYPE) == false) {
076                        invalid.add("Recipient type of \"" + personal + "\" is not defined");
077                        continue;
078                    }
079                    if (value.has(EMAIL_ADDRESS) == false) {
080                        invalid.add("Recipient \"" + personal + "\" has no email address");
081                        continue;
082                    }
083    
084                    Topic type = value.getTopic(RECIPIENT_TYPE);
085                    String email = value.getTopic(EMAIL_ADDRESS).getSimpleValue().toString();
086                    try {
087                        results.add(type.getUri(), email, personal);
088                    } catch (Exception e) {
089                        invalid.add("Email address \"" + email + "\" of recipient \"" + //
090                                personal + "\" is invalid");
091                    }
092                }
093            }
094            if (invalid.isEmpty() == false) {
095                throw new InvalidRecipients(invalid);
096            }
097            return results;
098        }
099    
100        public InternetAddress getSender() throws UnsupportedEncodingException, AddressException {
101            RelatedTopic sender = topic.getRelatedTopic(SENDER,//
102                    PARENT, CHILD, null, false, true);
103            if (sender == null) {
104                throw new IllegalArgumentException("Contact required");
105            }
106            String personal = sender.getSimpleValue().toString();
107            String address;
108            try { // throws runtime access
109                address = sender.getRelatingAssociation().getCompositeValue()//
110                        .getTopic(EMAIL_ADDRESS).getSimpleValue().toString();
111            } catch (Exception e) {
112                throw new IllegalArgumentException("Contact has no email address");
113            }
114            InternetAddress internetAddress = new InternetAddress(address, personal);
115            internetAddress.validate();
116            return internetAddress;
117        }
118    
119        public String getSubject() {
120            return topic.getCompositeValue().getTopic(SUBJECT).getSimpleValue().toString();
121        }
122    
123        public Topic getTopic() {
124            return topic;
125        }
126    
127        public Topic setMessageId(String messageId) {
128            DeepaMehtaTransaction tx = dms.beginTx();
129            try {
130                topic.getCompositeValue().set(DATE, new Date().toString(), null, new Directives());
131                topic.getCompositeValue().set(MESSAGE_ID, messageId, null,  new Directives());
132                tx.success();
133            } finally {
134                tx.finish();
135            }
136            return topic;
137        }
138    
139        public Set<Long> getAttachmentIds() {
140            Set<Long> attachments = new HashSet<Long>();
141            for (RelatedTopic attachment : topic.getRelatedTopics(AGGREGATION, PARENT, CHILD, FILE, false, false, 0)) {
142                attachments.add(attachment.getId());
143            }
144            return attachments;
145        }
146    }