001/* 002 * Copyright 2024 Anyware Services 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 */ 016package org.ametys.cms.repository.mentions; 017 018import java.util.HashSet; 019import java.util.Set; 020import java.util.regex.Matcher; 021import java.util.regex.Pattern; 022 023import org.apache.avalon.framework.component.Component; 024import org.apache.avalon.framework.service.ServiceException; 025import org.apache.avalon.framework.service.ServiceManager; 026import org.apache.avalon.framework.service.Serviceable; 027 028import org.ametys.core.user.User; 029import org.ametys.core.user.UserIdentity; 030import org.ametys.core.user.UserManager; 031import org.ametys.core.util.I18nUtils; 032import org.ametys.runtime.i18n.I18nizableText; 033import org.ametys.runtime.plugin.component.AbstractLogEnabled; 034 035/** 036 * Utils for Mentions 037 */ 038public class MentionUtils extends AbstractLogEnabled implements Component, Serviceable 039{ 040 /** Avalon role */ 041 public static final String ROLE = MentionUtils.class.getName(); 042 043 /** Regex used to extract mentions from a text. A mention is inside a @() */ 044 public static final String __EXTRACT_MENTIONS_REGEX_SIMPLE_TEXT = "@\\(([^()]+)\\)"; 045 046 /** Regex used to extract mentions from a text. A mention is inside a @() */ 047 public static final String __EXTRACT_MENTIONS_REGEX_RICH_TEXT = "data-ametys-mention-user=\"([^\"]+)\""; 048 049 /** The user manager */ 050 protected UserManager _userManager; 051 052 /** The i18n utils. */ 053 protected I18nUtils _i18nUtils; 054 055 public void service(ServiceManager manager) throws ServiceException 056 { 057 _userManager = (UserManager) manager.lookup(UserManager.ROLE); 058 _i18nUtils = (I18nUtils) manager.lookup(I18nUtils.ROLE); 059 } 060 061 /** 062 * Extract mentioned users from simple text content 063 * @param content the simple text content 064 * @return the set of mentioned users 065 */ 066 public static Set<UserIdentity> extractMentionedUsersFromSimpleText(String content) 067 { 068 Set<UserIdentity> mentionendUsers = new HashSet<>(); 069 if (content != null) 070 { 071 Pattern pattern = Pattern.compile(__EXTRACT_MENTIONS_REGEX_SIMPLE_TEXT); 072 Matcher matcher = pattern.matcher(content); 073 074 while (matcher.find()) 075 { 076 String userIdentityAsString = matcher.group(1); 077 UserIdentity userIdentity = UserIdentity.stringToUserIdentity(userIdentityAsString); 078 mentionendUsers.add(userIdentity); 079 } 080 } 081 return mentionendUsers; 082 } 083 084 /** 085 * Extract mentioned users from rich text content 086 * @param content the rich text content 087 * @return the set of mentioned users 088 */ 089 public Set<UserIdentity> extractMentionedUsersFromRichText(String content) 090 { 091 Set<UserIdentity> mentionedUsers = new HashSet<>(); 092 Pattern pattern = Pattern.compile("data-ametys-mention-user=\"([^\"]+)\""); 093 Matcher matcher = pattern.matcher(content); 094 095 while (matcher.find()) 096 { 097 String userIdentityAsString = matcher.group(1); 098 UserIdentity userIdentity = UserIdentity.stringToUserIdentity(userIdentityAsString); 099 mentionedUsers.add(userIdentity); 100 } 101 return mentionedUsers; 102 } 103 104 /** 105 * Transform syntax text of a rich text to display text using a regex to find the parts to transform and a function to transform them 106 * @param syntaxText the syntax text 107 * @param recipient the recipient of the mail, for mail purposes 108 * @return the transformed text with colors according to the recipient 109 */ 110 public String transformRichTextToReadableText(String syntaxText, UserIdentity recipient) 111 { 112 String readableText = syntaxText; 113 114 if (syntaxText != null) 115 { 116 Pattern pattern = Pattern.compile(__EXTRACT_MENTIONS_REGEX_RICH_TEXT); 117 Matcher matcher = pattern.matcher(syntaxText); 118 StringBuffer sb = new StringBuffer(); 119 120 while (matcher.find()) 121 { 122 String mentionBackgroundColor = _getMentionColor(recipient, matcher); 123 124 StringBuilder replaceBy = new StringBuilder("style=\"background: ").append(mentionBackgroundColor).append("; color: #1264a3\""); 125 126 matcher.appendReplacement(sb, Matcher.quoteReplacement(replaceBy.toString())); 127 } 128 matcher.appendTail(sb); 129 readableText = sb.toString(); 130 } 131 return readableText; 132 } 133 134 /** 135 * Transform syntax text of a simple text to display text using a regex to find the parts to transform and a function to transform them 136 * @param syntaxText the syntax text 137 * @param recipient the recipient of the mail, for mail purposes, can be null for any other purposes 138 * @return the transformed text with colors according to the recipient if not null, with full name in plain text otherwise 139 */ 140 public String transformTextToReadableText(String syntaxText, UserIdentity recipient) 141 { 142 String readableText = syntaxText; 143 144 if (syntaxText != null) 145 { 146 Pattern pattern = Pattern.compile(__EXTRACT_MENTIONS_REGEX_SIMPLE_TEXT); 147 Matcher matcher = pattern.matcher(syntaxText); 148 StringBuffer sb = new StringBuffer(); 149 150 while (matcher.find()) 151 { 152 String userIdentityAsString = matcher.group(1); 153 UserIdentity mentionedUserIdentity = UserIdentity.stringToUserIdentity(userIdentityAsString); 154 User mentionedUser = _userManager.getUser(mentionedUserIdentity); 155 String mentionedUserName = mentionedUser != null ? mentionedUser.getFullName() : _i18nUtils.translate(new I18nizableText("plugin.core", "PLUGINS_CORE_USERS_UNKNOWN_USER")); 156 157 StringBuilder replaceBy = new StringBuilder(mentionedUserName); 158 if (recipient != null) 159 { 160 String mentionBackgroundColor = _getMentionColor(recipient, matcher); 161 162 replaceBy = new StringBuilder("<span style=\"background: ").append(mentionBackgroundColor).append("; color: #1264a3\">") 163 .append(mentionedUserName) 164 .append("</span>"); 165 } 166 167 matcher.appendReplacement(sb, Matcher.quoteReplacement(replaceBy.toString())); 168 } 169 matcher.appendTail(sb); 170 readableText = sb.toString(); 171 } 172 return readableText; 173 } 174 175 private String _getMentionColor(UserIdentity recipient, Matcher matcher) 176 { 177 String userIdentityAsString = matcher.group(1); 178 UserIdentity mentionedUserIdentity = UserIdentity.stringToUserIdentity(userIdentityAsString); 179 180 String mentionBackgroundColor = "rgba(29, 155, 209, 0.1)"; 181 if (mentionedUserIdentity.equals(recipient)) 182 { 183 mentionBackgroundColor = "rgba(255, 198, 0, 0.18)"; 184 } 185 return mentionBackgroundColor; 186 } 187 188}