001/* 002 * (C) Copyright 2006-2018 Nuxeo (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 * Bogdan Stefanescu 018 * Ricardo Dias 019 * Estelle Giuly 020 */ 021package org.nuxeo.ecm.automation.features; 022 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.List; 026import java.util.Set; 027 028import org.apache.commons.lang3.StringUtils; 029import org.apache.commons.logging.Log; 030import org.apache.commons.logging.LogFactory; 031import org.apache.commons.text.StringEscapeUtils; 032import org.nuxeo.ecm.automation.core.scripting.CoreFunctions; 033import org.nuxeo.ecm.automation.core.util.StringList; 034import org.nuxeo.ecm.core.api.CoreSession; 035import org.nuxeo.ecm.core.api.DocumentModel; 036import org.nuxeo.ecm.core.api.DocumentRef; 037import org.nuxeo.ecm.core.api.IdRef; 038import org.nuxeo.ecm.core.api.NuxeoPrincipal; 039import org.nuxeo.ecm.core.api.PathRef; 040import org.nuxeo.ecm.core.query.sql.NXQL; 041import org.nuxeo.ecm.core.uidgen.UIDGeneratorService; 042import org.nuxeo.ecm.core.uidgen.UIDSequencer; 043import org.nuxeo.ecm.directory.Session; 044import org.nuxeo.ecm.directory.api.DirectoryService; 045import org.nuxeo.ecm.platform.usermanager.UserManager; 046import org.nuxeo.runtime.api.Framework; 047import org.nuxeo.runtime.services.config.ConfigurationService; 048 049/** 050 * @author <a href="mailto:[email protected]">Bogdan Stefanescu</a> 051 */ 052public class PlatformFunctions extends CoreFunctions { 053 054 private volatile DirectoryService dirService; 055 056 private static final Log log = LogFactory.getLog(PlatformFunctions.class); 057 058 private volatile UserManager userMgr; 059 060 public static final String HIBERNATE_SEQUENCER_PROPERTY = "org.nuxeo.ecm.core.uidgen.sequencer.hibernate"; 061 062 public UserManager getUserManager() { 063 if (userMgr == null) { 064 userMgr = Framework.getService(UserManager.class); 065 } 066 return userMgr; 067 } 068 069 public DirectoryService getDirService() { 070 if (dirService == null) { 071 dirService = Framework.getService(DirectoryService.class); 072 } 073 return dirService; 074 } 075 076 public String getVocabularyLabel(String voc, String key) { 077 try (Session session = getDirService().open(voc)) { 078 if (!session.hasEntry(key)) { 079 log.debug("Unable to find the key '" + key + "' in the vocabulary '" + voc + "'."); 080 return key; 081 } 082 DocumentModel doc = session.getEntry(key); 083 return (String) doc.getPropertyValue("label"); // no schema prefix for vocabularies 084 } 085 } 086 087 public NuxeoPrincipal getPrincipal(String username) { 088 return getUserManager().getPrincipal(username); 089 } 090 091 protected String getEmail(NuxeoPrincipal principal, String userSchemaName, String userEmailFieldName) { 092 if (principal == null) { 093 return null; 094 } 095 return (String) principal.getModel().getProperty(userSchemaName, userEmailFieldName); 096 } 097 098 public String getEmail(String username) { 099 UserManager userManager = getUserManager(); 100 return getEmail(userManager.getPrincipal(username), userManager.getUserSchemaName(), 101 userManager.getUserEmailField()); 102 } 103 104 public Set<NuxeoPrincipal> getPrincipalsFromGroup(String group) { 105 return getPrincipalsFromGroup(group, false); 106 } 107 108 public Set<NuxeoPrincipal> getPrincipalsFromGroup(String group, boolean ignoreGroups) { 109 PrincipalHelper ph = new PrincipalHelper(getUserManager(), null); 110 return ph.getPrincipalsFromGroup(group, !ignoreGroups); 111 } 112 113 public StringList getEmailsFromGroup(String group) { 114 return getEmailsFromGroup(group, false); 115 } 116 117 public StringList getEmailsFromGroup(String group, boolean ignoreGroups) { 118 PrincipalHelper ph = new PrincipalHelper(getUserManager(), null); 119 Set<String> emails = ph.getEmailsFromGroup(group, !ignoreGroups); 120 return new StringList(emails); 121 } 122 123 public StringList getPrincipalEmails(List<NuxeoPrincipal> principals) { 124 StringList result = new StringList(principals.size()); 125 String schemaName = getUserManager().getUserSchemaName(); 126 String fieldName = getUserManager().getUserEmailField(); 127 for (NuxeoPrincipal principal : principals) { 128 String email = getEmail(principal, schemaName, fieldName); 129 if (!StringUtils.isEmpty(email)) { 130 result.add(email); 131 } 132 } 133 return result; 134 } 135 136 public StringList getEmails(List<String> usernames) { 137 return getEmails(usernames, false); 138 } 139 140 /** 141 * Returns user emails 142 * 143 * @param usernames list of user names 144 * @param usePrefix indicates if user resolution takes into account nuxeo prefix <b>user:</b> 145 * @since 5.5 146 */ 147 public StringList getEmails(List<String> usernames, boolean usePrefix) { 148 if (usernames == null) { 149 return new StringList(0); 150 } 151 UserManager userManager = getUserManager(); 152 StringList result = new StringList(usernames.size()); 153 String schemaName = getUserManager().getUserSchemaName(); 154 String fieldName = getUserManager().getUserEmailField(); 155 for (String username : usernames) { 156 NuxeoPrincipal principal = null; 157 if (usePrefix) { 158 if (username.startsWith(NuxeoPrincipal.PREFIX)) { 159 principal = userManager.getPrincipal(username.replace(NuxeoPrincipal.PREFIX, "")); 160 } 161 } else { 162 principal = userManager.getPrincipal(username); 163 } 164 if (principal != null) { 165 String email = getEmail(principal, schemaName, fieldName); 166 if (!StringUtils.isEmpty(email)) { 167 result.add(email); 168 } 169 } 170 } 171 return result; 172 } 173 174 public String getNextId(final String key) { 175 ConfigurationService configurationService = Framework.getService(ConfigurationService.class); 176 boolean useHibernate = configurationService.isBooleanPropertyTrue(HIBERNATE_SEQUENCER_PROPERTY); 177 return getNextId(key, useHibernate ? "hibernateSequencer" : null); 178 } 179 180 public String getNextId(final String key, final String sequencerName) { 181 UIDGeneratorService uidGeneratorService = Framework.getService(UIDGeneratorService.class); 182 UIDSequencer seq = uidGeneratorService.getSequencer(sequencerName); 183 return Long.toString(seq.getNextLong(key)); 184 } 185 186 public static String htmlEscape(String str) { 187 return StringEscapeUtils.escapeHtml4(str); 188 } 189 190 /** 191 * Escapes a string according to NXQL escaping rules. 192 * <p> 193 * The resulting string is safe to include between single quotes in a NXQL expression. 194 * 195 * @param str the input string 196 * @return the escaped string 197 * @since 6.0-HF21, 7.10 198 */ 199 public static String nxqlEscape(String str) { 200 return NXQL.escapeStringInner(str); 201 } 202 203 /** 204 * Concatenate into the list given as first argument other arguments. Other arguments will be explosed if it is a 205 * list of object. ex: concatenateInto(myList, a, anotherList) with a is scalar object and anotherList is a list of 206 * object will produced myList.add(a) and the same for each object contained into the anotherList list. 207 * 208 * @param <T> 209 * @param list List of values of type A 210 * @param values Value can be instance of java.util.Collection<Object> or an array of Objects or simply a scalar 211 * Object. If Null, the parameter is ignored 212 * @return the list that contains the list contain and value (see value description) 213 * @exception xxxxx if in values there is at least one object type not compatible with the collection list 214 */ 215 @SuppressWarnings("unchecked") 216 public <T> List<T> concatenateIntoList(List<T> list, Object... values) { 217 218 if (list == null) { 219 throw new IllegalArgumentException("First parameter must not be null"); 220 } 221 222 for (Object value : values) { 223 if (value == null) { 224 continue; 225 } 226 227 if (value instanceof Object[]) { 228 for (Object subValue : (Object[]) value) { 229 if (subValue != null) { 230 list.add((T) subValue); 231 } 232 } 233 continue; 234 } 235 236 if (value instanceof Collection) { 237 for (Object subValue : (Collection<Object>) value) { 238 if (subValue != null) { 239 list.add((T) subValue); 240 } 241 } 242 continue; 243 } 244 245 list.add((T) value); 246 247 } 248 return list; 249 } 250 251 /** 252 * Idem than concatenateInto except that a new list is created. 253 */ 254 public <T> List<T> concatenateValuesAsNewList(Object... values) { 255 256 List<T> result = new ArrayList<>(); 257 return concatenateIntoList(result, values); 258 } 259 260 /** 261 * Checks if a document with the supplied id (or path) exists. 262 * 263 * @param session The CoreSession to obtain the document 264 * @param idOrPath The document Id or path 265 * @return true if the document exists, or false otherwise 266 */ 267 public boolean documentExists(CoreSession session, String idOrPath) { 268 DocumentRef documentRef = idOrPath.startsWith("/") ? new PathRef(idOrPath) : new IdRef(idOrPath); 269 return session.exists(documentRef); 270 } 271 272}