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