001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     bstefanescu
011 */
012package org.nuxeo.ecm.automation.features;
013
014import java.util.ArrayList;
015import java.util.Collection;
016import java.util.List;
017import java.util.Set;
018
019import org.apache.commons.lang.StringEscapeUtils;
020import org.apache.commons.lang.StringUtils;
021import org.nuxeo.ecm.automation.core.scripting.CoreFunctions;
022import org.nuxeo.ecm.automation.core.util.StringList;
023import org.nuxeo.ecm.core.api.DataModel;
024import org.nuxeo.ecm.core.api.DocumentModel;
025import org.nuxeo.ecm.core.api.NuxeoPrincipal;
026import org.nuxeo.ecm.core.uidgen.UIDSequencer;
027import org.nuxeo.ecm.directory.Session;
028import org.nuxeo.ecm.directory.api.DirectoryService;
029import org.nuxeo.ecm.platform.usermanager.UserManager;
030import org.nuxeo.runtime.api.Framework;
031
032/**
033 * @author <a href="mailto:bs@nuxeo.com">Bogdan Stefanescu</a>
034 */
035public class PlatformFunctions extends CoreFunctions {
036
037    private volatile DirectoryService dirService;
038
039    private volatile UserManager userMgr;
040
041    public UserManager getUserManager() {
042        if (userMgr == null) {
043            userMgr = Framework.getService(UserManager.class);
044        }
045        return userMgr;
046    }
047
048    public DirectoryService getDirService() {
049        if (dirService == null) {
050            dirService = Framework.getService(DirectoryService.class);
051        }
052        return dirService;
053    }
054
055    public String getVocabularyLabel(String voc, String key) {
056        try (Session session = getDirService().open(voc)) {
057            DocumentModel doc = session.getEntry(key);
058            // TODO: which is the best method to get "label" property when not
059            // knowing vocabulary schema?
060            // AT: the best is to accept it as a parameter of the method, and
061            // fallback on "label" when not given
062            DataModel dm = doc.getDataModels().values().iterator().next();
063            return (String) dm.getData("label");
064        }
065    }
066
067    public NuxeoPrincipal getPrincipal(String username) {
068        return getUserManager().getPrincipal(username);
069    }
070
071    protected String getEmail(NuxeoPrincipal principal, String userSchemaName, String userEmailFieldName)
072            {
073        if (principal == null) {
074            return null;
075        }
076        return (String) principal.getModel().getProperty(userSchemaName, userEmailFieldName);
077    }
078
079    public String getEmail(String username) {
080        UserManager userManager = getUserManager();
081        return getEmail(userManager.getPrincipal(username), userManager.getUserSchemaName(),
082                userManager.getUserEmailField());
083    }
084
085    public Set<NuxeoPrincipal> getPrincipalsFromGroup(String group) {
086        return getPrincipalsFromGroup(group, false);
087    }
088
089    public Set<NuxeoPrincipal> getPrincipalsFromGroup(String group, boolean ignoreGroups) {
090        PrincipalHelper ph = new PrincipalHelper(getUserManager(), null);
091        return ph.getPrincipalsFromGroup(group, !ignoreGroups);
092    }
093
094    public StringList getEmailsFromGroup(String group) {
095        return getEmailsFromGroup(group, false);
096    }
097
098    public StringList getEmailsFromGroup(String group, boolean ignoreGroups) {
099        PrincipalHelper ph = new PrincipalHelper(getUserManager(), null);
100        Set<String> emails = ph.getEmailsFromGroup(group, !ignoreGroups);
101        return new StringList(emails);
102    }
103
104    public StringList getPrincipalEmails(List<NuxeoPrincipal> principals) {
105        StringList result = new StringList(principals.size());
106        String schemaName = getUserManager().getUserSchemaName();
107        String fieldName = getUserManager().getUserEmailField();
108        for (NuxeoPrincipal principal : principals) {
109            String email = getEmail(principal, schemaName, fieldName);
110            if (!StringUtils.isEmpty(email)) {
111                result.add(email);
112            }
113        }
114        return result;
115    }
116
117    public StringList getEmails(List<String> usernames) {
118        return getEmails(usernames, false);
119    }
120
121    /**
122     * Returns user emails
123     *
124     * @param usernames list of user names
125     * @param usePrefix indicates if user resolution takes into account nuxeo prefix <b>user:</b>
126     * @since 5.5
127     */
128    public StringList getEmails(List<String> usernames, boolean usePrefix) {
129        if (usernames == null) {
130            return new StringList(0);
131        }
132        UserManager userManager = getUserManager();
133        StringList result = new StringList(usernames.size());
134        String schemaName = getUserManager().getUserSchemaName();
135        String fieldName = getUserManager().getUserEmailField();
136        for (String username : usernames) {
137            NuxeoPrincipal principal = null;
138            if (usePrefix) {
139                if (username.startsWith(NuxeoPrincipal.PREFIX)) {
140                    principal = userManager.getPrincipal(username.replace(NuxeoPrincipal.PREFIX, ""));
141                }
142            } else {
143                principal = userManager.getPrincipal(username);
144            }
145            if (principal != null) {
146                String email = getEmail(principal, schemaName, fieldName);
147                if (!StringUtils.isEmpty(email)) {
148                    result.add(email);
149                }
150            }
151        }
152        return result;
153    }
154
155    public String getNextId(final String key) {
156        UIDSequencer svc = Framework.getService(UIDSequencer.class);
157        return Integer.toString(svc.getNext(key));
158    }
159
160    public static String htmlEscape(String str) {
161        return StringEscapeUtils.escapeHtml(str);
162    }
163
164    /**
165     * Concatenate into the list given as first argument other arguments. Other arguments will be explosed if it is a
166     * list of object. ex: concatenateInto(myList, a, anotherList) with a is scalar object and anotherList is a list of
167     * object will produced myList.add(a) and the same for each object contained into the anotherList list.
168     *
169     * @param <T>
170     * @param list List of values of type A
171     * @param value Value can be instance of java.util.Collection<Object> or an array of Objects or simply a scalar
172     *            Object. If Null, the parameter is ignored
173     * @return the list that contains the list contain and value (see value description)
174     * @exception xxxxx if in values there is at least one object type not compatible with the collection list
175     */
176    @SuppressWarnings("unchecked")
177    public <T> List<T> concatenateIntoList(List<T> list, Object... values) {
178
179        if (list == null) {
180            throw new IllegalArgumentException("First parameter must not be null");
181        }
182
183        for (Object value : values) {
184            if (value == null) {
185                continue;
186            }
187
188            if (value instanceof Object[]) {
189                for (Object subValue : (Object[]) value) {
190                    if (subValue != null) {
191                        list.add((T) subValue);
192                    }
193                }
194                continue;
195            }
196
197            if (value instanceof Collection) {
198                for (Object subValue : (Collection<Object>) value) {
199                    if (subValue != null) {
200                        list.add((T) subValue);
201                    }
202                }
203                continue;
204            }
205
206            list.add((T) value);
207
208        }
209        return list;
210    }
211
212    /**
213     * Idem than concatenateInto except that a new list is created.
214     */
215    public <T> List<T> concatenateValuesAsNewList(Object... values) {
216
217        List<T> result = new ArrayList<T>();
218        return concatenateIntoList(result, values);
219    }
220
221}