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