diff --git a/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java b/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java index 302fccd092a28573e63ee184aa20a0d34a798c98..9777e18509a78a201f20c97924b9247a7b55dfdb 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java +++ b/src/main/java/org/olat/core/commons/services/notifications/NotificationHelper.java @@ -27,14 +27,18 @@ import java.util.List; import java.util.Locale; import java.util.Map; +import org.olat.core.commons.services.notifications.ui.NotificationNewsController; import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.User; -import org.olat.core.id.UserConstants; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; +import org.olat.core.util.cache.CacheWrapper; +import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.i18n.I18nManager; +import org.olat.user.UserManager; +import org.olat.user.propertyhandlers.UserPropertyHandler; /** @@ -50,7 +54,12 @@ import org.olat.core.util.i18n.I18nManager; public class NotificationHelper { private static final OLog log = Tracing.createLoggerFor(NotificationHelper.class); - + private static CacheWrapper<Long,String> userPropertiesCache; + + static { + userPropertiesCache = CoordinatorManager.getInstance().getCoordinator().getCacher().getCache(NotificationHelper.class.getSimpleName(), "userPropertiesCache"); + } + public static Map<Subscriber, SubscriptionInfo> getSubscriptionMap(Identity identity, Locale locale, boolean showWithNewsOnly, Date compareDate) { return getSubscriptionMap(identity, locale, showWithNewsOnly, compareDate, Collections.<String>emptyList()); } @@ -99,15 +108,38 @@ public class NotificationHelper { public static String getFormatedName(Identity ident) { Translator trans; User user = null; + String formattedName = null; + if (ident == null) { - trans = Util.createPackageTranslator(NotificationHelper.class, I18nManager.getInstance().getLocaleOrDefault(null)); + trans = Util.createPackageTranslator(NotificationNewsController.class, I18nManager.getInstance().getLocaleOrDefault(null)); + return trans.translate("user.unknown"); } else { - trans = Util.createPackageTranslator(NotificationHelper.class, I18nManager.getInstance().getLocaleOrDefault( + // Optimize: use from cache to not re-calculate user properties over and over again + formattedName = userPropertiesCache.get(ident.getKey()); + if (formattedName != null) { + return formattedName; + } + } + trans = Util.createPackageTranslator(NotificationNewsController.class, I18nManager.getInstance().getLocaleOrDefault( ident.getUser().getPreferences().getLanguage())); - user = ident.getUser(); + user = ident.getUser(); + + if (user == null) { + formattedName = trans.translate("user.unknown"); + } else { + // grap user properties from context + List<UserPropertyHandler> propertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor(NotificationHelper.class.getName(), false); + String[] properties = new String[propertyHandlers.size()]; + for (int i = 0; i < propertyHandlers.size(); i++) { + UserPropertyHandler propHandler = propertyHandlers.get(i); + properties[i] = propHandler.getUserProperty(user, trans.getLocale()); + } + formattedName = trans.translate("user.formatted", properties); } - if (user == null) return trans.translate("user.unknown"); - return user.getProperty(UserConstants.FIRSTNAME, null) + " " + user.getProperty(UserConstants.LASTNAME, null); + // put formatted name in cache, times out after 5 mins + userPropertiesCache.put(ident.getKey(), formattedName); + + return formattedName; } /** diff --git a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties index 4abab2e05a6f4ae6edfe5ccc3b2232822aed5589..162ad8a41673f2c40a6a34c57afeefc54e2b5037 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_de.properties @@ -31,6 +31,7 @@ command.unsubscribe=Abbestellen help.hover.notif=Hilfe zu den Benachrichtigungen subscription.listitem.dateprefix=am {0} user.unknown=unbekannt +user.formatted={0} {1} action.choose=Select confirm.delete=Wollen Sie die abonnierte Benachrichtigung f\u00FCr die Lernressource wirklich l\u00F6schen? error.publisherdeleted=Die Ressource wurde gel\u00F6scht und kann nicht mehr angezeigt werden. diff --git a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties index 992bee089f41e13d750009baf6548c3bf8f1cd57..bdd20c68821577a57e51dbf98d306bfa43eeed16 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/core/commons/services/notifications/ui/_i18n/LocalStrings_en.properties @@ -31,6 +31,7 @@ command.unsubscribe=Unsubscribe help.hover.notif=Help regarding notifications subscription.listitem.dateprefix=on {0} user.unknown=unknown +user.formatted={0} {1} action.choose=Select confirm.delete=Do you really want to delete this notification you subscribed to for your learning resource? email.nok=News could not be sent via e-mail. Please try again later or contact your support team. diff --git a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml index 3608aef9fd72f96b7543c9a1804047662607c96f..d0f6657b5b5aa8735674fe90c0ab841314c5db05 100644 --- a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml +++ b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml @@ -182,53 +182,48 @@ </property> </bean> + <!-- * * * * * * * --> + <!-- DEPRECATED!! use src/main/resources/infinispan-config.xml instead !! --> + <!-- Configure caches directly in infinispan files, not here. timeToLive not supported anymore --> + <!-- * * * * * * * --> + <!-- Cache beans --> <bean id="org.olat.login.LoginModule_blockafterfailedattempts" class="org.olat.core.util.cache.CacheConfig" > - <property name="timeToLive" value="300" /> <property name="timeToIdle" value="0" /> <property name="maxElementsInMemory" value="1000" /> </bean> <bean id="org.olat.ims.qti.process.QTIHelper_QTI_xml_Documents" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="3600" /> <property name="timeToIdle" value="1800" /> <!-- qti files may be large --> <property name="maxElementsInMemory" value="20" /> </bean> <bean id="org.olat.modules.wiki.WikiManager_wiki" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="14400" /> <property name="timeToIdle" value="1800" /> <property name="maxElementsInMemory" value="50" /> </bean> <bean id="org.olat.commons.calendar.ICalFileCalendarManager_calendar" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="3600" /> <property name="timeToIdle" value="3600" /> <property name="maxElementsInMemory" value="50" /> </bean> <bean id="org.olat.course.CourseFactory_courses" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="0" /> <property name="timeToIdle" value="3600" /> <property name="maxElementsInMemory" value="${course.cache.elements}" /> </bean> <bean id="org.olat.collaboration.CollaborationToolsFactory_tools" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="3600" /> <property name="timeToIdle" value="1800" /> <property name="maxElementsInMemory" value="5000" /> </bean> <bean id="org.olat.core.modules.glossary.GlossaryItemManager_glossary" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="7200" /> <property name="timeToIdle" value="1800" /> <property name="maxElementsInMemory" value="50" /> </bean> <bean id="org.olat.course.nodes.projectbroker.service.ProjectBrokerManagerImpl_pb" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="3600" /> <property name="timeToIdle" value="3600" /> <property name="maxElementsInMemory" value="50" /> </bean> <bean id="org.olat.course.assessment.NewCachePersistingAssessmentManager" class="org.olat.core.util.cache.CacheConfig"> - <property name="timeToLive" value="0" /> <property name="timeToIdle" value="60" /> <property name="maxElementsInMemory" value="20000" /> </bean> - </beans> diff --git a/src/main/java/org/olat/core/util/cache/CacheConfig.java b/src/main/java/org/olat/core/util/cache/CacheConfig.java index ba7ab132d3b03c8f11f85d8d055046f5ee1a17fb..2785d490235e22795884ba9deb11fb5fcf3bd671 100644 --- a/src/main/java/org/olat/core/util/cache/CacheConfig.java +++ b/src/main/java/org/olat/core/util/cache/CacheConfig.java @@ -38,6 +38,12 @@ package org.olat.core.util.cache; * Initial Date: 19.10.2007 <br> * @author Felix Jost, http://www.goodsolutions.ch */ + +/* * * * * * * * + DEPRECATED!! use src/main/resources/infinispan-config.xml instead !! + Configure caches directly in infinispan files, not here. timeToLive not supported anymore + * * * * * * * */ +@Deprecated public class CacheConfig { private int maxElementsInMemory = 10000; @@ -46,7 +52,6 @@ public class CacheConfig { private boolean diskPersistent = false; private String diskStorePath; private boolean eternal = false; - private int timeToLive = 120; private int timeToIdle = 120; private int diskExpiryThreadIntervalSeconds = 120; @@ -112,19 +117,6 @@ public class CacheConfig { this.eternal = eternal; } - public int getTimeToLive() { - return timeToLive; - } - - /** - * Set t he time in seconds to live for an element before it expires, - * i.e. the maximum time between creation time and when an element expires. - * It is only used if the element is not eternal. Default is 120 seconds. - */ - public void setTimeToLive(int timeToLive) { - this.timeToLive = timeToLive; - } - public int getTimeToIdle() { return timeToIdle; } diff --git a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml index 2d3b31c3e2207b4e70cb7f4a78022b7438642b2a..aea771b205228092be58fad1bcadec65091d9e23 100644 --- a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml +++ b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertiesContext.xml @@ -890,7 +890,7 @@ </bean> </entry> - <!-- fxdiff: FXOLAT-227 user properties used for group-mail-function --> + <!-- User properties used for group-mail-function --> <entry key="org.olat.group.ui.run.BusinessGroupSendToChooserForm"> <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> <property name="description" value=" " /> @@ -904,7 +904,7 @@ </entry> - <!-- fxdiff: FXOLAT-93 user properties used in Businesscards (mitgleidersite) --> + <!-- User properties used in Businesscards (mitgleidersite) --> <entry key="com.frentix.olat.user.UserBusinessCardController"> <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> <property name="description" value="BusinessCards in Membersite" /> @@ -920,7 +920,7 @@ </bean> </entry> - <!-- fxdiff: FXOLAT-356 user properties used for the mail-footer line together with i18nkey: "footer.with.userdata" --> + <!-- User properties used for the mail-footer line together with i18nkey: "footer.with.userdata" --> <entry key="org.olat.core.util.mail.MailHelper"> <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> <property name="description" value="Properties used for the mail footer for emails sent from this system. Configure i18nkey: 'footer.with.userdata' accordingly. " /> @@ -933,6 +933,19 @@ </property> </bean> </entry> + + <!-- User properties used for the mail-notifications line together with i18nkey: "user.formatted" --> + <entry key="org.olat.core.commons.services.notifications.NotificationHelper"> + <bean class="org.olat.user.propertyhandlers.UserPropertyUsageContext"> + <property name="description" value="Properties used for the notification emails sent from this system. Configure i18nkey: 'user.formatted' accordingly. " /> + <property name="propertyHandlers"> + <list> + <ref bean="userPropertyFirstName" /> + <ref bean="userPropertyLastName" /> + </list> + </property> + </bean> + </entry> <!-- Default configuration in case nothing else matches. diff --git a/src/main/resources/infinispan-config.xml b/src/main/resources/infinispan-config.xml index d1f1d3e1bdc5fbf4397ffe299c27a0e4b2c91956..118787fb946ef48dd7372f64f07b5ea535012ea3 100644 --- a/src/main/resources/infinispan-config.xml +++ b/src/main/resources/infinispan-config.xml @@ -73,7 +73,13 @@ <expiration maxIdle="300000" lifespan="300000" wakeUpInterval="5000"/> <transaction transactionMode="NON_TRANSACTIONAL" /> </namedCache> - + + <namedCache name="NotificationHelper@userPropertiesCache"> + <locking isolationLevel="READ_COMMITTED" concurrencyLevel="1000" lockAcquisitionTimeout="15000" useLockStriping="false"/> + <eviction maxEntries="2000" strategy="LRU"/> + <expiration maxIdle="120000" wakeUpInterval="15000"/> + <transaction transactionMode="NON_TRANSACTIONAL" /> + </namedCache> <!-- Hibernate cache