001/*
002 * (C) Copyright 2013 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Benjamin JALON<bjalon@nuxeo.com>
018 */
019package org.nuxeo.ecm.automation.core.operations.notification;
020
021import java.util.ArrayList;
022import java.util.List;
023
024import org.apache.commons.logging.Log;
025import org.apache.commons.logging.LogFactory;
026import org.nuxeo.ecm.core.api.DocumentModel;
027import org.nuxeo.ecm.platform.usermanager.UserManager;
028import org.nuxeo.runtime.api.Framework;
029
030/*
031 * MailBox expose resolver given a String, a List of String or an Array of String.
032 * String can be a username, a groupname or a direct email. See javadoc.
033 * A MailBox object represent a MailBox address.
034 * @since 5.9.1
035 */
036public class MailBox {
037
038    private static final Log log = LogFactory.getLog(MailBox.class);
039
040    private static final String USER_PREFIX = "user:";
041
042    public String firstname = "";
043
044    public String lastname = "";
045
046    public String address;
047
048    /**
049     * Fetch for each string given the mailbox target associated see
050     */
051    public static List<MailBox> fetchPersonsFromList(List<String> values, boolean isStrict) {
052        if (values == null) {
053            return new ArrayList<MailBox>();
054        }
055
056        List<MailBox> result = new ArrayList<MailBox>();
057        for (String info : values) {
058            result.addAll(fetchPersonsFromString(info, isStrict));
059        }
060
061        return result;
062    }
063
064    /**
065     * Resolve value to find the mailbox associated. if strict is true and if value is prefixed by "user:" then find the
066     * email address in his profile, otherwise the given string is considered as the email address. if strict is false,
067     * and there is comma. The value is considered as a list. For each substring the resolution is as explained below :
068     * if the substring startswith by "user:" then try to resolve the user email, otherwise try to fetch the user
069     * without prefix if not found considered the string as an email address.
070     */
071    public static List<MailBox> fetchPersonsFromString(String value, boolean isStrict) {
072        List<MailBox> result = new ArrayList<MailBox>();
073
074        // if strict waiting simply the user account or direct email address
075        if (isStrict) {
076            result.add(new MailBox(value, isStrict));
077            return result;
078        }
079
080        String[] valuesToResolve = value.split(",");
081        UserManager umgr = Framework.getService(UserManager.class);
082        for (String info : valuesToResolve) {
083
084            if (info.startsWith("user:")) {
085                result.add(new MailBox(info, isStrict));
086                continue;
087            }
088
089            if (info.startsWith("group:")) {
090                List<String> usernames = umgr.getUsersInGroupAndSubGroups(value.substring("group:".length()));
091                for (String username : usernames) {
092                    result.add(new MailBox("user:" + username, isStrict));
093                }
094                continue;
095            }
096
097            // Suppose that a username ?
098            DocumentModel user = umgr.getUserModel(info);
099            if (user != null) {
100                String address = (String) user.getPropertyValue("email");
101                String firstname = (String) user.getPropertyValue("firstName");
102                String lastname = (String) user.getPropertyValue("lastName");
103                result.add(new MailBox(address, firstname, lastname));
104                continue;
105            }
106
107            // Suppose that a groupname ?
108            DocumentModel group = umgr.getGroupModel(info);
109            if (group != null) {
110                @SuppressWarnings("unchecked")
111                List<String> usernames = (List<String>) group.getPropertyValue(umgr.getGroupMembersField());
112                if (usernames != null) {
113                    for (String username : usernames) {
114                        result.add(new MailBox("user:" + username, isStrict));
115                    }
116                    continue;
117                }
118            }
119            if (!info.contains("@")) {
120                log.warn("Can't really resolve the mailbox defined, anyway added. Check if something bad configured: "
121                        + info);
122            }
123            result.add(new MailBox(info, null, null));
124
125        }
126
127        return result;
128    }
129
130    public MailBox(String address, String firstname, String lastname) {
131        this.address = address;
132        this.firstname = firstname == null ? "" : firstname;
133        this.lastname = lastname == null ? "" : lastname;
134    }
135
136    public MailBox(DocumentModel user, boolean isStrict) {
137        initFromDocumentModel(user);
138    }
139
140    public MailBox(String info, boolean isStrict) {
141        if (info.startsWith(USER_PREFIX)) {
142            String userId = info.substring(USER_PREFIX.length());
143            DocumentModel user = getUmgr().getUserModel(userId);
144            if (user != null) {
145                initFromDocumentModel(user);
146                return;
147            }
148        }
149
150        if (!isStrict) {
151            // Try to fetch it from usermanager without prefix
152            DocumentModel user = getUmgr().getUserModel(info);
153            initFromDocumentModel(user);
154            return;
155        }
156
157        if (!info.contains("@")) {
158            log.warn("Info given seems not well formed, please check (sent anyway): " + info);
159        }
160        // String is directly the email address
161        address = info;
162
163    }
164
165    private void initFromDocumentModel(DocumentModel user) {
166        if (user != null && user.getPropertyValue("email") != null
167                && ((String) user.getPropertyValue("email")).contains("@")) {
168            address = (String) user.getPropertyValue("email");
169        }
170        if (user != null && user.getPropertyValue("firstName") != null
171                && !((String) user.getPropertyValue("firstName")).isEmpty()) {
172            firstname = (String) user.getPropertyValue("firstName");
173        }
174        if (user != null && user.getPropertyValue("lastName") != null
175                && !((String) user.getPropertyValue("lastName")).isEmpty()) {
176            firstname = (String) user.getPropertyValue("lastName");
177        }
178
179    }
180
181    public UserManager getUmgr() {
182        return Framework.getService(UserManager.class);
183    }
184
185    /**
186     * returning the mailbox address as String. If firstname and lastname is set add it into the returned string.
187     */
188    @Override
189    public String toString() {
190        if (!firstname.isEmpty() && !lastname.isEmpty()) {
191            return firstname + " " + lastname + "<" + address + ">";
192        }
193        return address;
194    }
195}