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