From c6655c82ebcfd517da23e7803236a93968895d42 Mon Sep 17 00:00:00 2001 From: srosse <none@none> Date: Thu, 3 Aug 2017 13:09:49 +0200 Subject: [PATCH] OO-2941: upgrade quartz and spring framework, refactor I18nModule to prevent dependency cycle --- pom.xml | 4 +- .../bps/course/nodes/vc/_spring/vcContext.xml | 4 +- .../links/LinksPortletRunController.java | 11 +- .../bps/onyx/plugin/_spring/onyxContext.xml | 6 +- .../NotificationsEmailAdminController.java | 37 +- .../SystemRegistrationManager.java | 31 +- .../statistics/StatisticsAdminController.java | 71 +-- .../olat/admin/user/SendTokenToUserForm.java | 10 +- .../org/olat/admin/user/imp/ImportStep00.java | 11 +- .../org/olat/basesecurity/AuthHelper.java | 8 +- .../_spring/baseSecurityContext.xml | 5 +- .../calendar/_spring/calendarContext.xml | 4 +- .../org/olat/core/_spring/mainCorecontext.xml | 7 +- .../impressum/ImpressumAdminController.java | 6 +- .../fullWebApp/BaseFullWebappController.java | 15 +- .../_spring/notificationsContext.xml | 6 +- .../scheduler/_spring/schedulerContext.xml | 16 +- .../_spring/taskExecutorCorecontext.xml | 4 +- .../manager/TaskExecutorManagerImpl.java | 5 +- .../configuration/AbstractOLATModule.java | 347 ------------ .../velocity/VelocityRenderDecorator.java | 8 +- .../gui/translator/PackageTranslator.java | 17 +- .../logging/LogRealTimeViewerController.java | 118 +++-- .../olat/core/servlets/OpenOLATServlet.java | 3 - .../core/util/_spring/utilCorecontext.xml | 2 +- .../util/i18n/I18nDirectoriesVisitor.java | 7 +- .../org/olat/core/util/i18n/I18nManager.java | 397 ++++---------- .../org/olat/core/util/i18n/I18nModule.java | 496 ++++++++++++------ .../util/i18n/_spring/i18nCorecontext.xml | 117 ----- .../devtools/TranslationDevController.java | 10 +- .../TranslationDevMainController.java | 20 +- .../i18n/devtools/TranslationDevManager.java | 121 ++--- .../devtools/_spring/devtoolsCorecontext.xml | 3 - .../util/i18n/ui/I18nConfigController.java | 27 +- .../ui/I18nConfigSubDeleteLangController.java | 18 +- .../I18nConfigSubDeletePackageController.java | 6 +- .../ui/I18nConfigSubExportLangController.java | 11 +- .../ui/I18nConfigSubImportLangController.java | 18 +- .../ui/I18nConfigSubNewLangController.java | 6 +- ...TranslationInterceptHandlerController.java | 23 +- .../ui/SingleKeyTranslatorController.java | 11 +- ...lationToolI18nItemEditCrumbController.java | 23 +- .../ui/TranslationToolLauncherController.java | 15 +- .../TranslationToolStartCrumbController.java | 108 ++-- .../assessment/_spring/assessmentContext.xml | 4 +- .../manager/CertificatesManagerImpl.java | 2 +- .../site/ui/CourseSiteAdminController.java | 6 +- .../statistic/MySQLTempStatTableCreator.java | 5 +- .../_spring/statisticsJobContext.xml | 6 +- .../org/olat/dispatcher/LocaleNegotiator.java | 6 +- .../qti/render/LocalizedXSLTransformer.java | 8 +- .../java/org/olat/ldap/LDAPLoginModule.java | 24 +- .../login/LoginAuthprovidersController.java | 6 +- .../lecture/_spring/lectureContext.xml | 12 +- .../ui/_i18n/LocalStrings_en.properties | 8 +- .../olat/modules/reminder/ReminderModule.java | 19 +- .../reminder/_spring/reminderContext.xml | 4 +- .../modules/video/_spring/videoContext.xml | 4 +- .../video/manager/VideoManagerImpl.java | 7 +- .../video/manager/VideoTranscodingJob.java | 3 +- .../org/olat/modules/vitero/ViteroModule.java | 32 +- .../portfolio/_spring/portfolioContext.xml | 12 +- .../LanguageChooserController.java | 10 +- .../olat/registration/PwChangeController.java | 13 +- .../registration/RegistrationController.java | 18 +- .../olat/registration/RegistrationForm2.java | 4 +- .../restapi/RegistrationWebService.java | 4 +- .../repository/_spring/repositoryContext.xml | 4 +- .../accesscontrol/_spring/acContext.xml | 4 +- .../olat/restapi/_spring/restApiContext.xml | 14 +- .../org/olat/restapi/i18n/I18nWebService.java | 8 +- .../system/NotificationsAdminWebService.java | 11 +- .../search/service/SearchServiceImpl.java | 14 +- .../org/olat/user/ChangePrefsController.java | 10 +- .../olat/user/PreferencesFormController.java | 6 +- .../user/_i18n/LocalStrings_en.properties | 4 +- .../services/scheduler/SchedulerTest.java | 25 +- .../org/olat/core/util/i18n/I18nTest.java | 103 ++-- .../accesscontrol/ACReservationDAOTest.java | 3 +- 79 files changed, 1108 insertions(+), 1508 deletions(-) delete mode 100644 src/main/java/org/olat/core/configuration/AbstractOLATModule.java delete mode 100644 src/main/java/org/olat/core/util/i18n/_spring/i18nCorecontext.xml diff --git a/pom.xml b/pom.xml index 8089884104f..9efdf9727a7 100644 --- a/pom.xml +++ b/pom.xml @@ -62,7 +62,7 @@ <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <targetJdk>1.8</targetJdk> - <org.springframework.version>3.2.18.RELEASE</org.springframework.version> + <org.springframework.version>4.3.10.RELEASE</org.springframework.version> <org.hibernate.version>5.2.10.Final</org.hibernate.version> <com.sun.jersey.version>1.19.4</com.sun.jersey.version> <jackson.version>1.9.2</jackson.version> @@ -2296,7 +2296,7 @@ <dependency> <groupId>org.quartz-scheduler</groupId> <artifactId>quartz</artifactId> - <version>1.8.6</version> + <version>2.2.3</version> </dependency> <dependency> <groupId>com.thoughtworks.xstream</groupId> diff --git a/src/main/java/de/bps/course/nodes/vc/_spring/vcContext.xml b/src/main/java/de/bps/course/nodes/vc/_spring/vcContext.xml index 548ddfc686c..35e4bd045d5 100644 --- a/src/main/java/de/bps/course/nodes/vc/_spring/vcContext.xml +++ b/src/main/java/de/bps/course/nodes/vc/_spring/vcContext.xml @@ -64,9 +64,9 @@ <!-- ################################## --> <!-- # VIRTUAL CLASSROOM SERVICE JOBS # --> <!-- ################################## --> - <bean id="adobeCleanupJob" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="adobeCleanupJob" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail"> - <bean class="org.springframework.scheduling.quartz.JobDetailBean"> + <bean class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="de.bps.course.nodes.vc.provider.adobe.AdobeConnectCleanupJob" /> <property name="jobDataAsMap"> <map> diff --git a/src/main/java/de/bps/olat/portal/links/LinksPortletRunController.java b/src/main/java/de/bps/olat/portal/links/LinksPortletRunController.java index eb8e42aecf4..209120917e9 100644 --- a/src/main/java/de/bps/olat/portal/links/LinksPortletRunController.java +++ b/src/main/java/de/bps/olat/portal/links/LinksPortletRunController.java @@ -38,8 +38,8 @@ import org.olat.core.gui.control.generic.closablewrapper.CloseableModalControlle import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.id.UserConstants; -import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -58,6 +58,9 @@ public class LinksPortletRunController extends BasicController { private Link backLink; private DialogBoxController delLinkCtrl; + @Autowired + private I18nModule i18nModule; + protected LinksPortletRunController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); @@ -76,9 +79,9 @@ public class LinksPortletRunController extends BasicController { } private void initOrUpdatePortletView(UserRequest ureq){ - String lang = I18nManager.getInstance().getLocaleKey(ureq.getLocale()); + String lang = i18nModule.getLocaleKey(ureq.getLocale()); if (lang == null) { - lang = I18nManager.getInstance().getLocaleKey(I18nModule.getDefaultLocale()); + lang = i18nModule.getLocaleKey(I18nModule.getDefaultLocale()); } // fxdiff: compare with language-base not with variant... int underlinePos = lang.indexOf("_"); @@ -199,7 +202,7 @@ public class LinksPortletRunController extends BasicController { } } else if (linkName.contains(LINKADD)){ // add a link to institution: - PortletLink newLink = new PortletLink("", "", "", I18nManager.getInstance().getLocaleKey(ureq.getLocale()), "", null); + PortletLink newLink = new PortletLink("", "", "", i18nModule.getLocaleKey(ureq.getLocale()), "", null); // find institution and port in link! String institution = link.getCommand().substring(LINKADD.length()); PortletInstitution inst = LinksPortlet.getContent().get(institution); diff --git a/src/main/java/de/bps/onyx/plugin/_spring/onyxContext.xml b/src/main/java/de/bps/onyx/plugin/_spring/onyxContext.xml index a2d626a2e08..8f8f2d6ba80 100644 --- a/src/main/java/de/bps/onyx/plugin/_spring/onyxContext.xml +++ b/src/main/java/de/bps/onyx/plugin/_spring/onyxContext.xml @@ -6,13 +6,13 @@ http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- update job for onyx results --> -<bean id="updateQtiResultsTriggerOnyx" class="org.springframework.scheduling.quartz.CronTriggerBean"> +<bean id="updateQtiResultsTriggerOnyx" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="updateOnyxResults.${onyx.update.results.job}" /> <property name="cronExpression" value="0 0 2 * * ?"/><!-- 2am, daily --> <property name="startDelay" value="90000" /> </bean> -<bean id="updateOnyxResults.enabled" class="org.springframework.scheduling.quartz.JobDetailBean"> +<bean id="updateOnyxResults.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="de.bps.jobs.UpdateOnyxResults" /> <property name="jobDataAsMap"> <map> @@ -21,7 +21,7 @@ </property> </bean> -<bean id="updateOnyxResults.disabled" class="org.springframework.scheduling.quartz.JobDetailBean"> +<bean id="updateOnyxResults.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <!-- NOTE: reusing the notifications.DummyJob here --> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> diff --git a/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java b/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java index 2e33fbdee0d..958f10a11d4 100644 --- a/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java +++ b/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java @@ -24,6 +24,8 @@ */ package org.olat.admin.notifications; +import java.util.List; + import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -33,10 +35,12 @@ import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; -import org.quartz.JobDetail; +import org.quartz.CronTrigger; +import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; -import org.springframework.scheduling.quartz.CronTriggerBean; +import org.quartz.Trigger; +import org.springframework.beans.factory.annotation.Autowired; /** @@ -49,20 +53,26 @@ import org.springframework.scheduling.quartz.CronTriggerBean; */ public class NotificationsEmailAdminController extends BasicController { private static final String TRIGGER_NOTIFY = "notification.start.button"; + + private final JobKey notificationsJobKey = new JobKey("org.olat.notifications.job.enabled", Scheduler.DEFAULT_GROUP); - private VelocityContainer content; private Link startNotifyButton; + + @Autowired + private Scheduler scheduler; public NotificationsEmailAdminController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); - content = createVelocityContainer("index"); + VelocityContainer content = createVelocityContainer("index"); boolean enabled; String cronExpression = ""; try { CoreSpringFactory.getBean("org.olat.notifications.job.enabled"); enabled = true; - CronTriggerBean bean = (CronTriggerBean)CoreSpringFactory.getBean("sendNotificationsEmailTrigger"); - cronExpression = bean.getCronExpression(); + List<? extends Trigger> triggers = scheduler.getTriggersOfJob(notificationsJobKey); + if(triggers.size() == 1 && triggers.get(0) instanceof CronTrigger) { + cronExpression = ((CronTrigger)triggers.get(0)).getCronExpression(); + } } catch (Exception e) { enabled = false; } @@ -71,31 +81,20 @@ public class NotificationsEmailAdminController extends BasicController { putInitialPanel(content); } - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * org.olat.core.gui.components.Component, - * org.olat.core.gui.control.Event) - */ @Override public void event(UserRequest ureq, Component source, Event event) { if (source == startNotifyButton) { //trigger the cron job try { - Scheduler scheduler = CoreSpringFactory.getImpl(Scheduler.class); - JobDetail detail = scheduler.getJobDetail("org.olat.notifications.job.enabled", Scheduler.DEFAULT_GROUP); - scheduler.triggerJob(detail.getName(), detail.getGroup()); + CoreSpringFactory.getImpl(Scheduler.class).triggerJob(notificationsJobKey); } catch (SchedulerException e) { logError("", e); } } } - /** - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ @Override protected void doDispose() { //nothing to do } - -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/admin/registration/SystemRegistrationManager.java b/src/main/java/org/olat/admin/registration/SystemRegistrationManager.java index 6c9f9583256..93c9c4606e1 100644 --- a/src/main/java/org/olat/admin/registration/SystemRegistrationManager.java +++ b/src/main/java/org/olat/admin/registration/SystemRegistrationManager.java @@ -24,7 +24,10 @@ */ package org.olat.admin.registration; -import java.text.ParseException; +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; + import java.util.ArrayList; import java.util.Calendar; import java.util.HashMap; @@ -63,10 +66,11 @@ import org.olat.group.model.SearchBusinessGroupParams; import org.olat.instantMessaging.InstantMessagingModule; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; -import org.quartz.CronTrigger; import org.quartz.JobDetail; +import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; +import org.quartz.Trigger; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; @@ -171,7 +175,7 @@ public class SystemRegistrationManager implements InitializingBean { public void send() { try { - scheduler.triggerJob(SCHEDULER_NAME, Scheduler.DEFAULT_GROUP); + scheduler.triggerJob(new JobKey(SCHEDULER_NAME, Scheduler.DEFAULT_GROUP)); } catch (SchedulerException e) { log.error("", e); } @@ -250,7 +254,7 @@ public class SystemRegistrationManager implements InitializingBean { // System config msgProperties.put("instantMessagingEnabled", String.valueOf(CoreSpringFactory.getImpl(InstantMessagingModule.class).isEnabled())); - msgProperties.put("enabledLanguages", I18nModule.getEnabledLanguageKeys().toString()); + msgProperties.put("enabledLanguages", CoreSpringFactory.getImpl(I18nModule.class).getEnabledLanguageKeys().toString()); msgProperties.put("clusterEnabled", clusterMode); msgProperties.put("debuggingEnabled", String.valueOf(Settings.isDebuging())); @@ -318,19 +322,16 @@ public class SystemRegistrationManager implements InitializingBean { String cronExpression = createCronTriggerExpression(); try { - // Create job with cron trigger configuration - JobDetail jobDetail = new JobDetail(SCHEDULER_NAME, Scheduler.DEFAULT_GROUP, SystemRegistrationJob.class); - CronTrigger trigger = new CronTrigger(); - trigger.setName(TRIGGER); - // Use this cron expression for debugging, tries to send data every minute - //trigger.setCronExpression("0 * * * * ?"); - trigger.setCronExpression(cronExpression); - // Schedule job now + JobDetail jobDetail = newJob(SystemRegistrationJob.class) + .withIdentity(SCHEDULER_NAME, Scheduler.DEFAULT_GROUP) + .build(); + Trigger trigger = newTrigger() + .withIdentity(TRIGGER) + .withSchedule(cronSchedule(cronExpression)) + .build(); scheduler.scheduleJob(jobDetail, trigger); - } catch (ParseException e) { + } catch (Exception e) { log.error("Illegal cron expression for system registration", e); - } catch (SchedulerException e) { - log.error("Can not start system registration scheduler", e); } log.info("Registration background job successfully started: "+cronExpression, null); } diff --git a/src/main/java/org/olat/admin/statistics/StatisticsAdminController.java b/src/main/java/org/olat/admin/statistics/StatisticsAdminController.java index f6635f31062..6bdd1266246 100644 --- a/src/main/java/org/olat/admin/statistics/StatisticsAdminController.java +++ b/src/main/java/org/olat/admin/statistics/StatisticsAdminController.java @@ -41,11 +41,12 @@ import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.course.statistic.StatisticUpdateManager; -import org.quartz.JobDetail; +import org.quartz.CronTrigger; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.quartz.Trigger; -import org.springframework.scheduling.quartz.CronTriggerBean; +import org.quartz.TriggerKey; +import org.springframework.beans.factory.annotation.Autowired; /** * Admin Controller for statistics - similar to the notifications controller. @@ -70,6 +71,9 @@ public class StatisticsAdminController extends BasicController { private DialogBoxController dialogCtr_; + @Autowired + private Scheduler scheduler; + public StatisticsAdminController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); content = createVelocityContainer("index"); @@ -82,38 +86,42 @@ public class StatisticsAdminController extends BasicController { } private void refreshUIState() { + + log_.info("refreshUIState: schedulerFactoryBean found"); + boolean enabled = false; String cronExpression = ""; - if (CoreSpringFactory.containsBean("schedulerFactoryBean")) { - log_.info("refreshUIState: schedulerFactoryBean found"); - Object schedulerFactoryBean = CoreSpringFactory.getBean("schedulerFactoryBean"); - if (schedulerFactoryBean!=null && schedulerFactoryBean instanceof Scheduler) { - Scheduler schedulerBean = (Scheduler) schedulerFactoryBean; - int triggerState; - try { - triggerState = schedulerBean.getTriggerState("updateStatisticsTrigger", null/*trigger group*/); - enabled = (triggerState!=Trigger.STATE_NONE) && (triggerState!=Trigger.STATE_ERROR); - log_.info("refreshUIState: updateStatisticsTrigger state was "+triggerState+", enabled now: "+enabled); - } catch (SchedulerException e) { - log_.warn("refreshUIState: Got a SchedulerException while asking for the updateStatisticsTrigger's state", e); - } - } - CronTriggerBean triggerBean = (CronTriggerBean) CoreSpringFactory.getBean("updateStatisticsTrigger"); - JobDetail jobDetail = triggerBean.getJobDetail(); - enabled &= jobDetail.getName().equals("org.olat.statistics.job.enabled"); - log_.info("refreshUIState: org.olat.statistics.job.enabled check, enabled now: "+enabled); - cronExpression = triggerBean.getCronExpression(); - StatisticUpdateManager statisticUpdateManager = getStatisticUpdateManager(); - if (statisticUpdateManager==null) { - log_.info("refreshUIState: statisticUpdateManager not configured"); - enabled = false; + Trigger.TriggerState triggerState; + try { + TriggerKey triggerKey = new TriggerKey("updateStatisticsTrigger", null/*trigger group*/); + triggerState = scheduler.getTriggerState(triggerKey); + enabled = triggerState != Trigger.TriggerState.NONE && triggerState!=Trigger.TriggerState.ERROR; + + Trigger trigger = scheduler.getTrigger(triggerKey); + if(trigger == null) { + enabled &= false; } else { - enabled &= statisticUpdateManager.isEnabled(); - log_.info("refreshUIState: statisticUpdateManager configured, enabled now: "+enabled); + enabled &= trigger.getJobKey().getName().equals("org.olat.statistics.job.enabled"); + if(trigger instanceof CronTrigger) { + log_.info("refreshUIState: org.olat.statistics.job.enabled check, enabled now: "+enabled); + cronExpression = ((CronTrigger)trigger).getCronExpression(); + } } + + log_.info("refreshUIState: updateStatisticsTrigger state was "+triggerState+", enabled now: "+enabled); + } catch (SchedulerException e) { + log_.warn("refreshUIState: Got a SchedulerException while asking for the updateStatisticsTrigger's state", e); + } + + StatisticUpdateManager statisticUpdateManager = getStatisticUpdateManager(); + if (statisticUpdateManager==null) { + log_.info("refreshUIState: statisticUpdateManager not configured"); + enabled = false; } else { - log_.info("refreshUIState: schedulerFactoryBean not found"); + enabled &= statisticUpdateManager.isEnabled(); + log_.info("refreshUIState: statisticUpdateManager configured, enabled now: "+enabled); } + if (enabled) { content.contextPut("status", getTranslator().translate("statistics.status.enabled", new String[]{ cronExpression })); } else { @@ -150,6 +158,7 @@ public class StatisticsAdminController extends BasicController { } } + @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == dialogCtr_) { if (DialogBoxUIFactory.isYesEvent(event)) { @@ -165,12 +174,6 @@ public class StatisticsAdminController extends BasicController { } } - - /** - * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, - * org.olat.core.gui.components.Component, - * org.olat.core.gui.control.Event) - */ @Override public void event(UserRequest ureq, Component source, Event event) { if (STATISTICS_FULL_RECALCULATION_TRIGGER_BUTTON.equals(event.getCommand())) { diff --git a/src/main/java/org/olat/admin/user/SendTokenToUserForm.java b/src/main/java/org/olat/admin/user/SendTokenToUserForm.java index 89081c6588e..3510ddf2708 100644 --- a/src/main/java/org/olat/admin/user/SendTokenToUserForm.java +++ b/src/main/java/org/olat/admin/user/SendTokenToUserForm.java @@ -42,6 +42,7 @@ import org.olat.core.id.UserConstants; import org.olat.core.util.Encoder; import org.olat.core.util.Util; import org.olat.core.util.i18n.I18nManager; +import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.mail.MailBundle; import org.olat.core.util.mail.MailManager; import org.olat.core.util.mail.MailerResult; @@ -64,6 +65,11 @@ public class SendTokenToUserForm extends FormBasicController { private TextElement mailText; private String dummyKey; + + @Autowired + private I18nModule i18nModule; + @Autowired + private I18nManager i18nManager; @Autowired private MailManager mailManager; @Autowired @@ -122,7 +128,7 @@ public class SendTokenToUserForm extends FormBasicController { Translator userTrans = Util.createPackageTranslator(RegistrationManager.class, locale) ; String body = userTrans.translate("pwchange.intro", new String[] { user.getName() }) + userTrans.translate("pwchange.body", new String[] { - serverpath, dummyKey, I18nManager.getInstance().getLocaleKey(locale) + serverpath, dummyKey, i18nModule.getLocaleKey(locale) }); return body; } @@ -147,7 +153,7 @@ public class SendTokenToUserForm extends FormBasicController { } Preferences prefs = user.getUser().getPreferences(); - Locale locale = I18nManager.getInstance().getLocaleOrDefault(prefs.getLanguage()); + Locale locale = i18nManager.getLocaleOrDefault(prefs.getLanguage()); String emailAdress = user.getUser().getProperty(UserConstants.EMAIL, locale); TemporaryKey tk = registrationManager.loadTemporaryKeyByEmail(emailAdress); diff --git a/src/main/java/org/olat/admin/user/imp/ImportStep00.java b/src/main/java/org/olat/admin/user/imp/ImportStep00.java index 0005b9bf3ff..2a46213ab29 100644 --- a/src/main/java/org/olat/admin/user/imp/ImportStep00.java +++ b/src/main/java/org/olat/admin/user/imp/ImportStep00.java @@ -60,7 +60,6 @@ import org.olat.core.gui.media.MediaResource; import org.olat.core.id.Identity; import org.olat.core.id.UserConstants; import org.olat.core.util.StringHelper; -import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; import org.olat.registration.RegistrationManager; import org.olat.registration.TemporaryKey; @@ -124,6 +123,8 @@ class ImportStep00 extends BasicStep { @Autowired private UserManager um; @Autowired + private I18nModule i18nModule; + @Autowired private BaseSecurity securityManager; @Autowired private ShibbolethModule shibbolethModule; @@ -165,7 +166,7 @@ class ImportStep00 extends BasicStep { return true; } - String defaultlang = I18nModule.getDefaultLocale().toString(); + String defaultlang = i18nModule.getDefaultLocale().toString(); List<String> importedEmails = new ArrayList<String>(); boolean importDataError = false; @@ -184,7 +185,7 @@ class ImportStep00 extends BasicStep { // org.olat.admin.user.imp.UserImportController // are required and have to be submitted in the right order // - pwd can be enabled / disabled by configuration - Collection<String> languages = I18nModule.getEnabledLanguageKeys(); + Collection<String> languages = i18nModule.getEnabledLanguageKeys(); String[] lines = inp.split("\r?\n"); for (int i = 0; i < lines.length; i++) { if(i % 25 == 0) { @@ -449,7 +450,7 @@ class ImportStep00 extends BasicStep { private Mapper createMapper(UserRequest ureq) { final String charset = UserManager.getInstance().getUserCharset(ureq.getIdentity()); Mapper m = new Mapper() { - @SuppressWarnings({"synthetic-access" }) + @Override public MediaResource handle(String relPath, HttpServletRequest request) { setTranslator(UserManager.getInstance().getPropertyHandlerTranslator(getTranslator())); String headerLine = translate("table.user.login") + " *"; @@ -459,7 +460,7 @@ class ImportStep00 extends BasicStep { dataLine += "\t" + "olat4you"; } headerLine += "\t" + translate("table.user.lang"); - dataLine += "\t" + I18nManager.getInstance().getLocaleKey(getLocale()); + dataLine += "\t" + i18nModule.getLocaleKey(getLocale()); UserPropertyHandler userPropertyHandler; for (int i = 0; i < userPropertyHandlers.size(); i++) { userPropertyHandler = userPropertyHandlers.get(i); diff --git a/src/main/java/org/olat/basesecurity/AuthHelper.java b/src/main/java/org/olat/basesecurity/AuthHelper.java index f6708fee6aa..fab7172cc5b 100644 --- a/src/main/java/org/olat/basesecurity/AuthHelper.java +++ b/src/main/java/org/olat/basesecurity/AuthHelper.java @@ -219,7 +219,7 @@ public class AuthHelper { * @return true if login was successful, false otherwise */ public static int doAnonymousLogin(UserRequest ureq, Locale locale) { - Collection<String> supportedLanguages = I18nModule.getEnabledLanguageKeys(); + Collection<String> supportedLanguages = CoreSpringFactory.getImpl(I18nModule.class).getEnabledLanguageKeys(); if ( locale == null || ! supportedLanguages.contains(locale.toString()) ) { locale = I18nModule.getDefaultLocale(); } @@ -266,7 +266,7 @@ public class AuthHelper { } } - Collection<String> supportedLanguages = I18nModule.getEnabledLanguageKeys(); + Collection<String> supportedLanguages = CoreSpringFactory.getImpl(I18nModule.class).getEnabledLanguageKeys(); if ( locale == null || ! supportedLanguages.contains(locale.toString()) ) { locale = I18nModule.getDefaultLocale(); } @@ -358,10 +358,10 @@ public class AuthHelper { boolean wasGuest = false; UserSession usess = ureq.getUserSession(); if(usess != null && usess.getRoles() != null) { - wasGuest = ureq.getUserSession().getRoles().isGuestOnly(); + wasGuest = usess.getRoles().isGuestOnly(); } - String lang = I18nManager.getInstance().getLocaleKey(ureq.getLocale()); + String lang = CoreSpringFactory.getImpl(I18nModule.class).getLocaleKey(ureq.getLocale()); HttpSession session = ureq.getHttpReq().getSession(false); // next line fires a valueunbound event to UserSession, which does some // stuff on logout diff --git a/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml b/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml index f2a10a370bb..88ed650d5ba 100644 --- a/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml +++ b/src/main/java/org/olat/basesecurity/_spring/baseSecurityContext.xml @@ -10,14 +10,11 @@ <context:component-scan base-package="org.olat.basesecurity" /> - <!-- manager --> - <bean id="baseSecurityManager" class="org.olat.basesecurity.BaseSecurityManager" init-method="init" - depends-on="database, i18nModule, triggerI18nModuleInit"> + <bean id="baseSecurityManager" class="org.olat.basesecurity.BaseSecurityManager" init-method="init" depends-on="database"> <property name="resourceManager" ref="resourceManager"/> <property name="loginModule" ref="loginModule"/> <property name="dbInstance" ref="database"/> <property name="invitationDao" ref="invitationDao" /> <property name="dbVendor" value="${db.vendor}" /> </bean> - </beans> \ No newline at end of file diff --git a/src/main/java/org/olat/commons/calendar/_spring/calendarContext.xml b/src/main/java/org/olat/commons/calendar/_spring/calendarContext.xml index 5a5369adfe5..750df1f6e94 100644 --- a/src/main/java/org/olat/commons/calendar/_spring/calendarContext.xml +++ b/src/main/java/org/olat/commons/calendar/_spring/calendarContext.xml @@ -10,7 +10,7 @@ <context:component-scan base-package="org.olat.commons.calendar" /> - <bean id="calendarImportTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="calendarImportTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="calendarImportJob" /> <!-- adjust cron style syntax for your needs A "Cron-Expression" is a string comprised of 6 or 7 fields separated by white space. The 6 mandatory and 1 optional fields are as follows: @@ -30,7 +30,7 @@ <property name="startDelay" value="40000" /> </bean> - <bean id="calendarImportJob" class="org.springframework.scheduling.quartz.JobDetailBean"> + <bean id="calendarImportJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.olat.commons.calendar.ImportCalendarJob" /> </bean> diff --git a/src/main/java/org/olat/core/_spring/mainCorecontext.xml b/src/main/java/org/olat/core/_spring/mainCorecontext.xml index 3ab96ee70d0..69bc796fff3 100644 --- a/src/main/java/org/olat/core/_spring/mainCorecontext.xml +++ b/src/main/java/org/olat/core/_spring/mainCorecontext.xml @@ -8,12 +8,11 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - <context:component-scan base-package="org.olat.core.dispatcher.mapper,org.olat.core.id.context,org.olat.core.commons.controllers.impressum,org.olat.core.gui.render.velocity" /> + <context:component-scan base-package="org.olat.core.dispatcher.mapper,org.olat.core.id.context,org.olat.core.commons.controllers.impressum,org.olat.core.helpers,org.olat.core.gui.render.velocity" /> <bean id="coreSpringFactory" class="org.olat.core.CoreSpringFactory" /> <import resource="classpath:/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml"/> - <import resource="classpath:/org/olat/core/util/i18n/_spring/i18nCorecontext.xml"/> <import resource="classpath:/org/olat/core/util/_spring/utilCorecontext.xml"/> <import resource="classpath:/org/olat/core/util/i18n/devtools/_spring/devtoolsCorecontext.xml"/> <import resource="classpath:/org/olat/core/util/event/_spring/frameworkStartedEventCorecontext.xml"/> @@ -41,13 +40,13 @@ <property name="parserPoolSize" value="${velocity.parser.pool.size}" /> </bean> - <bean id="mapperSlayerTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="mapperSlayerTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="mapperSlayerJob" /> <property name="cronExpression" value="0 5 0/1 * * ?" /> <property name="startDelay" value="200000" /> </bean> - <bean id="mapperSlayerJob" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="mapperSlayerJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.dispatcher.mapper.manager.MapperZombieSlayerJob" /> </bean> diff --git a/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java b/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java index ee7371c11b5..08c97ecef81 100644 --- a/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java +++ b/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java @@ -73,6 +73,8 @@ public class ImpressumAdminController extends FormBasicController { private final VFSContainer impressumDir; private final VFSContainer termsOfUseDir; + @Autowired + private I18nModule i18nModule; @Autowired private I18nManager i18nManager; @Autowired @@ -116,7 +118,7 @@ public class ImpressumAdminController extends FormBasicController { List<ButtonGroup> impressumButtons = new ArrayList<>(); impressumCont.contextPut("buttons", impressumButtons); - for(String lang:I18nModule.getEnabledLanguageKeys()) { + for(String lang:i18nModule.getEnabledLanguageKeys()) { FormLink editLink = uifactory .addFormLink("impressum." + lang, "impressum", getTranslated(lang), "impressum.file", impressumCont, Link.BUTTON | Link.NONTRANSLATED); editLink.setLabel(null, null); @@ -146,7 +148,7 @@ public class ImpressumAdminController extends FormBasicController { List<ButtonGroup> termsOfUseButtons = new ArrayList<>(); termsCont.contextPut("buttons", termsOfUseButtons); - for(String lang:I18nModule.getEnabledLanguageKeys()) { + for(String lang:i18nModule.getEnabledLanguageKeys()) { FormLink editLink = uifactory.addFormLink("termofuser." + lang, "termsofuse", getTranslated(lang), "termofuse.file", termsCont, Link.BUTTON | Link.NONTRANSLATED); editLink.setLabel(null, null); String filePath = "index_" + lang + ".html"; diff --git a/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java b/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java index a9f4cd1f294..8b2f579b360 100644 --- a/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java +++ b/src/main/java/org/olat/core/commons/fullWebApp/BaseFullWebappController.java @@ -114,6 +114,7 @@ import org.olat.course.assessment.ui.mode.AssessmentModeGuardController; import org.olat.course.assessment.ui.mode.ChooseAssessmentModeEvent; import org.olat.gui.control.UserToolsMenuController; import org.olat.home.HomeSite; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -185,6 +186,11 @@ public class BaseFullWebappController extends BasicController implements DTabs, private final boolean isAdmin; private final int maxTabs = 20; + @Autowired + private I18nModule i18nModule; + @Autowired + private I18nManager i18nManager; + public BaseFullWebappController(UserRequest ureq, BaseFullWebappControllerParts baseFullWebappControllerParts) { // only-use-in-super-call, since we define our own super(ureq, null); @@ -350,14 +356,15 @@ public class BaseFullWebappController extends BasicController implements DTabs, // will start the translation tool in translation mode, if the overlay // feature is enabled it will start in customizing mode // fxdiff: allow user-managers to use the inline translation also. - if (ureq.getUserSession().isAuthenticated() - && (ureq.getUserSession().getRoles().isOLATAdmin() || ureq.getUserSession().getRoles().isUserManager()) - && (I18nModule.isTransToolEnabled() || I18nModule.isOverlayEnabled())) { + UserSession usess = ureq.getUserSession(); + if (usess.isAuthenticated() + && (usess.getRoles().isOLATAdmin() || usess.getRoles().isUserManager()) + && (i18nModule.isTransToolEnabled() || i18nModule.isOverlayEnabled())) { inlineTranslationC = wbo.createInlineTranslationDispatcherController(ureq, getWindowControl()); Preferences guiPrefs = ureq.getUserSession().getGuiPreferences(); Boolean isInlineTranslationEnabled = (Boolean) guiPrefs.get(I18nModule.class, I18nModule.GUI_PREFS_INLINE_TRANSLATION_ENABLED, Boolean.FALSE); - I18nManager.getInstance().setMarkLocalizedStringsEnabled(ureq.getUserSession(), isInlineTranslationEnabled); + i18nManager.setMarkLocalizedStringsEnabled(ureq.getUserSession(), isInlineTranslationEnabled); mainVc.put("inlineTranslation", inlineTranslationC.getInitialComponent()); } diff --git a/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml b/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml index 4d026f0150b..932c363c47e 100644 --- a/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml +++ b/src/main/java/org/olat/core/commons/services/notifications/_spring/notificationsContext.xml @@ -63,7 +63,7 @@ is 10min after midnight. --> - <bean id="sendNotificationsEmailTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="sendNotificationsEmailTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="org.olat.notifications.job.${cluster.singleton.services}" /> <!-- adjust cron style syntax for your notification needs "0 10 0 * *" e.g. 10 minutes after midnight @@ -87,12 +87,12 @@ <property name="startDelay" value="300000" /> </bean> - <bean id="org.olat.notifications.job.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="org.olat.notifications.job.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.notifications.manager.EmailNotificationJob" /> </bean> <!-- dummy bean --> - <bean id="org.olat.notifications.job.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="org.olat.notifications.job.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> diff --git a/src/main/java/org/olat/core/commons/services/scheduler/_spring/schedulerContext.xml b/src/main/java/org/olat/core/commons/services/scheduler/_spring/schedulerContext.xml index d570acedcfb..19d35e7235a 100644 --- a/src/main/java/org/olat/core/commons/services/scheduler/_spring/schedulerContext.xml +++ b/src/main/java/org/olat/core/commons/services/scheduler/_spring/schedulerContext.xml @@ -16,8 +16,8 @@ to the MBeanExporter Bean at the end. How to add a new job: 1. Create you class which extends from QuartzJobBean see ChangePresenceJob as example 2. Create a file called "olatextconfig.xml" with your own beans and place it in the same directory as this file. It will be loaded automatically. -3. Add a bean definition where your job is created like ="<bean id="changePresenceJob" class="org.springframework.scheduling.quartz.JobDetailBean">" -4. Create a scheduler for your definded bean: Either an SimpleTriggerBean or an CronTriggerBean +3. Add a bean definition where your job is created like ="<bean id="changePresenceJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">" +4. Create a scheduler for your definded bean: Either an SimpleTriggerFactoryBean or an CronTriggerFactoryBean 5. Add your trigger bean to the SchedulerFactoryBean list. --> @@ -61,7 +61,7 @@ How to add a new job: <!-- add referenced schedulers here --> <!-- Only needed in cluster mode, dumps jmx info to disc --> -<bean id="dumpJMXJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> +<bean id="dumpJMXJobTrigger" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <property name="jobDetail" ref="dumpJMXJob" /> <!-- 5 minute --> <property name="startDelay" value="300000" /> @@ -72,7 +72,7 @@ How to add a new job: <!-- Example bean for cron style scheduling--> <!-- OLAT-5093 start delay ensures there's no conflict with server startup and db not being ready yet --> <!-- -<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> +<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="exampleJob" /> <property name="cronExpression" value="0 0 6 * * ?" /> <property name="startDelay" value="300000" /> @@ -81,7 +81,7 @@ How to add a new job: <!-- job definition --> -<bean id="dumpJMXJob" class="org.springframework.scheduling.quartz.JobDetailBean"> +<bean id="dumpJMXJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.olat.admin.jmx.DumpJMXJob"/> <property name="jobDataAsMap"> <map> @@ -103,7 +103,7 @@ How to add a new job: <!-- SEARCH INDEXING CONFIGURATION --> - <bean id="searchIndexingTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="searchIndexingTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="org.olat.search.job.${search.indexing.cronjob}" /> <property name="cronExpression" ref="searchIndexCronGenerator" /> <!-- OLAT-5093 start delay ensures there's no conflict with server startup and db not being ready yet --> @@ -116,12 +116,12 @@ How to add a new job: <property name="cronExpression" value="${search.indexing.cronjob.expression}" /> </bean> - <bean id="org.olat.search.job.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="org.olat.search.job.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.search.service.indexer.SearchIndexingJob"/> </bean> <!-- dummy bean --> - <bean id="org.olat.search.job.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="org.olat.search.job.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <!-- NOTE: reusing the notifications.DummyJob here --> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> diff --git a/src/main/java/org/olat/core/commons/services/taskexecutor/_spring/taskExecutorCorecontext.xml b/src/main/java/org/olat/core/commons/services/taskexecutor/_spring/taskExecutorCorecontext.xml index 3dfedfa0560..564f9696967 100644 --- a/src/main/java/org/olat/core/commons/services/taskexecutor/_spring/taskExecutorCorecontext.xml +++ b/src/main/java/org/olat/core/commons/services/taskexecutor/_spring/taskExecutorCorecontext.xml @@ -34,13 +34,13 @@ </bean> <!-- Persistent task executor job --> - <bean id="taskExecutorTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="taskExecutorTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="taskExecutorJob" /> <!-- every day at 1:21 --> <property name="cronExpression" value="10 */5 * * * ?" /> <property name="startDelay" value="60000" /> </bean> - <bean id="taskExecutorJob" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="taskExecutorJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.taskexecutor.manager.ExecutorJob" /> </bean> diff --git a/src/main/java/org/olat/core/commons/services/taskexecutor/manager/TaskExecutorManagerImpl.java b/src/main/java/org/olat/core/commons/services/taskexecutor/manager/TaskExecutorManagerImpl.java index 777d9f829bb..b014f529c67 100644 --- a/src/main/java/org/olat/core/commons/services/taskexecutor/manager/TaskExecutorManagerImpl.java +++ b/src/main/java/org/olat/core/commons/services/taskexecutor/manager/TaskExecutorManagerImpl.java @@ -46,7 +46,7 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.manager.BasicManager; import org.olat.resource.OLATResource; -import org.quartz.JobDetail; +import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; @@ -150,8 +150,7 @@ public class TaskExecutorManagerImpl extends BasicManager implements TaskExecuto @Override public void executeTaskToDo() { try { - JobDetail detail = scheduler.getJobDetail("taskExecutorJob", Scheduler.DEFAULT_GROUP); - scheduler.triggerJob(detail.getName(), detail.getGroup()); + scheduler.triggerJob(new JobKey("taskExecutorJob", Scheduler.DEFAULT_GROUP)); } catch (SchedulerException e) { log.error("", e); } diff --git a/src/main/java/org/olat/core/configuration/AbstractOLATModule.java b/src/main/java/org/olat/core/configuration/AbstractOLATModule.java deleted file mode 100644 index 9d6042498f4..00000000000 --- a/src/main/java/org/olat/core/configuration/AbstractOLATModule.java +++ /dev/null @@ -1,347 +0,0 @@ -/** -* OLAT - Online Learning and Training<br> -* http://www.olat.org -* <p> -* Licensed under the Apache License, Version 2.0 (the "License"); <br> -* you may not use this file except in compliance with the License.<br> -* You may obtain a copy of the License at -* <p> -* http://www.apache.org/licenses/LICENSE-2.0 -* <p> -* Unless required by applicable law or agreed to in writing,<br> -* software distributed under the License is distributed on an "AS IS" BASIS, <br> -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> -* See the License for the specific language governing permissions and <br> -* limitations under the License. -* <p> -* Copyright (c) since 2004 at Multimedia- & E-Learning Services (MELS),<br> -* University of Zurich, Switzerland. -* <hr> -* <a href="http://www.openolat.org"> -* OpenOLAT - Online Learning and Training</a><br> -* This file has been modified by the OpenOLAT community. Changes are licensed -* under the Apache 2.0 license as the original file. -* <p> -*/ -package org.olat.core.configuration; - -import java.util.HashMap; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.atomic.AtomicInteger; - -import org.olat.core.gui.control.Event; -import org.olat.core.logging.LogDelegator; -import org.olat.core.logging.OLog; -import org.olat.core.logging.StartupException; -import org.olat.core.logging.Tracing; -import org.olat.core.util.StringHelper; -import org.olat.core.util.event.GenericEventListener; - -/** - * Description:<br> - * Default/abstract class with helper methods. <br> - * The abstract olat module features reading and writing of configuration - * properties to config and properties files. The idea is that the system can be - * configured with default values either in the config xml file or by providing - * reasonable default values directly in the module code. - * <p> - * The developer should provide a GUI for each value that can be configured at - * runtime without the need of rebooting the entire system. But this is up to - * the programmer who implements the setter methods for the config values. - * <p> - * The getter methods will load the configuration in the following order: - * <ol> - * <li> - * <code>olatdata/system/configuration/fully.qualified.ClassName.properties</code> - * </li> - * <li>falling back to<code>olat.local.properties</code></li> - * <li>falling back to<code>olat.properties</code></li> - * <li>falling back to default value defined in method call</li> - * </ol> - * The class does also provide save methods. Setting a config parameter will - * store it always in the user space config file - * <code>olatdata/system/configuration/fully.qualified.ClassName.properties</code> - * and not in the olat.properties, those are only the default values in case no - * other configuration. - * <p> - * To work properly in a cluster environment, the module will fire a - * ModuleConfigurationChangedEvent at the end of each save cycle. This event is - * catched automatically and the abstract method initFromChangedProperties() is - * called. - * <p> - * For more information on how the storing mechanism of the configuration works - * please have a look at the PersistedProperties class. - * <p> - * If you want to use the properties mechanism in a spring loaded class, use the - * PersistedProperties class directly to read/write your application - * configuration. - * <p> - * Initial Date: 01.10.2007 <br> - * - * @author Felix Jost, http://www.goodsolutions.ch - * @author Florian Gnägi, http://www.frentix.com - */ -public abstract class AbstractOLATModule extends LogDelegator implements GenericEventListener { - protected PersistedProperties moduleConfigProperties; - private Properties moduleDefaultConfig; - - public static final Map<Class<?>,AtomicInteger> starts = new HashMap<Class<?>,AtomicInteger>(); - - public AbstractOLATModule() { - if(!starts.containsKey(this.getClass())) { - starts.put(this.getClass(), new AtomicInteger(1)); - } else { - starts.get(this.getClass()).incrementAndGet(); - } - } - - public static void printStats() { - OLog logger = Tracing.createLoggerFor(AbstractOLATModule.class); - for(Map.Entry<Class<?>, AtomicInteger> entry:starts.entrySet()) { - if(entry.getValue().get() > 1) { - logger.info(entry.getValue().get() + " :: " + entry.getKey()); - } - } - } - - /** - * Initialize the module. Called by the spring framework at startup time - */ - public final void init(Properties moduleConfig) { - // Default module configuration from xml file - this.moduleDefaultConfig = moduleConfig; - // Let the module set the default properties - if (moduleConfigProperties == null) throw new StartupException("PersistedProperties is null. You have to set Persisted properties in spring config when you use abstractOlatModule!"); - initDefaultProperties(); - init(); - } - - public abstract void init(); - - - public abstract void setPersistedProperties(PersistedProperties persistedProperties); - - /** - * Called during module initialization to read the default values from the - * configuration and set them as config properties default. - */ - protected abstract void initDefaultProperties(); - - /** - * Called whenever the properties configuraton changed (e.g. on this or on another - * cluster node). The properties have been reloaded prior to when this method is executed. - */ - protected abstract void initFromChangedProperties(); - - - /** - * Return an int value for certain config-parameter. If the parameter does - * not exist, return the defaultValue. - * - * @param parameterName - * @param defaultValue - * @param - * @return The int value. - */ - protected int getIntConfigParameter(String parameterName, int defaultValue) { - String stringValue = moduleDefaultConfig.getProperty(parameterName); - if (StringHelper.containsNonWhitespace(stringValue)) { - try { - return Integer.parseInt(stringValue.trim()); - } catch (Exception ex) { - logWarn("Cannot parse to integer conf-parameter '" + parameterName + "', value=" + stringValue, null); - } - } - logInfo("Take default value for integer conf-parameter '" + parameterName + "', value=" + defaultValue, null); - return defaultValue; - } - - /** - * Return a string value for certain config-parameter. If the parameter does - * not exist, return the defaultValue. - * - * @param parameterName - * @param defaultValue - * @param - * @return The string value. Can be empty, but never null - */ - protected String getStringConfigParameter(String parameterName, String defaultValue, boolean allowEmptyString) { - String stringValue = moduleDefaultConfig.getProperty(parameterName); - if (stringValue != null) { - if (allowEmptyString || StringHelper.containsNonWhitespace(stringValue)) { - return stringValue.trim(); - } - } - logInfo("Take default value for String conf-parameter '" + parameterName + "', value=" + defaultValue, null); - return defaultValue; - } - - /** - * Return a boolean value for certain config-parameter. If the paramter does - * not exist, return the defaultValue. 'true' and 'enabled' return <code>true</code>, 'false' and 'disabled' return <code>false</code>. - * - * @param parameterName - * @param defaultValue - * @return - */ - protected boolean getBooleanConfigParameter(String parameterName, boolean defaultValue) { - String stringValue = moduleDefaultConfig.getProperty(parameterName); - if ((stringValue != null) && (stringValue.trim().equalsIgnoreCase("TRUE") || stringValue.trim().equalsIgnoreCase("ENABLED"))) { - return true; - } - if ((stringValue != null) && (stringValue.trim().equalsIgnoreCase("FALSE") || stringValue.trim().equalsIgnoreCase("DISABLED"))) { - return false; - } - logInfo("Take default Boolean conf-parameter '" + parameterName + "', value=" + stringValue - + ", only true/false supported => take default value.", null); - return defaultValue; - } - - // - // Delegate methods used to get and set the values and default in the user - // configuration using the persisted properties. - // - - /** - * Return a string value for certain propertyName-parameter. - * - * @param propertyName - * @param allowEmptyString - * true: empty strings are valid values; false: emtpy strings are - * discarded - * @return the value from the configuration or the default value or ""/NULL - * (depending on allowEmptyString flag) - */ - protected String getStringPropertyValue(String propertyName, boolean allowEmptyString) { - // delegate to new property based config style - return moduleConfigProperties.getStringPropertyValue(propertyName, allowEmptyString); - } - /** - * Set a string property - * - * @param propertyName - * The key - * @param value - * The Value - * @param saveConfiguration - * true: will save property and fire event; false: will not save, - * but set a dirty flag - */ - protected void setStringProperty(String propertyName, String value, boolean saveConfiguration) { - // delegate to new property based config style - moduleConfigProperties.setStringProperty(propertyName, value, saveConfiguration); - logAudit("change system property: " + propertyName, value); - } - /** - * Retrun an int value for a certain propertyName - * - * @param propertyName - * @return the value from the configuration or the default value or 0 - */ - protected int getIntPropertyValue(String propertyName) { - // delegate to new property based config style - return moduleConfigProperties.getIntPropertyValue(propertyName); - } - /** - * Set an int property - * - * @param propertyName - * The key - * @param value - * The Value - * @param saveConfiguration - * true: will save property and fire event; false: will not save, - * but set a dirty flag - */ - protected void setIntProperty(String propertyName, int value, boolean saveConfiguration) { - // delegate to new property based config style - moduleConfigProperties.setIntProperty(propertyName, value, saveConfiguration); - logAudit("change system property: " + propertyName, Integer.toString(value)); - } - /** - * Return a boolean value for certain propertyName - * - * @param propertyName - * @return the value from the configuration or the default value or false - */ - protected boolean getBooleanPropertyValue(String propertyName) { - // delegate to new property based config style - return moduleConfigProperties.getBooleanPropertyValue(propertyName); - } - /** - * Set a boolean property - * - * @param propertyName - * The key - * @param value - * The Value - * @param saveConfiguration - * true: will save property and fire event; false: will not save, - * but set a dirty flag - */ - protected void setBooleanProperty(String propertyName, boolean value, boolean saveConfiguration) { - // delegate to new property based config style - moduleConfigProperties.setBooleanProperty(propertyName, value, saveConfiguration); - logAudit("change system property: " + propertyName, Boolean.toString(value)); - } - /** - * Save the properties configuration to disk and notify other nodes about - * change. This is only done when there are dirty changes, otherwhile the - * method call does nothing. - */ - protected void savePropertiesAndFireChangedEvent() { - // delegate to new property based config style - moduleConfigProperties.savePropertiesAndFireChangedEvent(); - } - /** - * Clear the properties and save the empty properties to the file system. - */ - protected void clearAndSaveProperties() { - // delegate to new property based config style - moduleConfigProperties.clearAndSaveProperties(); - } - /** - * Set a default value for a string property - * @param propertyName - * @param value - */ - protected void setStringPropertyDefault(String key, String value){ - // delegate to new property based config style - moduleConfigProperties.setStringPropertyDefault(key, value); - } - /** - * Set a default value for a boolean property - * @param propertyName - * @param value - */ - protected void setBooleanPropertyDefault(String key, boolean value){ - // delegate to new property based config style - moduleConfigProperties.setBooleanPropertyDefault(key, value); - } - /** - * Set a default value for an integer property - * @param propertyName - * @param value - */ - protected void setIntPropertyDefault(String key, int value){ - // delegate to new property based config style - moduleConfigProperties.setIntPropertyDefault(key, value); - } - - /** - * @see org.olat.core.util.event.GenericEventListener#event(org.olat.core.gui.control.Event) - */ - public void event(Event event) { - if (event instanceof PersistedPropertiesChangedEvent) { - PersistedPropertiesChangedEvent persistedPropertiesEvent = (PersistedPropertiesChangedEvent) event; - if (!persistedPropertiesEvent.isEventOnThisNode()) { - // Reload the module configuration from disk, only when event not fired by this node - moduleConfigProperties.loadPropertiesFromFile(); - } - // Call abstract method to initialize after the property changed, even when changes - // were triggered by this node. - initFromChangedProperties(); - } - } -} diff --git a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java index 269a4cee654..f7f61642d63 100644 --- a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java +++ b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java @@ -982,15 +982,17 @@ public class VelocityRenderDecorator implements Closeable { } public Languages getLanguages() { - I18nManager i18nMgr = I18nManager.getInstance(); - Collection<String> enabledKeysSet = I18nModule.getEnabledLanguageKeys(); + I18nManager i18nMgr = CoreSpringFactory.getImpl(I18nManager.class); + I18nModule i18nModule = CoreSpringFactory.getImpl(I18nModule.class); + + Collection<String> enabledKeysSet = i18nModule.getEnabledLanguageKeys(); Map<String, String> langNames = new HashMap<String, String>(); Map<String, String> langTranslators = new HashMap<String, String>(); String[] enabledKeys = ArrayHelper.toArray(enabledKeysSet); String[] names = new String[enabledKeys.length]; for (int i = 0; i < enabledKeys.length; i++) { String key = enabledKeys[i]; - String langName = i18nMgr.getLanguageInEnglish(key, I18nModule.isOverlayEnabled()); + String langName = i18nMgr.getLanguageInEnglish(key, i18nModule.isOverlayEnabled()); langNames.put(key, langName); names[i] = langName; String author = i18nMgr.getLanguageAuthor(key); diff --git a/src/main/java/org/olat/core/gui/translator/PackageTranslator.java b/src/main/java/org/olat/core/gui/translator/PackageTranslator.java index 2558f5c6fd5..e0c7cb79537 100644 --- a/src/main/java/org/olat/core/gui/translator/PackageTranslator.java +++ b/src/main/java/org/olat/core/gui/translator/PackageTranslator.java @@ -32,6 +32,7 @@ import java.io.Writer; import java.util.Locale; import org.apache.log4j.Level; +import org.olat.core.CoreSpringFactory; import org.olat.core.helpers.Settings; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; @@ -51,12 +52,19 @@ public class PackageTranslator implements Translator { private final String packageName; private Locale locale; private int fallBackLevel = 0; + + private final I18nModule i18nModule; + private final I18nManager i18nManager; + + private PackageTranslator(String packageName, Locale locale, boolean fallBack, Translator fallBackTranslator) { this.locale = locale; this.packageName = packageName; this.fallBackTranslator = fallBackTranslator; this.fallBack = fallBack; + i18nManager = CoreSpringFactory.getImpl(I18nManager.class); + i18nModule = CoreSpringFactory.getImpl(I18nModule.class); } public void setFallBack(PackageTranslator fallback){ @@ -198,9 +206,8 @@ public class PackageTranslator implements Translator { */ @Override public String translate(String key, String[] args, boolean fallBackToDefaultLocale) { - I18nManager i18n = I18nManager.getInstance(); - boolean overlayEnabled = I18nModule.isOverlayEnabled(); - String val = i18n.getLocalizedString(packageName, key, args, locale, overlayEnabled, fallBackToDefaultLocale); + boolean overlayEnabled = i18nModule.isOverlayEnabled(); + String val = i18nManager.getLocalizedString(packageName, key, args, locale, overlayEnabled, fallBackToDefaultLocale); if (val == null) { // if not found, try the fallBackTranslator if (fallBackTranslator != null && fallBackLevel < 10) { @@ -209,10 +216,10 @@ public class PackageTranslator implements Translator { } else if (fallBack) { // both fallback and fallbacktranslator does not // make sense; latest translator in chain should // fallback to application fallback. - val = i18n.getLocalizedString(I18nModule.getApplicationFallbackBundle(), key, args, locale, overlayEnabled, fallBackToDefaultLocale); + val = i18nManager.getLocalizedString(i18nModule.getApplicationFallbackBundle(), key, args, locale, overlayEnabled, fallBackToDefaultLocale); if (val == null) { // lastly fall back to brasato framework fallback - val = i18n.getLocalizedString(I18nModule.getCoreFallbackBundle(), key, args, locale, overlayEnabled, fallBackToDefaultLocale); + val = i18nManager.getLocalizedString(i18nModule.getCoreFallbackBundle(), key, args, locale, overlayEnabled, fallBackToDefaultLocale); } } } diff --git a/src/main/java/org/olat/core/logging/LogRealTimeViewerController.java b/src/main/java/org/olat/core/logging/LogRealTimeViewerController.java index 86e13430246..75f3c56297b 100644 --- a/src/main/java/org/olat/core/logging/LogRealTimeViewerController.java +++ b/src/main/java/org/olat/core/logging/LogRealTimeViewerController.java @@ -19,9 +19,13 @@ */ package org.olat.core.logging; +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; +import static org.quartz.impl.matchers.KeyMatcher.keyEquals; + import java.io.IOException; import java.io.StringWriter; -import java.text.ParseException; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -31,6 +35,7 @@ import org.apache.log4j.Logger; import org.apache.log4j.PatternLayout; import org.apache.log4j.WriterAppender; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.scheduler.DummyJob; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.htmlheader.jscss.JSAndCSSComponent; @@ -41,14 +46,16 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.util.Formatter; -import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; +import org.quartz.JobKey; import org.quartz.JobListener; import org.quartz.Scheduler; import org.quartz.SchedulerException; -import org.quartz.jobs.NoOpJob; +import org.quartz.Trigger; +import org.quartz.TriggerKey; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -68,10 +75,13 @@ public class LogRealTimeViewerController extends BasicController implements JobL private Logger log4JLogger; private WriterAppender writerAppender; private StringWriter writer; - private JobDetail jobDetail; - private String jobName; + private JobKey jobKey; + private TriggerKey triggerKey; private Link updateLink, startLink, stopLink; private boolean removeLogNoise; + + @Autowired + private Scheduler scheduler; /** * Constructor for creating a real time log viewer controller @@ -106,21 +116,23 @@ public class LogRealTimeViewerController extends BasicController implements JobL updateLogViewFromWriter(); // Add job to read from the string writer every second try { - jobName = "Log_Displayer_Job_" + this.hashCode(); - jobDetail = new JobDetail(jobName, LOG_DISPLAYER_GROUP, NoOpJob.class); - jobDetail.addJobListener(jobName); - CronTrigger trigger = new CronTrigger(); - trigger.setName(jobName); - trigger.setGroup(LOG_DISPLAYER_GROUP); - trigger.setCronExpression("* * * * * ?"); + jobKey = new JobKey("Log_Displayer_Job_" + this.hashCode(), LOG_DISPLAYER_GROUP); + triggerKey = new TriggerKey("Log_Displayer_Trigger_" + this.hashCode(), LOG_DISPLAYER_GROUP); + + JobDetail jobDetail = newJob(DummyJob.class) + .withIdentity(jobKey) + .build(); + + Trigger trigger = newTrigger() + .withIdentity(triggerKey) + .withSchedule(cronSchedule("* * * * * ?")) + .build(); + // Schedule job now - Scheduler scheduler = (Scheduler) CoreSpringFactory.getBean("schedulerFactoryBean"); - scheduler.addJobListener(this); + scheduler.getListenerManager().addJobListener(this, keyEquals(jobKey)); scheduler.scheduleJob(jobDetail, trigger); - } catch (ParseException e) { + } catch (Exception e) { logError("Can not parse log viewer cron expression", e); - } catch (SchedulerException e) { - logError("Problem when creating log viewer scheduler", e); } // Add one second interval to update the log view every second JSAndCSSComponent jsc = new JSAndCSSComponent("intervall", this.getClass(), 3000); @@ -138,13 +150,12 @@ public class LogRealTimeViewerController extends BasicController implements JobL */ @Override protected void doDispose() { - if (logViewerVC != null) { // don't clean up twice Scheduler scheduler = (Scheduler) CoreSpringFactory.getBean("schedulerFactoryBean"); // remove scheduler job first try { - scheduler.deleteJob(jobName, LOG_DISPLAYER_GROUP); - scheduler.removeJobListener(jobName); + scheduler.deleteJob(jobKey); + scheduler.getListenerManager().removeJobListener(jobKey.getName()); } catch (SchedulerException e) { logError("Can not delete log viewer job", e); } @@ -193,44 +204,51 @@ public class LogRealTimeViewerController extends BasicController implements JobL protected void event(UserRequest ureq, Component source, Event event) { if (source == updateLink) { updateLogViewFromWriter(); + } else if (source == stopLink) { + doStop(); + } else if (source == startLink) { + doStart(); + } + } + + private void doStart() { + // update viewable links + logViewerVC.remove(startLink); + updateLink = LinkFactory.createButtonSmall("logviewer.link.update", logViewerVC, this); + stopLink = LinkFactory.createButtonSmall("logviewer.link.stop", logViewerVC, this); + // re-add appender to logger + log4JLogger.addAppender(writerAppender); + // resume trigger job + try { + Scheduler scheduler = (Scheduler) CoreSpringFactory.getBean("schedulerFactoryBean"); + scheduler.resumeJob(jobKey); + } catch (SchedulerException e) { + logError("Can not resume log viewer job", e); } - if (source == stopLink) { - // update viewable links - logViewerVC.remove(stopLink); - logViewerVC.remove(updateLink); - startLink = LinkFactory.createButtonSmall("logviewer.link.start", logViewerVC, this); - // remove logger appender - log4JLogger.removeAppender(writerAppender); - // pause log update trigger job - try { - Scheduler scheduler = (Scheduler) CoreSpringFactory.getBean("schedulerFactoryBean"); - scheduler.pauseJob(jobName, LOG_DISPLAYER_GROUP); - } catch (SchedulerException e) { - logError("Can not pause log viewer job", e); - } + } + + private void doStop() { + // update viewable links + logViewerVC.remove(stopLink); + logViewerVC.remove(updateLink); + startLink = LinkFactory.createButtonSmall("logviewer.link.start", logViewerVC, this); + // remove logger appender + log4JLogger.removeAppender(writerAppender); + // pause log update trigger job + try { + Scheduler scheduler = (Scheduler) CoreSpringFactory.getBean("schedulerFactoryBean"); + scheduler.pauseJob(jobKey); + } catch (SchedulerException e) { + logError("Can not pause log viewer job", e); } - if (source == startLink) { - // update viewable links - logViewerVC.remove(startLink); - updateLink = LinkFactory.createButtonSmall("logviewer.link.update", logViewerVC, this); - stopLink = LinkFactory.createButtonSmall("logviewer.link.stop", logViewerVC, this); - // re-add appender to logger - log4JLogger.addAppender(writerAppender); - // resume trigger job - try { - Scheduler scheduler = (Scheduler) CoreSpringFactory.getBean("schedulerFactoryBean"); - scheduler.resumeJob(jobName, LOG_DISPLAYER_GROUP); - } catch (SchedulerException e) { - logError("Can not resume log viewer job", e); - } - } } /** * @see org.quartz.JobListener#getName() */ + @Override public String getName() { - return jobName; + return jobKey.getName(); } /** diff --git a/src/main/java/org/olat/core/servlets/OpenOLATServlet.java b/src/main/java/org/olat/core/servlets/OpenOLATServlet.java index 5ead513dede..b78d55c54b0 100644 --- a/src/main/java/org/olat/core/servlets/OpenOLATServlet.java +++ b/src/main/java/org/olat/core/servlets/OpenOLATServlet.java @@ -36,7 +36,6 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.services.taskexecutor.TaskExecutorManager; import org.olat.core.commons.services.webdav.WebDAVDispatcher; -import org.olat.core.configuration.AbstractOLATModule; import org.olat.core.configuration.AbstractSpringModule; import org.olat.core.configuration.PreWarm; import org.olat.core.dispatcher.Dispatcher; @@ -127,8 +126,6 @@ public class OpenOLATServlet extends HttpServlet { //preload extensions ExtManager.getInstance().getExtensions(); - - AbstractOLATModule.printStats(); AbstractSpringModule.printStats(); preWarm(); } 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 e48bab49995..9dfa12cb166 100644 --- a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml +++ b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml @@ -8,7 +8,7 @@ http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> - <context:component-scan base-package="org.olat.core.util.session,org.olat.core.util.vfs.version,org.olat.core.helpers" /> + <context:component-scan base-package="org.olat.core.util.session,org.olat.core.util.vfs.version,org.olat.core.util.i18n" /> <bean id="codeHelper" class="org.olat.core.util.CodeHelper" > <constructor-arg value="${node.id}" /> diff --git a/src/main/java/org/olat/core/util/i18n/I18nDirectoriesVisitor.java b/src/main/java/org/olat/core/util/i18n/I18nDirectoriesVisitor.java index bf1233447f3..54bea141813 100644 --- a/src/main/java/org/olat/core/util/i18n/I18nDirectoriesVisitor.java +++ b/src/main/java/org/olat/core/util/i18n/I18nDirectoriesVisitor.java @@ -36,9 +36,10 @@ import org.olat.core.util.FileVisitor; * @author gnaegi */ class I18nDirectoriesVisitor implements FileVisitor { - private OLog log = Tracing.createLoggerFor(I18nDirectoriesVisitor.class); + private static final OLog log = Tracing.createLoggerFor(I18nDirectoriesVisitor.class); private String basePath; private List<String> bundles = new LinkedList<String>(); + private final List<String> referenceLangKeys; /** * Packag scope constructor @@ -46,8 +47,9 @@ class I18nDirectoriesVisitor implements FileVisitor { * @param basePathConfig The base path to be subtracted from the file name to * get the classname */ - I18nDirectoriesVisitor(String basePathConfig) { + I18nDirectoriesVisitor(String basePathConfig, List<String> referenceLangKeys) { basePath = basePathConfig; + this.referenceLangKeys = referenceLangKeys; } /** @@ -58,7 +60,6 @@ class I18nDirectoriesVisitor implements FileVisitor { if (file.isFile()) { // regular file String toBeChechedkFilName = file.getName(); // match? - List<String> referenceLangKeys = I18nModule.getTransToolReferenceLanguages(); for (String langKey : referenceLangKeys) { String computedFileName = I18nModule.LOCAL_STRINGS_FILE_PREFIX + langKey + I18nModule.LOCAL_STRINGS_FILE_POSTFIX; if (toBeChechedkFilName.equals(computedFileName)) { diff --git a/src/main/java/org/olat/core/util/i18n/I18nManager.java b/src/main/java/org/olat/core/util/i18n/I18nManager.java index 1d96939ef14..2af4f1d209b 100644 --- a/src/main/java/org/olat/core/util/i18n/I18nManager.java +++ b/src/main/java/org/olat/core/util/i18n/I18nManager.java @@ -30,7 +30,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; -import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -71,9 +70,7 @@ import org.olat.core.helpers.Settings; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; -import org.olat.core.logging.StartupException; import org.olat.core.logging.Tracing; -import org.olat.core.manager.BasicManager; import org.olat.core.util.AlwaysEmptyMap; import org.olat.core.util.CodeHelper; import org.olat.core.util.FileUtils; @@ -83,8 +80,8 @@ import org.olat.core.util.StringHelper; import org.olat.core.util.UserSession; import org.olat.core.util.WebappHelper; import org.olat.core.util.session.UserSessionManager; -import org.springframework.core.io.ClassPathResource; -import org.springframework.core.io.Resource; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** @@ -96,12 +93,14 @@ import org.springframework.core.io.Resource; * * @author Felix Jost */ +@Service("I18nManager") +public class I18nManager { -public class I18nManager extends BasicManager { + private static final OLog log = Tracing.createLoggerFor(I18nManager.class); + private static final String BUNDLE_INLINE_TRANSLATION_INTERCEPTOR = "org.olat.core.util.i18n.ui"; private static final String BUNDLE_EXCEPTION = "org.olat.core.gui.exception"; private static I18nManager INSTANCE; - private static final OLog log = Tracing.createLoggerFor(I18nManager.class); public static final String FILE_NOT_FOUND_ERROR_PREFIX = ":::file not found"; public static final String USESS_KEY_I18N_MARK_LOCALIZED_STRINGS = "I18N_MARK_LOCALIZED_STRINGS"; @@ -139,17 +138,16 @@ public class I18nManager extends BasicManager { private ConcurrentMap<String, Properties> cachedBundles = new ConcurrentHashMap<String, Properties>(); private ConcurrentMap<String, String> cachedJSTranslatorData = new ConcurrentHashMap<String, String>(); private ConcurrentMap<String, Deque<String>> referencingBundlesIndex = new ConcurrentHashMap<String, Deque<String>>(); - private static final ConcurrentMap<Locale,String> localeToLocaleKey = new ConcurrentHashMap<>(); private boolean cachingEnabled = true; + + private final I18nModule i18nModule; - private static FilenameFilter i18nFileFilter = new FilenameFilter() { - public boolean accept(File dir, String name) { - // don't add overlayLocales as selectable availableLanguages - // (LocaleStrings_de__VENDOR.properties) - if (name.startsWith(I18nModule.LOCAL_STRINGS_FILE_PREFIX) && name.indexOf("_") != 0 && name.endsWith(I18nModule.LOCAL_STRINGS_FILE_POSTFIX)) { return true; } - return false; - } - }; + @Autowired + public I18nManager(I18nModule i18nModule) { + this.i18nModule = i18nModule; + setCachingEnabled(i18nModule.isCachingEnabled()); + INSTANCE = this; + } /** * @return the manager @@ -217,7 +215,7 @@ public class I18nManager extends BasicManager { // file if (overlayEnabled) { - Locale overlayLocale = I18nModule.getOverlayLocales().get(locale); + Locale overlayLocale = i18nModule.getOverlayLocales().get(locale); if (overlayLocale != null) { properties = getProperties(overlayLocale, bundleName, resolveRecursively, recursionLevel); if (properties != null) { @@ -257,7 +255,7 @@ public class I18nManager extends BasicManager { // 1. Check on variant String variant = locale.getVariant(); if (!variant.equals("")) { - Locale newLoc = I18nModule.getAllLocales().get(locale.getLanguage() + "_" + locale.getCountry()); + Locale newLoc = i18nModule.getAllLocales().get(locale.getLanguage() + "_" + locale.getCountry()); if (newLoc != null) msg = getLocalizedString(bundleName, key, args, newLoc, overlayEnabled, false, fallBackToFallbackLocale, resolveRecursively, recursionLevel); } @@ -265,7 +263,7 @@ public class I18nManager extends BasicManager { // 2. Check on country String country = locale.getCountry(); if (!country.equals("")) { - Locale newLoc = I18nModule.getAllLocales().get(locale.getLanguage()); + Locale newLoc = i18nModule.getAllLocales().get(locale.getLanguage()); if (newLoc != null) msg = getLocalizedString(bundleName, key, args, newLoc, overlayEnabled, false, fallBackToFallbackLocale, resolveRecursively, recursionLevel); } @@ -280,16 +278,16 @@ public class I18nManager extends BasicManager { // no: return null to indicate nothing was found so that callers may // use fallbacks if (fallBackToDefaultLocale) { - return getLocalizedString(bundleName, key, args, I18nModule.getDefaultLocale(), overlayEnabled, false, fallBackToFallbackLocale, + return getLocalizedString(bundleName, key, args, i18nModule.getDefaultLocale(), overlayEnabled, false, fallBackToFallbackLocale, resolveRecursively, recursionLevel); } else { if (fallBackToFallbackLocale) { // fallback to fallback locale - Locale fallbackLocale = I18nModule.getFallbackLocale(); + Locale fallbackLocale = i18nModule.getFallbackLocale(); if (fallbackLocale.equals(locale)) { // finish when when already in fallback locale - if (isLogDebugEnabled()) { - logWarn("Could not find translation for bundle::" + bundleName + " and key::" + key + if (log.isDebug()) { + log.warn("Could not find translation for bundle::" + bundleName + " and key::" + key + " ; not even in default or fallback packages", null); } return null; @@ -374,7 +372,7 @@ public class I18nManager extends BasicManager { * @return List of i18n items */ public List<I18nItem> findExistingI18nItems(Locale targetLocale, String limitToBundleName, boolean includeBundlesChildren) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); List<I18nItem> foundTranslationItems = new LinkedList<I18nItem>(); for (String bundleName : allBundles) { if (limitToBundleName == null || limitToBundleName.equals(bundleName) @@ -411,7 +409,7 @@ public class I18nManager extends BasicManager { */ public List<I18nItem> findMissingI18nItems(Locale referenceLocale, Locale targetLocale, String limitToBundleName, boolean includeBundlesChildren) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); List<I18nItem> foundTranslationItems = new LinkedList<I18nItem>(); for (String bundleName : allBundles) { if (limitToBundleName == null || limitToBundleName.equals(bundleName) @@ -450,7 +448,7 @@ public class I18nManager extends BasicManager { */ public List<I18nItem> findExistingAndMissingI18nItems(Locale referenceLocale, Locale targetLocale, String limitToBundleName, boolean includeBundlesChildren) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); List<I18nItem> foundTranslationItems = new LinkedList<I18nItem>(); for (String bundleName : allBundles) { if (limitToBundleName == null || limitToBundleName.equals(bundleName) @@ -504,7 +502,7 @@ public class I18nManager extends BasicManager { */ public List<I18nItem> findI18nItemsByValueSearch(String searchString, Locale searchLocale, Locale targetLocale, String limitToBundleName, boolean includeBundlesChildren) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); List<I18nItem> foundTranslationItems = new LinkedList<I18nItem>(); searchString = searchString.toLowerCase(); String[] parts = searchString.split("\\*"); @@ -553,7 +551,7 @@ public class I18nManager extends BasicManager { */ public List<I18nItem> findI18nItemsByKeySearch(String searchString, Locale searchLocale, Locale targetLocale, String limitToBundleName, boolean includeBundlesChildren) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); List<I18nItem> foundTranslationItems = new LinkedList<I18nItem>(); searchString = searchString.toLowerCase(); for (String bundleName : allBundles) { @@ -674,17 +672,17 @@ public class I18nManager extends BasicManager { public void saveOrUpdateI18nItem(I18nItem i18nItem, String value) { Properties properties = getPropertiesWithoutResolvingRecursively(i18nItem.getLocale(), i18nItem.getBundleName()); // Add logging block to find bogus save issues - if (isLogDebugEnabled()) { + if (log.isDebug()) { String itemIdent = i18nItem.getLocale() + ":" + buildI18nItemIdentifyer(i18nItem.getBundleName(), i18nItem.getKey()); if (properties.containsKey(i18nItem.getKey())) { if (StringHelper.containsNonWhitespace(value)) { - logDebug("Updating i18n item::" + itemIdent + " with new value::" + value, null); + log.debug("Updating i18n item::" + itemIdent + " with new value::" + value, null); } else { - logDebug("Deleting i18n item::" + itemIdent + " because new value is emty", null); + log.debug("Deleting i18n item::" + itemIdent + " because new value is emty", null); } } else { if (StringHelper.containsNonWhitespace(value)) { - logDebug("Creating i18n item::" + itemIdent + " with new value::" + value, null); + log.debug("Creating i18n item::" + itemIdent + " with new value::" + value, null); } } } @@ -731,7 +729,7 @@ public class I18nManager extends BasicManager { * @return */ public int countI18nItems(Locale locale, String limitToBundleName, boolean includeBundlesChildren) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); int counter = 0; for (String bundleName : allBundles) { if (limitToBundleName == null || limitToBundleName.equals(bundleName) @@ -755,7 +753,7 @@ public class I18nManager extends BasicManager { * @return */ public int countBundles(String limitToBundleName, boolean includeBundlesChildren) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); if (limitToBundleName == null) { return allBundles.size(); } else if (!includeBundlesChildren) { return (allBundles.contains(limitToBundleName) ? 1 : 0); } @@ -799,7 +797,7 @@ public class I18nManager extends BasicManager { // Try to resolve all keys within this properties and add to // cache if (resolveRecursively) { - resolvePropertiesInternalKeys(locale, bundleName, props, I18nModule.isOverlayEnabled(), recursionLevel); + resolvePropertiesInternalKeys(locale, bundleName, props, i18nModule.isOverlayEnabled(), recursionLevel); cachedBundles.put(key, props); } if (locale == null) { @@ -819,14 +817,14 @@ public class I18nManager extends BasicManager { // // 1) Try to load the bundle from a configured source path // This is also used to load the overlay properties - File baseDir = I18nModule.getPropertyFilesBaseDir(locale, bundleName); + File baseDir = i18nModule.getPropertyFilesBaseDir(locale, bundleName); if (baseDir != null) { File f = getPropertiesFile(locale, bundleName, baseDir); // if file exists load properties from file, otherwise // proceed with 2) if (f.exists()) { is = new FileInputStream(f); - if (logDebug) logDebug("loading LocalStrings from file::" + f.getAbsolutePath(), null); + if (logDebug) log.debug("loading LocalStrings from file::" + f.getAbsolutePath(), null); } } // @@ -838,7 +836,7 @@ public class I18nManager extends BasicManager { String relPath = bundleName.replace('.', '/') + "/" + I18N_DIRNAME + "/" + fileName; ClassLoader classLoader = this.getClass().getClassLoader(); is = classLoader.getResourceAsStream(relPath); - if (logDebug && is != null) logDebug("loading LocalStrings from classpath relpath::" + relPath, null); + if (logDebug && is != null) log.debug("loading LocalStrings from classpath relpath::" + relPath, null); } // Now load the properties from resource (file, classpath or // langpacks) @@ -974,10 +972,10 @@ public class I18nManager extends BasicManager { */ public void saveOrUpdateProperties(Properties properties, Locale locale, String bundleName) { String key = calcPropertiesFileKey(locale, bundleName); - if (isLogDebugEnabled()) logDebug("saveOrUpdateProperties for key::" + key, null); + if (log.isDebug()) log.debug("saveOrUpdateProperties for key::" + key, null); // 1) Save file to disk - File baseDir = I18nModule.getPropertyFilesBaseDir(locale, bundleName); + File baseDir = i18nModule.getPropertyFilesBaseDir(locale, bundleName); if (baseDir == null) { throw new AssertException("Can not save or update properties file for bundle::" + bundleName + " and language::" + locale.toString() + " - no base directory found, probably loaded from jar!"); } File propertiesFile = getPropertiesFile(locale, bundleName, baseDir); @@ -999,11 +997,11 @@ public class I18nManager extends BasicManager { try { if (fileStream != null) fileStream.close(); } catch (IOException e) { - logError("Could not close stream after save or update to file::" + propertiesFile.getAbsolutePath(), e); + log.error("Could not close stream after save or update to file::" + propertiesFile.getAbsolutePath(), e); } } // 2) Check if bundle was already in list of known bundles, add it - List<String> knownBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> knownBundles = i18nModule.getBundleNamesContainingI18nFiles(); if (!knownBundles.contains(bundleName)) { knownBundles.add(bundleName); Collections.sort(knownBundles); @@ -1038,7 +1036,7 @@ public class I18nManager extends BasicManager { */ public void deleteProperties(Locale locale, String bundleName) { String key = calcPropertiesFileKey(locale, bundleName); - if (isLogDebugEnabled()) logDebug("deleteProperties for key::" + key, null); + if (log.isDebug()) log.debug("deleteProperties for key::" + key, null); if (locale != null) { // metadata files are not in cache // 1) Remove from cache first @@ -1050,7 +1048,7 @@ public class I18nManager extends BasicManager { } } // 2) Remove from filesystem - File baseDir = I18nModule.getPropertyFilesBaseDir(locale, bundleName); + File baseDir = i18nModule.getPropertyFilesBaseDir(locale, bundleName); if (baseDir == null) { if (baseDir == null) { throw new AssertException("Can not delete properties file for bundle::" + bundleName + " and language::" + locale.toString() + " - no base directory found, probably loaded from jar!"); } @@ -1060,8 +1058,8 @@ public class I18nManager extends BasicManager { // 3) Check if for this bundle any other language file exists, if // not remove // the bundle from the list of translatable bundles - List<String> knownBundles = I18nModule.getBundleNamesContainingI18nFiles(); - Set<String> knownLangs = I18nModule.getAvailableLanguageKeys(); + List<String> knownBundles = i18nModule.getBundleNamesContainingI18nFiles(); + Set<String> knownLangs = i18nModule.getAvailableLanguageKeys(); boolean foundOther = false; for (String lang : knownLangs) { f = getPropertiesFile(getLocaleOrDefault(lang), bundleName, baseDir); @@ -1102,13 +1100,13 @@ public class I18nManager extends BasicManager { StringBuilder data = new StringBuilder(); // we build an js object with key-value pairs data.append("var transData = {"); - Locale referenceLocale = I18nModule.getFallbackLocale(); + Locale referenceLocale = i18nModule.getFallbackLocale(); Properties properties = getPropertiesWithoutResolvingRecursively(referenceLocale, bundleName); Set<Object> keys = properties.keySet(); boolean addComma = false; for (Object keyObject : keys) { String key = (String) keyObject; - String value = getLocalizedString(bundleName, key, null, locale, I18nModule.isOverlayEnabled(), true); + String value = getLocalizedString(bundleName, key, null, locale, i18nModule.isOverlayEnabled(), true); if (value == null) { // use bundlename:key as value in case the key can't be // translated @@ -1133,12 +1131,12 @@ public class I18nManager extends BasicManager { public JSONObject getJSONTranslatorData(Locale locale, String bundleName) { JSONObject array = new JSONObject(); - Locale referenceLocale = I18nModule.getFallbackLocale(); + Locale referenceLocale = i18nModule.getFallbackLocale(); Properties properties = getPropertiesWithoutResolvingRecursively(referenceLocale, bundleName); Set<Object> keys = properties.keySet(); for (Object keyObject : keys) { String key = (String) keyObject; - String value = getLocalizedString(bundleName, key, null, locale, I18nModule.isOverlayEnabled(), true); + String value = getLocalizedString(bundleName, key, null, locale, i18nModule.isOverlayEnabled(), true); if (value == null) { // use bundlename:key as value in case the key can't be // translated @@ -1151,7 +1149,7 @@ public class I18nManager extends BasicManager { try { array.put(key, value); } catch (JSONException e) { - logError("", e); + log.error("", e); } } return array; @@ -1165,7 +1163,7 @@ public class I18nManager extends BasicManager { * @return */ public Long getLastModifiedDate(Locale locale, String bundleName) { - File baseDir = I18nModule.getPropertyFilesBaseDir(locale, bundleName); + File baseDir = i18nModule.getPropertyFilesBaseDir(locale, bundleName); if (baseDir != null) { File propertyFile = getPropertiesFile(locale, bundleName, baseDir); return (propertyFile.lastModified()); @@ -1188,9 +1186,11 @@ public class I18nManager extends BasicManager { * method, or the default locale if the language was not found */ public Locale getLocaleOrDefault(String localeKey) { - if (localeKey == null || !I18nModule.getAvailableLanguageKeys().contains(localeKey)) { return I18nModule.getDefaultLocale(); } - Locale loc = I18nModule.getAllLocales().get(localeKey); - if (loc == null) loc = I18nModule.getDefaultLocale(); + if (localeKey == null || !i18nModule.getAvailableLanguageKeys().contains(localeKey)) { + return i18nModule.getDefaultLocale(); + } + Locale loc = i18nModule.getAllLocales().get(localeKey); + if (loc == null) loc = i18nModule.getDefaultLocale(); return loc; } @@ -1206,8 +1206,10 @@ public class I18nManager extends BasicManager { * method, or if no language was found */ public Locale getLocaleOrNull(String localeKey) { - if (localeKey == null || (!I18nModule.getAvailableLanguageKeys().contains(localeKey) && !I18nModule.getOverlayLanguageKeys().contains(localeKey))) { return null; } - Locale loc = I18nModule.getAllLocales().get(localeKey); + if (localeKey == null || (!i18nModule.getAvailableLanguageKeys().contains(localeKey) && !i18nModule.getOverlayLanguageKeys().contains(localeKey))) { + return null; + } + Locale loc = i18nModule.getAllLocales().get(localeKey); return loc; } @@ -1223,9 +1225,9 @@ public class I18nManager extends BasicManager { public String getLanguageTranslated(String languageKey, boolean overlayEnabled) { // Load it from package without fallback String translated = null; - Locale locale = I18nModule.getAllLocales().get(languageKey); + Locale locale = i18nModule.getAllLocales().get(languageKey); if(locale != null) { - translated = getLocalizedString(I18nModule.getCoreFallbackBundle(), "this.language.translated", null, locale, overlayEnabled, false, false, false, 0); + translated = getLocalizedString(i18nModule.getCoreFallbackBundle(), "this.language.translated", null, locale, overlayEnabled, false, false, false, 0); } if (translated == null) { // Use the english version as callback @@ -1242,12 +1244,12 @@ public class I18nManager extends BasicManager { * @return */ public Map<String, String> getEnabledLanguagesTranslated() { - Collection<String> enabledLangs = I18nModule.getEnabledLanguageKeys(); + Collection<String> enabledLangs = i18nModule.getEnabledLanguageKeys(); Map<String, String> translatedLangs = new HashMap<String, String>(11); for (String langKey : enabledLangs) { String translated = cachedLangTranslated.get(langKey); if(translated == null) { - String newTranslated = getLanguageTranslated(langKey, I18nModule.isOverlayEnabled()); + String newTranslated = getLanguageTranslated(langKey, i18nModule.isOverlayEnabled()); translated = cachedLangTranslated.putIfAbsent(langKey, newTranslated); if(translated == null) { translated = newTranslated; @@ -1268,7 +1270,7 @@ public class I18nManager extends BasicManager { */ public String getLanguageInEnglish(String languageKey, boolean overlayEnabled) { // Load it from package without fallback - String inEnglish = getLocalizedString(I18nModule.getCoreFallbackBundle(), "this.language.in.english", null, I18nModule + String inEnglish = getLocalizedString(i18nModule.getCoreFallbackBundle(), "this.language.in.english", null, i18nModule .getAllLocales().get(languageKey), overlayEnabled, false, false, false, 0); if (inEnglish == null) { // use key as fallback @@ -1287,7 +1289,7 @@ public class I18nManager extends BasicManager { */ public String getLanguageAuthor(String languageKey) { // Load it from package without fallback - String authors = getLocalizedString(I18nModule.getCoreFallbackBundle(), "this.language.translator.names", null, I18nModule + String authors = getLocalizedString(i18nModule.getCoreFallbackBundle(), "this.language.translator.names", null, i18nModule .getAllLocales().get(languageKey), false, false, false, false, 0); if (authors == null) { return "-"; } return authors; @@ -1322,21 +1324,18 @@ public class I18nManager extends BasicManager { public static void attachI18nInfoToThread(HttpServletRequest hreq) { UserSession usess = CoreSpringFactory.getImpl(UserSessionManager.class).getUserSession(hreq); if (threadLocalLocale == null) { - I18nManager.getInstance().logError("can't attach i18n info to thread: threadLocalLocale is null", null); + log.error("can't attach i18n info to thread: threadLocalLocale is null", null); } else { if (threadLocalLocale.getThreadLocale() != null) { - I18nManager.getInstance().logWarn( - "try to attach i18n info to thread, but threadLocalLocale is not null - a thread forgot to remove it!", new Exception("attachI18nInfoToThread")); + log.warn("try to attach i18n info to thread, but threadLocalLocale is not null - a thread forgot to remove it!", new Exception("attachI18nInfoToThread")); } threadLocalLocale.setThredLocale(usess.getLocale()); } if (threadLocalIsMarkLocalizedStringsEnabled == null) { - I18nManager.getInstance().logError("can't attach i18n info to thread: threadLocalIsMarkLocalizedStringsEnabled is null", null); + log.error("can't attach i18n info to thread: threadLocalIsMarkLocalizedStringsEnabled is null", null); } else { if (threadLocalIsMarkLocalizedStringsEnabled.isMarkLocalizedStringsEnabled() != null) { - I18nManager.getInstance().logWarn( - "try to attach i18n info to thread, but threadLocalIsMarkLocalizedStringsEnabled is not null - a thread forgot to remove it!", - null); + log.warn("try to attach i18n info to thread, but threadLocalIsMarkLocalizedStringsEnabled is not null - a thread forgot to remove it!", null); } Boolean isMarkLocalizedStringsEnabled = (Boolean) usess.getEntry(USESS_KEY_I18N_MARK_LOCALIZED_STRINGS); if (isMarkLocalizedStringsEnabled != null) { @@ -1347,7 +1346,7 @@ public class I18nManager extends BasicManager { public static void updateLocaleInfoToThread(UserSession usess) { if (threadLocalLocale == null) { - I18nManager.getInstance().logError("can't attach i18n info to thread: threadLocalLocale is null", null); + log.error("can't attach i18n info to thread: threadLocalLocale is null", null); } else { threadLocalLocale.setThredLocale(usess.getLocale()); } @@ -1377,7 +1376,7 @@ public class I18nManager extends BasicManager { Locale locale = threadLocalLocale.getThreadLocale(); if (locale != null) return threadLocalLocale.getThreadLocale(); } - return I18nModule.getDefaultLocale(); + return i18nModule.getDefaultLocale(); } /** @@ -1431,7 +1430,7 @@ public class I18nManager extends BasicManager { try { return (Integer.parseInt(bundlePrioValue.trim())); } catch (NumberFormatException e) { - logWarn("Can not parse metadata priority for bundle::" + bundleName, e); + log.warn("Can not parse metadata priority for bundle::" + bundleName, e); } } // 2) Not found, try with parent bundle @@ -1459,7 +1458,7 @@ public class I18nManager extends BasicManager { try { keyPriority = Integer.parseInt(keyPriorityValue.trim()); } catch (NumberFormatException e) { - logWarn("Can not parse metadata priority for key::" + bundleName + ":" + key, e); + log.warn("Can not parse metadata priority for key::" + bundleName + ":" + key, e); } } return keyPriority; @@ -1596,7 +1595,7 @@ public class I18nManager extends BasicManager { cachedJSTranslatorData = new AlwaysEmptyMap<String, String>(); referencingBundlesIndex = new AlwaysEmptyMap<String, Deque<String>>(); } - this.cachingEnabled = useCache; + cachingEnabled = useCache; } /** @@ -1604,74 +1603,7 @@ public class I18nManager extends BasicManager { * filesystem */ public boolean isCachingEnabled() { - return this.cachingEnabled; - } - - /** - * Helper method to create a locale from a given locale key ('de', 'de_CH', - * 'de_CH_ZH') - * - * @param localeKey - * @return the locale or NULL if no locale could be generated from this string - */ - Locale createLocale(String localeKey) { - Locale aloc = null; - // de - // de_CH - // de_CH_zueri - String[] parts = localeKey.split("_"); - switch (parts.length) { - case 1: - aloc = new Locale(parts[0]); - break; - case 2: - aloc = new Locale(parts[0], parts[1]); - break; - case 3: - String lastPart = parts[2]; - // Add all remaining parts to variant, variant can contain - // underscores according to Locale spec - for (int i = 3; i < parts.length; i++) { - String part = parts[i]; - lastPart = lastPart + "_" + part; - } - aloc = new Locale(parts[0], parts[1], lastPart); - break; - default: - return null; - } - // Test if the locale has been constructed correctly. E.g. when the - // language part is not existing in the ISO chart, the locale can - // convert to something else. - // E.g. he_HE_HE will convert automatically to iw_HE_HE - if (aloc.toString().equals(localeKey)) { - return aloc; - } else { - return null; - } - } - - /** - * Create a local that represents the overlay locale for the given locale - * - * @param locale The original locale - * @return The overlay locale - */ - Locale createOverlay(Locale locale) { - String lang = locale.getLanguage(); - String country = (locale.getCountry() == null ? "" : locale.getCountry()); - String variant = createOverlayKeyForLanguage(locale.getVariant() == null ? "" : locale.getVariant()); - Locale overlay = new Locale(lang, country, variant); - return overlay; - } - - /** - * Add the overlay postfix to the given language key - * @param langKey - * @return - */ - String createOverlayKeyForLanguage(String langKey) { - return langKey + "__" + I18nModule.getOverlayName(); + return cachingEnabled; } /** @@ -1686,49 +1618,10 @@ public class I18nManager extends BasicManager { * @return */ public String buildI18nFilename(Locale locale) { - String langKey = getLocaleKey(locale); + String langKey = i18nModule.getLocaleKey(locale); return I18nModule.LOCAL_STRINGS_FILE_PREFIX + langKey + I18nModule.LOCAL_STRINGS_FILE_POSTFIX; } - /** - * Calculate the locale key that identifies the given locale. Adds support for - * the overlay mechanism. - * - * @param locale - * @return - */ - public String getLocaleKey(Locale locale) { - String key = localeToLocaleKey.get(locale); - if(key == null) { - String langKey = locale.getLanguage(); - String country = locale.getCountry(); - // Only add country when available - in case of an overlay country is - // set to - // an empty value - if (StringHelper.containsNonWhitespace(country)) { - langKey = langKey + "_" + country; - } - String variant = locale.getVariant(); - // Only add the _ separator if the variant contains something in - // addition to - // the overlay, otherways use the __ only - if (StringHelper.containsNonWhitespace(variant)) { - if (variant.startsWith("__" + I18nModule.getOverlayName())) { - langKey += variant; - } else { - langKey = langKey + "_" + variant; - } - } - - key = localeToLocaleKey.putIfAbsent(locale, langKey); - if(key == null) { - key = langKey; - } - - } - return key; - } - /** * Calculate the language key from the given overlay locale without the locale * (the original language before adding the overlay postfix) @@ -1737,11 +1630,11 @@ public class I18nManager extends BasicManager { * @return The original language key or NULL if not found */ public String createOrigianlLocaleKeyForOverlay(Locale overlay) { - Map<Locale,Locale> overlaysLooup = I18nModule.getOverlayLocales(); + Map<Locale,Locale> overlaysLooup = i18nModule.getOverlayLocales(); Set<Map.Entry<Locale, Locale>> entries = overlaysLooup.entrySet(); for (Map.Entry<Locale, Locale> entry : entries) { - if (getLocaleKey(entry.getValue()).equals(getLocaleKey(overlay))) { - return getLocaleKey(entry.getKey()); + if (i18nModule.getLocaleKey(entry.getValue()).equals(i18nModule.getLocaleKey(overlay))) { + return i18nModule.getLocaleKey(entry.getKey()); } } return null; @@ -1758,79 +1651,6 @@ public class I18nManager extends BasicManager { return bundleName + ":" + key; } - /** - * Search in all packages on the source patch for packages that contain an - * _i18n directory that can be used to store olatcore localization files - * - * @return set of bundles that contain olatcore i18n compatible localization - * files - */ - List<String> searchForBundleNamesContainingI18nFiles() { - List<String> foundBundles; - // 1) First search on normal source path of application - String srcPath = null; - File applicationDir = I18nModule.getTransToolApplicationLanguagesSrcDir(); - if (applicationDir != null) { - srcPath = applicationDir.getAbsolutePath(); - } else { - // Fall back to compiled classes - srcPath = WebappHelper.getBuildOutputFolderRoot(); - } - if(StringHelper.containsNonWhitespace(srcPath)) { - I18nDirectoriesVisitor srcVisitor = new I18nDirectoriesVisitor(srcPath); - FileUtils.visitRecursively(new File(srcPath), srcVisitor); - foundBundles = srcVisitor.getBundlesContainingI18nFiles(); - // 3) For jUnit tests, add also the I18n test dir - if (Settings.isJUnitTest()) { - Resource testres = new ClassPathResource("olat.local.properties"); - String jUnitSrcPath = null; - try { - jUnitSrcPath = testres.getFile().getAbsolutePath(); - } catch (IOException e) { - throw new StartupException("Could not find classpath resource for: test-classes/olat.local.property ", e); - } - - - I18nDirectoriesVisitor juniSrcVisitor = new I18nDirectoriesVisitor(jUnitSrcPath); - FileUtils.visitRecursively(new File(jUnitSrcPath), juniSrcVisitor); - foundBundles.addAll(juniSrcVisitor.getBundlesContainingI18nFiles()); - } - // Sort alphabetically - Collections.sort(foundBundles); - } else { - foundBundles = new ArrayList<String>(); - } - return foundBundles; - } - - /** - * Search for available languages in the given directory. The translation - * files must start with 'LocalStrings_' and end with '.properties'. - * Everything in between is considered a language key. - * <p> - * If the directory contains jar files, those files are opened and searched - * for languages files as well. In this case, the algorythm only looks for - * translation files that are in the org/olat/core/_i18n package - * - * @param i18nDir - * @return set of language keys the system will find translations for - */ - Set<String> searchForAvailableLanguages(File i18nDir) { - Set<String> foundLanguages = new TreeSet<String>(); - i18nDir = new File(i18nDir.getAbsolutePath()+"/org/olat/_i18n"); - if (i18nDir.exists()) { - // First check for locale files - String[] langFiles = i18nDir.list(i18nFileFilter); - for (String langFileName : langFiles) { - String lang = langFileName.substring(I18nModule.LOCAL_STRINGS_FILE_PREFIX.length(), langFileName.lastIndexOf(".")); - foundLanguages.add(lang); - if (isLogDebugEnabled()) logDebug("Adding lang::" + lang + " from filename::" + langFileName + " from dir::" - + i18nDir.getAbsolutePath(), null); - } - } - return foundLanguages; - } - /** * Searches within a jar file for available languages. * @@ -1852,15 +1672,14 @@ public class I18nManager extends BasicManager { // check for executables if (checkForExecutables && (jarEntryName.endsWith("java") || jarEntryName.endsWith("class"))) { return new TreeSet<String>(); } // search for core util in jar - if (jarEntryName.indexOf(I18nModule.getCoreFallbackBundle().replace(".", "/") + "/" + I18N_DIRNAME) != -1) { + if (jarEntryName.indexOf(i18nModule.getCoreFallbackBundle().replace(".", "/") + "/" + I18N_DIRNAME) != -1) { // don't add overlayLocales as selectable // availableLanguages if (jarEntryName.indexOf("__") == -1 && jarEntryName.indexOf(I18nModule.LOCAL_STRINGS_FILE_PREFIX) != -1) { String lang = jarEntryName.substring(jarEntryName.indexOf(I18nModule.LOCAL_STRINGS_FILE_PREFIX) + I18nModule.LOCAL_STRINGS_FILE_PREFIX.length(), jarEntryName.lastIndexOf(".")); foundLanguages.add(lang); - if (isLogDebugEnabled()) logDebug("Adding lang::" + lang + " from filename::" + jarEntryName + " in jar::" + jar.getName(), - null); + if (log.isDebug()) log.debug("Adding lang::" + lang + " from filename::" + jarEntryName + " in jar::" + jar.getName(), null); } } } @@ -1881,7 +1700,7 @@ public class I18nManager extends BasicManager { * @param toCopyI18nKeys */ public void copyLanguagesFromJar(File jarFile, Collection<String> toCopyI18nKeys) { - if (!I18nModule.isTransToolEnabled()) { + if (!i18nModule.isTransToolEnabled()) { throw new AssertException("Programming error - can only copy i18n files from a language pack to the source when in translation mode"); } JarFile jar = null; @@ -1896,9 +1715,9 @@ public class I18nManager extends BasicManager { if (jarEntryName.endsWith(I18N_DIRNAME + "/" + I18nModule.LOCAL_STRINGS_FILE_PREFIX + i18nKey + I18nModule.LOCAL_STRINGS_FILE_POSTFIX)) { File targetBaseDir; if (i18nKey.equals("de") || i18nKey.equals("en")) { - targetBaseDir = I18nModule.getTransToolApplicationLanguagesSrcDir(); + targetBaseDir = i18nModule.getTransToolApplicationLanguagesSrcDir(); } else { - targetBaseDir = I18nModule.getTransToolApplicationOptLanguagesSrcDir(); + targetBaseDir = i18nModule.getTransToolApplicationOptLanguagesSrcDir(); } // Copy file File targetFile = new File(targetBaseDir, jarEntryName); @@ -1948,18 +1767,18 @@ public class I18nManager extends BasicManager { String relPath = "/" + bundleName + "/" + I18N_DIRNAME + "/" + fileName; // Load file from path File f = new File(sourceDir, relPath); - if (f.exists() || I18nModule.isTransToolEnabled()) { return f; } + if (f.exists() || i18nModule.isTransToolEnabled()) { return f; } return f; } public boolean createNewLanguage(String localeKey, String languageInEnglish, String languageTranslated, String authors) { - if (!I18nModule.isTransToolEnabled()) { throw new AssertException( + if (!i18nModule.isTransToolEnabled()) { throw new AssertException( "Can not create a new language when the translation tool is not enabled and the transtool source pathes are not configured! Check your olat.properties files"); } - if (I18nModule.getAvailableLanguageKeys().contains(localeKey)) { return false; } + if (i18nModule.getAvailableLanguageKeys().contains(localeKey)) { return false; } // Create new property file in the brasato bundle and re-initialize // everything - String coreFallbackBundle = I18nModule.getApplicationFallbackBundle(); - File transToolCoreLanguagesDir = I18nModule.getTransToolApplicationOptLanguagesSrcDir(); + String coreFallbackBundle = i18nModule.getApplicationFallbackBundle(); + File transToolCoreLanguagesDir = i18nModule.getTransToolApplicationOptLanguagesSrcDir(); String i18nDirRelPath = "/" + coreFallbackBundle.replace(".", "/") + "/" + I18nManager.I18N_DIRNAME; File transToolCoreLanguagesDir_I18n = new File(transToolCoreLanguagesDir, i18nDirRelPath); File newPropertiesFile = new File(transToolCoreLanguagesDir_I18n, I18nModule.LOCAL_STRINGS_FILE_PREFIX + localeKey @@ -1987,12 +1806,12 @@ public class I18nManager extends BasicManager { newProperties.store(fileStream, null); fileStream.flush(); // Now set new language as enabled to allow user to translate the language. - Collection<String> enabledLangKeys = I18nModule.getEnabledLanguageKeys(); + Collection<String> enabledLangKeys = i18nModule.getEnabledLanguageKeys(); enabledLangKeys.add(localeKey); // Reinitialize languages with new language - I18nModule.reInitializeAndFlushCache(); + i18nModule.reInitializeAndFlushCache(); // Now add new language as new language (will re-initialize everything a second time) - I18nModule.setEnabledLanguageKeys(enabledLangKeys); + i18nModule.setEnabledLanguageKeys(enabledLangKeys); return true; } catch (FileNotFoundException e) { @@ -2004,7 +1823,7 @@ public class I18nManager extends BasicManager { try { if (fileStream != null) fileStream.close(); } catch (IOException e) { - logError("Could not close stream after creating new language file::" + newPropertiesFile.getAbsolutePath(), e); + log.error("Could not close stream after creating new language file::" + newPropertiesFile.getAbsolutePath(), e); } } } @@ -2017,22 +1836,22 @@ public class I18nManager extends BasicManager { * logging */ public void deleteLanguage(String deleteLangKey, boolean reallyDeleteIt) { - Locale deleteLoclae = I18nModule.getAllLocales().get(deleteLangKey); + Locale deleteLoclae = i18nModule.getAllLocales().get(deleteLangKey); // copy bundles list to prevent concurrent modification exception List<String> bundlesCopy = new ArrayList<String>(); - bundlesCopy.addAll(I18nModule.getBundleNamesContainingI18nFiles()); + bundlesCopy.addAll(i18nModule.getBundleNamesContainingI18nFiles()); for (String bundleName : bundlesCopy) { if (reallyDeleteIt) { deleteProperties(deleteLoclae, bundleName); - logDebug("Deleted bundle::" + bundleName + " and lang::" + deleteLangKey, null); + log.debug("Deleted bundle::" + bundleName + " and lang::" + deleteLangKey, null); } else { // just log - logInfo("Dry-run-delete of bundle::" + bundleName + " and lang::" + deleteLangKey, null); + log.info("Dry-run-delete of bundle::" + bundleName + " and lang::" + deleteLangKey, null); } } // Now reinitialize everything if (reallyDeleteIt) { - I18nModule.reInitializeAndFlushCache(); + i18nModule.reInitializeAndFlushCache(); } } @@ -2065,7 +1884,7 @@ public class I18nManager extends BasicManager { for (String langKey : languageKeys) { Locale locale = getLocaleOrNull(langKey); // Add all bundles in the current language - for (String bundleName : I18nModule.getBundleNamesContainingI18nFiles()) { + for (String bundleName : i18nModule.getBundleNamesContainingI18nFiles()) { Properties propertyFile = getPropertiesWithoutResolvingRecursively(locale, bundleName); String entryFileName = bundleName.replace(".", "/") + "/" + I18N_DIRNAME + "/" + buildI18nFilename(locale); // Create jar entry for this path, name and last modified @@ -2074,21 +1893,21 @@ public class I18nManager extends BasicManager { // Write properties to jar file out.putNextEntry(jarEntry); propertyFile.store(out, null); - if (isLogDebugEnabled()) { - logDebug("Adding file::" + entryFileName + " + to jar", null); + if (log.isDebug()) { + log.debug("Adding file::" + entryFileName + " + to jar", null); } } } - logDebug("Finished writing jar file::" + file.getAbsolutePath(), null); + log.debug("Finished writing jar file::" + file.getAbsolutePath(), null); } catch (Exception e) { - logError("Could not write jar file", e); + log.error("Could not write jar file", e); return null; } finally { try { out.close(); stream.close(); } catch (IOException e) { - logError("Could not close stream of jar file", e); + log.error("Could not close stream of jar file", e); return null; } } @@ -2099,12 +1918,6 @@ public class I18nManager extends BasicManager { * Private helper methods *************************/ - /** - * [used by spring] - */ - private I18nManager() { - INSTANCE = this; - } /** * Helper method to create a key that uniquely identifies a property file @@ -2119,7 +1932,7 @@ public class I18nManager extends BasicManager { if (locale == null) { return bundleName + ":" + METADATA_KEY; } else { - return bundleName + ":" + getLocaleKey(locale); + return bundleName + ":" + i18nModule.getLocaleKey(locale); } } diff --git a/src/main/java/org/olat/core/util/i18n/I18nModule.java b/src/main/java/org/olat/core/util/i18n/I18nModule.java index e893d052069..3957c24f119 100644 --- a/src/main/java/org/olat/core/util/i18n/I18nModule.java +++ b/src/main/java/org/olat/core/util/i18n/I18nModule.java @@ -21,29 +21,40 @@ package org.olat.core.util.i18n; import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Set; +import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; -import org.olat.core.configuration.AbstractOLATModule; -import org.olat.core.configuration.Destroyable; -import org.olat.core.configuration.PersistedProperties; +import org.olat.core.configuration.AbstractSpringModule; import org.olat.core.gui.control.Event; import org.olat.core.helpers.Settings; import org.olat.core.id.OLATResourceable; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; +import org.olat.core.logging.StartupException; import org.olat.core.logging.Tracing; import org.olat.core.util.ArrayHelper; +import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.WebappHelper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.resource.OresHelper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.ClassPathResource; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Service; /** * <h3>Description:</h3> The I18nModule initializes the localization @@ -54,8 +65,8 @@ import org.olat.core.util.resource.OresHelper; * * @author Florian Gnaegi, frentix GmbH, http://www.frentix.com */ - -public class I18nModule extends AbstractOLATModule implements Destroyable { +@Service("i18nModule") +public class I18nModule extends AbstractSpringModule { private static final OLog log = Tracing.createLoggerFor(I18nModule.class); @@ -81,71 +92,75 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { private static final String CONFIG_LANGUAGES_ENABLED = "enabledLanguages"; private static final String CONFIG_LANGUAGES_ENABLED_ALL = "all"; private static final String CONFIG_DEFAULT_LANG = "defaultLanguage"; - private static final String CONFIG_FALLBACK_LANG = "fallbackLanguage"; - private static final String CONFIG_LANGUAGES_REFERENCES = "transToolReferenceLanguages"; - private static final String CONFIG_OVERLAY = "overlayName"; - private static final String CONFIG_OVERLAY_ENABLED = "overlayEnabled"; - private static final String CONFIG_CACHING_ENABLED = "cachingEnabled"; - private static final String CONFIG_LANGUAGE_LIST_ENABLED = "dropDownListEnabled"; - private static final String CONFIG_APPLICATION_FALLBACK_BUNDLE = "applicationFallbackBundle"; - private static final String CONFIG_CORE_FALLBACK_BUNDLE = "coreFallbackBundle"; - private static final String CONFIG_TRANS_TOOL_ENABLED = "transToolEnabled"; - private static final String CONFIG_TRANS_TOOL_APPLICATION_SRC_PATH = "transToolApplicationSrcPath"; - private static final String CONFIG_TRANS_TOOL_APPLICATION_OPT_SRC_PATH = "transToolApplicationOptSrcPath"; + + @Value("${enabledLanguages}") + private String enabledLanguages; + @Value("${defaultlang:en}") + private String defaultLanguage; + @Value("${fallbacklang:en}") + private String fallbackLanguage; // General configuration - private static String overlayName; - private static boolean overlayEnabled; - private static boolean cachingEnabled; - private static boolean languageDropDownListEnabled; + private final String overlayName = "customizing"; + private final boolean overlayEnabled = true; + + @Value("${localization.cache:true}") + private boolean cachingEnabled; + private boolean languageDropDownListEnabled = true; // Lists of the available and enabled languages and locales - private static final Set<String> availableLanguages = new HashSet<String>(); - private static final Set<String> translatableLanguages = new HashSet<String>(); - private static final Map<String, File> translatableLangAppBaseDirLookup = new HashMap<String, File>(); + private final Set<String> availableLanguages = new HashSet<>(); + private final Set<String> translatableLanguages = new HashSet<>(); + private final Map<String, File> translatableLangAppBaseDirLookup = new HashMap<>(); // keys: lang string, values: locale - private static final Map<String, Locale> allLocales = new HashMap<String, Locale>(); + private static final Map<String, Locale> allLocales = new HashMap<>(); // keys: orig Locale, values: overlay Locale - private static final Map<Locale, Locale> overlayLocales = new HashMap<Locale, Locale>(); - private static final Set<String> overlayLanguagesKeys = new HashSet<String>(); - private static final Set<String> enabledLanguagesKeys = new HashSet<String>(); + private final Map<Locale, Locale> overlayLocales = new HashMap<>(); + private final Set<String> overlayLanguagesKeys = new HashSet<>(); + private final Set<String> enabledLanguagesKeys = new HashSet<>(); // The default locale (used on loginscreen and as first fallback) and the // fallback (used as second fallback) private static Locale defaultLocale; - private static Locale fallbackLocale; + private Locale fallbackLocale; // The available bundles - private static List<String> bundleNames = null; // sorted alphabetically - private static String coreFallbackBundle = null; - private static String applicationFallbackBundle = null; + private List<String> bundleNames; // sorted alphabetically + + private final String coreFallbackBundle = "org.olat.core"; + private final String applicationFallbackBundle = "org.olat"; + // Translation tool related configuration - private static final List<String> transToolReferenceLanguages = new ArrayList<String>(); - private static File transToolApplicationLanguagesDir = null; - private static File transToolApplicationOptLanguagesSrcDir = null; - private static boolean transToolEnabled = false; + private final List<String> transToolReferenceLanguages = new ArrayList<>(); + + @Value("${i18n.application.src.dir}") + private String transToolApplicationSrcPath; + private File transToolApplicationLanguagesDir; + @Value("${i18n.application.opt.src.dir}") + private String transToolApplicationOptSrcPath; + private File transToolApplicationOptLanguagesSrcDir; + @Value("${is.translation.server:disabled}") + private String transToolEnabled; + private final String referenceLanguages = "en,de"; + + private final ConcurrentMap<Locale,String> localeToLocaleKey = new ConcurrentHashMap<>(); + // When running on a cluster, we need an event when flushing the i18n cache to do this on all machines private static OLATResourceable I18N_CACHE_FLUSHED_EVENT_CHANNEL; // Reference to instance for static methods - private static I18nModule INSTANCE; - private CoordinatorManager coordinatorManager; + private final CoordinatorManager coordinatorManager; - /** - * [spring] - */ - private I18nModule(CoordinatorManager coordinatorManager) { - super(); + @Autowired + public I18nModule(CoordinatorManager coordinatorManager, WebappHelper webappHelper) { + super(coordinatorManager); + assert webappHelper != null; this.coordinatorManager = coordinatorManager; - //if (INSTANCE != null && !Settings.isJUnitTest()) { throw new OLATRuntimeException("Tried to construct I18nModule, but module was already loaded!", null); } - INSTANCE = this; } @Override protected void initDefaultProperties() { // First read default configuration from the module config and then set // is as default in the properties - String defaultLanguageKey = getStringConfigParameter(CONFIG_DEFAULT_LANG, "en", false); - setStringPropertyDefault(CONFIG_DEFAULT_LANG, defaultLanguageKey); - String enabledLanguagesConfig = getStringConfigParameter(CONFIG_LANGUAGES_ENABLED, CONFIG_LANGUAGES_ENABLED_ALL, false); - setStringPropertyDefault(CONFIG_LANGUAGES_ENABLED, enabledLanguagesConfig); + setStringPropertyDefault(CONFIG_DEFAULT_LANG, defaultLanguage); + setStringPropertyDefault(CONFIG_LANGUAGES_ENABLED, enabledLanguages); } @Override @@ -185,8 +200,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { // can't be changed at runtime and are project specific // Set configured reference languages - String referenceLanguagesConfig = getStringConfigParameter(CONFIG_LANGUAGES_REFERENCES, "en", false); - String[] referenceAndFallbackKeys = referenceLanguagesConfig.split(","); + String[] referenceAndFallbackKeys = referenceLanguages.split(","); // remove whitespace and check for douplicates for (int i = 0; i < referenceAndFallbackKeys.length; i++) { String langKey = referenceAndFallbackKeys[i]; @@ -194,61 +208,39 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { transToolReferenceLanguages.add(langKey); } - // Language overlay: used to override a language with some custom wording - overlayName = getStringConfigParameter(CONFIG_OVERLAY, "customizing", false); - overlayEnabled = getBooleanConfigParameter(CONFIG_OVERLAY_ENABLED, true); - // Set caching configuration of local strings - cachingEnabled = getBooleanConfigParameter(CONFIG_CACHING_ENABLED, true); - logInfo("Localization caching set to: " + cachingEnabled, null); + log.info("Localization caching set to: " + cachingEnabled, null); // Set how the list of available availableLanguages will be shown // (drop-down[true] or in one line[false]) - languageDropDownListEnabled = getBooleanConfigParameter(CONFIG_LANGUAGE_LIST_ENABLED, true); - logInfo("Configuring 'dropDownListEnabled = " + languageDropDownListEnabled + "'", null); + log.info("Configuring 'dropDownListEnabled = " + languageDropDownListEnabled + "'", null); // Set additional source path to load languages from and to store // languages when using the translation tool. Init the values even when transtool is not configured for development mode - String appSrc = getStringConfigParameter(CONFIG_TRANS_TOOL_APPLICATION_SRC_PATH, "", false); - if (StringHelper.containsNonWhitespace(appSrc)) { - appSrc = appSrc.trim(); - transToolApplicationLanguagesDir = new File(appSrc); + if (StringHelper.containsNonWhitespace(transToolApplicationSrcPath)) { + transToolApplicationSrcPath = transToolApplicationSrcPath.trim(); + transToolApplicationLanguagesDir = new File(transToolApplicationSrcPath); } - String optAppSrc = getStringConfigParameter(CONFIG_TRANS_TOOL_APPLICATION_OPT_SRC_PATH, "", false); - if (StringHelper.containsNonWhitespace(optAppSrc)) { - optAppSrc = optAppSrc.trim(); - transToolApplicationOptLanguagesSrcDir = new File(optAppSrc); + if (StringHelper.containsNonWhitespace(transToolApplicationOptSrcPath)) { + transToolApplicationOptSrcPath = transToolApplicationOptSrcPath.trim(); + transToolApplicationOptLanguagesSrcDir = new File(transToolApplicationOptSrcPath); } // Enable or disable translation tool and i18n source directories - transToolEnabled = getBooleanConfigParameter(CONFIG_TRANS_TOOL_ENABLED, false); - if (transToolEnabled) { - // + boolean translationToolEnabled = "enabled".equals(transToolEnabled); + if (translationToolEnabled) { if (transToolApplicationLanguagesDir != null && transToolApplicationOptLanguagesSrcDir != null) { // Check if configuration is valid, otherwise disable translation server mode } else { // disable, pathes not configured properly - transToolEnabled = false; - } - // error handling, notify on console about disabled translation tool - if (!transToolEnabled) { - logWarn( - "Translation configuration enabled but invalid translation tool source path defined. Disabling translation tool. Fix your configuration in spring config of i18Module", - null); - logWarn(" transToolApplicationSrcPath::" + appSrc + " transToolApplicationI18nSrcPath::" + optAppSrc, null); + translationToolEnabled = false; + log.warn("Translation configuration enabled but invalid translation tool source path defined. Disabling translation tool. Fix your configuration in spring config of i18Module", null); + log.warn(" transToolApplicationSrcPath::" + transToolApplicationSrcPath + " transToolApplicationI18nSrcPath::" + transToolApplicationOptSrcPath, null); } } - I18nManager i18nMgr = I18nManager.getInstance(); - i18nMgr.setCachingEnabled(cachingEnabled); - // Get all bundles that contain i18n files initBundleNames(); - // Set the base bundles for olatcore and the application. When a key is - // not found, the manager looks it up in the application base and the in - // the core base bundle before it gives up - applicationFallbackBundle = getStringConfigParameter(CONFIG_APPLICATION_FALLBACK_BUNDLE, "org.olat", false); - coreFallbackBundle = getStringConfigParameter(CONFIG_CORE_FALLBACK_BUNDLE, "org.olat.core", false); // Search for all available languages on the build path and initialize them doInitAvailableLanguages(); @@ -257,15 +249,13 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { // the persisted system configuration doInitLanguageConfiguration(); - logInfo("Configured i18nModule with default language::" + getDefaultLocale().toString() + " and the reference languages '" - + referenceLanguagesConfig + "' and the following enabled languages: " + enabledLanguagesKeys.toString(), null); + log.info("Configured i18nModule with default language::" + getDefaultLocale().toString() + " and the reference languages '" + + referenceLanguages + "' and the following enabled languages: " + enabledLanguagesKeys.toString(), null); } - /** - * - * @see org.olat.core.configuration.Destroyable#destroy() - */ + @Override public void destroy() { + super.destroy(); // remove from event channel if (I18N_CACHE_FLUSHED_EVENT_CHANNEL != null) { coordinatorManager.getCoordinator().getEventBus().deregisterFor(this, I18N_CACHE_FLUSHED_EVENT_CHANNEL); @@ -277,21 +267,20 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * Initialize the available languages and load all locales */ private void doInitAvailableLanguages() { - I18nManager i18nMgr = I18nManager.getInstance(); // Search all availableLanguages files that exist String i18nDirRelPath = File.separator + applicationFallbackBundle.replace(".", File.separator) + File.separator + I18nManager.I18N_DIRNAME; if (transToolApplicationLanguagesDir != null) { File coreSrcI18nDir = new File(transToolApplicationLanguagesDir, i18nDirRelPath); if (coreSrcI18nDir.exists()) { - for (String languageCode : i18nMgr.searchForAvailableLanguages(transToolApplicationLanguagesDir)) { + for (String languageCode : searchForAvailableLanguages(transToolApplicationLanguagesDir)) { if (availableLanguages.contains(languageCode)) { String path = ""; if (transToolApplicationOptLanguagesSrcDir != null) path = transToolApplicationOptLanguagesSrcDir.getAbsolutePath(); - logDebug("Skipping duplicate or previously loaded language::" + languageCode + " found in " +path , null); + log.debug("Skipping duplicate or previously loaded language::" + languageCode + " found in " +path , null); continue; } - logDebug("Detected translatable language " + languageCode + " in " + transToolApplicationLanguagesDir.getAbsolutePath(), null); + log.debug("Detected translatable language " + languageCode + " in " + transToolApplicationLanguagesDir.getAbsolutePath(), null); availableLanguages.add(languageCode); translatableLanguages.add(languageCode); translatableLangAppBaseDirLookup.put(languageCode, transToolApplicationLanguagesDir); @@ -300,12 +289,12 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { } // 2) Add languages from the translation tool source path if (isTransToolEnabled()) { - for (String languageCode : i18nMgr.searchForAvailableLanguages(transToolApplicationOptLanguagesSrcDir)) { + for (String languageCode : searchForAvailableLanguages(transToolApplicationOptLanguagesSrcDir)) { if (availableLanguages.contains(languageCode)) { - logDebug("Skipping duplicate or previously loaded language::" + languageCode + " found in " + transToolApplicationOptLanguagesSrcDir.getAbsolutePath(), null); + log.debug("Skipping duplicate or previously loaded language::" + languageCode + " found in " + transToolApplicationOptLanguagesSrcDir.getAbsolutePath(), null); continue; } - logDebug("Detected translatable language " + languageCode + " in " + transToolApplicationOptLanguagesSrcDir.getAbsolutePath(), null); + log.debug("Detected translatable language " + languageCode + " in " + transToolApplicationOptLanguagesSrcDir.getAbsolutePath(), null); availableLanguages.add(languageCode); translatableLanguages.add(languageCode); translatableLangAppBaseDirLookup.put(languageCode, transToolApplicationOptLanguagesSrcDir); @@ -316,12 +305,12 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { if(StringHelper.containsNonWhitespace(folderRoot)) { //started from WEB-INF/classes File libDir = new File(WebappHelper.getBuildOutputFolderRoot()); - for (String languageCode : i18nMgr.searchForAvailableLanguages(libDir)) { + for (String languageCode : searchForAvailableLanguages(libDir)) { if (availableLanguages.contains(languageCode)) { - logDebug("Skipping duplicate or previously loaded language::" + languageCode + " found in " + libDir.getAbsolutePath(), null); + log.debug("Skipping duplicate or previously loaded language::" + languageCode + " found in " + libDir.getAbsolutePath(), null); continue; } - logDebug("Detected non-translatable language " + languageCode + " in " + libDir.getAbsolutePath(), null); + log.debug("Detected non-translatable language " + languageCode + " in " + libDir.getAbsolutePath(), null); availableLanguages.add(languageCode); // don't add to translatable languages nor to source lookup maps - those // langs are read only @@ -332,23 +321,23 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { String[] enabledLanguages = enabledLanguagesConfig.split(","); for (String languageCode : enabledLanguages) { if (availableLanguages.contains(languageCode)) { - logWarn("Skipping duplicate or previously loaded language::" + languageCode + " found in " + log.warn("Skipping duplicate or previously loaded language::" + languageCode + " found in " + LANG_PACKS_DIRECTORY.getAbsolutePath(), null); continue; } - logDebug("Force non-translatable language " + languageCode + " defined from enabledLanguages.", null); + log.debug("Force non-translatable language " + languageCode + " defined from enabledLanguages.", null); availableLanguages.add(languageCode); } } // 4) Add languages from the customizing lang packs - for (String languageCode : i18nMgr.searchForAvailableLanguages(LANG_PACKS_DIRECTORY)) { + for (String languageCode : searchForAvailableLanguages(LANG_PACKS_DIRECTORY)) { if (availableLanguages.contains(languageCode)) { - logWarn("Skipping duplicate or previously loaded language::" + languageCode + " found in " + log.warn("Skipping duplicate or previously loaded language::" + languageCode + " found in " + LANG_PACKS_DIRECTORY.getAbsolutePath(), null); continue; } - logDebug("Detected non-translatable language " + languageCode + " in " + LANG_PACKS_DIRECTORY.getAbsolutePath(), null); + log.debug("Detected non-translatable language " + languageCode + " in " + LANG_PACKS_DIRECTORY.getAbsolutePath(), null); availableLanguages.add(languageCode); // don't add to translatable languages nor to source lookup maps - those // langs are read only @@ -363,9 +352,9 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { // // Build list of all locales and the overlay locales if available for (String langKey : availableLanguages) { - Locale locale = i18nMgr.createLocale(langKey); + Locale locale = createLocale(langKey); if (locale == null) { - logError("Could not create locale for lang::" + langKey + ", skipping language and remove it from list of available languages", + log.error("Could not create locale for lang::" + langKey + ", skipping language and remove it from list of available languages", null); toRemoveLangs.add(langKey); continue; @@ -377,12 +366,12 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { // // Add overlay if (isOverlayEnabled()) { - Locale overlayLocale = i18nMgr.createOverlay(locale); + Locale overlayLocale = createOverlay(locale); // Calculate the overlay key as used as reference. Note, this is not the // same as overlayLocale.toString(), this would add '_' for each element - String overlayKey = i18nMgr.getLocaleKey(overlayLocale); + String overlayKey = getLocaleKey(overlayLocale); if (overlayLocale == null) { - logError("Could not create overlay locale for lang::" + langKey + " (" + overlayKey + "), skipping language", null); + log.error("Could not create overlay locale for lang::" + langKey + " (" + overlayKey + "), skipping language", null); continue; } // Don't add same overlay twice @@ -402,38 +391,180 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { translatableLangAppBaseDirLookup.remove(langKey); } // Set fallback locale from configuration - String fallbackLangKey = getStringConfigParameter(CONFIG_FALLBACK_LANG, Locale.ENGLISH.toString(), false); // fallbackLangKey can't be null because EN is guaranteed to be available, // see above - fallbackLocale = allLocales.get(fallbackLangKey); + fallbackLocale = allLocales.get(fallbackLanguage); // Check if translation tool reference languages are available if (isTransToolEnabled() && transToolReferenceLanguages.size() == 0) { - logError("Did not find the fallback language configuration in the configuration, using language::en instead", null); + log.error("Did not find the fallback language configuration in the configuration, using language::en instead", null); } else { for (String langKey : transToolReferenceLanguages) { if (!allLocales.containsKey(langKey)) { - logError("The configured fallback language::" + langKey + " does not exist. Using language::en instead", null); + log.error("The configured fallback language::" + langKey + " does not exist. Using language::en instead", null); + } + } + } + } + + /** + * Search for available languages in the given directory. The translation + * files must start with 'LocalStrings_' and end with '.properties'. + * Everything in between is considered a language key. + * <p> + * If the directory contains jar files, those files are opened and searched + * for languages files as well. In this case, the algorythm only looks for + * translation files that are in the org/olat/core/_i18n package + * + * @param i18nDir + * @return set of language keys the system will find translations for + */ + Set<String> searchForAvailableLanguages(File i18nDir) { + Set<String> foundLanguages = new TreeSet<String>(); + i18nDir = new File(i18nDir.getAbsolutePath()+"/org/olat/_i18n"); + if (i18nDir.exists()) { + // First check for locale files + String[] langFiles = i18nDir.list(i18nFileFilter); + for (String langFileName : langFiles) { + String lang = langFileName.substring(I18nModule.LOCAL_STRINGS_FILE_PREFIX.length(), langFileName.lastIndexOf(".")); + foundLanguages.add(lang); + log.debug("Adding lang::" + lang + " from filename::" + langFileName + " from dir::" + i18nDir.getAbsolutePath(), null); + } + } + return foundLanguages; + } + + /** + * Create a local that represents the overlay locale for the given locale + * + * @param locale The original locale + * @return The overlay locale + */ + Locale createOverlay(Locale locale) { + String lang = locale.getLanguage(); + String country = (locale.getCountry() == null ? "" : locale.getCountry()); + String variant = createOverlayKeyForLanguage(locale.getVariant() == null ? "" : locale.getVariant()); + Locale overlay = new Locale(lang, country, variant); + return overlay; + } + + /** + * Add the overlay postfix to the given language key + * @param langKey + * @return + */ + String createOverlayKeyForLanguage(String langKey) { + return langKey + "__" + getOverlayName(); + } + + /** + * Helper method to create a locale from a given locale key ('de', 'de_CH', + * 'de_CH_ZH') + * + * @param localeKey + * @return the locale or NULL if no locale could be generated from this string + */ + Locale createLocale(String localeKey) { + Locale aloc = null; + // de + // de_CH + // de_CH_zueri + String[] parts = localeKey.split("_"); + switch (parts.length) { + case 1: + aloc = new Locale(parts[0]); + break; + case 2: + aloc = new Locale(parts[0], parts[1]); + break; + case 3: + String lastPart = parts[2]; + // Add all remaining parts to variant, variant can contain + // underscores according to Locale spec + for (int i = 3; i < parts.length; i++) { + String part = parts[i]; + lastPart = lastPart + "_" + part; + } + aloc = new Locale(parts[0], parts[1], lastPart); + break; + default: + return null; + } + // Test if the locale has been constructed correctly. E.g. when the + // language part is not existing in the ISO chart, the locale can + // convert to something else. + // E.g. he_HE_HE will convert automatically to iw_HE_HE + if (aloc.toString().equals(localeKey)) { + return aloc; + } else { + return null; + } + } + + /** + * Calculate the locale key that identifies the given locale. Adds support for + * the overlay mechanism. + * + * @param locale + * @return + */ + public String getLocaleKey(Locale locale) { + String key = localeToLocaleKey.get(locale); + if(key == null) { + String langKey = locale.getLanguage(); + String country = locale.getCountry(); + // Only add country when available - in case of an overlay country is + // set to + // an empty value + if (StringHelper.containsNonWhitespace(country)) { + langKey = langKey + "_" + country; + } + String variant = locale.getVariant(); + // Only add the _ separator if the variant contains something in + // addition to + // the overlay, otherways use the __ only + if (StringHelper.containsNonWhitespace(variant)) { + if (variant.startsWith("__" + getOverlayName())) { + langKey += variant; + } else { + langKey = langKey + "_" + variant; } } + + key = localeToLocaleKey.putIfAbsent(locale, langKey); + if(key == null) { + key = langKey; + } + } + return key; } + + private static FilenameFilter i18nFileFilter = new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + // don't add overlayLocales as selectable availableLanguages + // (LocaleStrings_de__VENDOR.properties) + if (name.startsWith(I18nModule.LOCAL_STRINGS_FILE_PREFIX) && name.indexOf("_") != 0 && name.endsWith(I18nModule.LOCAL_STRINGS_FILE_POSTFIX)) { return true; } + return false; + } + }; private void doInitLanguageConfiguration() { // Set the default language String defaultLanguageKey = getStringPropertyValue(CONFIG_DEFAULT_LANG, false); Locale newDefaultLocale = allLocales.get(defaultLanguageKey); if (newDefaultLocale == null) { - logError("Could not set default locale to value::" + defaultLanguageKey + " - no such language found. Using fallback locale instead", + log.error("Could not set default locale to value::" + defaultLanguageKey + " - no such language found. Using fallback locale instead", null); newDefaultLocale = allLocales.get(transToolReferenceLanguages.get(0)); } else if (!availableLanguages.contains(newDefaultLocale.toString())) { - logError("Did not find the default language::" + newDefaultLocale.toString() + log.error("Did not find the default language::" + newDefaultLocale.toString() + " in the available availableLanguages files! Using fallback locale instead", null); newDefaultLocale = allLocales.get(transToolReferenceLanguages.get(0)); } defaultLocale = newDefaultLocale; - logInfo("Setting default locale::" + newDefaultLocale.toString(), null); + log.info("Setting default locale::" + newDefaultLocale.toString(), null); // Enabling configured languages (a subset of the available languages) String[] enabledLanguages; @@ -450,12 +581,12 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { enabledLanguagesKeys.add(langKey); } // else skip this entry } - logInfo("Enabling languages::" + enabledLanguagesConfig, null); + log.info("Enabling languages::" + enabledLanguagesConfig, null); // Make sure that the configured default language is enabled if (!enabledLanguagesKeys.contains(getDefaultLocale().toString())) { String defLang = getDefaultLocale().toString(); enabledLanguagesKeys.add(defLang); - logWarn("The configured default language::" + defLang + " is not in the list of enabled languages. Enabling language::" + defLang, + log.warn("The configured default language::" + defLang + " is not in the list of enabled languages. Enabling language::" + defLang, null); } } @@ -476,11 +607,11 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * * @param newDefaultLocale */ - public static void setDefaultLocale(Locale newDefaultLocale) { + public void setDefaultLocale(Locale newDefaultLocale) { if (defaultLocale == null || !defaultLocale.toString().equals(newDefaultLocale.toString())) { // Just set the string property here. This will fire an event and // call the method initFromChangedProperties() - INSTANCE.setStringProperty(CONFIG_DEFAULT_LANG, newDefaultLocale.toString(), true); + setStringProperty(CONFIG_DEFAULT_LANG, newDefaultLocale.toString(), true); } } @@ -488,7 +619,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * @return The locale that is used when a string is not found in any other * locale */ - public static Locale getFallbackLocale() { + public Locale getFallbackLocale() { return fallbackLocale; } @@ -499,7 +630,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { /** * @return true: caching is enabled; false: caching is disabled */ - static boolean isCachingEnabled() { + public boolean isCachingEnabled() { return cachingEnabled; } @@ -509,7 +640,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * the enabled languages to get the list of languages that are enabled * to be used */ - public static Set<String> getAvailableLanguageKeys() { + public Set<String> getAvailableLanguageKeys() { return availableLanguages; } @@ -518,7 +649,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * tool. Theses are the languages that are available in the source * form. Languages embedded in jars can't be edited. */ - public static Set<String> getTranslatableLanguageKeys() { + public Set<String> getTranslatableLanguageKeys() { return translatableLanguages; } @@ -526,7 +657,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * @return the map (with dummy value) of all languages including * overlayLocales (as a String) */ - public static Map<String, Locale> getAllLocales() { + public Map<String, Locale> getAllLocales() { return allLocales; } @@ -534,7 +665,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * @return The lookup map of the overlay locales. Key: the locale; value: the * corresponding overlay */ - public static Map<Locale, Locale> getOverlayLocales() { + public Map<Locale, Locale> getOverlayLocales() { return overlayLocales; } @@ -543,7 +674,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * de_CH, en, ...). those are the languages which can be chosen by the * user */ - public static Collection<String> getEnabledLanguageKeys() { + public Collection<String> getEnabledLanguageKeys() { synchronized (enabledLanguagesKeys) { return new HashSet<String>(enabledLanguagesKeys); } @@ -552,8 +683,8 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { /** * @return as keys: a List of Strings with the supported languages overlay keys */ - public static Set<String> getOverlayLanguageKeys() { - return overlayLanguagesKeys; + public Set<String> getOverlayLanguageKeys() { + return overlayLanguagesKeys; } @@ -563,7 +694,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * * @param newEnabledLangKeys */ - public static void setEnabledLanguageKeys(Collection<String> newEnabledLangKeys) { + public void setEnabledLanguageKeys(Collection<String> newEnabledLangKeys) { if (!newEnabledLangKeys.equals(enabledLanguagesKeys)) { String newEnabledConfig = ""; for (String enabledKey : newEnabledLangKeys) { @@ -576,7 +707,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { // Just set the string property here. This will fire an event and // call the method initFromChangedProperties() - INSTANCE.setStringProperty(CONFIG_LANGUAGES_ENABLED, newEnabledConfig.toString(), true); + setStringProperty(CONFIG_LANGUAGES_ENABLED, newEnabledConfig.toString(), true); // No need to reinitialize i18n Module, setting the new property will already do this } } @@ -584,14 +715,14 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { /** * @return A list of language keys that are reference and fallback languages */ - public static List<String> getTransToolReferenceLanguages() { + public List<String> getTransToolReferenceLanguages() { return transToolReferenceLanguages; } /** * @return All bundles that contain a _i18n directory with translation files */ - public static List<String> getBundleNamesContainingI18nFiles() { + public List<String> getBundleNamesContainingI18nFiles() { return bundleNames; } @@ -599,7 +730,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * @return The bundle name that contains the commonly used translations from * the olatcore framework */ - public static String getCoreFallbackBundle() { + public String getCoreFallbackBundle() { return coreFallbackBundle; } @@ -607,7 +738,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * @return The bundle name that contains the commonly used translations from * the application */ - public static String getApplicationFallbackBundle() { + public String getApplicationFallbackBundle() { return applicationFallbackBundle; } @@ -617,7 +748,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * * @return true: enabled; false: disabled */ - public static boolean isOverlayEnabled() { + public boolean isOverlayEnabled() { return (overlayEnabled && StringHelper.containsNonWhitespace(overlayName)); } @@ -627,7 +758,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * * @return name of the overlay */ - public static String getOverlayName() { + public String getOverlayName() { if (isOverlayEnabled()) return overlayName; else return null; } @@ -636,17 +767,61 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * @return true: enable the translation tool; false: disable the translation * tool */ - public static boolean isTransToolEnabled() { - return transToolEnabled; + public boolean isTransToolEnabled() { + return "enabled".equals(transToolEnabled); } /** * search for bundles that contain i18n files. Searches in the org.olat.core * package */ - static void initBundleNames() { - I18nManager i18nMgr = I18nManager.getInstance(); - bundleNames = i18nMgr.searchForBundleNamesContainingI18nFiles(); + void initBundleNames() { + bundleNames = searchForBundleNamesContainingI18nFiles(); + } + + /** + * Search in all packages on the source patch for packages that contain an + * _i18n directory that can be used to store olatcore localization files + * + * @return set of bundles that contain olatcore i18n compatible localization + * files + */ + List<String> searchForBundleNamesContainingI18nFiles() { + List<String> foundBundles; + // 1) First search on normal source path of application + String srcPath = null; + File applicationDir = getTransToolApplicationLanguagesSrcDir(); + if (applicationDir != null) { + srcPath = applicationDir.getAbsolutePath(); + } else { + // Fall back to compiled classes + srcPath = WebappHelper.getBuildOutputFolderRoot(); + } + if(StringHelper.containsNonWhitespace(srcPath)) { + I18nDirectoriesVisitor srcVisitor = new I18nDirectoriesVisitor(srcPath, getTransToolReferenceLanguages()); + FileUtils.visitRecursively(new File(srcPath), srcVisitor); + foundBundles = srcVisitor.getBundlesContainingI18nFiles(); + // 3) For jUnit tests, add also the I18n test dir + if (Settings.isJUnitTest()) { + Resource testres = new ClassPathResource("olat.local.properties"); + String jUnitSrcPath = null; + try { + jUnitSrcPath = testres.getFile().getAbsolutePath(); + } catch (IOException e) { + throw new StartupException("Could not find classpath resource for: test-classes/olat.local.property ", e); + } + + + I18nDirectoriesVisitor juniSrcVisitor = new I18nDirectoriesVisitor(jUnitSrcPath, getTransToolReferenceLanguages()); + FileUtils.visitRecursively(new File(jUnitSrcPath), juniSrcVisitor); + foundBundles.addAll(juniSrcVisitor.getBundlesContainingI18nFiles()); + } + // Sort alphabetically + Collections.sort(foundBundles); + } else { + foundBundles = new ArrayList<String>(); + } + return foundBundles; } /** @@ -657,7 +832,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * @param bundleName * @return The file or null if the language is not read-write configured */ - public static File getPropertyFilesBaseDir(Locale locale, String bundleName) { + public File getPropertyFilesBaseDir(Locale locale, String bundleName) { // 1) Special case, junit test files are not in olat source path // We don't want translator to translate those files! if (Settings.isJUnitTest() && bundleName.startsWith("org.olat.core.util.i18n.junittestdata") ) { @@ -670,21 +845,19 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { return transToolApplicationLanguagesDir; } // 3) Locale files from core or application - String localeKey = I18nManager.getInstance().getLocaleKey(locale); + String localeKey = getLocaleKey(locale); return translatableLangAppBaseDirLookup.get(localeKey); } /** * Reinitialize the entire i18n system */ - public static void reInitializeAndFlushCache() { - synchronized (enabledLanguagesKeys) { - // Re-initialize all local caches - doReInitialize(); - // Notify other nodes to reInitialize the caches as well - I18nReInitializeCachesEvent changedConfigEvent = new I18nReInitializeCachesEvent(); - CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(changedConfigEvent, I18N_CACHE_FLUSHED_EVENT_CHANNEL); - } + public void reInitializeAndFlushCache() { + // Re-initialize all local caches + doReInitialize(); + // Notify other nodes to reInitialize the caches as well + I18nReInitializeCachesEvent changedConfigEvent = new I18nReInitializeCachesEvent(); + CoordinatorManager.getInstance().getCoordinator().getEventBus().fireEventToListenersOf(changedConfigEvent, I18N_CACHE_FLUSHED_EVENT_CHANNEL); } /** @@ -692,7 +865,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * is decoupled from the reInitialize() to prevent endless firing of events * in the cluster. */ - private static void doReInitialize() { + private void doReInitialize() { synchronized (enabledLanguagesKeys) { // Clear everything availableLanguages.clear(); @@ -705,13 +878,14 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { transToolReferenceLanguages.clear(); I18nManager.getInstance().clearCaches(); // Now rebuild everything from scratch - INSTANCE.doInit(); + doInit(); } } /** * @see org.olat.core.configuration.AbstractOLATModule#event(org.olat.core.gui.control.Event) */ + @Override public void event(Event event) { // First delegate to AbstractOLATModule super.event(event); @@ -731,7 +905,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * * @return */ - public static File getTransToolApplicationLanguagesSrcDir() { + public File getTransToolApplicationLanguagesSrcDir() { return transToolApplicationLanguagesDir; } @@ -741,13 +915,7 @@ public class I18nModule extends AbstractOLATModule implements Destroyable { * * @return */ - public static File getTransToolApplicationOptLanguagesSrcDir() { + public File getTransToolApplicationOptLanguagesSrcDir() { return transToolApplicationOptLanguagesSrcDir; } - - @Override - public void setPersistedProperties(PersistedProperties persistedProperties) { - this.moduleConfigProperties = persistedProperties; - } - } diff --git a/src/main/java/org/olat/core/util/i18n/_spring/i18nCorecontext.xml b/src/main/java/org/olat/core/util/i18n/_spring/i18nCorecontext.xml deleted file mode 100644 index 0083981366b..00000000000 --- a/src/main/java/org/olat/core/util/i18n/_spring/i18nCorecontext.xml +++ /dev/null @@ -1,117 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<beans xmlns="http://www.springframework.org/schema/beans" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xmlns:context="http://www.springframework.org/schema/context" - xsi:schemaLocation=" - http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans.xsd"> - -<bean id="I18nManager" class="org.olat.core.util.i18n.I18nManager" /> - -<bean id="i18nModule" class="org.olat.core.util.i18n.I18nModule" destroy-method="destroy" depends-on="I18nManager, org.olat.core.util.WebappHelper"> - <constructor-arg ref="coordinatorManager" /> - <property name="persistedProperties"> - <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy"> - <constructor-arg index="0" ref="coordinatorManager"/> - <constructor-arg index="1" ref="i18nModule" /> - </bean> - </property> - -</bean> - - <bean id="triggerI18nModuleInit" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> - <property name="targetObject" ref="i18nModule" /> - <property name="targetMethod" value="init" /> - <property name="arguments"> - <value> - <!-- - Default setting for enabled languages: comma separated list of lang keys. Set to 'all' to - enable all languages that can be found in the source code - Example: - <enabledLanguages>en,de,fr,it,es,da,cs,el,ru,pl,zh_CN,zh_TW,lt,fa,pt_PT,pt_BR,tr,hu,sq,in,ar,rm,af,iw,vi,mn</enabledLanguages> - or - <enabledLanguages>all</enabledLanguages> - NOTE: this default setting will be overridden by the values configured in - olatdata/system/configuration/org.olat.core.util.i18n.I18nModule.properties - --> - enabledLanguages=${enabledLanguages} - <!-- - Default setting for the system default locale to use: language of login page - NOTE: this default setting will be overridden by the values configured in - olatdata/system/configuration/org.olat.core.util.i18n.I18nModule.properties - --> - defaultLanguage=${defaultlang} - <!-- - The language that is used as a fallback in case the system does not find a key in the - users language nor in the default language. Note that in this language - all keys must exist! Since developers only add the 'de' and 'en' keys it is strongly recommended - that you don't set it to any other value that this. If unsure, use the default 'de'. - --> - fallbackLanguage=${fallbacklang} - <!-- - The application fallback bundle contains the common words used everywhere in your web application. - During translation, when a translation is not found, the system checks if the fallback bundle contains - the translation. Here you find things you often use in your application. - If unsure, leave default value. - --> - applicationFallbackBundle=org.olat - <!-- - The olatcore fallback bundle contains the common words used everywhere in the core framework. - During translation, when a translation is not found, the system checks if the fallback bundle contains - the translation. Here you find things like 'yes', 'no' etc. Normally you don't change this. - In the fallback chain the system first checks for the application fallback and as last option it then - checks for the olatcore fallback - If unsure, leave default value. - --> - coreFallbackBundle=org.olat.core - <!-- - Name of the overlay that should be used to customize the language. E.g. if your overlay - files are labelled "de__customizing" you must set "customizing" here. The overlay properties files are - stored in olatdata/customizing/lang/overlay/* - If unsure, leave default value. - --> - overlayName=customizing - <!-- - Enable or disable the customizing overlay feature. If set to true it is not possible to customize - the interface text elements. If unsure, set to true. - --> - overlayEnabled=true - <!-- - Whether to cache i18n properties files (recommended in production). - If unsure, set to true. - --> - cachingEnabled=${localization.cache} - <!-- - Define language selection list style on login page. true=drop-box, false=in one line. - If unsure, leave default value. - --> - dropDownListEnabled=true - <!-- - Enable the translation tool. This is only enabled on the official OLAT translation server - at translation.olat.org. If you want to setup your own translation server you must specify - the following path in order to work properly: - i18n.application.src.dir : path to the source of your application code, typically olat3/webapp/WEB-INF/src - i18n.application.opt.src.dir : path to the source of your application i18n files, typically olat3_i18n/src/main/java - i18n.core.src.dir : path to the source of the framework core code, typically olatcore/src/main/java - i18n.core.opt.src.dir : path to the source of the framework i18n files, typically olatcore_i18n/src/main/java - In most cases you can set this value to disabled and ignore the application and core src path. - You can still use the translation tool to customize the languages using the overlay feature - If unsure, set to disabled in the olat.local.properties. - - Values are disabled / enabled, this is also used to enable the translation status job. - see your olat.properties or olat.local.properties for the value set. - --> - transToolEnabled=${is.translation.server} - transToolApplicationSrcPath=${i18n.application.src.dir} - transToolApplicationOptSrcPath=${i18n.application.opt.src.dir} - <!-- - The languages that serve as a base in the translation tool. Note that in those languages - all keys must exist! Since developers only add the 'de' and 'en' keys it is strongly recommended - that you don't set it to any other value that this. If unsure, use the default 'en,de'. - --> - transToolReferenceLanguages=de,en - </value> - </property> -</bean> - -</beans> diff --git a/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevController.java b/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevController.java index 80564f48230..311f951ec15 100644 --- a/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevController.java +++ b/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevController.java @@ -37,9 +37,6 @@ import org.springframework.beans.factory.annotation.Autowired; public class TranslationDevController extends FormBasicController { - @Autowired - private TranslationDevManager translationDevManager; - private String[] values = { "" }; private String[] keys = { "on" }; @@ -93,6 +90,11 @@ public class TranslationDevController extends FormBasicController { private TextElement addKeyValue; private TextElement addKeyKey; private FormLink submitAdd; + + @Autowired + private I18nModule i18nModule; + @Autowired + private TranslationDevManager translationDevManager; public TranslationDevController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); @@ -103,7 +105,7 @@ public class TranslationDevController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - if(!I18nModule.isTransToolEnabled()){ + if(!i18nModule.isTransToolEnabled()){ setFormWarning("devtools.warning"); } diff --git a/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevMainController.java b/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevMainController.java index b40197ca083..a97a91e1491 100644 --- a/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevMainController.java +++ b/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevMainController.java @@ -26,17 +26,17 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.MainLayoutBasicController; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** - * Description:<br> - * TODO: rhaag Class Description for TranslationDevMainController - * * <P> * Initial Date: 23.09.2008 <br> * @author Roman Haag, frentix GmbH, roman.haag@frentix.com */ public class TranslationDevMainController extends MainLayoutBasicController { - private final VelocityContainer vc; + + @Autowired + private I18nModule i18nModule; /** * @param ureq @@ -44,18 +44,12 @@ public class TranslationDevMainController extends MainLayoutBasicController { */ public TranslationDevMainController(UserRequest ureq, WindowControl control) { super(ureq, control); - vc = createVelocityContainer("translationdev"); - String srcPath = I18nModule.getTransToolApplicationLanguagesSrcDir().getAbsolutePath(); + VelocityContainer vc = createVelocityContainer("translationdev"); + String srcPath = i18nModule.getTransToolApplicationLanguagesSrcDir().getAbsolutePath(); vc.contextPut("srcPath", srcPath); - //TODO RH: check for enabled debug-mode in order to prevent caching! -// vc.contextPut("cachingDisabled", I18nModule.isCachingEnabled()); - -// formFactory.addTextElement(name, maxLen, initialValue, i18nLabel, formItemContainer) putInitialPanel(vc); } - - /** * @see org.olat.core.gui.control.DefaultController#doDispose() */ @@ -71,4 +65,4 @@ public class TranslationDevMainController extends MainLayoutBasicController { protected void event(UserRequest ureq, Component source, Event event) { // } -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevManager.java b/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevManager.java index 3776ef6f83e..14deaff880f 100644 --- a/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevManager.java +++ b/src/main/java/org/olat/core/util/i18n/devtools/TranslationDevManager.java @@ -33,9 +33,9 @@ import java.util.Iterator; import java.util.List; import java.util.Locale; import java.util.Map; +import java.util.Map.Entry; import java.util.Properties; import java.util.Set; -import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -48,6 +48,8 @@ import org.olat.core.util.StringHelper; import org.olat.core.util.i18n.I18nItem; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; /** @@ -59,27 +61,20 @@ import org.olat.core.util.i18n.I18nModule; * * @author Roman Haag, frentix GmbH, roman.haag@frentix.com */ +@Service("translationDevManager") public class TranslationDevManager extends BasicManager { - - private static TranslationDevManager INSTANCE; private static final OLog log = Tracing.createLoggerFor(TranslationDevManager.class); - I18nManager i18nMgr; - private StringBuffer logText = new StringBuffer(); - - /** - * [spring] - */ - private TranslationDevManager(I18nManager i18nManager) { - this.i18nMgr = i18nManager; - INSTANCE = this; - } - public static TranslationDevManager getInstance() { - return INSTANCE; - } + private StringBuffer logText = new StringBuffer(); + + @Autowired + private I18nManager i18nMgr; + @Autowired + private I18nModule i18nModule; + protected Set<String> getAllLanguages() { - return I18nModule.getAvailableLanguageKeys(); + return i18nModule.getAvailableLanguageKeys(); } protected void renameKeyTask(String bundleName, String origKey, String targetKey) { @@ -124,7 +119,7 @@ public class TranslationDevManager extends BasicManager { int counter = 0; Pattern resolvingKeyPattern = Pattern.compile("\\$\\{?("+originBundleName+")+:([\\w\\.\\-]*[\\w\\-])\\}?"); - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); Set<String> allLangs = getAllLanguages(); for (String langKey : allLangs) { Locale locale = i18nMgr.getLocaleOrNull(langKey); @@ -163,7 +158,7 @@ public class TranslationDevManager extends BasicManager { lastPos = matcher.end(); newValue.append(value.substring(lastPos)); log.info("Key:: " + key + " should get changed to value:: " + newValue.toString()); - logText.append(i18nMgr.getPropertiesFile(locale, bundleName, I18nModule.getPropertyFilesBaseDir(locale, bundleName)) + + logText.append(i18nMgr.getPropertiesFile(locale, bundleName, i18nModule.getPropertyFilesBaseDir(locale, bundleName)) + " update reference in lang::" + locale.getLanguage() + " bundle::" + bundleName + " key::" + key + " value::" + value + " \n\t to new value:: " + newValue.toString() + "\n"); counter ++; // changeValueForSingleKey(locale, bundleName, key, newValue.toString()); @@ -194,7 +189,6 @@ public class TranslationDevManager extends BasicManager { i18nMgr.saveOrUpdateProperties(tempProp, locale, bundleName); checkForEmptyPropertyAndDelete(locale, bundleName); - checkForEmptyBundleAndDelete(bundleName); } protected void addKey(Locale locale, String bundleName, String key, String value) { @@ -210,12 +204,6 @@ public class TranslationDevManager extends BasicManager { } } - private void checkForEmptyBundleAndDelete(String bundleName) { - // if _i18n is empty: - // TODO: RH: remove dir, remove .cvs - // deletePackage(bundleName); - } - public void movePackageTask(String originBundleName, String targetBundleName) { //remove package priority from metadata first deleteKey(null, originBundleName, I18nManager.METADATA_BUNDLE_PRIORITY_KEY); @@ -232,7 +220,7 @@ public class TranslationDevManager extends BasicManager { } public void movePackageByMovingSingleKeysTask(String originBundleName, String targetBundleName) { - Properties properties = i18nMgr.getPropertiesWithoutResolvingRecursively(I18nModule.getFallbackLocale(), originBundleName); + Properties properties = i18nMgr.getPropertiesWithoutResolvingRecursively(i18nModule.getFallbackLocale(), originBundleName); Set<Object> keys = properties.keySet(); for (Object keyObj : keys) { String key = (String) keyObj; @@ -272,7 +260,7 @@ public class TranslationDevManager extends BasicManager { public void renameLanguageTask(Locale sourceLocale, Locale targetLocale){ //check if targetLocale exists already - Set<String> allLangKeys = I18nModule.getAvailableLanguageKeys(); + Set<String> allLangKeys = i18nModule.getAvailableLanguageKeys(); if (allLangKeys.contains(targetLocale.getLanguage())){ log.error("Target Language " + targetLocale.getLanguage() + " already exists! "); } @@ -301,7 +289,7 @@ public class TranslationDevManager extends BasicManager { * @param reallyRemoveIt true: really remove it; false: dry run, only produce logging */ public void removeXKeysTask(boolean reallyRemoveIt){ - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); Set<String> allLangs = getAllLanguages(); int counter = 0; for (String langKey : allLangs) { @@ -320,7 +308,7 @@ public class TranslationDevManager extends BasicManager { } } log.info("XKEY detected in lang::" + locale.getLanguage() + " bundle::" + bundleName + " key::" + key); - File propertyFileDir = I18nModule.getPropertyFilesBaseDir(locale, bundleName); + File propertyFileDir = i18nModule.getPropertyFilesBaseDir(locale, bundleName); if(propertyFileDir != null) { File propertyFile = i18nMgr.getPropertiesFile(locale, bundleName, propertyFileDir); logText.append(propertyFile + " XKEY detected in lang::" + locale.getLanguage() + " bundle::" + bundleName + " key::" + key + " value::" + value + "\n"); @@ -339,7 +327,7 @@ public class TranslationDevManager extends BasicManager { } public void sortKeysTask(boolean reallySortIt){ - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); Set<String> allLangs = getAllLanguages(); int counter = 0; for (String langKey : allLangs) { @@ -366,7 +354,7 @@ public class TranslationDevManager extends BasicManager { * @param reallyRemoveIt true: really remove it; false: dry run, only produce logging */ public void removeTodoKeysTask(boolean reallyRemoveIt) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); Set<String> allLangs = getAllLanguages(); int counter = 0; String[] comparisonStrings = {"TODO"}; @@ -385,7 +373,7 @@ public class TranslationDevManager extends BasicManager { if (value.length() > comparisonStrings[i].length()+1) { log.warn("this is a TODO-Key WITH TEXT::" + value.substring(comparisonStrings[i].length()) + "::"); } else { - logText.append(i18nMgr.getPropertiesFile(locale, bundleName, I18nModule.getPropertyFilesBaseDir(locale, bundleName)) + + logText.append(i18nMgr.getPropertiesFile(locale, bundleName, i18nModule.getPropertyFilesBaseDir(locale, bundleName)) + " TODO-Key detected in lang::" + locale.getLanguage() + " bundle::" + bundleName + " key::" + key + " value::" + value + "\n"); if (reallyRemoveIt) { deleteKey(locale, bundleName, key); @@ -405,7 +393,7 @@ public class TranslationDevManager extends BasicManager { * @param reallyRemoveIt true: really remove it; false: dry run, only produce logging */ public void removeEmptyKeysTask(boolean reallyRemoveIt) { - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); int counter = 0; Set<String> allLangs = getAllLanguages(); for (String langKey : allLangs) { @@ -418,7 +406,7 @@ public class TranslationDevManager extends BasicManager { String value = properties.getProperty(key); if (!StringHelper.containsNonWhitespace(value) ) { log.info("empty Key detected in lang::" + locale.getLanguage() + " bundle::" + bundleName + " key::" + key + " value::" + value); - File propertyFileDir = I18nModule.getPropertyFilesBaseDir(locale, bundleName); + File propertyFileDir = i18nModule.getPropertyFilesBaseDir(locale, bundleName); if(propertyFileDir != null) { File propertyFile = i18nMgr.getPropertiesFile(locale, bundleName, propertyFileDir); logText.append(propertyFile + " empty Key detected in lang" + locale.getLanguage() + " bundle::" + bundleName + " key::" + key + " value::" + value + "\n"); @@ -447,7 +435,7 @@ public class TranslationDevManager extends BasicManager { // first get all available keys from de and en language Set<String> validCombinedKeys = new HashSet<String>(); //copy list to prevent concurrent modification exception - List<String> allBundles = new ArrayList<String>(I18nModule.getBundleNamesContainingI18nFiles()); + List<String> allBundles = new ArrayList<String>(i18nModule.getBundleNamesContainingI18nFiles()); for (String bundleName : allBundles) { for (String refLangKey : referenceLanguages) { Properties properties = i18nMgr.getPropertiesWithoutResolvingRecursively(i18nMgr.getLocaleOrNull(refLangKey), bundleName); @@ -520,7 +508,7 @@ public class TranslationDevManager extends BasicManager { * reallyCopy: set to true to create Props/keys in Head, false: only log them */ public void getLostTranslationsFromBranch(boolean reallyCopy, String[] referenceLanguages, String pathToOlatBranch, String pathToCoreBranch){ - List<String> allBundles = new ArrayList<String>(I18nModule.getBundleNamesContainingI18nFiles()); + List<String> allBundles = new ArrayList<String>(i18nModule.getBundleNamesContainingI18nFiles()); Set<String> allLangs = getAllLanguages(); //loop over all langs @@ -626,12 +614,12 @@ public class TranslationDevManager extends BasicManager { * false: dry run, only produce logging */ public void removeReferenceLanguageCopiesTask(boolean reallyRemoveIt){ - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); // don't remove EN and DE here, this is a shared Map!! int counter = 0; int aliasCounter = 0; //prepare exclusion list - String exKeys = FileUtils.load(new File(I18nModule.getTransToolApplicationLanguagesSrcDir() + "/org/olat/core/util/i18n/devtools/exclusionKeys.txt"), "UTF-8"); + String exKeys = FileUtils.load(new File(i18nModule.getTransToolApplicationLanguagesSrcDir() + "/org/olat/core/util/i18n/devtools/exclusionKeys.txt"), "UTF-8"); String[] exArray = exKeys.split("\n"); List<String> exList = new ArrayList<String>(Arrays.asList(exArray)); @@ -675,7 +663,7 @@ public class TranslationDevManager extends BasicManager { } if (readyToDelete) { counter++; - logText.append(i18nMgr.getPropertiesFile(locale, bundleName, I18nModule.getPropertyFilesBaseDir(locale, bundleName)) + + logText.append(i18nMgr.getPropertiesFile(locale, bundleName, i18nModule.getPropertyFilesBaseDir(locale, bundleName)) + " value of key found in reference -> remove lang::" + locale.getLanguage() + " bundle::" + bundleName + " key::" + key + " value::" + value + "\n"); } } @@ -689,9 +677,9 @@ public class TranslationDevManager extends BasicManager { // do this only for reference language! public List<I18nItem> getDouplicateKeys(){ - Locale refLocale = I18nModule.getDefaultLocale(); + Locale refLocale = i18nModule.getDefaultLocale(); List<I18nItem> doupList = new ArrayList<I18nItem>(); - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); Map<String, String> tempKeyMap = new HashMap<String, String>(); for (String bundleName : allBundles) { @@ -716,9 +704,9 @@ public class TranslationDevManager extends BasicManager { //do this only for reference language! public List<I18nItem> getDouplicateValues(){ - Locale refLocale = I18nModule.getDefaultLocale(); + Locale refLocale = i18nModule.getDefaultLocale(); List<I18nItem> doupList = new ArrayList<I18nItem>(); - List<String> allBundles = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> allBundles = i18nModule.getBundleNamesContainingI18nFiles(); Map<String, String> tempKeyMap = new HashMap<String, String>(); for (String bundleName : allBundles) { @@ -755,10 +743,10 @@ public class TranslationDevManager extends BasicManager { } private File getBundlePath(String bundleName){ - Locale locale = I18nModule.getAllLocales().get("de"); - File baseDir = I18nModule.getPropertyFilesBaseDir(locale, bundleName); + Locale locale = i18nModule.getAllLocales().get("de"); + File baseDir = i18nModule.getPropertyFilesBaseDir(locale, bundleName); if (baseDir != null) { - File deFile = I18nManager.getInstance().getPropertiesFile(locale, bundleName, baseDir); + File deFile = i18nMgr.getPropertiesFile(locale, bundleName, baseDir); return deFile.getParentFile(); } return null; @@ -800,43 +788,4 @@ public class TranslationDevManager extends BasicManager { out.close(); } } - - public void logToFile(String fname){ -// FileUtils.save(new File("/Users/rhaag/Desktop/devtoolsoutput/"+fname+".txt"), logText.toString(), "UTF-8"); -// logText = new StringBuffer(); - } - - -// String srcPath; -// if (bundleName.startsWith("org.olat.core")) { -// srcPath = I18nModule.getTransToolCoreLanguagesSrcDir().getAbsolutPath(); -// if (srcPath == null) { -// log.error("Can not add bundle priority to core while olatcore source path is not configured! Check olatcore.src in olat.properties"); -// return; -// } -// } else { -// srcPath = I18nModule.getTransToolApplicationLanguagesSrcDir().getAbsolutPath(); -// } -// File baseDir = new File(srcPath + bundleName.replace(".", "/")); -// if (baseDir.exists()) { -// addMissingBundlePriority(baseDir, priority); -// } else { -// log.error("Can not add priority to bundle::" + bundleName + " - invalid source path::" + baseDir.getAbsolutePath()); -// } -// } -// -// private void addMissingBundlePriority(File dir, int priority) { -// File[] files = dir.listFiles(DirectoryFilter.DIRECTORY_FILTER); -// for (File childDir : files) { -// if (childDir.getName().equals(I18nManager.I18N_DIRNAME )) { -// // add priority to file -// int bundle1Prio = getBundlePriority(metadata1, bundle1); -// -// } else { -// // do it recursively -// addMissingBundlePriority(childDir, priority); -// } -// } -// } - } diff --git a/src/main/java/org/olat/core/util/i18n/devtools/_spring/devtoolsCorecontext.xml b/src/main/java/org/olat/core/util/i18n/devtools/_spring/devtoolsCorecontext.xml index e4c33b1f1b5..ff6bcb4ce67 100644 --- a/src/main/java/org/olat/core/util/i18n/devtools/_spring/devtoolsCorecontext.xml +++ b/src/main/java/org/olat/core/util/i18n/devtools/_spring/devtoolsCorecontext.xml @@ -5,9 +5,6 @@ http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> -<bean id="translationDevManager" class="org.olat.core.util.i18n.devtools.TranslationDevManager"> - <constructor-arg ref="I18nManager" /> -</bean> <!-- Devel / snoop user session --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> <property name="order" value="15120" /> diff --git a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigController.java b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigController.java index a49cb3bd422..0485dcf8481 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigController.java @@ -40,6 +40,7 @@ import org.olat.core.gui.control.generic.closablewrapper.CloseableModalControlle import org.olat.core.util.ArrayHelper; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** * <h3>Description:</h3> This controller offers a workflow to configure the @@ -68,6 +69,11 @@ class I18nConfigController extends FormBasicController { private FormLink createLanguageLink, deleteLanguageLink, importPackageLink, exportPackageLink, deletePackageLink; private CloseableModalController cmc; private Controller subCtr; + + @Autowired + private I18nManager i18nMgr; + @Autowired + private I18nModule i18nModule; /** * Constructor for the language configuration workflow @@ -86,15 +92,14 @@ class I18nConfigController extends FormBasicController { */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - I18nManager i18nMgr = I18nManager.getInstance(); // // Add default languages pulldown - Set<String> availableKeys = I18nModule.getAvailableLanguageKeys(); + Set<String> availableKeys = i18nModule.getAvailableLanguageKeys(); String[] defaultlangKeys = ArrayHelper.toArray(availableKeys); String[] defaultLangValues = new String[defaultlangKeys.length]; for (int i = 0; i < defaultlangKeys.length; i++) { String key = defaultlangKeys[i]; - String explLang = i18nMgr.getLanguageInEnglish(key, I18nModule.isOverlayEnabled()); + String explLang = i18nMgr.getLanguageInEnglish(key, i18nModule.isOverlayEnabled()); String all = explLang; if (explLang != null && !explLang.equals(key)) all += " (" + key + ")"; defaultLangValues[i] = all; @@ -111,10 +116,10 @@ class I18nConfigController extends FormBasicController { // Add enabled languages checkboxes String[] availablelangKeys = ArrayHelper.toArray(availableKeys); String[] availableValues = new String[availablelangKeys.length]; - int referenceKeyCount = i18nMgr.countI18nItems(I18nModule.getFallbackLocale(), null, true); + int referenceKeyCount = i18nMgr.countI18nItems(i18nModule.getFallbackLocale(), null, true); for (int i = 0; i < availablelangKeys.length; i++) { String key = availablelangKeys[i]; - String explLang = i18nMgr.getLanguageInEnglish(key, I18nModule.isOverlayEnabled()); + String explLang = i18nMgr.getLanguageInEnglish(key, i18nModule.isOverlayEnabled()); String all = explLang; if (explLang != null && !explLang.equals(key)) all += " (" + key + ")"; // count translation status @@ -133,12 +138,12 @@ class I18nConfigController extends FormBasicController { enabledLangSelection.setEscapeHtml(false); enabledLangSelection.addActionListener(FormEvent.ONCLICK); // Radios/Checkboxes need onclick because of IE bug OLAT-5753 // Enable current enabled languages - for (String langKey : I18nModule.getEnabledLanguageKeys()) { + for (String langKey : i18nModule.getEnabledLanguageKeys()) { enabledLangSelection.select(langKey, true); } // // Add create / delete links, but only when translation tool is configured - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { createLanguageLink = uifactory.addFormLink("configuration.management.create", formLayout, Link.BUTTON); deleteLanguageLink = uifactory.addFormLink("configuration.management.delete", formLayout, Link.BUTTON); } @@ -166,12 +171,12 @@ class I18nConfigController extends FormBasicController { if (source == defaultLangSelection) { // Get new default language and update I18nModule accordingly String langKey = defaultLangSelection.getSelectedKey(); - Locale defaultLocale = I18nManager.getInstance().getLocaleOrNull(langKey); + Locale defaultLocale = i18nMgr.getLocaleOrNull(langKey); this.flc.contextPut("defaultLangKey", defaultLocale.toString()); - I18nModule.setDefaultLocale(defaultLocale); + i18nModule.setDefaultLocale(defaultLocale); // Make sure this language is in the list of enabled languages enabledLangSelection.select(langKey, true); - I18nModule.getEnabledLanguageKeys().add(langKey); + i18nModule.getEnabledLanguageKeys().add(langKey); } else if (source == enabledLangSelection) { // Get enabled values, make sure the default language is enabled and @@ -195,7 +200,7 @@ class I18nConfigController extends FormBasicController { // showWarning("configuration.fallback.lang.must.be.enabed", fallbackLangKey); // } - I18nModule.setEnabledLanguageKeys(enabledLangKeys); + i18nModule.setEnabledLanguageKeys(enabledLangKeys); } else if (source == createLanguageLink) { // Show new language sub form in an overlay window diff --git a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeleteLangController.java b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeleteLangController.java index 4346c295905..541d10682b6 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeleteLangController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeleteLangController.java @@ -46,6 +46,7 @@ import org.olat.core.logging.AssertException; import org.olat.core.util.ArrayHelper; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -68,6 +69,11 @@ class I18nConfigSubDeleteLangController extends FormBasicController { private DialogBoxController dialogCtr; private FormLink cancelButton; private FormSubmit submitButton; + + @Autowired + private I18nManager i18nMgr; + @Autowired + private I18nModule i18nModule; /** * Constructor for the delete-language workflow @@ -77,7 +83,7 @@ class I18nConfigSubDeleteLangController extends FormBasicController { */ public I18nConfigSubDeleteLangController(UserRequest ureq, WindowControl control) { super(ureq, control, LAYOUT_VERTICAL); - if (!I18nModule.isTransToolEnabled()) { throw new AssertException( + if (!i18nModule.isTransToolEnabled()) { throw new AssertException( "Languages can only be deleted when the translation tool is enabled and the translation tool source pathes are configured in the olat.properties"); } initForm(ureq); } @@ -88,13 +94,12 @@ class I18nConfigSubDeleteLangController extends FormBasicController { */ @Override protected void initForm(FormItemContainer formLayout, Controller listener,UserRequest ureq) { - I18nManager i18nMgr = I18nManager.getInstance(); // A title, displayed in fieldset setFormTitle("configuration.management.delete.title"); setFormDescription("configuration.management.delete.description"); // // Add languages checkboxes - Set<String> deletableKeysUnsorted = I18nModule.getTranslatableLanguageKeys(); + Set<String> deletableKeysUnsorted = i18nModule.getTranslatableLanguageKeys(); String[] deletableKeys = ArrayHelper.toArray(deletableKeysUnsorted); String[] availableValues = new String[deletableKeys.length]; for (int i = 0; i < deletableKeys.length; i++) { @@ -132,10 +137,10 @@ class I18nConfigSubDeleteLangController extends FormBasicController { showError("configuration.management.delete.error", defaultKey); return; } - String fallbackKey = I18nModule.getFallbackLocale().toString(); + String fallbackKey = i18nModule.getFallbackLocale().toString(); if (toDelete.contains(fallbackKey)) { deleteLangSelection.select(fallbackKey, false); - showError("configuration.management.delete.error", I18nModule.getFallbackLocale().toString()); + showError("configuration.management.delete.error", i18nModule.getFallbackLocale().toString()); return; } dialogCtr = activateYesNoDialog(ureq, translate("configuration.management.delete.confirm.title"), translate( @@ -146,12 +151,13 @@ class I18nConfigSubDeleteLangController extends FormBasicController { * @see org.olat.core.gui.control.DefaultController#event(org.olat.core.gui.UserRequest, * org.olat.core.gui.control.Controller, org.olat.core.gui.control.Event) */ + @Override public void event(UserRequest ureq, Controller source, Event event) { if (source == dialogCtr) { if (DialogBoxUIFactory.isYesEvent(event)) { // Yes case, delete now for (String deleteLang : deleteLangSelection.getSelectedKeys()) { - I18nManager.getInstance().deleteLanguage(deleteLang, true); + i18nMgr.deleteLanguage(deleteLang, true); logAudit("Deleted language::" + deleteLang, null); } // wow, everything worked fine diff --git a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeletePackageController.java b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeletePackageController.java index e1c28ae035d..949464188b9 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeletePackageController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubDeletePackageController.java @@ -43,6 +43,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.modal.DialogBoxController; import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -64,6 +65,9 @@ class I18nConfigSubDeletePackageController extends FormBasicController { private DialogBoxController dialogCtr; private FormLink cancelButton; private FormSubmit submitButton; + + @Autowired + private I18nModule i18nModule; /** * Constructor for the delete-language pack workflow @@ -121,7 +125,7 @@ class I18nConfigSubDeletePackageController extends FormBasicController { logAudit("Deleted language pack::" + deleteLangPack, null); } // Reset i18n system - I18nModule.reInitializeAndFlushCache(); + i18nModule.reInitializeAndFlushCache(); // wow, everything worked fine showInfo("configuration.management.package.delete.success", deleteLangPackSelection.getSelectedKeys().toString()); fireEvent(ureq, Event.DONE_EVENT); diff --git a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubExportLangController.java b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubExportLangController.java index 719f9a824e4..91d0b7a8072 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubExportLangController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubExportLangController.java @@ -47,6 +47,7 @@ import org.olat.core.util.ArrayHelper; import org.olat.core.util.CodeHelper; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -67,6 +68,11 @@ class I18nConfigSubExportLangController extends FormBasicController { private MultipleSelectionElement exportLangSelection; private FormLink cancelButton; private FormSubmit submitButton; + + @Autowired + private I18nModule i18nModule; + @Autowired + private I18nManager i18nMgr; /** * Constructor for the export-language workflow @@ -85,13 +91,12 @@ class I18nConfigSubExportLangController extends FormBasicController { */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - I18nManager i18nMgr = I18nManager.getInstance(); // A title, displayed in fieldset setFormTitle("configuration.management.package.export.title"); setFormDescription("configuration.management.package.export.description"); // // Add languages checkboxes - Set<String> availableKeysUnsorted = I18nModule.getAvailableLanguageKeys(); + Set<String> availableKeysUnsorted = i18nModule.getAvailableLanguageKeys(); String[] availableKeys = ArrayHelper.toArray(availableKeysUnsorted); String[] availableValues = new String[availableKeys.length]; for (int i = 0; i < availableKeys.length; i++) { @@ -127,7 +132,7 @@ class I18nConfigSubExportLangController extends FormBasicController { } String tmpFileName = CodeHelper.getGlobalForeverUniqueID(); // crate new temp file - File exportFile = I18nManager.getInstance().createLanguageJarFile(toExport, tmpFileName); + File exportFile = i18nMgr.createLanguageJarFile(toExport, tmpFileName); if (exportFile != null) { String fileName = "language_export_" + Settings.getApplicationName() + "_" + Settings.getVersion() + ".jar"; // Create a temporary media resource that gets deleted from the diff --git a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubImportLangController.java b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubImportLangController.java index e5429c050e1..23ee6e96110 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubImportLangController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubImportLangController.java @@ -41,6 +41,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.util.ArrayHelper; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** * <h3>Description:</h3> This form allows the user to import languages from a @@ -61,6 +62,11 @@ class I18nConfigSubImportLangController extends FormBasicController { private FileElement importFile; private FormLink cancelButton; private MultipleSelectionElement importKeys; + + @Autowired + private I18nModule i18nModule; + @Autowired + private I18nManager i18nManager; public I18nConfigSubImportLangController(UserRequest ureq, WindowControl control) { super(ureq, control, LAYOUT_VERTICAL); @@ -71,7 +77,7 @@ class I18nConfigSubImportLangController extends FormBasicController { protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { // A title, displayed in fieldset setFormTitle("configuration.management.package.import.title"); - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { setFormDescription("configuration.management.package.import.description.transserver"); } else { setFormDescription("configuration.management.package.import.description"); @@ -108,15 +114,15 @@ class I18nConfigSubImportLangController extends FormBasicController { Collection<String> importLangKeys = importKeys.getSelectedKeys(); Set<String> alreadyInstalledLangs = new HashSet<String>(); for (String langKey : importLangKeys) { - if (I18nModule.getAvailableLanguageKeys().contains(langKey)) { + if (i18nModule.getAvailableLanguageKeys().contains(langKey)) { alreadyInstalledLangs.add(langKey); } } - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { // In translation mode importing will copy the language package // over an existing language or create a new language File tmpJar = importFile.getUploadFile(); - I18nManager.getInstance().copyLanguagesFromJar(tmpJar, importLangKeys); + i18nManager.copyLanguagesFromJar(tmpJar, importLangKeys); logAudit("Uploaded languages from jar::" + importFile.getUploadFileName(), null); showInfo("configuration.management.package.import.success", importLangKeys.toString()); @@ -139,7 +145,7 @@ class I18nConfigSubImportLangController extends FormBasicController { } } // Reset i18n system - I18nModule.reInitializeAndFlushCache(); + i18nModule.reInitializeAndFlushCache(); fireEvent(ureq, Event.DONE_EVENT); } } @@ -153,7 +159,7 @@ class I18nConfigSubImportLangController extends FormBasicController { } else if (source == importFile) { if (importFile.isUploadSuccess()) { File tmpJar = importFile.getUploadFile(); - Set<String> importLangKeys = I18nManager.getInstance().sarchForAvailableLanguagesInJarFile(tmpJar, true); + Set<String> importLangKeys = i18nManager.sarchForAvailableLanguagesInJarFile(tmpJar, true); if (importLangKeys.size() == 0) { showError("configuration.management.package.import.failure.empty"); return; diff --git a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubNewLangController.java b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubNewLangController.java index 397c6ba305e..ccd78fd9d2c 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubNewLangController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/I18nConfigSubNewLangController.java @@ -51,6 +51,7 @@ import org.olat.core.util.Util; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -72,6 +73,9 @@ import org.olat.user.UserManager; class I18nConfigSubNewLangController extends FormBasicController { private TextElement newLanguage, newCountry, newVariant, newTranslatedInEnglish, newTranslatedInLanguage, newTranslator; private FormLink cancelButton; + + @Autowired + private I18nModule i18nModule; /** * Constructor for the new-language workflow @@ -81,7 +85,7 @@ class I18nConfigSubNewLangController extends FormBasicController { */ protected I18nConfigSubNewLangController(UserRequest ureq, WindowControl control) { super(ureq, control, LAYOUT_DEFAULT); - if (!I18nModule.isTransToolEnabled()) { throw new AssertException( + if (!i18nModule.isTransToolEnabled()) { throw new AssertException( "New languages can only be created when the translation tool is enabled and the translation tool source pathes are configured in the olat.properties"); } initForm(ureq); } diff --git a/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java b/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java index 790cf85b08a..c65e010f507 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/InlineTranslationInterceptHandlerController.java @@ -25,6 +25,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import org.apache.commons.lang.StringEscapeUtils; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.ComponentRenderer; @@ -48,6 +49,7 @@ import org.olat.core.util.i18n.I18nItem; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.prefs.Preferences; +import org.springframework.beans.factory.annotation.Autowired; /** * Description:<br> @@ -86,6 +88,11 @@ public class InlineTranslationInterceptHandlerController extends BasicController private static final Pattern patternInput = Pattern.compile("<input[^>]*?" + decoratedTranslatedPattern + ".*?>"); private static final Pattern patAttribute = Pattern.compile("<[^>]*?" + decoratedTranslatedPattern + "[^>]*?>"); + @Autowired + private I18nManager i18nMgr; + @Autowired + private I18nModule i18nModule; + /** * Constructor * @@ -200,16 +207,14 @@ public class InlineTranslationInterceptHandlerController extends BasicController if (StringHelper.containsNonWhitespace(bundle) && StringHelper.containsNonWhitespace(key)) { // Get userconfigured reference locale Preferences guiPrefs = ureq.getUserSession().getGuiPreferences(); - List<String> referenceLangs = I18nModule.getTransToolReferenceLanguages(); - String referencePrefs = (String) guiPrefs.get(I18nModule.class, I18nModule.GUI_PREFS_PREFERRED_REFERENCE_LANG, referenceLangs - .get(0)); - I18nManager i18nMgr = I18nManager.getInstance(); + List<String> referenceLangs = i18nModule.getTransToolReferenceLanguages(); + String referencePrefs = (String) guiPrefs.get(I18nModule.class, I18nModule.GUI_PREFS_PREFERRED_REFERENCE_LANG, referenceLangs.get(0)); Locale referenceLocale = i18nMgr.getLocaleOrNull(referencePrefs); // Set target local to current user language Locale targetLocale = i18nMgr.getLocaleOrNull(ureq.getLocale().toString()); - if (I18nModule.isOverlayEnabled() && !I18nModule.isTransToolEnabled()) { + if (i18nModule.isOverlayEnabled() && !i18nModule.isTransToolEnabled()) { // use overlay locale when in customizing mode - targetLocale = I18nModule.getOverlayLocales().get(targetLocale); + targetLocale = i18nModule.getOverlayLocales().get(targetLocale); } List<I18nItem> i18nItems = i18nMgr.findExistingAndMissingI18nItems(referenceLocale, targetLocale, bundle, false); if(i18nItems.isEmpty()) { @@ -222,7 +227,7 @@ public class InlineTranslationInterceptHandlerController extends BasicController // running - // must be done before instantiating the translation controller i18nMgr.setMarkLocalizedStringsEnabled(ureq.getUserSession(), false); - i18nItemEditCtr = new TranslationToolI18nItemEditCrumbController(ureq, getWindowControl(), i18nItems, referenceLocale, !I18nModule.isTransToolEnabled()); + i18nItemEditCtr = new TranslationToolI18nItemEditCrumbController(ureq, getWindowControl(), i18nItems, referenceLocale, !i18nModule.isTransToolEnabled()); listenTo(i18nItemEditCtr); // set current key from the package as current translation item for (I18nItem item : i18nItems) { @@ -251,7 +256,7 @@ public class InlineTranslationInterceptHandlerController extends BasicController protected void event(UserRequest ureq, Controller source, Event event) { if (source == cmc) { // user closed dialog, go back to inline translation mode - I18nManager.getInstance().setMarkLocalizedStringsEnabled(ureq.getUserSession(), true); + i18nMgr.setMarkLocalizedStringsEnabled(ureq.getUserSession(), true); } } @@ -459,7 +464,7 @@ public class InlineTranslationInterceptHandlerController extends BasicController inlineTranslationURLBuilder.buildURI(link, new String[] { ARG_BUNDLE, ARG_KEY, ARG_IDENT }, arguments); link.append("\" title=\""); String combinedKey = arguments[0] + ":" + arguments[1]; - if (I18nModule.isTransToolEnabled()) { + if (CoreSpringFactory.getImpl(I18nModule.class).isTransToolEnabled()) { link.append(StringEscapeUtils.escapeHtml(inlineTrans.translate("inline.translate", new String[] { combinedKey }))); } else { link.append(StringEscapeUtils.escapeHtml(inlineTrans.translate("inline.customize.translate", new String[] { combinedKey }))); diff --git a/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java b/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java index cb94ae14990..82235c18f85 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/SingleKeyTranslatorController.java @@ -40,6 +40,7 @@ import org.olat.core.util.Util; import org.olat.core.util.i18n.I18nItem; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -61,7 +62,10 @@ public class SingleKeyTranslatorController extends FormBasicController { private static final String LBL_NAME_PREFIX = "lbl."; private Map<String, TextElement> textElements; + @Autowired private I18nManager i18nMng; + @Autowired + private I18nModule i18nModule; public SingleKeyTranslatorController(UserRequest ureq, WindowControl wControl, String keyToTranslate, Class<?> translatorBaseClass) { this(ureq,wControl,new String[]{keyToTranslate},translatorBaseClass); @@ -94,12 +98,9 @@ public class SingleKeyTranslatorController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { - // load 18n-stuff - i18nMng = I18nManager.getInstance(); + Map<Locale, Locale> allOverlays = i18nModule.getOverlayLocales(); - Map<Locale, Locale> allOverlays = I18nModule.getOverlayLocales(); - - Collection<String> enabledKeys = I18nModule.getEnabledLanguageKeys(); + Collection<String> enabledKeys = i18nModule.getEnabledLanguageKeys(); bundles = new ArrayList<I18nRowBundle>(); for (String key : enabledKeys) { Locale loc = i18nMng.getLocaleOrNull(key); diff --git a/src/main/java/org/olat/core/util/i18n/ui/TranslationToolI18nItemEditCrumbController.java b/src/main/java/org/olat/core/util/i18n/ui/TranslationToolI18nItemEditCrumbController.java index d378cb02ea0..fa41cbea99c 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/TranslationToolI18nItemEditCrumbController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/TranslationToolI18nItemEditCrumbController.java @@ -46,6 +46,7 @@ import org.olat.core.util.i18n.I18nItem; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.prefs.Preferences; +import org.springframework.beans.factory.annotation.Autowired; /** * <h3>Description:</h3> This controller can be used to edit one or more @@ -83,7 +84,10 @@ public class TranslationToolI18nItemEditCrumbController extends CrumbFormBasicCo // true when the overlay files are edited and not the language files itself private boolean customizingMode = false; - private final I18nManager i18nMgr; + @Autowired + private I18nManager i18nMgr; + @Autowired + private I18nModule i18nModule; /** * Constructor for the item edit controller. Use the @@ -101,12 +105,11 @@ public class TranslationToolI18nItemEditCrumbController extends CrumbFormBasicCo public TranslationToolI18nItemEditCrumbController(UserRequest ureq, WindowControl control, List<I18nItem> i18nItems, Locale referenceLocale, boolean customizingMode) { super(ureq, control, "translationToolI18nItemEdit"); - i18nMgr = I18nManager.getInstance(); this.customizingMode = customizingMode; this.i18nItems = i18nItems; if(referenceLocale == null) { Preferences guiPrefs = ureq.getUserSession().getGuiPreferences(); - List<String> referenceLangs = I18nModule.getTransToolReferenceLanguages(); + List<String> referenceLangs = i18nModule.getTransToolReferenceLanguages(); String referencePrefs = (String)guiPrefs.get(I18nModule.class, I18nModule.GUI_PREFS_PREFERRED_REFERENCE_LANG, referenceLangs.get(0)); this.referenceLocale = i18nMgr.getLocaleOrNull(referencePrefs); if(this.referenceLocale == null) { @@ -200,7 +203,7 @@ public class TranslationToolI18nItemEditCrumbController extends CrumbFormBasicCo flc.contextPut("compareSwitchEnabled", compareEnabledPrefs); // Add compare language selection - Set<String> availableLangKeys = I18nModule.getAvailableLanguageKeys(); + Set<String> availableLangKeys = i18nModule.getAvailableLanguageKeys(); String[] comparelangKeys = ArrayHelper.toArray(availableLangKeys); String[] compareLangValues = new String[comparelangKeys.length]; for (int i = 0; i < comparelangKeys.length; i++) { @@ -218,14 +221,14 @@ public class TranslationToolI18nItemEditCrumbController extends CrumbFormBasicCo if (compareLocale == null) compareLocale = I18nModule.getDefaultLocale(); compareLangSelection = uifactory.addDropdownSingleselect("compareLangSelection", flc, comparelangKeys, compareLangValues, null); compareLangSelection.setDomReplacementWrapperRequired(false); - compareLangSelection.select(i18nMgr.getLocaleKey(compareLocale), true); - flc.contextPut("compareLanguageKey", i18nMgr.getLocaleKey(compareLocale)); + compareLangSelection.select(i18nModule.getLocaleKey(compareLocale), true); + flc.contextPut("compareLanguageKey", i18nModule.getLocaleKey(compareLocale)); compareLangSelection.addActionListener(FormEvent.ONCHANGE); compareLangSelection.setEnabled(compareEnabledPrefs.booleanValue()); // Add target box - flc.contextPut("targetLanguageKey", i18nMgr.getLocaleKey(currentItem.getLocale())); - flc.contextPut("targetLanguage", i18nMgr.getLanguageTranslated(i18nMgr.getLocaleKey(currentItem.getLocale()), false)); + flc.contextPut("targetLanguageKey", i18nModule.getLocaleKey(currentItem.getLocale())); + flc.contextPut("targetLanguage", i18nMgr.getLanguageTranslated(i18nModule.getLocaleKey(currentItem.getLocale()), false)); targetArea = uifactory.addTextAreaElement("targetArea", "edit.targetArea", -1, 5, -1, true, null, flc); // Add annotation box annotationArea = uifactory.addTextAreaElement("annotationArea", "edit.annotationArea", -1, 1, -1, true, null, flc); @@ -254,11 +257,11 @@ public class TranslationToolI18nItemEditCrumbController extends CrumbFormBasicCo // don't edit annotations in customizing mode annotationArea.setEnabled(false); // target lang flags and lang name - Locale origLocale = I18nModule.getAllLocales().get(i18nMgr.createOrigianlLocaleKeyForOverlay(currentItem.getLocale())); + Locale origLocale = i18nModule.getAllLocales().get(i18nMgr.createOrigianlLocaleKeyForOverlay(currentItem.getLocale())); if(origLocale == null) { origLocale = currentItem.getLocale(); } - String localeKey = i18nMgr.getLocaleKey(origLocale); + String localeKey = i18nModule.getLocaleKey(origLocale); flc.contextPut("targetLanguageKey", localeKey); flc.contextPut("targetLanguage", i18nMgr.getLanguageTranslated(localeKey, true)); } diff --git a/src/main/java/org/olat/core/util/i18n/ui/TranslationToolLauncherController.java b/src/main/java/org/olat/core/util/i18n/ui/TranslationToolLauncherController.java index ea3789dfcad..8d9bc978de8 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/TranslationToolLauncherController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/TranslationToolLauncherController.java @@ -35,6 +35,7 @@ import org.olat.core.gui.control.generic.popup.PopupBrowserWindow; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.prefs.Preferences; +import org.springframework.beans.factory.annotation.Autowired; /** * <h3>Description:</h3> This controller offers a panel for translators. On the @@ -52,6 +53,9 @@ import org.olat.core.util.prefs.Preferences; public class TranslationToolLauncherController extends BasicController { private VelocityContainer translationToolLauncherVC; private Link startTranslationToolLink, enableInlineTranslationLink, disableInlineTranslationLink, cacheFlushLink; + + @Autowired + private I18nModule i18nModule; /** * Constructor for the translation tool start panel controller @@ -66,7 +70,7 @@ public class TranslationToolLauncherController extends BasicController { startTranslationToolLink = LinkFactory.createButton("start", translationToolLauncherVC, this); startTranslationToolLink.setTarget("_transtool"); // Add link to flush the cache - if (I18nManager.getInstance().isCachingEnabled()) { + if (i18nModule.isCachingEnabled()) { cacheFlushLink = LinkFactory.createButton("cache.flush", translationToolLauncherVC, this); } // Add inline translation status and link @@ -74,11 +78,11 @@ public class TranslationToolLauncherController extends BasicController { updateInlineTranslationStatusAndLink(guiPrefs); putInitialPanel(translationToolLauncherVC); // Enable or disable entire translation tool - boolean isTranslationToolEnabled = I18nModule.isTransToolEnabled(); + boolean isTranslationToolEnabled = i18nModule.isTransToolEnabled(); translationToolLauncherVC.contextPut("transToolEnabled", Boolean.valueOf(isTranslationToolEnabled)); // Enable or disable customizing tool. The customzing tool is only enabled // when not configured as translation tool server - translationToolLauncherVC.contextPut("customizingToolEnabled", Boolean.valueOf(!isTranslationToolEnabled && I18nModule.isOverlayEnabled())); + translationToolLauncherVC.contextPut("customizingToolEnabled", Boolean.valueOf(!isTranslationToolEnabled && i18nModule.isOverlayEnabled())); } /* @@ -93,8 +97,9 @@ public class TranslationToolLauncherController extends BasicController { if (source == startTranslationToolLink) { // wrap the content controller into a full header layout ControllerCreator controllerCreator = new ControllerCreator() { + @Override public Controller createController(UserRequest uureq, WindowControl wControl) { - return new TranslationToolMainController(uureq, wControl, !I18nModule.isTransToolEnabled()); + return new TranslationToolMainController(uureq, wControl, !i18nModule.isTransToolEnabled()); } }; // no need for later disposal, opens in popup window and will be disposed @@ -112,7 +117,7 @@ public class TranslationToolLauncherController extends BasicController { } else if (source == cacheFlushLink) { // clear i18n cache - I18nModule.reInitializeAndFlushCache(); + i18nModule.reInitializeAndFlushCache(); showInfo("cache.flush.ok"); } } diff --git a/src/main/java/org/olat/core/util/i18n/ui/TranslationToolStartCrumbController.java b/src/main/java/org/olat/core/util/i18n/ui/TranslationToolStartCrumbController.java index bd63a8b2538..15af7b4c197 100644 --- a/src/main/java/org/olat/core/util/i18n/ui/TranslationToolStartCrumbController.java +++ b/src/main/java/org/olat/core/util/i18n/ui/TranslationToolStartCrumbController.java @@ -50,6 +50,7 @@ import org.olat.core.util.i18n.I18nItem; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.prefs.Preferences; +import org.springframework.beans.factory.annotation.Autowired; /** * <h3>Description:</h3> This is the start controller for the translation tool @@ -112,6 +113,12 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { private Locale targetLocale; // true when the overlay files are edited and not the language files itself private boolean customizingMode = false; + + @Autowired + private I18nModule i18nModule; + @Autowired + private I18nManager i18nManager; + /** * Constructor for the start crumb controller * @@ -135,12 +142,12 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { FormUIFactory formFactory = FormUIFactory.getInstance(); - I18nManager i18nMgr = I18nManager.getInstance(); - List<String> bundleNames = I18nModule.getBundleNamesContainingI18nFiles(); + + List<String> bundleNames = i18nModule.getBundleNamesContainingI18nFiles(); String[] bundlesKeys = buildBundleArrayKeys(bundleNames, true); String[] bundlesValues = buildBundleArrayValues(bundleNames, true); // call init methods for each form part - initLanguageSelectorElements(ureq.getUserSession(), formFactory, i18nMgr, formLayout); + initLanguageSelectorElements(ureq.getUserSession(), formFactory, formLayout); initMissingItemsElements(formFactory, formLayout, bundlesKeys, bundlesValues); initExistingItemsElements(formFactory, formLayout, bundlesKeys, bundlesValues); initAllItemsElements(formFactory, formLayout, bundlesKeys, bundlesValues); @@ -155,22 +162,22 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { this.flc.contextPut("customizingPrefix", (customizingMode ? "customize." : "")); } - private void initLanguageSelectorElements(UserSession usess, FormUIFactory formFactory, I18nManager i18nMgr, + private void initLanguageSelectorElements(UserSession usess, FormUIFactory formFactory, FormItemContainer formLayout) { // Add language selection as a subform List<String> referenceLangs; if (customizingMode) { // Add all enabled languages that can be customized - referenceLangs = new ArrayList<String>(I18nModule.getEnabledLanguageKeys()); + referenceLangs = new ArrayList<>(i18nModule.getEnabledLanguageKeys()); } else { // Add configured reference languages in translation mode - referenceLangs = I18nModule.getTransToolReferenceLanguages(); + referenceLangs = i18nModule.getTransToolReferenceLanguages(); } String[] referencelangKeys = ArrayHelper.toArray(referenceLangs); String[] referenceLangValues = new String[referencelangKeys.length]; for (int i = 0; i < referencelangKeys.length; i++) { String key = referencelangKeys[i]; - String explLang = i18nMgr.getLanguageInEnglish(key, false); + String explLang = i18nManager.getLanguageInEnglish(key, false); String all = explLang; if (explLang != null && !explLang.equals(key)) all += " (" + key + ")"; referenceLangValues[i] = all; @@ -178,13 +185,13 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { ArrayHelper.sort(referencelangKeys, referenceLangValues, false, true, false); // Build css classes for reference languages // Use first reference locale as default - referenceLocale = i18nMgr.getLocaleOrNull(referenceLangs.get(0)); + referenceLocale = i18nManager.getLocaleOrNull(referenceLangs.get(0)); // Override with user preset Preferences guiPrefs = usess.getGuiPreferences(); String referencePrefs = (String) guiPrefs.get(I18nModule.class, I18nModule.GUI_PREFS_PREFERRED_REFERENCE_LANG, referenceLangs.get(0)); for (String refLang : referencelangKeys) { if (referencePrefs.equals(refLang)) { - referenceLocale = i18nMgr.getLocaleOrNull(referencePrefs); + referenceLocale = i18nManager.getLocaleOrNull(referencePrefs); break; } } @@ -197,10 +204,10 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { Set<String> translatableKeys; if (customizingMode) { // Use all enabled languages in customizing mode - translatableKeys = I18nModule.getOverlayLanguageKeys(); + translatableKeys = i18nModule.getOverlayLanguageKeys(); } else { // Allow translators to also translate other languages if they really desire. Show all languages. - translatableKeys = I18nModule.getTranslatableLanguageKeys(); + translatableKeys = i18nModule.getTranslatableLanguageKeys(); } String[] targetlangKeys = ArrayHelper.toArray(translatableKeys); String[] targetLangValues = new String[targetlangKeys.length]; @@ -211,10 +218,10 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { // overlay enabled, this would double the customizing extension to the key String explLang; if (customizingMode) { - String origKey = i18nMgr.createOrigianlLocaleKeyForOverlay(I18nModule.getAllLocales().get(key)); - explLang = i18nMgr.getLanguageInEnglish(origKey, true); + String origKey = i18nManager.createOrigianlLocaleKeyForOverlay(i18nModule.getAllLocales().get(key)); + explLang = i18nManager.getLanguageInEnglish(origKey, true); } else { - explLang = i18nMgr.getLanguageInEnglish(key, false); + explLang = i18nManager.getLanguageInEnglish(key, false); } String all = explLang; if (explLang != null && !explLang.equals(key)) all += " (" + key + ")"; @@ -226,26 +233,26 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { // Select current language if in list or the first one in the menu if (customizingMode) { // Use same as reference language in customizing mode - targetLocale = I18nModule.getOverlayLocales().get(referenceLocale); + targetLocale = i18nModule.getOverlayLocales().get(referenceLocale); // Disable target lang selection - user should only choose reference language, target is updated automatically targetLangSelection.setEnabled(false); } else { // Use users current language in translation mode targetLocale = getTranslator().getLocale(); - if (!Arrays.asList(targetlangKeys).contains(i18nMgr.getLocaleKey(targetLocale))) { - targetLocale = i18nMgr.getLocaleOrNull(targetlangKeys[0]); + if (!Arrays.asList(targetlangKeys).contains(i18nModule.getLocaleKey(targetLocale))) { + targetLocale = i18nManager.getLocaleOrNull(targetlangKeys[0]); } } - targetLangSelection.select(i18nMgr.getLocaleKey(targetLocale), true); + targetLangSelection.select(i18nModule.getLocaleKey(targetLocale), true); // Add lang key for image - don't use customizing lang key if (customizingMode) { - this.flc.contextPut("targetLangKey", i18nMgr.createOrigianlLocaleKeyForOverlay(targetLocale)); + this.flc.contextPut("targetLangKey", i18nManager.createOrigianlLocaleKeyForOverlay(targetLocale)); } else { this.flc.contextPut("targetLangKey", targetLocale.toString()); } targetLangSelection.addActionListener(FormEvent.ONCHANGE); // Add progress bar as normal component (not a form element) - int bundlesCount = i18nMgr.countBundles(null, true); + int bundlesCount = i18nManager.countBundles(null, true); progressBar = new ProgressBar("progressBar", 300, 0, 0, translate("start.progressBar.unitLabel", bundlesCount + "")); this.flc.put("progressBar", progressBar); } @@ -389,10 +396,9 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { * */ private void updateStatistics() { - I18nManager i18nMgr = I18nManager.getInstance(); // update progress bar with all package values - int toTranslateCount = i18nMgr.countI18nItems(referenceLocale, null, true); - int translatedCount = i18nMgr.countI18nItems(targetLocale, null, true); + int toTranslateCount = i18nManager.countI18nItems(referenceLocale, null, true); + int translatedCount = i18nManager.countI18nItems(targetLocale, null, true); progressBar.setMax(toTranslateCount); progressBar.setActual(translatedCount); // calculate package dependent values for missing keys display @@ -400,9 +406,9 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { if (missingBundle.equals(ALL_BUNDLES_IDENTIFYER)) { this.flc.contextPut("missingCount", (toTranslateCount - translatedCount)); } else { - int missingToTranslateCount = i18nMgr.countI18nItems(referenceLocale, missingBundle, missingBundlesIncludeBundlesChildrenSwitch + int missingToTranslateCount = i18nManager.countI18nItems(referenceLocale, missingBundle, missingBundlesIncludeBundlesChildrenSwitch .isSelected(0)); - int missingTranslatedCount = i18nMgr.countI18nItems(targetLocale, missingBundle, missingBundlesIncludeBundlesChildrenSwitch + int missingTranslatedCount = i18nManager.countI18nItems(targetLocale, missingBundle, missingBundlesIncludeBundlesChildrenSwitch .isSelected(0)); this.flc.contextPut("missingCount", (missingToTranslateCount - missingTranslatedCount)); } @@ -410,7 +416,7 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { if (existingBundle.equals(ALL_BUNDLES_IDENTIFYER)) { this.flc.contextPut("existingCount", translatedCount); } else { - int existingTranslateCount = i18nMgr.countI18nItems(referenceLocale, existingBundle, existingBundlesIncludeBundlesChildrenSwitch.isSelected(0)); + int existingTranslateCount = i18nManager.countI18nItems(referenceLocale, existingBundle, existingBundlesIncludeBundlesChildrenSwitch.isSelected(0)); this.flc.contextPut("existingCount", existingTranslateCount); } // calculate package dependent values for all keys display @@ -418,7 +424,7 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { if (allBundle.equals(ALL_BUNDLES_IDENTIFYER)) { this.flc.contextPut("allCount", toTranslateCount); } else { - int allToTranslateCount = i18nMgr.countI18nItems(referenceLocale, allBundle, allBundlesIncludeBundlesChildrenSwitch.isSelected(0)); + int allToTranslateCount = i18nManager.countI18nItems(referenceLocale, allBundle, allBundlesIncludeBundlesChildrenSwitch.isSelected(0)); this.flc.contextPut("allCount", allToTranslateCount); } } @@ -428,10 +434,9 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { * instead of the translation texts */ private void setCustomizingTextLabels() { - I18nManager i18nMgr = I18nManager.getInstance(); referenceLangSelection.setLabel("start.customize.referenceLangSelection", null); targetLangSelection.setLabel("start.customize.targetLangSelection", null); - int bundlesCount = i18nMgr.countBundles(null, true); + int bundlesCount = i18nManager.countBundles(null, true); progressBar.setUnitLabel(translate("start.customize.progressBar.unitLabel", bundlesCount + "")); missingTranslateButton.setI18nKey("generic.customize.translateButton"); allTranslateButton.setI18nKey("generic.customize.translateButton"); @@ -448,13 +453,12 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { * org.olat.core.gui.components.form.flexible.impl.FormEvent) */ protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { - I18nManager i18nMgr = I18nManager.getInstance(); if (source == targetLangSelection) { String langKey = targetLangSelection.getSelectedKey(); - targetLocale = i18nMgr.getLocaleOrNull(langKey); + targetLocale = i18nManager.getLocaleOrNull(langKey); // Add lang key for image - don't use customizing lang key if (customizingMode) { - this.flc.contextPut("targetLangKey", i18nMgr.createOrigianlLocaleKeyForOverlay(targetLocale)); + this.flc.contextPut("targetLangKey", i18nManager.createOrigianlLocaleKeyForOverlay(targetLocale)); } else { this.flc.contextPut("targetLangKey", targetLocale.toString()); } @@ -462,17 +466,17 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { } else if (source == referenceLangSelection) { String langKey = referenceLangSelection.getSelectedKey(); - referenceLocale = i18nMgr.getLocaleOrNull(langKey); + referenceLocale = i18nManager.getLocaleOrNull(langKey); // update in gui prefs Preferences guiPrefs = ureq.getUserSession().getGuiPreferences(); guiPrefs.putAndSave(I18nModule.class, I18nModule.GUI_PREFS_PREFERRED_REFERENCE_LANG, referenceLocale.toString()); // update GUI - this.flc.contextPut("referenceLangKey", i18nMgr.getLocaleKey(referenceLocale)); + this.flc.contextPut("referenceLangKey", i18nModule.getLocaleKey(referenceLocale)); // Set target language to reference language when in customizing mode if (customizingMode) { - targetLocale = I18nModule.getOverlayLocales().get(referenceLocale); - targetLangSelection.select(i18nMgr.getLocaleKey(targetLocale), true); - this.flc.contextPut("targetLangKey", i18nMgr.getLocaleKey(referenceLocale)); + targetLocale = i18nModule.getOverlayLocales().get(referenceLocale); + targetLangSelection.select(i18nModule.getLocaleKey(targetLocale), true); + this.flc.contextPut("targetLangKey", i18nModule.getLocaleKey(referenceLocale)); } updateStatistics(); @@ -481,10 +485,10 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { if (bundle.equals(ALL_BUNDLES_IDENTIFYER)) bundle = null; boolean includeBundlesChildren = missingBundlesIncludeBundlesChildrenSwitch.isSelected(0); // use the fallback locale because it won't find the key if not already translated in the searchLocale - List<I18nItem> i18nItems = i18nMgr.findMissingI18nItems(referenceLocale, targetLocale, bundle, + List<I18nItem> i18nItems = i18nManager.findMissingI18nItems(referenceLocale, targetLocale, bundle, includeBundlesChildren); boolean prioSortEnabled = missingBundlesPrioritySortSwitch.isSelected(0); - i18nMgr.sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); + i18nManager.sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); deactivateAndDisposeChildCrumbController(); // first the list controller TranslationToolI18nItemListCrumbController i18nItemlistCrumbCtr = new TranslationToolI18nItemListCrumbController(ureq, @@ -501,9 +505,9 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { String bundle = existingBundlesSelection.getSelectedKey(); if (bundle.equals(ALL_BUNDLES_IDENTIFYER)) bundle = null; boolean includeBundlesChildren = existingBundlesIncludeBundlesChildrenSwitch.isSelected(0); - List<I18nItem> i18nItems = i18nMgr.findExistingI18nItems(targetLocale, bundle, includeBundlesChildren); + List<I18nItem> i18nItems = i18nManager.findExistingI18nItems(targetLocale, bundle, includeBundlesChildren); boolean prioSortEnabled = existingBundlesPrioritySortSwitch.isSelected(0); - i18nMgr.sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); + i18nManager.sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); deactivateAndDisposeChildCrumbController(); // first the list controller TranslationToolI18nItemListCrumbController i18nItemlistCrumbCtr = new TranslationToolI18nItemListCrumbController(ureq, @@ -520,10 +524,10 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { String bundle = allBundlesSelection.getSelectedKey(); if (bundle.equals(ALL_BUNDLES_IDENTIFYER)) bundle = null; boolean includeBundlesChildren = allBundlesIncludeBundlesChildrenSwitch.isSelected(0); - List<I18nItem> i18nItems = i18nMgr.findExistingAndMissingI18nItems(referenceLocale, targetLocale, bundle, + List<I18nItem> i18nItems = i18nManager.findExistingAndMissingI18nItems(referenceLocale, targetLocale, bundle, includeBundlesChildren); boolean prioSortEnabled = allBundlesPrioritySortSwitch.isSelected(0); - i18nMgr.sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); + i18nManager.sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); deactivateAndDisposeChildCrumbController(); // first the list controller TranslationToolI18nItemListCrumbController i18nItemlistCrumbCtr = new TranslationToolI18nItemListCrumbController(ureq, @@ -545,14 +549,14 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { Locale searchLocale = (searchReferenceTargetSelection.getSelectedKey().equals(KEYS_REFERENCE) ? referenceLocale : targetLocale); if (searchKeyValueSelection.getSelectedKey().equals(KEYS_KEY)) { // use the fallback locale because it won't find the key if not already translated in the searchLocale - i18nItems = i18nMgr.findI18nItemsByKeySearch(searchString, I18nModule.getFallbackLocale(), targetLocale, bundle, + i18nItems = i18nManager.findI18nItemsByKeySearch(searchString, i18nModule.getFallbackLocale(), targetLocale, bundle, includeBundlesChildren); } else { - i18nItems = i18nMgr.findI18nItemsByValueSearch(searchString, searchLocale, targetLocale, bundle, + i18nItems = i18nManager.findI18nItemsByValueSearch(searchString, searchLocale, targetLocale, bundle, includeBundlesChildren); } boolean prioSortEnabled = searchBundlesPrioritySortSwitch.isSelected(0); - I18nManager.getInstance().sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); + i18nManager.sortI18nItems(i18nItems, prioSortEnabled, prioSortEnabled); deactivateAndDisposeChildCrumbController(); // first the list controller TranslationToolI18nItemListCrumbController i18nItemlistCrumbCtr = new TranslationToolI18nItemListCrumbController(ureq, @@ -607,28 +611,28 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { } else if (source == missingBundlesPrioritySortSwitch) { boolean enabled = missingBundlesPrioritySortSwitch.isSelected(0); - List<String> bundleNames = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> bundleNames = i18nModule.getBundleNamesContainingI18nFiles(); String[] bundlesKeys = buildBundleArrayKeys(bundleNames, enabled); String[] bundlesValues = buildBundleArrayValues(bundleNames, enabled); missingBundlesSelection.setKeysAndValues(bundlesKeys, bundlesValues, null); } else if (source == existingBundlesPrioritySortSwitch) { boolean enabled = existingBundlesPrioritySortSwitch.isSelected(0); - List<String> bundleNames = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> bundleNames = i18nModule.getBundleNamesContainingI18nFiles(); String[] bundlesKeys = buildBundleArrayKeys(bundleNames, enabled); String[] bundlesValues = buildBundleArrayValues(bundleNames, enabled); existingBundlesSelection.setKeysAndValues(bundlesKeys, bundlesValues, null); } else if (source == allBundlesPrioritySortSwitch) { boolean enabled = allBundlesPrioritySortSwitch.isSelected(0); - List<String> bundleNames = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> bundleNames = i18nModule.getBundleNamesContainingI18nFiles(); String[] bundlesKeys = buildBundleArrayKeys(bundleNames, enabled); String[] bundlesValues = buildBundleArrayValues(bundleNames, enabled); allBundlesSelection.setKeysAndValues(bundlesKeys, bundlesValues, null); } else if (source == searchBundlesPrioritySortSwitch) { boolean enabled = searchBundlesPrioritySortSwitch.isSelected(0); - List<String> bundleNames = I18nModule.getBundleNamesContainingI18nFiles(); + List<String> bundleNames = i18nModule.getBundleNamesContainingI18nFiles(); String[] bundlesKeys = buildBundleArrayKeys(bundleNames, enabled); String[] bundlesValues = buildBundleArrayValues(bundleNames, enabled); searchBundlesSelection.setKeysAndValues(bundlesKeys, bundlesValues, null); @@ -675,7 +679,7 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { for (String bundle : bundleNames) { copy.add(bundle); } - I18nManager.getInstance().sortBundles(copy, true); + i18nManager.sortBundles(copy, true); bundlesListKeys.addAll(copy); } else { bundlesListKeys.addAll(bundleNames); @@ -700,7 +704,7 @@ class TranslationToolStartCrumbController extends CrumbFormBasicController { for (String bundle : bundleNames) { copy.add(bundle); } - I18nManager.getInstance().sortBundles(copy, true); + i18nManager.sortBundles(copy, true); bundlesListValues.addAll(copy); } else { bundlesListValues.addAll(bundleNames); diff --git a/src/main/java/org/olat/course/assessment/_spring/assessmentContext.xml b/src/main/java/org/olat/course/assessment/_spring/assessmentContext.xml index 95cedcd772a..91b2d0754a2 100644 --- a/src/main/java/org/olat/course/assessment/_spring/assessmentContext.xml +++ b/src/main/java/org/olat/course/assessment/_spring/assessmentContext.xml @@ -10,13 +10,13 @@ <context:component-scan base-package="org.olat.course.assessment" /> - <bean id="assessmentNotificationsTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="assessmentNotificationsTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="assessmentNotificationsJob" /> <property name="cronExpression" value="1 * * * * ?" /> <property name="startDelay" value="55000" /> </bean> - <bean id="assessmentNotificationsJob" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="assessmentNotificationsJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.course.assessment.manager.AssessmentModeNotificationJob" /> </bean> diff --git a/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java b/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java index 44c2f7e8f00..1ae56fc5e9c 100644 --- a/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java +++ b/src/main/java/org/olat/course/certificate/manager/CertificatesManagerImpl.java @@ -874,7 +874,7 @@ public class CertificatesManagerImpl implements CertificatesManager, MessageList Float score = workUnit.getScore(); String lang = identity.getUser().getPreferences().getLanguage(); - Locale locale = I18nManager.getInstance().getLocaleOrDefault(lang); + Locale locale = i18nManager.getLocaleOrDefault(lang); Boolean passed = workUnit.getPassed(); Date dateCertification = certificate.getCreationDate(); Date dateFirstCertification = getDateFirstCertification(identity, resource.getKey()); diff --git a/src/main/java/org/olat/course/site/ui/CourseSiteAdminController.java b/src/main/java/org/olat/course/site/ui/CourseSiteAdminController.java index 02198886963..66e426c58ad 100644 --- a/src/main/java/org/olat/course/site/ui/CourseSiteAdminController.java +++ b/src/main/java/org/olat/course/site/ui/CourseSiteAdminController.java @@ -57,6 +57,7 @@ import org.olat.course.site.model.LanguageConfiguration; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; import org.olat.repository.controllers.ReferencableEntriesSearchController; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -80,6 +81,9 @@ public class CourseSiteAdminController extends FormBasicController { private CourseSiteConfiguration siteConfiguration; private final RepositoryManager repositoryManager; + @Autowired + private I18nModule i18nModule; + public CourseSiteAdminController(UserRequest ureq, WindowControl wControl, CourseSiteConfiguration siteConfiguration) { super(ureq, wControl); @@ -128,7 +132,7 @@ public class CourseSiteAdminController extends FormBasicController { } } - for(String langKey:I18nModule.getEnabledLanguageKeys()) { + for(String langKey:i18nModule.getEnabledLanguageKeys()) { if(langToConfigMap.containsKey(langKey)) { LanguageConfiguration langConfig = langToConfigMap.get(langKey); RepositoryEntry re = repositoryManager.lookupRepositoryEntryBySoftkey(langConfig.getRepoSoftKey(), false); diff --git a/src/main/java/org/olat/course/statistic/MySQLTempStatTableCreator.java b/src/main/java/org/olat/course/statistic/MySQLTempStatTableCreator.java index 28c96b5ebad..c64f4a3c402 100644 --- a/src/main/java/org/olat/course/statistic/MySQLTempStatTableCreator.java +++ b/src/main/java/org/olat/course/statistic/MySQLTempStatTableCreator.java @@ -98,7 +98,7 @@ public class MySQLTempStatTableCreator implements IStatisticUpdater { long fromSeconds = from.getTime() / 1000l; long untilSeconds = until.getTime() / 1000l; - jdbcTemplate_.update( + long numLoggingActions = jdbcTemplate_.update( "insert into o_stat_temptable (creationdate,businesspath,userproperty2,userproperty4,userproperty10,userproperty3) " + "select " + "creationdate,businesspath,userproperty2,userproperty4,userproperty10,userproperty3 " + @@ -107,8 +107,7 @@ public class MySQLTempStatTableCreator implements IStatisticUpdater { " where " + "actionverb='launch' and actionobject='node' and creationdate>from_unixtime('"+ fromSeconds +"') and creationdate<=from_unixtime('"+ untilSeconds +"');"); - long numLoggingActions = jdbcTemplate_.queryForLong("select count(*) from o_stat_temptable;"); - log_.info("updateStatistic: insert done. number of logging actions: "+numLoggingActions); + log_.info("updateStatistic: insert done. number of logging actions: " + numLoggingActions); } catch(RuntimeException e) { log_.warn("updateStatistic: ran into a RuntimeException: "+e, e); } catch(Error er) { diff --git a/src/main/java/org/olat/course/statistic/_spring/statisticsJobContext.xml b/src/main/java/org/olat/course/statistic/_spring/statisticsJobContext.xml index e079b063686..29d74357e51 100644 --- a/src/main/java/org/olat/course/statistic/_spring/statisticsJobContext.xml +++ b/src/main/java/org/olat/course/statistic/_spring/statisticsJobContext.xml @@ -6,7 +6,7 @@ <!-- --> - <bean id="updateStatisticsTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="updateStatisticsTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="org.olat.statistics.job.${cluster.singleton.services}" /> <!-- adjust cron style syntax for your notification needs "0 10 0 * *" e.g. 10 minutes after midnight @@ -27,12 +27,12 @@ <property name="startDelay" value="300000" /> </bean> - <bean id="org.olat.statistics.job.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="org.olat.statistics.job.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.course.statistic.UpdateStatisticsJob"/> </bean> <!-- dummy bean --> - <bean id="org.olat.statistics.job.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="org.olat.statistics.job.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <!-- NOTE: reusing the notifications.DummyJob here --> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> diff --git a/src/main/java/org/olat/dispatcher/LocaleNegotiator.java b/src/main/java/org/olat/dispatcher/LocaleNegotiator.java index b3d83dd2f70..b6d7893dfab 100644 --- a/src/main/java/org/olat/dispatcher/LocaleNegotiator.java +++ b/src/main/java/org/olat/dispatcher/LocaleNegotiator.java @@ -24,6 +24,7 @@ import java.util.Enumeration; import java.util.Locale; import java.util.Map; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.util.i18n.I18nModule; @@ -98,8 +99,9 @@ public class LocaleNegotiator { * match language and country and the final ty it with language only */ public static Locale getNegotiatedLocale(Locale loc) { - Map<String,Locale> allLocales = I18nModule.getAllLocales(); - Collection<String> enabledLanguageKeys = I18nModule.getEnabledLanguageKeys(); + I18nModule i18nModule = CoreSpringFactory.getImpl(I18nModule.class); + Map<String,Locale> allLocales = i18nModule.getAllLocales(); + Collection<String> enabledLanguageKeys = i18nModule.getEnabledLanguageKeys(); String lang = loc.getLanguage(); //search a direct match first de_CH_bs... diff --git a/src/main/java/org/olat/ims/qti/render/LocalizedXSLTransformer.java b/src/main/java/org/olat/ims/qti/render/LocalizedXSLTransformer.java index 2c7dba6f738..47ca6dcb0b7 100644 --- a/src/main/java/org/olat/ims/qti/render/LocalizedXSLTransformer.java +++ b/src/main/java/org/olat/ims/qti/render/LocalizedXSLTransformer.java @@ -51,13 +51,14 @@ import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.dom.DOMDocument; import org.dom4j.io.DocumentSource; +import org.olat.core.CoreSpringFactory; import org.olat.core.dispatcher.impl.StaticMediaDispatcher; import org.olat.core.gui.translator.Translator; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; -import org.olat.core.util.i18n.I18nManager; +import org.olat.core.util.i18n.I18nModule; import org.olat.ims.qti.QTI12ResultDetailsController; import org.olat.ims.resources.IMSEntityResolver; import org.xml.sax.EntityResolver; @@ -116,11 +117,12 @@ public class LocalizedXSLTransformer { */ // cluster_ok only in VM public static LocalizedXSLTransformer getInstance(Locale locale) { - LocalizedXSLTransformer instance = instanceHash.get(I18nManager.getInstance().getLocaleKey(locale)); + I18nModule i18nModule = CoreSpringFactory.getImpl(I18nModule.class); + LocalizedXSLTransformer instance = instanceHash.get(i18nModule.getLocaleKey(locale)); if (instance == null) { Translator trans = Util.createPackageTranslator(QTI12ResultDetailsController.class, locale); LocalizedXSLTransformer newInstance = new LocalizedXSLTransformer(trans); - instance = instanceHash.putIfAbsent(I18nManager.getInstance().getLocaleKey(locale), newInstance); //see javadoc of ConcurrentHashMap + instance = instanceHash.putIfAbsent(i18nModule.getLocaleKey(locale), newInstance); //see javadoc of ConcurrentHashMap if(instance == null) { //newInstance was put into the map instance = newInstance; } diff --git a/src/main/java/org/olat/ldap/LDAPLoginModule.java b/src/main/java/org/olat/ldap/LDAPLoginModule.java index e3e351c8486..839b802b92f 100644 --- a/src/main/java/org/olat/ldap/LDAPLoginModule.java +++ b/src/main/java/org/olat/ldap/LDAPLoginModule.java @@ -20,11 +20,14 @@ package org.olat.ldap; +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; + import java.io.FileInputStream; import java.security.KeyStore; import java.security.cert.Certificate; import java.security.cert.X509Certificate; -import java.text.ParseException; import java.util.Date; import java.util.Enumeration; @@ -35,10 +38,9 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; -import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; -import org.quartz.SchedulerException; +import org.quartz.Trigger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -267,21 +269,23 @@ public class LDAPLoginModule extends AbstractSpringModule { private void initCronSyncJob() { try { // Create job with cron trigger configuration - JobDetail jobDetail = new JobDetail("LDAP_Cron_Syncer_Job", Scheduler.DEFAULT_GROUP, LDAPUserSynchronizerJob.class); - CronTrigger trigger = new CronTrigger(); - trigger.setName("LDAP_Cron_Syncer_Trigger"); - trigger.setCronExpression(ldapSyncCronSyncExpression); + JobDetail jobDetail = newJob(LDAPUserSynchronizerJob.class) + .withIdentity("LDAP_Cron_Syncer_Job", Scheduler.DEFAULT_GROUP) + .build(); + Trigger trigger = newTrigger() + .withIdentity("LDAP_Cron_Syncer_Trigger") + .withSchedule(cronSchedule(ldapSyncCronSyncExpression)) + .build(); + // Schedule job now scheduler.scheduleJob(jobDetail, trigger); log.info("LDAP cron syncer is enabled with expression::" + ldapSyncCronSyncExpression); - } catch (ParseException e) { + } catch (Exception e) { setLdapSyncCronSync(false); log.error("LDAP configuration in attribute 'ldapSyncCronSyncExpression' is not valid (" + ldapSyncCronSyncExpression + "). See http://quartz.sourceforge.net/javadoc/org/quartz/CronTrigger.html to learn more about the cron syntax. Disabling LDAP cron syncing", e); - } catch (SchedulerException e) { - log.error("Error while scheduling LDAP cron sync job. Disabling LDAP cron syncing", e); } } diff --git a/src/main/java/org/olat/login/LoginAuthprovidersController.java b/src/main/java/org/olat/login/LoginAuthprovidersController.java index 08a57b79b85..83dccae10dd 100644 --- a/src/main/java/org/olat/login/LoginAuthprovidersController.java +++ b/src/main/java/org/olat/login/LoginAuthprovidersController.java @@ -84,6 +84,8 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl private Link anoLink; private StackedPanel dmzPanel; + @Autowired + private I18nModule i18nModule; @Autowired private LoginModule loginModule; @@ -283,14 +285,14 @@ public class LoginAuthprovidersController extends MainLayoutBasicController impl aboutVC.contextPut("version", Settings.getFullVersionInfo()); // Add translator and languages info I18nManager i18nMgr = I18nManager.getInstance(); - Collection<String> enabledKeysSet = I18nModule.getEnabledLanguageKeys(); + Collection<String> enabledKeysSet = i18nModule.getEnabledLanguageKeys(); Map<String, String> langNames = new HashMap<String, String>(); Map<String, String> langTranslators = new HashMap<String, String>(); String[] enabledKeys = ArrayHelper.toArray(enabledKeysSet); String[] names = new String[enabledKeys.length]; for (int i = 0; i < enabledKeys.length; i++) { String key = enabledKeys[i]; - String langName = i18nMgr.getLanguageInEnglish(key, I18nModule.isOverlayEnabled()); + String langName = i18nMgr.getLanguageInEnglish(key, i18nModule.isOverlayEnabled()); langNames.put(key, langName); names[i] = langName; String author = i18nMgr.getLanguageAuthor(key); diff --git a/src/main/java/org/olat/modules/lecture/_spring/lectureContext.xml b/src/main/java/org/olat/modules/lecture/_spring/lectureContext.xml index 0bda9385b78..7b76f6e05bc 100644 --- a/src/main/java/org/olat/modules/lecture/_spring/lectureContext.xml +++ b/src/main/java/org/olat/modules/lecture/_spring/lectureContext.xml @@ -77,7 +77,7 @@ </bean> <!-- Lectures reminder job --> - <bean id="reminderLecturesTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="reminderLecturesTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="reminderLecturesJob.${cluster.singleton.services}" /> <!-- adjust cron style syntax for your notification needs "0 10 0 * *" e.g. 10 minutes after midnight @@ -99,17 +99,17 @@ <property name="startDelay" value="60000" /> </bean> - <bean id="reminderLecturesJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="reminderLecturesJob.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.modules.lecture.manager.ReminderLecturesJob" /> </bean> <!-- dummy bean --> - <bean id="reminderLecturesJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="reminderLecturesJob.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> <!-- Lectures auto close job --> - <bean id="autoCloseLecturesTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="autoCloseLecturesTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="autoCloseLecturesJob.${cluster.singleton.services}" /> <!-- adjust cron style syntax for your notification needs "0 10 0 * *" e.g. 10 minutes after midnight @@ -131,12 +131,12 @@ <property name="startDelay" value="60000" /> </bean> - <bean id="autoCloseLecturesJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="autoCloseLecturesJob.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.modules.lecture.manager.AutoCloseLecturesJob" /> </bean> <!-- dummy bean --> - <bean id="autoCloseLecturesJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="autoCloseLecturesJob.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> diff --git a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties index 6b88fa06628..f955ec9ad8a 100644 --- a/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/lecture/ui/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Mon Jul 17 21:15:51 CEST 2017 +#Thu Aug 03 10:50:01 CEST 2017 active=Active add.lecture=New lecture block add.reason=Add reason @@ -81,7 +81,7 @@ form.managedflags.intro.short=This lecture block has been created by an external in.progress=In process info.lecture.block.optional=This lecture block is optional. info.no.lectures=You don't follow any lectures for the moment. -infos.participant.attendance.rate=Personal attendance rate: {0}% +infos.participant.attendance.rate=Personal attendance rate\: {0}% interceptor.start=You have now a roll call for the course "{0}" {1} from {4} until {5}. lecture.absence.default.authorized=Absence per default authorized lecture.admin.course.override.title=Configuration - can be overridden at course level @@ -223,7 +223,7 @@ table.header.entry=Course table.header.export=Export table.header.external.ref=Ext. ref. table.header.id=ID -table.header.infos=<i class='o_icon o_icon-lg o_icon_info'> </i> +table.header.infos=<i class\='o_icon o_icon-lg o_icon_info'> </i> table.header.lecture.1=1 table.header.lecture.10=10 table.header.lecture.11=11 @@ -242,6 +242,8 @@ table.header.lecture.block=Lecture block table.header.location=Location table.header.log.action=Action table.header.log.author=Changed by +table.header.log.effective.end.date=Effective end date +table.header.log.effective.lectures=Effective lectures table.header.log.planned.lectures=Planned lectures table.header.log.user=User table.header.planned.lectures=Lectures diff --git a/src/main/java/org/olat/modules/reminder/ReminderModule.java b/src/main/java/org/olat/modules/reminder/ReminderModule.java index 41d5017bbf8..7c800102df5 100644 --- a/src/main/java/org/olat/modules/reminder/ReminderModule.java +++ b/src/main/java/org/olat/modules/reminder/ReminderModule.java @@ -19,7 +19,8 @@ */ package org.olat.modules.reminder; -import java.text.ParseException; +import static org.quartz.CronScheduleBuilder.cronSchedule; + import java.util.ArrayList; import java.util.List; import java.util.TimeZone; @@ -32,8 +33,8 @@ import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.modules.reminder.model.SendTime; import org.quartz.CronTrigger; import org.quartz.Scheduler; -import org.quartz.SchedulerException; import org.quartz.Trigger; +import org.quartz.TriggerKey; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -48,6 +49,8 @@ import org.springframework.stereotype.Service; public class ReminderModule extends AbstractSpringModule { private static final OLog log = Tracing.createLoggerFor(ReminderModule.class); + + private final TriggerKey reminderTriggerKey = new TriggerKey("reminderTrigger", Scheduler.DEFAULT_GROUP); private static final String REMINDER_ENABLED = "remiNder.enabled"; private static final String SMS_ENABLED = "sms.enabled"; @@ -129,24 +132,28 @@ public class ReminderModule extends AbstractSpringModule { } return selectedSpi; } + /** * Default 0 0 9/1 * * ? * */ private void configureQuartzJob() { try { - Trigger trigger = scheduler.getTrigger("reminderTrigger", Scheduler.DEFAULT_GROUP); + Trigger trigger = scheduler.getTrigger(reminderTriggerKey); if(trigger instanceof CronTrigger) { CronTrigger cronTrigger = (CronTrigger)trigger; String currentCronExpression = cronTrigger.getCronExpression(); String cronExpression = getCronExpression(); if(!cronExpression.equals(currentCronExpression)) { log.info("Start reminder with this cron expression: " + cronExpression); - cronTrigger.setCronExpression(cronExpression); - scheduler.rescheduleJob("reminderTrigger", Scheduler.DEFAULT_GROUP, (Trigger)cronTrigger.clone()); + + Trigger newTrigger = cronTrigger.getTriggerBuilder() + .withSchedule(cronSchedule(cronExpression)) + .build(); + scheduler.rescheduleJob(reminderTriggerKey, newTrigger); } } - } catch (SchedulerException | ParseException e) { + } catch (Exception e) { log.error("", e); } } diff --git a/src/main/java/org/olat/modules/reminder/_spring/reminderContext.xml b/src/main/java/org/olat/modules/reminder/_spring/reminderContext.xml index 2e6f5480c79..e5e946533e8 100644 --- a/src/main/java/org/olat/modules/reminder/_spring/reminderContext.xml +++ b/src/main/java/org/olat/modules/reminder/_spring/reminderContext.xml @@ -25,12 +25,12 @@ </property> </bean> - <bean id="reminderTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="reminderTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="reminderJobDetail" /> <property name="cronExpression" value="0 0 9 * * ?" /> </bean> - <bean id="reminderJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="reminderJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.modules.reminder.manager.ReminderJob"/> </bean> diff --git a/src/main/java/org/olat/modules/video/_spring/videoContext.xml b/src/main/java/org/olat/modules/video/_spring/videoContext.xml index 7d962b2e32c..077b68312b4 100644 --- a/src/main/java/org/olat/modules/video/_spring/videoContext.xml +++ b/src/main/java/org/olat/modules/video/_spring/videoContext.xml @@ -6,7 +6,7 @@ http://www.springframework.org/schema/beans/spring-beans.xsd"> - <bean id="videoTranscodingTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="videoTranscodingTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="videoTranscodingJobDetail" /> <!-- adjust cron style syntax for your notification needs "0 10 0 * *" e.g. 10 minutes after midnight @@ -30,7 +30,7 @@ <property name="startDelay" value="350000" /> </bean> - <bean id="videoTranscodingJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> + <bean id="videoTranscodingJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.olat.modules.video.manager.VideoTranscodingJob" /> </bean> diff --git a/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java b/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java index 28d716d331b..269638ae7d8 100644 --- a/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java +++ b/src/main/java/org/olat/modules/video/manager/VideoManagerImpl.java @@ -86,7 +86,7 @@ import org.olat.repository.RepositoryEntryImportExport; import org.olat.repository.RepositoryEntryImportExport.RepositoryEntryImport; import org.olat.repository.RepositoryManager; import org.olat.resource.OLATResource; -import org.quartz.JobDetail; +import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; @@ -116,6 +116,8 @@ public class VideoManagerImpl implements VideoManager { private static final SimpleDateFormat displayDateFormat = new SimpleDateFormat("HH:mm:ss"); private static final SimpleDateFormat vttDateFormat = new SimpleDateFormat("HH:mm:ss.SSS"); + + private final JobKey videoJobKey = new JobKey("videoTranscodingJobDetail", Scheduler.DEFAULT_GROUP); @Autowired private MovieService movieService; @@ -427,8 +429,7 @@ public class VideoManagerImpl implements VideoManager { // 3) Start transcoding immediately, force job execution if (videoModule.isTranscodingLocal()) { try { - JobDetail detail = scheduler.getJobDetail("videoTranscodingJobDetail", Scheduler.DEFAULT_GROUP); - scheduler.triggerJob(detail.getName(), detail.getGroup()); + scheduler.triggerJob(videoJobKey); } catch (SchedulerException e) { log.error("Error while starting video transcoding job", e); } diff --git a/src/main/java/org/olat/modules/video/manager/VideoTranscodingJob.java b/src/main/java/org/olat/modules/video/manager/VideoTranscodingJob.java index 8bb6cfd3d27..b6508b5706b 100644 --- a/src/main/java/org/olat/modules/video/manager/VideoTranscodingJob.java +++ b/src/main/java/org/olat/modules/video/manager/VideoTranscodingJob.java @@ -41,7 +41,6 @@ import org.olat.modules.video.VideoTranscoding; import org.olat.resource.OLATResource; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; -import org.quartz.StatefulJob; /** * @@ -49,7 +48,7 @@ import org.quartz.StatefulJob; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class VideoTranscodingJob extends JobWithDB implements StatefulJob { +public class VideoTranscodingJob extends JobWithDB { /** * diff --git a/src/main/java/org/olat/modules/vitero/ViteroModule.java b/src/main/java/org/olat/modules/vitero/ViteroModule.java index 4b53ac19524..69ae3452f0b 100644 --- a/src/main/java/org/olat/modules/vitero/ViteroModule.java +++ b/src/main/java/org/olat/modules/vitero/ViteroModule.java @@ -19,8 +19,11 @@ */ package org.olat.modules.vitero; +import static org.quartz.CronScheduleBuilder.cronSchedule; +import static org.quartz.JobBuilder.newJob; +import static org.quartz.TriggerBuilder.newTrigger; + import java.net.URI; -import java.text.ParseException; import java.util.Calendar; import javax.ws.rs.core.UriBuilder; @@ -32,10 +35,10 @@ import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.modules.vitero.manager.ViteroZombieSlayerJob; -import org.quartz.CronTrigger; import org.quartz.JobDetail; import org.quartz.Scheduler; -import org.quartz.SchedulerException; +import org.quartz.Trigger; +import org.quartz.TriggerKey; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -146,20 +149,25 @@ public class ViteroModule extends AbstractSpringModule implements ConfigOnOff { private void initCronJob() { try { - if(scheduler.getTrigger("Vitero_Cleaner_Cron_Trigger", Scheduler.DEFAULT_GROUP) == null) { - JobDetail jobDetail = new JobDetail("Vitero_Cleaner_Cron_Job", Scheduler.DEFAULT_GROUP, ViteroZombieSlayerJob.class); - CronTrigger trigger = new CronTrigger(); + TriggerKey triggerKey = new TriggerKey("Vitero_Cleaner_Cron_Trigger", Scheduler.DEFAULT_GROUP); + if(scheduler.getTrigger(triggerKey) == null) { + + // Create job with cron trigger configuration + JobDetail jobDetail = newJob(ViteroZombieSlayerJob.class) + .withIdentity("Vitero_Cleaner_Cron_Job", Scheduler.DEFAULT_GROUP) + .build(); Calendar cal = Calendar.getInstance(); cal.add(Calendar.SECOND, 30); - trigger.setStartTime(cal.getTime()); - trigger.setName("Vitero_Cleaner_Cron_Trigger"); - trigger.setCronExpression(cronExpression); + Trigger trigger = newTrigger() + .withIdentity("Vitero_Cleaner_Cron_Trigger") + .withSchedule(cronSchedule(cronExpression)) + .startAt(cal.getTime()) + .build(); + scheduler.scheduleJob(jobDetail, trigger); } - } catch (ParseException e) { - log.error("Cannot start the Quartz Job which clean the Vitero rooms", e); - } catch (SchedulerException e) { + } catch (Exception e) { log.error("Cannot start the Quartz Job which clean the Vitero rooms", e); } } diff --git a/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml b/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml index 94c3cbd3be9..5d5f9f883bd 100644 --- a/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml +++ b/src/main/java/org/olat/portfolio/_spring/portfolioContext.xml @@ -69,7 +69,7 @@ </bean> <!-- Deadline Job --> - <bean id="epDeadlineTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="epDeadlineTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="epDeadlineJob.${cluster.singleton.services}" /> <!-- adjust cron style syntax for your notification needs "0 10 0 * *" e.g. 10 minutes after midnight @@ -88,16 +88,16 @@ <property name="startDelay" value="60000" /> </bean> - <bean id="epDeadlineJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="epDeadlineJob.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.portfolio.manager.EPDeadlineJob" /> </bean> <!-- dummy bean --> - <bean id="epDeadlineJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="epDeadlineJob.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> - <bean id="invitationCleanupTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="invitationCleanupTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="invitationCleanupJob.${cluster.singleton.services}" /> <!-- adjust cron style syntax for your notification needs "0 10 0 * *" e.g. 10 minutes after midnight @@ -119,11 +119,11 @@ <property name="startDelay" value="150000" /> </bean> - <bean id="invitationCleanupJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="invitationCleanupJob.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.portfolio.manager.InvitationCleanupJob" /> </bean> <!-- dummy bean --> - <bean id="invitationCleanupJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="invitationCleanupJob.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> diff --git a/src/main/java/org/olat/registration/LanguageChooserController.java b/src/main/java/org/olat/registration/LanguageChooserController.java index a321d1cfa26..4c06a4c99f2 100644 --- a/src/main/java/org/olat/registration/LanguageChooserController.java +++ b/src/main/java/org/olat/registration/LanguageChooserController.java @@ -41,12 +41,10 @@ import org.olat.core.util.event.MultiUserEvent; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.resource.OresHelper; import org.olat.dispatcher.LocaleNegotiator; +import org.springframework.beans.factory.annotation.Autowired; /** - * Description:<br> - * TODO: srosse Class Description for LanguageChooserController - * * <P> * Initial Date: 17 nov. 2009 <br> * @author srosse, stephane.rosse@frentix.com, www.frentix.com @@ -59,6 +57,8 @@ public class LanguageChooserController extends FormBasicController { private boolean fireStandardEvent = true; + @Autowired + private I18nManager i18nManager; /** * @param ureq @@ -94,7 +94,7 @@ public class LanguageChooserController extends FormBasicController { @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == langs) { - Locale loc = I18nManager.getInstance().getLocaleOrDefault(getSelectedLanguage()); + Locale loc = i18nManager.getLocaleOrDefault(getSelectedLanguage()); MultiUserEvent mue = new LanguageChangedEvent(loc, ureq); setLocale(loc, true); ureq.getUserSession().setLocale(loc); @@ -124,7 +124,7 @@ public class LanguageChooserController extends FormBasicController { */ @Override protected void initForm(FormItemContainer formLayout, Controller listener, final UserRequest ureq) { - Map<String, String> languages = I18nManager.getInstance().getEnabledLanguagesTranslated(); + Map<String, String> languages = i18nManager.getEnabledLanguagesTranslated(); String[] langKeys = StringHelper.getMapKeysAsStringArray(languages); String[] langValues = StringHelper.getMapValuesAsStringArray(languages); ArrayHelper.sort(langKeys, langValues, false, true, false); diff --git a/src/main/java/org/olat/registration/PwChangeController.java b/src/main/java/org/olat/registration/PwChangeController.java index 5b10fd76a14..1a4f1e29d81 100644 --- a/src/main/java/org/olat/registration/PwChangeController.java +++ b/src/main/java/org/olat/registration/PwChangeController.java @@ -54,6 +54,7 @@ import org.olat.core.id.UserConstants; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; import org.olat.core.util.i18n.I18nManager; +import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.mail.MailBundle; import org.olat.core.util.mail.MailHelper; import org.olat.core.util.mail.MailManager; @@ -70,8 +71,6 @@ import org.springframework.beans.factory.annotation.Autowired; */ public class PwChangeController extends BasicController { - private static String SEPARATOR = "____________________________________________________________________\n"; - private Panel passwordPanel; private Link pwchangeHomelink; private final VelocityContainer myContent; @@ -85,6 +84,10 @@ public class PwChangeController extends BasicController { private String pwKey; private TemporaryKey tempKey; + @Autowired + private I18nModule i18nModule; + @Autowired + private I18nManager i18nManager; @Autowired private UserModule userModule; @Autowired @@ -248,7 +251,7 @@ public class PwChangeController extends BasicController { return null; } Preferences prefs = identity.getUser().getPreferences(); - Locale locale = I18nManager.getInstance().getLocaleOrDefault(prefs.getLanguage()); + Locale locale = i18nManager.getLocaleOrDefault(prefs.getLanguage()); ureq.getUserSession().setLocale(locale); myContent.contextPut("locale", locale); @@ -274,8 +277,8 @@ public class PwChangeController extends BasicController { .append("<div class='o_body'>") .append(userTrans.translate("pwchange.headline")) .append(userTrans.translate("pwchange.intro", new String[] { identity.getName() })) - .append(userTrans.translate("pwchange.body", new String[] { serverpath, tk.getRegistrationKey(), I18nManager.getInstance().getLocaleKey(ureq.getLocale()) })) - .append(userTrans.translate("pwchange.body.alt", new String[] { serverpath, tk.getRegistrationKey(), I18nManager.getInstance().getLocaleKey(ureq.getLocale()) })) + .append(userTrans.translate("pwchange.body", new String[] { serverpath, tk.getRegistrationKey(), i18nModule.getLocaleKey(ureq.getLocale()) })) + .append(userTrans.translate("pwchange.body.alt", new String[] { serverpath, tk.getRegistrationKey(), i18nModule.getLocaleKey(ureq.getLocale()) })) .append("</div>") .append("<div class='o_footer'>") .append(userTrans.translate("reg.wherefrom", new String[] { serverpath, today, ip })) diff --git a/src/main/java/org/olat/registration/RegistrationController.java b/src/main/java/org/olat/registration/RegistrationController.java index b37da45a021..4fde7fa7f95 100644 --- a/src/main/java/org/olat/registration/RegistrationController.java +++ b/src/main/java/org/olat/registration/RegistrationController.java @@ -97,6 +97,8 @@ public class RegistrationController extends BasicController implements Activatea private String uniqueRegistrationKey; private TemporaryKey tempKey; + @Autowired + private I18nModule i18nModule; @Autowired private I18nManager i18nManager; @Autowired @@ -131,7 +133,7 @@ public class RegistrationController extends BasicController implements Activatea // support for legacy lang parameter lang = ureq.getParameter("lang"); } - if (lang != null && ! lang.equals(i18nManager.getLocaleKey(getLocale()))) { + if (lang != null && ! lang.equals(i18nModule.getLocaleKey(getLocale()))) { Locale loc = i18nManager.getLocaleOrDefault(lang); ureq.getUserSession().setLocale(loc); setLocale(loc, true); @@ -154,7 +156,7 @@ public class RegistrationController extends BasicController implements Activatea // render in a modal dialog, no need to add the 3cols layout controller // wrapper //fxdiff FXOLAT-113: business path in DMZ - if(I18nModule.getEnabledLanguageKeys().size() == 1) { + if(i18nModule.getEnabledLanguageKeys().size() == 1) { wizInfoController.setCurStep(2); createEmailForm(ureq); } else { @@ -169,7 +171,7 @@ public class RegistrationController extends BasicController implements Activatea // error, there should be an entry showError("regkey.missingentry"); //fxdiff FXOLAT-113: business path in DMZ - if(I18nModule.getEnabledLanguageKeys().size() == 1) { + if(i18nModule.getEnabledLanguageKeys().size() == 1) { wizInfoController.setCurStep(2); createEmailForm(ureq); } else { @@ -232,7 +234,7 @@ public class RegistrationController extends BasicController implements Activatea } private void createRegForm2(UserRequest ureq, String proposedUsername, boolean userInUse, boolean usernameReadonly) { - registrationForm = new RegistrationForm2(ureq, getWindowControl(), I18nManager.getInstance().getLocaleKey(getLocale()), proposedUsername, userInUse, usernameReadonly); + registrationForm = new RegistrationForm2(ureq, getWindowControl(), i18nModule.getLocaleKey(getLocale()), proposedUsername, userInUse, usernameReadonly); listenTo(registrationForm); regarea.setContent(registrationForm.getInitialComponent()); } @@ -303,11 +305,11 @@ public class RegistrationController extends BasicController implements Activatea if (tk == null) tk = registrationManager.createTemporaryKeyByEmail(email, ip, RegistrationManager.REGISTRATION); myContent.contextPut("regKey", tk.getRegistrationKey()); - String link = serverpath + "/dmz/registration/index.html?key=" + tk.getRegistrationKey() + "&language=" + i18nManager.getLocaleKey(ureq.getLocale()); + String link = serverpath + "/dmz/registration/index.html?key=" + tk.getRegistrationKey() + "&language=" + i18nModule.getLocaleKey(ureq.getLocale()); String[] bodyAttrs = new String[]{ serverpath, //0 tk.getRegistrationKey(), //1 - i18nManager.getLocaleKey(ureq.getLocale()), //2 + i18nModule.getLocaleKey(ureq.getLocale()), //2 "<a href=\"" + link + "\">" + link + "</a>" //3 }; @@ -370,8 +372,8 @@ public class RegistrationController extends BasicController implements Activatea if (event == Event.DONE_EVENT) { String lang = registrationForm.getLangKey(); // change language if different then current language - if (! lang.equals(I18nManager.getInstance().getLocaleKey(ureq.getLocale()))) { - Locale loc = I18nManager.getInstance().getLocaleOrDefault(lang); + if (! lang.equals(i18nModule.getLocaleKey(ureq.getLocale()))) { + Locale loc = i18nManager.getLocaleOrDefault(lang); ureq.getUserSession().setLocale(loc); getTranslator().setLocale(loc); } diff --git a/src/main/java/org/olat/registration/RegistrationForm2.java b/src/main/java/org/olat/registration/RegistrationForm2.java index f4fed839d77..02bc13267e4 100644 --- a/src/main/java/org/olat/registration/RegistrationForm2.java +++ b/src/main/java/org/olat/registration/RegistrationForm2.java @@ -77,6 +77,8 @@ public class RegistrationForm2 extends FormBasicController { @Autowired private UserModule userModule; + @Autowired + private I18nManager i18nManager; /** * @param name @@ -174,7 +176,7 @@ public class RegistrationForm2 extends FormBasicController { uifactory.addSpacerElement("lang", formLayout, true); // second the user language - Map<String, String> languages = I18nManager.getInstance().getEnabledLanguagesTranslated(); + Map<String, String> languages = i18nManager.getEnabledLanguagesTranslated(); lang = uifactory.addDropdownSingleselect("user.language", formLayout, StringHelper.getMapKeysAsStringArray(languages), StringHelper.getMapValuesAsStringArray(languages), diff --git a/src/main/java/org/olat/registration/restapi/RegistrationWebService.java b/src/main/java/org/olat/registration/restapi/RegistrationWebService.java index 14be04afef3..2305d8c1037 100644 --- a/src/main/java/org/olat/registration/restapi/RegistrationWebService.java +++ b/src/main/java/org/olat/registration/restapi/RegistrationWebService.java @@ -45,7 +45,7 @@ import org.olat.core.helpers.Settings; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.Util; -import org.olat.core.util.i18n.I18nManager; +import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.mail.MailBundle; import org.olat.core.util.mail.MailManager; import org.olat.core.util.mail.MailerResult; @@ -126,7 +126,7 @@ public class RegistrationWebService { String[] bodyAttrs = new String[] { serverpath, tk.getRegistrationKey(), - I18nManager.getInstance().getLocaleKey(locale) + CoreSpringFactory.getImpl(I18nModule.class).getLocaleKey(locale) }; String[] whereFromAttrs = new String [] { serverpath, today, ip }; String body = translator.translate("reg.body", bodyAttrs) + SEPARATOR + translator.translate("reg.wherefrom", whereFromAttrs); diff --git a/src/main/java/org/olat/repository/_spring/repositoryContext.xml b/src/main/java/org/olat/repository/_spring/repositoryContext.xml index 42418ac70ce..9c0dc8925cf 100644 --- a/src/main/java/org/olat/repository/_spring/repositoryContext.xml +++ b/src/main/java/org/olat/repository/_spring/repositoryContext.xml @@ -10,13 +10,13 @@ <context:component-scan base-package="org.olat.repository" /> - <bean id="automaticLifecycleTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="automaticLifecycleTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="automaticLifecycleJob" /> <property name="cronExpression" value="0 45 5 * * ?" /> <property name="startDelay" value="55000" /> </bean> - <bean id="automaticLifecycleJob" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="automaticLifecycleJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.repository.manager.AutomaticLifecycleJob" /> </bean> diff --git a/src/main/java/org/olat/resource/accesscontrol/_spring/acContext.xml b/src/main/java/org/olat/resource/accesscontrol/_spring/acContext.xml index 00e121ceeec..6b353d79936 100644 --- a/src/main/java/org/olat/resource/accesscontrol/_spring/acContext.xml +++ b/src/main/java/org/olat/resource/accesscontrol/_spring/acContext.xml @@ -73,14 +73,14 @@ <property name="order" value="7220" /> </bean> - <bean id="acReservationCleanupJob" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> + <bean id="acReservationCleanupJob" class="org.springframework.scheduling.quartz.SimpleTriggerFactoryBean"> <property name="jobDetail" ref="acReservationCleanupJobDetail"/> <!-- 60 seconds --> <property name="repeatInterval" value="60000"/> <property name="startDelay" value="30000" /> </bean> - <bean id="acReservationCleanupJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"> + <bean id="acReservationCleanupJobDetail" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.olat.resource.accesscontrol.manager.ReservationsJob" /> </bean> diff --git a/src/main/java/org/olat/restapi/_spring/restApiContext.xml b/src/main/java/org/olat/restapi/_spring/restApiContext.xml index 7836d4a86a0..74745c58a9b 100644 --- a/src/main/java/org/olat/restapi/_spring/restApiContext.xml +++ b/src/main/java/org/olat/restapi/_spring/restApiContext.xml @@ -51,7 +51,7 @@ </property> </bean> - <bean id="systemSamplerTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="systemSamplerTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="systemSamplerJob" /> <!-- adjust cron style syntax for your needs A "Cron-Expression" is a string comprised of 6 or 7 fields separated by white space. The 6 mandatory and 1 optional fields are as follows: @@ -71,32 +71,32 @@ <property name="startDelay" value="60000" /> </bean> - <bean id="systemSamplerJob" class="org.springframework.scheduling.quartz.JobDetailBean"> + <bean id="systemSamplerJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.olat.restapi.system.SamplerJob" /> </bean> - <bean id="procSamplerTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="procSamplerTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="procSamplerJob" /> <property name="cronExpression" value="5 3,8,13,18,23,28,33,38,43,48,53,58 * * * ?" /> <property name="startDelay" value="30000" /> </bean> - <bean id="procSamplerJob" class="org.springframework.scheduling.quartz.JobDetailBean"> + <bean id="procSamplerJob" class="org.springframework.scheduling.quartz.JobDetailFactoryBean"> <property name="jobClass" value="org.olat.restapi.system.ProcSamplerJob" /> </bean> <!-- Deadline Job --> - <bean id="restTokenTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> + <bean id="restTokenTrigger" class="org.springframework.scheduling.quartz.CronTriggerFactoryBean"> <property name="jobDetail" ref="restTokenJob.${cluster.singleton.services}" /> <!-- every day at 1:21 --> <property name="cronExpression" value="0 21 1 * * ?" /> <property name="startDelay" value="60000" /> </bean> - <bean id="restTokenJob.enabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="restTokenJob.enabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.restapi.security.RestTokenJob" /> </bean> - <bean id="restTokenJob.disabled" class="org.springframework.scheduling.quartz.JobDetailBean" lazy-init="true"> + <bean id="restTokenJob.disabled" class="org.springframework.scheduling.quartz.JobDetailFactoryBean" lazy-init="true"> <property name="jobClass" value="org.olat.core.commons.services.scheduler.DummyJob" /> </bean> diff --git a/src/main/java/org/olat/restapi/i18n/I18nWebService.java b/src/main/java/org/olat/restapi/i18n/I18nWebService.java index dedd11c75ba..20653689525 100644 --- a/src/main/java/org/olat/restapi/i18n/I18nWebService.java +++ b/src/main/java/org/olat/restapi/i18n/I18nWebService.java @@ -31,6 +31,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; +import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.util.StringHelper; import org.olat.core.util.i18n.I18nManager; @@ -83,7 +84,8 @@ public class I18nWebService { @Path("{package}/{key}") @Produces(MediaType.TEXT_PLAIN) public Response getTranslation(@PathParam("package") String packageName, @PathParam("key") String key, @QueryParam("locale") String localeKey, @Context HttpServletRequest request) { - I18nManager i18n = I18nManager.getInstance(); + I18nManager i18n = CoreSpringFactory.getImpl(I18nManager.class); + I18nModule i18nModule = CoreSpringFactory.getImpl(I18nModule.class); Locale locale = null; if(StringHelper.containsNonWhitespace(localeKey)) { @@ -96,10 +98,10 @@ public class I18nWebService { } if(locale == null) { - locale = I18nModule.getDefaultLocale(); + locale = i18nModule.getDefaultLocale(); } - boolean overlayEnabled = I18nModule.isOverlayEnabled(); + boolean overlayEnabled = i18nModule.isOverlayEnabled(); String val = i18n.getLocalizedString(packageName, key, EMPTY_ARRAY, locale, overlayEnabled, true); return Response.ok(val).build(); } diff --git a/src/main/java/org/olat/restapi/system/NotificationsAdminWebService.java b/src/main/java/org/olat/restapi/system/NotificationsAdminWebService.java index a75227d390b..d6eb54c5816 100644 --- a/src/main/java/org/olat/restapi/system/NotificationsAdminWebService.java +++ b/src/main/java/org/olat/restapi/system/NotificationsAdminWebService.java @@ -33,8 +33,8 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.restapi.system.vo.NotificationsStatus; -import org.quartz.JobDetail; import org.quartz.JobExecutionContext; +import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; @@ -46,6 +46,8 @@ public class NotificationsAdminWebService { private static final OLog log = Tracing.createLoggerFor(NotificationsAdminWebService.class); + private final JobKey notificationsJobKey = new JobKey("org.olat.notifications.job.enabled", Scheduler.DEFAULT_GROUP); + /** * Return the status of the notifications job: running, stopped * @response.representation.200.mediaType application/xml, application/json @@ -77,10 +79,9 @@ public class NotificationsAdminWebService { private String getJobStatus() { try { Scheduler scheduler = CoreSpringFactory.getImpl(Scheduler.class); - @SuppressWarnings("unchecked") List<JobExecutionContext> jobs = scheduler.getCurrentlyExecutingJobs(); for(JobExecutionContext job:jobs) { - if("org.olat.notifications.job.enabled".equals(job.getJobDetail().getName())) { + if("org.olat.notifications.job.enabled".equals(job.getJobDetail().getKey().getName())) { return "running"; } } @@ -103,9 +104,7 @@ public class NotificationsAdminWebService { public Response setStatus(@FormParam("status") String status) { if("running".equals(status)) { try { - Scheduler scheduler = CoreSpringFactory.getImpl(Scheduler.class); - JobDetail detail = scheduler.getJobDetail("org.olat.notifications.job.enabled", Scheduler.DEFAULT_GROUP); - scheduler.triggerJob(detail.getName(), detail.getGroup()); + CoreSpringFactory.getImpl(Scheduler.class).triggerJob(notificationsJobKey); } catch (SchedulerException e) { log.error("", e); } diff --git a/src/main/java/org/olat/search/service/SearchServiceImpl.java b/src/main/java/org/olat/search/service/SearchServiceImpl.java index b1fe565851f..6d886142b7e 100644 --- a/src/main/java/org/olat/search/service/SearchServiceImpl.java +++ b/src/main/java/org/olat/search/service/SearchServiceImpl.java @@ -80,6 +80,7 @@ import org.olat.search.service.indexer.MainIndexer; import org.olat.search.service.searcher.JmsSearchProvider; import org.olat.search.service.spell.SearchSpellChecker; import org.quartz.JobDetail; +import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; @@ -90,6 +91,8 @@ import org.quartz.SchedulerException; public class SearchServiceImpl implements SearchService, GenericEventListener { private static final OLog log = Tracing.createLoggerFor(SearchServiceImpl.class); + private final JobKey indexerJobKey = new JobKey("org.olat.search.job.enabled", Scheduler.DEFAULT_GROUP); + private Index indexer; private SearchModule searchModuleConfig; private MainIndexer mainIndexer; @@ -180,13 +183,13 @@ public class SearchServiceImpl implements SearchService, GenericEventListener { if (indexer==null) throw new AssertException ("Try to call startIndexing() but indexer is null"); try { - JobDetail detail = scheduler.getJobDetail("org.olat.search.job.enabled", Scheduler.DEFAULT_GROUP); + JobDetail detail = scheduler.getJobDetail(indexerJobKey); if(detail == null) { if("disabled".equals(indexerCron)) { indexer.startFullIndex(); } } else { - scheduler.triggerJob(detail.getName(), detail.getGroup()); + scheduler.triggerJob(indexerJobKey); } log.info("startIndexing..."); } catch (SchedulerException e) { @@ -202,13 +205,13 @@ public class SearchServiceImpl implements SearchService, GenericEventListener { if (indexer==null) throw new AssertException ("Try to call stopIndexing() but indexer is null"); try { - JobDetail detail = scheduler.getJobDetail("org.olat.search.job.enabled", Scheduler.DEFAULT_GROUP); + JobDetail detail = scheduler.getJobDetail(indexerJobKey); if(detail == null) { if("disabled".equals(indexerCron)) { indexer.stopFullIndex(); } } else { - scheduler.interrupt(detail.getName(), detail.getGroup()); + scheduler.interrupt(indexerJobKey); } log.info("stopIndexing."); } catch (SchedulerException e) { @@ -243,8 +246,7 @@ public class SearchServiceImpl implements SearchService, GenericEventListener { if (startingFullIndexingAllowed()) { try { - JobDetail detail = scheduler.getJobDetail("org.olat.search.job.enabled", Scheduler.DEFAULT_GROUP); - scheduler.triggerJob(detail.getName(), detail.getGroup()); + scheduler.triggerJob(indexerJobKey); } catch (SchedulerException e) { log.error("", e); } diff --git a/src/main/java/org/olat/user/ChangePrefsController.java b/src/main/java/org/olat/user/ChangePrefsController.java index f5c493e634e..0d1bd3f44c0 100644 --- a/src/main/java/org/olat/user/ChangePrefsController.java +++ b/src/main/java/org/olat/user/ChangePrefsController.java @@ -52,7 +52,7 @@ import org.olat.core.id.context.HistoryModule; import org.olat.core.util.StringHelper; import org.olat.core.util.UserSession; import org.olat.core.util.WebappHelper; -import org.olat.core.util.i18n.I18nManager; +import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.prefs.Preferences; import org.olat.core.util.prefs.PreferencesFactory; import org.olat.core.util.session.UserSessionManager; @@ -296,11 +296,13 @@ class UserPrefsResetForm extends FormBasicController { private MultipleSelectionElement resetElements; private String[] keys, values; - private final UserSessionManager sessionManager; + @Autowired + private I18nModule i18nModule; + @Autowired + private UserSessionManager sessionManager; public UserPrefsResetForm(UserRequest ureq, WindowControl wControl, Identity changeableIdentity) { super(ureq, wControl); - sessionManager = CoreSpringFactory.getImpl(UserSessionManager.class); tobeChangedIdentity = changeableIdentity; initForm(ureq); } @@ -363,7 +365,7 @@ class UserPrefsResetForm extends FormBasicController { if(logout) { //if logout, need a redirect to the login page - String lang = I18nManager.getInstance().getLocaleKey(ureq.getLocale()); + String lang = i18nModule.getLocaleKey(ureq.getLocale()); ureq.getDispatchResult().setResultingMediaResource( new RedirectMediaResource(WebappHelper.getServletContextPath() + "/dmz/?lang=" + lang + "&logout=true")); } diff --git a/src/main/java/org/olat/user/PreferencesFormController.java b/src/main/java/org/olat/user/PreferencesFormController.java index 76ef2677b9f..981570a7e58 100644 --- a/src/main/java/org/olat/user/PreferencesFormController.java +++ b/src/main/java/org/olat/user/PreferencesFormController.java @@ -50,6 +50,7 @@ import org.olat.core.util.Util; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.i18n.I18nModule; import org.olat.core.util.mail.MailModule; +import org.springframework.beans.factory.annotation.Autowired; /** * This form controller provides an interface to change the user's system @@ -70,6 +71,9 @@ public class PreferencesFormController extends FormBasicController { private Identity tobeChangedIdentity; private SingleSelection language, fontsize, charset, notificationInterval, mailSystem; private static final String[] mailIntern = new String[]{"intern.only","send.copy"}; + + @Autowired + private I18nModule i18nModule; /** * Constructor for the user preferences form @@ -193,7 +197,7 @@ public class PreferencesFormController extends FormBasicController { String langKey = prefs.getLanguage(); // Preselect the users language if available. Maye not anymore enabled on // this server - if (prefs.getLanguage() != null && I18nModule.getEnabledLanguageKeys().contains(langKey)) { + if (prefs.getLanguage() != null && i18nModule.getEnabledLanguageKeys().contains(langKey)) { language.select(prefs.getLanguage(), true); } else { language.select(I18nModule.getDefaultLocale().toString(), true); diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties index 86b7a6f281c..26632eae883 100644 --- a/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/user/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Thu Sep 03 11:09:03 CEST 2015 +#Thu Aug 03 10:54:35 CEST 2017 Failed=File upload failed. NoImage=This file format cannot be uploaded as image. ULLimitExceeded=Your image must not exceed {0} kByte. @@ -65,7 +65,7 @@ interval.two-hourly=Every two hours interval.weekly=Weekly landing.pages=Landing page logo.header=Enterprise logo (Formats .jpg .jpeg .png .gif only) -logo.select=$:ul.select +logo.select=$\:ul.select mail.intern.only=Send e-mails to the OpenOLAT internal inbox mail.send.copy=Send e-mails to the OpenOLAT internal inbox and the address {0} mail.system=E-mail delivery diff --git a/src/test/java/org/olat/core/commons/services/scheduler/SchedulerTest.java b/src/test/java/org/olat/core/commons/services/scheduler/SchedulerTest.java index 33dbdb7d6c6..6d0a9d0ac8f 100644 --- a/src/test/java/org/olat/core/commons/services/scheduler/SchedulerTest.java +++ b/src/test/java/org/olat/core/commons/services/scheduler/SchedulerTest.java @@ -25,19 +25,22 @@ */ package org.olat.core.commons.services.scheduler; -import static org.junit.Assert.assertEquals; +import static org.quartz.JobBuilder.newJob; import java.text.ParseException; import java.util.Calendar; import java.util.Date; +import org.junit.Assert; import org.junit.Test; import org.olat.test.OlatTestCase; import org.quartz.JobDetail; import org.quartz.Scheduler; import org.quartz.SchedulerException; +import org.quartz.TriggerUtils; +import org.quartz.spi.OperableTrigger; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.scheduling.quartz.SimpleTriggerBean; +import org.springframework.scheduling.quartz.SimpleTriggerFactoryBean; /** * Description:<br> @@ -53,8 +56,11 @@ public class SchedulerTest extends OlatTestCase { @Test public void testSimpleTrigger() throws SchedulerException, ParseException { - JobDetail job = new JobDetail("schedulerTestJobSimpleTrigger", Scheduler.DEFAULT_GROUP, SchedulerTestJob.class); - SimpleTriggerBean trigger = new SimpleTriggerBean(); + JobDetail job = newJob(SchedulerTestJob.class) + .withIdentity("schedulerTestJobSimpleTrigger", Scheduler.DEFAULT_GROUP) + .build(); + + SimpleTriggerFactoryBean trigger = new SimpleTriggerFactoryBean(); trigger.setName("Test scheduler trigger"); trigger.setStartDelay(0); trigger.setRepeatInterval(1000); @@ -62,14 +68,17 @@ public class SchedulerTest extends OlatTestCase { trigger.setJobDetail(job); trigger.afterPropertiesSet(); // Schedule job now - scheduler.scheduleJob(job, trigger); + scheduler.scheduleJob(job, trigger.getObject()); + + sleep(20);//because of cal.add(Calendar.MILLISECOND, 11); - //check next time + //check number of calls to the job + org.quartz.Calendar quartzCal = scheduler.getCalendar(trigger.getObject().getCalendarName()); Calendar cal = Calendar.getInstance(); Date start = cal.getTime(); cal.add(Calendar.SECOND, 5); - cal.add(Calendar.MILLISECOND, 011); + cal.add(Calendar.MILLISECOND, 11); Date end = cal.getTime(); - assertEquals(5, trigger.computeNumTimesFiredBetween(start, end)); + Assert.assertEquals(5, TriggerUtils.computeFireTimesBetween((OperableTrigger)trigger.getObject(), quartzCal, start, end).size()); } } diff --git a/src/test/java/org/olat/core/util/i18n/I18nTest.java b/src/test/java/org/olat/core/util/i18n/I18nTest.java index e98b518ca21..1c3965a469a 100644 --- a/src/test/java/org/olat/core/util/i18n/I18nTest.java +++ b/src/test/java/org/olat/core/util/i18n/I18nTest.java @@ -77,6 +77,8 @@ public class I18nTest extends OlatTestCase { @Autowired private I18nManager i18nMgr; @Autowired + private I18nModule i18nModule; + @Autowired private TranslationDevManager tDMgr; private static final String testSourceBundle = "org.olat.core.util.i18n.junittestdata.devtools.source"; private static final String testTargetBundle = "org.olat.core.util.i18n.junittestdata.devtools.target"; @@ -95,7 +97,7 @@ public class I18nTest extends OlatTestCase { public void tearDown() throws Exception { String testNewBundle = "org.olat.core.util.i18n.junittestdata.new"; Locale testLocale = i18nMgr.getLocaleOrDefault("de"); - File baseDir = I18nModule.getPropertyFilesBaseDir(testLocale, testNewBundle); + File baseDir = i18nModule.getPropertyFilesBaseDir(testLocale, testNewBundle); // only delete files when basedir available if (baseDir == null) return; File testFile = i18nMgr.getPropertiesFile(testLocale, testNewBundle, baseDir); @@ -129,17 +131,17 @@ public class I18nTest extends OlatTestCase { Locale testLocale = i18nMgr.getLocaleOrDefault("de"); // cleanup devtools source/target files // 1) source files - File baseDir = I18nModule.getPropertyFilesBaseDir(testLocale, testSourceBundle); + File baseDir = i18nModule.getPropertyFilesBaseDir(testLocale, testSourceBundle); File testSFile = i18nMgr.getPropertiesFile(testLocale, testSourceBundle, baseDir); File sourcePath = testSFile.getParentFile().getParentFile(); FileUtils.deleteDirsAndFiles(sourcePath, true, true); // 2) target files - baseDir = I18nModule.getPropertyFilesBaseDir(testLocale, testTargetBundle); + baseDir = i18nModule.getPropertyFilesBaseDir(testLocale, testTargetBundle); File testTFile = i18nMgr.getPropertiesFile(testLocale, testTargetBundle, baseDir); File targetPath = testTFile.getParentFile().getParentFile(); FileUtils.deleteDirsAndFiles(targetPath, true, true); // 3) move target files - baseDir = I18nModule.getPropertyFilesBaseDir(testLocale, testMoveTargetBundle); + baseDir = i18nModule.getPropertyFilesBaseDir(testLocale, testMoveTargetBundle); File testMFile = i18nMgr.getPropertiesFile(testLocale, testMoveTargetBundle, baseDir); File movePath = testMFile.getParentFile().getParentFile().getParentFile(); FileUtils.deleteDirsAndFiles(movePath, true, true); @@ -150,7 +152,7 @@ public class I18nTest extends OlatTestCase { // set languages that is used as reference: all keys there are the keys should not to be deleted String[] referenceLanguages = new String[]{"de", "en"}; // set the languages that should be cleaned up - Set<String> targetLanguages = I18nModule.getTranslatableLanguageKeys(); + Set<String> targetLanguages = i18nModule.getTranslatableLanguageKeys(); //Set<String> targetLanguages = new HashSet<String>(); //targetLanguages.add("en"); tDMgr.removeDeletedKeys(false, referenceLanguages, targetLanguages); @@ -158,7 +160,7 @@ public class I18nTest extends OlatTestCase { @Test public void testMoveKeyTask() { - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { prepareDevToolTests(); Locale testLocale = i18nMgr.getLocaleOrDefault("de"); String ktm = "key.to.move"; @@ -182,38 +184,35 @@ public class I18nTest extends OlatTestCase { //check for changed references in value //if correctly done, should still be resolvable assertTrue(sourcePropResolved.getProperty("key.to.stay2").indexOf(matchString)!=-1); - tDMgr.logToFile("moveKey"); } } @Test public void testMovePackageTask(){ - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { prepareDevToolTests(); tDMgr.movePackageTask(testSourceBundle, testTargetBundle); i18nMgr.clearCaches(); Properties sourceProp = i18nMgr.getPropertiesWithoutResolvingRecursively(null, testSourceBundle); assertTrue(sourceProp.isEmpty()); Properties targetProp = i18nMgr.getPropertiesWithoutResolvingRecursively(null, testTargetBundle); - assertFalse(targetProp.isEmpty()); - tDMgr.logToFile("movePackage"); + assertFalse(targetProp.isEmpty()); } } @Test public void testMovePackageByMovingSingleKeysTask(){ - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { prepareDevToolTests(); tDMgr.movePackageByMovingSingleKeysTask(testSourceBundle, testTargetBundle); i18nMgr.clearCaches(); Properties sourceProp = i18nMgr.getPropertiesWithoutResolvingRecursively(null, testSourceBundle); assertTrue(sourceProp.isEmpty()); Properties targetProp = i18nMgr.getPropertiesWithoutResolvingRecursively(null, testTargetBundle); - assertFalse(targetProp.isEmpty()); - tDMgr.logToFile("movePackageSingle"); + assertFalse(targetProp.isEmpty()); } } @Test public void testMergePackageTask(){ - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { prepareDevToolTests(); tDMgr.mergePackageTask(testSourceBundle, testTargetBundle); i18nMgr.clearCaches(); @@ -224,7 +223,7 @@ public class I18nTest extends OlatTestCase { } @Test public void testRenameLanguageTask(){ - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { prepareDevToolTests(); // create source Locale xxLocale = new Locale("xx"); @@ -256,9 +255,9 @@ public class I18nTest extends OlatTestCase { } @Test public void testMoveLanguageTask(){ - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { prepareDevToolTests(); - String srcPath = I18nModule.getTransToolApplicationLanguagesSrcDir().getAbsolutePath() + "/../../test/java/org/olat/core/util/i18n/junittestdata/devtools"; + String srcPath = i18nModule.getTransToolApplicationLanguagesSrcDir().getAbsolutePath() + "/../../test/java/org/olat/core/util/i18n/junittestdata/devtools"; String targetPath = srcPath + "/../movetarget"; //only copy: target should exist Locale mvLocale = i18nMgr.getLocaleOrDefault("de"); @@ -287,30 +286,26 @@ public class I18nTest extends OlatTestCase { //remove after execution! @Test public void testRemoveXKeyTask(){ - tDMgr.removeXKeysTask(false); - tDMgr.logToFile("XKeys"); + tDMgr.removeXKeysTask(false); } //remove after execution! @Test public void testRemoveTodoKeyTask(){ tDMgr.removeTodoKeysTask(false); - tDMgr.logToFile("todoKeys"); } //remove after execution! @Test public void testRemoveEmptyKeysTask(){ tDMgr.removeEmptyKeysTask(false); - tDMgr.logToFile("emptyKeys"); } //remove after execution! @Test public void testRemoveReferenceLanguageCopiesTask(){ - if (I18nModule.isTransToolEnabled()) { - tDMgr.removeReferenceLanguageCopiesTask(false); - tDMgr.logToFile("refLangCopied"); + if (i18nModule.isTransToolEnabled()) { + tDMgr.removeReferenceLanguageCopiesTask(false); } } @@ -318,11 +313,11 @@ public class I18nTest extends OlatTestCase { * Test method i18nManager.searchForAvailableLanguages() */ @Test public void testSearchForAvailableLanguages() { - if (I18nModule.isTransToolEnabled()) { + if (i18nModule.isTransToolEnabled()) { // Try to load i18n files and a jar from the testdata dir - File testDataDir = new File(I18nModule.getTransToolApplicationLanguagesSrcDir(), "/../../test/java/org/olat/core/util/i18n/junittestdata/"); + File testDataDir = new File(i18nModule.getTransToolApplicationLanguagesSrcDir(), "/../../test/java/org/olat/core/util/i18n/junittestdata/"); assertTrue(testDataDir.exists()); - Set<String> foundLanguages = i18nMgr.searchForAvailableLanguages(testDataDir); + Set<String> foundLanguages = i18nModule.searchForAvailableLanguages(testDataDir); // Set must contain some LocalStrings file: assertTrue(foundLanguages.contains("de")); assertTrue(foundLanguages.contains("en")); @@ -333,7 +328,7 @@ public class I18nTest extends OlatTestCase { // Final check assertEquals(6, foundLanguages.size()); } else { - Set<String> foundLanguages = I18nModule.getAvailableLanguageKeys(); + Set<String> foundLanguages = i18nModule.getAvailableLanguageKeys(); // Set must contain some LocaleStrings from the jar package assertTrue(foundLanguages.contains("fr")); assertTrue(foundLanguages.contains("zh_CN")); @@ -345,7 +340,7 @@ public class I18nTest extends OlatTestCase { */ @Test public void testSearchForBundleNamesContainingI18nFiles() { long start = System.currentTimeMillis(); - List<String> foundBundles = i18nMgr.searchForBundleNamesContainingI18nFiles(); + List<String> foundBundles = i18nModule.searchForBundleNamesContainingI18nFiles(); long end = System.currentTimeMillis(); log.info("Searching for " + foundBundles.size() + " bundles on OLAT source path took me " + (end-start) + "ms", "testSearchForBundleNamesContainingI18nFiles"); // Must contain packages from core @@ -361,7 +356,7 @@ public class I18nTest extends OlatTestCase { * Test method i18nManager.buildI18nFilename() */ @Test public void testBuildI18nFilename() { - String overlay = I18nModule.getOverlayName(); + String overlay = i18nModule.getOverlayName(); String testFileName = i18nMgr.buildI18nFilename(new Locale("de")); assertEquals("LocalStrings_de.properties", testFileName); testFileName = i18nMgr.buildI18nFilename(new Locale("de","","__" + overlay)); @@ -386,9 +381,9 @@ public class I18nTest extends OlatTestCase { locale = i18nMgr.getLocaleOrDefault("xy"); assertEquals(I18nModule.getDefaultLocale(), locale); // Test trying to get overlay via getLocale method which should not return the overlay - Locale overlay = i18nMgr.getLocaleOrDefault("de__" + I18nModule.getOverlayName()); + Locale overlay = i18nMgr.getLocaleOrDefault("de__" + i18nModule.getOverlayName()); assertEquals(I18nModule.getDefaultLocale(), overlay); - overlay = i18nMgr.getLocaleOrDefault("zh_CN__" + I18nModule.getOverlayName()); + overlay = i18nMgr.getLocaleOrDefault("zh_CN__" + i18nModule.getOverlayName()); assertEquals(I18nModule.getDefaultLocale(), overlay); } @@ -397,25 +392,25 @@ public class I18nTest extends OlatTestCase { */ @Test public void testCreateLocale() { // standard locale - Locale loc = i18nMgr.createLocale("de"); + Locale loc = i18nModule.createLocale("de"); assertNotNull(loc); assertEquals("de",loc.getLanguage()); assertEquals("",loc.getCountry()); assertEquals("",loc.getVariant()); // with country - loc = i18nMgr.createLocale("de_CH"); + loc = i18nModule.createLocale("de_CH"); assertNotNull(loc); assertEquals("de", loc.getLanguage()); assertEquals("CH", loc.getCountry()); assertEquals("", loc.getVariant()); // with variant - loc = i18nMgr.createLocale("de_CH_ZH"); + loc = i18nModule.createLocale("de_CH_ZH"); assertNotNull(loc); assertEquals("de", loc.getLanguage()); assertEquals("CH", loc.getCountry()); assertEquals("ZH", loc.getVariant()); // with variant but no country - loc = i18nMgr.createLocale("de__VENDOR"); + loc = i18nModule.createLocale("de__VENDOR"); assertNotNull(loc); assertEquals("de", loc.getLanguage()); assertEquals("", loc.getCountry()); @@ -423,21 +418,21 @@ public class I18nTest extends OlatTestCase { // // With overlay // with language - String overlay = I18nModule.getOverlayName(); - loc = i18nMgr.createLocale("de"); - Locale over = i18nMgr.createOverlay(loc); + String overlay = i18nModule.getOverlayName(); + loc = i18nModule.createLocale("de"); + Locale over = i18nModule.createOverlay(loc); assertEquals("de____" + overlay, over.toString()); - assertEquals(i18nMgr.createOverlayKeyForLanguage(loc.toString()), i18nMgr.getLocaleKey(over)); + assertEquals(i18nModule.createOverlayKeyForLanguage(loc.toString()), i18nModule.getLocaleKey(over)); // with country - loc = i18nMgr.createLocale("de_CH"); - over = i18nMgr.createOverlay(loc); + loc = i18nModule.createLocale("de_CH"); + over = i18nModule.createOverlay(loc); assertEquals("de_CH___" + overlay, over.toString()); - assertEquals(i18nMgr.createOverlayKeyForLanguage(loc.toString()), i18nMgr.getLocaleKey(over)); + assertEquals(i18nModule.createOverlayKeyForLanguage(loc.toString()), i18nModule.getLocaleKey(over)); // with variant - loc = i18nMgr.createLocale("de_CH_ZH"); - over = i18nMgr.createOverlay(loc); + loc = i18nModule.createLocale("de_CH_ZH"); + over = i18nModule.createOverlay(loc); assertEquals("de_CH_ZH__" + overlay, over.toString()); - assertEquals(i18nMgr.createOverlayKeyForLanguage(loc.toString()), i18nMgr.getLocaleKey(over)); + assertEquals(i18nModule.createOverlayKeyForLanguage(loc.toString()), i18nModule.getLocaleKey(over)); } /** @@ -454,8 +449,8 @@ public class I18nTest extends OlatTestCase { * Test methods i18nManager.getLanguageTranslated() i18nManager.getLanguageInEnglish() */ @Test public void testGetPropertyFile() { - if (I18nModule.isTransToolEnabled()) { - File baseDir = I18nModule.getPropertyFilesBaseDir(i18nMgr.getLocaleOrDefault("de"), "org.olat.core"); + if (i18nModule.isTransToolEnabled()) { + File baseDir = i18nModule.getPropertyFilesBaseDir(i18nMgr.getLocaleOrDefault("de"), "org.olat.core"); assertNotNull(baseDir); File file = i18nMgr.getPropertiesFile(i18nMgr.getLocaleOrDefault("de"), "org.olat.core", baseDir); assertTrue(file.exists()); @@ -486,7 +481,7 @@ public class I18nTest extends OlatTestCase { // test with non existing files String testNewBundle = "org.olat.core.util.i18n.junittestdata.new"; Locale testLocale = i18nMgr.getLocaleOrDefault("de"); - File baseDir = I18nModule.getPropertyFilesBaseDir(testLocale, testNewBundle); + File baseDir = i18nModule.getPropertyFilesBaseDir(testLocale, testNewBundle); File testFile = i18nMgr.getPropertiesFile(testLocale, testNewBundle, baseDir); // clean first existing files from previous broken testcase if (testFile.exists()) { @@ -580,11 +575,11 @@ public class I18nTest extends OlatTestCase { */ @Ignore @Test public void testCountI18nItemsAndBundles() { - I18nModule.initBundleNames(); // remove dirty stuff from previous tests - int bundleCounter = I18nModule.getBundleNamesContainingI18nFiles().size(); + i18nModule.initBundleNames(); // remove dirty stuff from previous tests + int bundleCounter = i18nModule.getBundleNamesContainingI18nFiles().size(); String testNewBundle = "org.olat.core.util.i18n.junittestdata.new"; Locale testLocale = i18nMgr.getLocaleOrDefault("de"); - File baseDir = I18nModule.getPropertyFilesBaseDir(testLocale, testNewBundle); + File baseDir = i18nModule.getPropertyFilesBaseDir(testLocale, testNewBundle); File testFile = i18nMgr.getPropertiesFile(testLocale, testNewBundle, baseDir); // clean first existing files from previous broken testcase if (testFile.exists()) { @@ -598,7 +593,7 @@ public class I18nTest extends OlatTestCase { i18nMgr.saveOrUpdateProperties(props, testLocale, testNewBundle); assertEquals(2, i18nMgr.countI18nItems(testLocale, testNewBundle, false)); assertEquals(0, i18nMgr.countI18nItems(i18nMgr.getLocaleOrDefault("en"), testNewBundle, false)); - assertEquals(bundleCounter + 1, I18nModule.getBundleNamesContainingI18nFiles().size()); + assertEquals(bundleCounter + 1, i18nModule.getBundleNamesContainingI18nFiles().size()); // test all bundles int allCount = i18nMgr.countI18nItems(testLocale, null, true); assertEquals(allCount, i18nMgr.countI18nItems(testLocale, null, false)); @@ -607,7 +602,7 @@ public class I18nTest extends OlatTestCase { assertEquals(allCount-1, i18nMgr.countI18nItems(testLocale, null, false)); i18nMgr.deleteProperties(testLocale, testNewBundle); assertEquals(allCount-2, i18nMgr.countI18nItems(testLocale, null, false)); - assertEquals(bundleCounter, I18nModule.getBundleNamesContainingI18nFiles().size()); + assertEquals(bundleCounter, i18nModule.getBundleNamesContainingI18nFiles().size()); // count bundles tests assertEquals(0, i18nMgr.countBundles("org.olat.core.util.i18n.nonexisting", true)); assertEquals(1, i18nMgr.countBundles("org.olat.core.util.i18n.ui", true)); diff --git a/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java b/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java index 312b24fe930..7058754d1c7 100644 --- a/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java +++ b/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java @@ -35,6 +35,7 @@ import org.olat.resource.OLATResource; import org.olat.resource.accesscontrol.manager.ACReservationDAO; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; +import org.quartz.JobKey; import org.quartz.Scheduler; import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; @@ -57,7 +58,7 @@ public class ACReservationDAOTest extends OlatTestCase { @Before public void interruptReservationJob() { try { - scheduler.pauseJob("acReservationCleanupJobDetail", Scheduler.DEFAULT_GROUP); + scheduler.pauseJob(new JobKey("acReservationCleanupJobDetail", Scheduler.DEFAULT_GROUP)); } catch (SchedulerException e) { log.error("Cannot intterupt the reservation job.", e); } -- GitLab