diff --git a/src/main/java/org/olat/commons/memberlist/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/commons/memberlist/ui/_i18n/LocalStrings_pt_BR.properties index 4fe088176c71242206e40116f3b1e36ee72377dd..8b9e3eaec7112d2ffb23fd980f82462a47bd5c23 100644 --- a/src/main/java/org/olat/commons/memberlist/ui/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/commons/memberlist/ui/_i18n/LocalStrings_pt_BR.properties @@ -1,5 +1,11 @@ -#Mon Jan 16 21:03:20 CET 2017 +#Tue Jul 10 14:20:16 CEST 2018 +contact.list.coaches=Treinadores +contact.list.external=Recipientes externos +contact.list.others=Diversos +contact.list.owners=Propriet\u00E1rios +contact.list.participants=Participantes +contact.list.waiting=Lista de espera +nomembers=No members table.header.firstTime=Entrando table.header.lastTime=\u00DAltima visita table.header.online=$org.olat.group.ui.main\:table.header.online -nomembers=No members \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pt_BR.properties index dbfdf6f5384dc9a994e988f9216cb928f0c8161e..e08220ae40ea61e442a490b118a47177bf4590ae 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pt_BR.properties @@ -1,4 +1,4 @@ -#Tue Jul 03 20:15:29 CEST 2018 +#Tue Jul 10 14:21:08 CEST 2018 Directory=Pasta FileDeleteFailed=Arquivos/pastas <b>{0}</b> n\u00E3o puderam ser apagados. FileDeleted=Arquivos/pastas <b>{0}</b> apagados com sucesso. @@ -131,6 +131,7 @@ unzip=Descompactar unzip.alreadyexists=Uma pasta com o nome {0} j\u00E1 existe. Talvez voc\u00EA tenha descompactado este arquivo anteriormente. Voc\u00EA pode renomear a pasta {0} e descompactar o arquivo novamente. versions=Vers\u00F5es versions.revisions=Vers\u00F5es +warning.file.selection.empty=Voc\u00EA precisa escolher pelo menos um arquivo webdav.link=WebDAV link webdav.link.http=Quando voc\u00EA encontrar problemas de conex\u00E3o, o seguinte link alternativo pode ser utilizado. Consulte a ajuda para obter mais informa\u00E7\u00F5es. zip=Zip diff --git a/src/main/java/org/olat/core/dispatcher/ErrorsDispatcher.java b/src/main/java/org/olat/core/dispatcher/ErrorsDispatcher.java new file mode 100644 index 0000000000000000000000000000000000000000..23ec12aadb44c90c5d9efd78d47df4f774c09d11 --- /dev/null +++ b/src/main/java/org/olat/core/dispatcher/ErrorsDispatcher.java @@ -0,0 +1,56 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <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 the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <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> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.dispatcher; + +import java.io.IOException; +import java.io.PrintWriter; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; + +/** + * Used to override the standard error page of Tomcat. The goal is to + * suppress the stack trace at any cost. + * + * Initial date: 25 juil. 2018<br> + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +public class ErrorsDispatcher implements Dispatcher { + + private static final OLog log = Tracing.createLoggerFor(ErrorsDispatcher.class); + + @Override + public void execute(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + try(PrintWriter writer = response.getWriter()) { + writer.append("<!DOCTYPE html><html>") + .append("<head><title>Unexpected error</title></head>") + .append("<body><h3>An unexpected error occured... Sorry!</h3><p>Error code: ") + .append(Integer.toString(response.getStatus())) + .append("</p></body></html>"); + } catch(Exception e) { + log.error("", e); + } + } +} diff --git a/src/main/java/org/olat/core/dispatcher/_spring/dispatcherContext.xml b/src/main/java/org/olat/core/dispatcher/_spring/dispatcherContext.xml index 25e5df61dcc19e3c40739a62203b9634ecde10fd..863186aed0179f9870af3fe68829829fed231b69 100644 --- a/src/main/java/org/olat/core/dispatcher/_spring/dispatcherContext.xml +++ b/src/main/java/org/olat/core/dispatcher/_spring/dispatcherContext.xml @@ -46,6 +46,9 @@ <entry key="/error/"> <ref bean="errorMailBean" /> </entry> + <entry key="/errors/"> + <ref bean="errorsBean" /> + </entry> <entry key="/math/"> <ref bean="mathwebbean" /> </entry> @@ -80,6 +83,8 @@ <property name="mailManager" ref="mailManager"/> <property name="securityManager" ref="baseSecurityManager"/> </bean> + + <bean id="errorsBean" class="org.olat.core.dispatcher.ErrorsDispatcher" /> <!-- all olat dispatchers --> <bean id="dmzbean" class="org.olat.dispatcher.DMZDispatcher"> diff --git a/src/main/java/org/olat/core/gui/control/navigation/AbstractSiteDefinition.java b/src/main/java/org/olat/core/gui/control/navigation/AbstractSiteDefinition.java index 1708d98543fe52cfb79160cfacbb1045f56ab9da..752f3e50593232205c40ceebdfb579973a317e6c 100644 --- a/src/main/java/org/olat/core/gui/control/navigation/AbstractSiteDefinition.java +++ b/src/main/java/org/olat/core/gui/control/navigation/AbstractSiteDefinition.java @@ -30,6 +30,8 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.configuration.AbstractConfigOnOff; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.WindowControl; +import org.olat.core.logging.OLog; +import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; /** @@ -37,6 +39,8 @@ import org.olat.core.util.StringHelper; */ public abstract class AbstractSiteDefinition extends AbstractConfigOnOff implements SiteDefinition { + private static final OLog log = Tracing.createLoggerFor(AbstractSiteDefinition.class); + private int order; private String defaultSiteSecurityCallbackBeanId; @@ -65,7 +69,7 @@ public abstract class AbstractSiteDefinition extends AbstractConfigOnOff impleme String secCallbackBeanId = config.getSecurityCallbackBeanId(); if(StringHelper.containsNonWhitespace(secCallbackBeanId)) { - Object siteSecCallback = CoreSpringFactory.getBean(secCallbackBeanId); + Object siteSecCallback = getSiteSecurityCallback(secCallbackBeanId); if (siteSecCallback instanceof SiteViewSecurityCallback) { if(!((SiteViewSecurityCallback)siteSecCallback).isAllowedToViewSite(ureq)) { return null; @@ -77,6 +81,15 @@ public abstract class AbstractSiteDefinition extends AbstractConfigOnOff impleme return createSite(ureq, wControl, config); } + private Object getSiteSecurityCallback(String secCallbackBeanId) { + try { + return CoreSpringFactory.getBean(secCallbackBeanId); + } catch (Exception e) { + log.error("Cannot find security callback: " + secCallbackBeanId + " return administrator only security callback"); + return CoreSpringFactory.getBean("adminSiteSecurityCallback"); + } + } + protected abstract SiteInstance createSite(UserRequest ureq, WindowControl wControl, SiteConfiguration config); protected SiteConfiguration getSiteConfiguration() { diff --git a/src/main/java/org/olat/core/gui/control/winmgr/_content/serverpart.html b/src/main/java/org/olat/core/gui/control/winmgr/_content/serverpart.html index 8297a5e466b540b43a35d7de1b466548c6b4967f..84e7c87359243d2ef0d93253f87d286cd6cc6490 100644 --- a/src/main/java/org/olat/core/gui/control/winmgr/_content/serverpart.html +++ b/src/main/java/org/olat/core/gui/control/winmgr/_content/serverpart.html @@ -30,7 +30,7 @@ var timestampLastPoll = new Date().getTime(); // set timestamp cookie to inform other windows that they are outdated var sbtimestamp = new Date().getTime(); var sbcookie = 'OLAT-UI-TIMESTAMP'; -if (window.opener == null) document.cookie = sbcookie+'='+sbtimestamp+'; path=/'; +if (window.opener == null) document.cookie = sbcookie+'='+sbtimestamp+'; path=/; SameSite=strict'; ## starts an interval which checks every second whether to send an poll request based on ## the pollperiod or not 10 min after the last click the poll process stops diff --git a/src/main/java/org/olat/core/servlets/OpenOLATServlet.java b/src/main/java/org/olat/core/servlets/OpenOLATServlet.java index 618be5c9c82f18bef623a9b80ae92b4fca65237b..1c8f7c8faffa2dde509d403f4974cd65183dbc90 100644 --- a/src/main/java/org/olat/core/servlets/OpenOLATServlet.java +++ b/src/main/java/org/olat/core/servlets/OpenOLATServlet.java @@ -26,6 +26,7 @@ import java.util.Map; import javax.servlet.RequestDispatcher; import javax.servlet.ServletConfig; import javax.servlet.ServletException; +import javax.servlet.SessionCookieConfig; import javax.servlet.annotation.MultipartConfig; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; @@ -124,6 +125,12 @@ public class OpenOLATServlet extends HttpServlet { } } + if(Settings.isSecurePortAvailable()) { + SessionCookieConfig cookieConfig = servletConfig.getServletContext().getSessionCookieConfig(); + cookieConfig.setSecure(true); + cookieConfig.setHttpOnly(true); + } + //preload extensions ExtManager.getInstance().getExtensions(); AbstractSpringModule.printStats(); diff --git a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties index bf53fee27e9a43a82686da2928e3385dc7b737c2..4e233e8901c5074cd4b1bf99d87c157304b7b059 100644 --- a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_de.properties @@ -1,5 +1,5 @@ #Mon Mar 02 09:54:04 CET 2009 -at.least.one.recipient=Sie m\u00FCssen mindesten ein Empf\u00E4nger w\u00E4hlen. +at.least.one.recipient=Sie m\u00FCssen mindestens ein Empf\u00E4nger w\u00E4hlen. diff --git a/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties index 75061e229341baeb3ed154461f89458b6d49ca1c..6da27dfc927d14c9c3322d808d53628a2a5db5db 100644 --- a/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/course/db/_i18n/LocalStrings_pt_BR.properties @@ -1,4 +1,4 @@ -#Tue Jul 03 20:15:30 CEST 2018 +#Tue Jul 10 14:21:10 CEST 2018 command.new_db=Criar novo banco de dados customDb.category=Nome customDb.create=Criar diff --git a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_pt_BR.properties index 3cd27baa4473d5ec0a18feefb8f814b0288c9410..8bef35f21d21c15268aba905188d36ad7eab2593 100644 --- a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_pt_BR.properties @@ -1,4 +1,4 @@ -#Mon Feb 08 21:36:00 CET 2016 +#Tue Jul 10 14:21:25 CEST 2018 access.form.label=Acesso ao curso inteiro tem access.legend=Modificar acesso ao curso inteiro alternative=Pesquisar por elemento de curso alternativo @@ -141,6 +141,7 @@ publish.catalog.add.title=Adicionar "{0}" ao cat\u00E1logo publish.catalog.box=Adicionar curso ao cat\u00E1logo publish.catalog.error=Voc\u00EA deve criar pelo menos uma entrada de cat\u00E1logo. publish.catalog.header=Criar entrada no cat\u00E1logo +publish.catalog.header.title=Criar entrada de cat\u00E1logo para o curso "{0}" publish.catalog.reminder1=Sem a entrada de cursos no cat\u00E1logo, eles ser\u00E3o dif\u00EDceis de serem encontrados pelos estudantes. Por isso, \u00E9 recomendado selecionar um ou v\u00E1rios n\u00EDveis de cat\u00E1logo em que o curso deve ser listado. Voc\u00EA pode adicionar mais ou remover entradas de cat\u00E1logo existentes a qualquer momento. publish.catalog.reminder2=Nota\: um curso \u00E9 vis\u00EDvel no cat\u00E1logo somente quando o acesso do curso \u00E9 definido como todos os "utilizadores registados" ou "usu\u00E1rios registrados e convidados" no passo anterior. Selecione "Voltar" para alterar essas configura\u00E7\u00F5es de acesso. publish.header=Publicar modifica\u00E7\u00F5es de elementos de curso diff --git a/src/main/java/org/olat/course/highscore/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/course/highscore/ui/_i18n/LocalStrings_pt_BR.properties index b1eb8d7c7689af06b0bde922d557e016137914e8..3c108a25d1f5b314f2f814505e9f6072bb89fdb5 100644 --- a/src/main/java/org/olat/course/highscore/ui/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/course/highscore/ui/_i18n/LocalStrings_pt_BR.properties @@ -1,4 +1,4 @@ -#Thu Feb 08 13:43:35 CET 2018 +#Tue Jul 10 14:21:27 CEST 2018 controller.title=Configura\u00E7\u00F5es "HighScore" do elemento do seu curso datestart.toearly=Por favor, escolha uma data de in\u00EDcio no futuro. example.date=(Exemplo\: 26/06/2016 10\:28) diff --git a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java index b5d27a4137bf9fd1d1223fab5ebdac87682bf8b5..1564435fe3b7610f97a846508e2b931503001188 100644 --- a/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java +++ b/src/main/java/org/olat/course/nodes/gta/manager/GTAManagerImpl.java @@ -923,7 +923,7 @@ public class GTAManagerImpl implements GTAManager { } AssignmentResponse response; - if(currentTask == null) { + if(currentTask == null || !StringHelper.containsNonWhitespace(currentTask.getTaskName())) { TaskList reloadedTasks = loadForUpdate(tasks); File tasksFolder = getTasksDirectory(courseEnv, cNode); @@ -941,11 +941,20 @@ public class GTAManagerImpl implements GTAManager { response = AssignmentResponse.NO_MORE_TASKS; } else { TaskProcess nextStep = nextStep(TaskProcess.assignment, cNode); - TaskImpl task = createTask(taskName, reloadedTasks, nextStep, businessGroup, identity, cNode); - task.setAssignmentDate(new Date()); - dbInstance.getCurrentEntityManager().persist(task); + TaskImpl task; + if(currentTask == null) { + task = createTask(taskName, reloadedTasks, nextStep, businessGroup, identity, cNode); + task.setAssignmentDate(new Date()); + dbInstance.getCurrentEntityManager().persist(task); + } else { + task = (TaskImpl)currentTask; + task.setTaskName(taskName); + task.setTaskStatus(nextStep); + task.setAssignmentDate(new Date()); + task = dbInstance.getCurrentEntityManager().merge(task); + } dbInstance.commit(); - syncAssessmentEntry((TaskImpl)currentTask, cNode, Role.user); + syncAssessmentEntry(task, cNode, Role.user); response = new AssignmentResponse(task, Status.ok); } } else { diff --git a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java index 471a4f3e81e6715ccf38d370ef2ba9861687449a..cbf91dab3bfa9223d158f0fd5e5a8ecf4adfe40f 100644 --- a/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java +++ b/src/main/java/org/olat/course/nodes/iq/QTI21AssessmentRunController.java @@ -370,7 +370,7 @@ public class QTI21AssessmentRunController extends BasicController implements Gen if (ureq != null) { allChats = ureq.getUserSession().getChats(); } - if (allChats == null || allChats.size() == 0) { + if (allChats == null || allChats.isEmpty()) { startButton.setEnabled (true); mainVC.contextPut("hasChatWindowOpen", false); } else { @@ -522,10 +522,12 @@ public class QTI21AssessmentRunController extends BasicController implements Gen if(!displayCtrl.isResultsVisible()) { doExitAssessment(ureq, event, true); initAssessment(ureq); + fireEvent(ureq, Event.CHANGED_EVENT); } } else if(QTI21Event.CLOSE_RESULTS.equals(qe.getCommand())) { doExitAssessment(ureq, event, true); initAssessment(ureq); + fireEvent(ureq, Event.CHANGED_EVENT); } } } diff --git a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_de.properties index 48745814f4f1b47b2fd47930e004d04ce09c1916..b252e43553ee350975448415d14fd1a54be209b8 100644 --- a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_de.properties @@ -110,7 +110,7 @@ qti.form.date.start.error.mandatory=Es muss mindestens ein Anfangsdatum angegebe qti.form.enablecancel=Abbrechen erlauben qti.form.enablesuspend=Unterbrechen erlauben qti.form.fullwindow=Nur Modul anzeigen, LMS ausblenden -qti.form.limit.attempts=Anzahl L\u00F6sungsversuche limitieren +qti.form.limit.attempts=Anzahl L\u00F6sungsversuche des Tests limitieren qti.form.max.score.item=Max. Punkte der Frage anzeigen qti.form.menudisplay=Menu-Navigation anzeigen qti.form.menuenable=Menu-Navigation erlauben @@ -192,4 +192,4 @@ warning.assessment.mode=Folgende Pr\u00FCfungkonfiguration ist aktiv: validate.xml.signature=Testquitting validieren warning.assessment.mode.date={0} von {1} bis {2} warning.test.with.essay=$org.olat.ims.qti.editor\:warning.test.with.essay -warning.users.extra.time=Sie m\u00FCssen mindesten ein Benutzer ausw\u00E4hlen, deren Test man verl\u00E4ngern kann. +warning.users.extra.time=Sie m\u00FCssen mindestens ein Benutzer ausw\u00E4hlen, deren Test man verl\u00E4ngern kann. diff --git a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties index ddfc92d984a0d7bdd7d38631cfa7ebab2c2b218c..bfcfc09e6d1132066569770de4639d3aa17ac9fb 100644 --- a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_en.properties @@ -110,7 +110,7 @@ qti.form.date.start.error.mandatory=At least a starting date must be indicated. qti.form.enablecancel=Allow to cancel qti.form.enablesuspend=Allow to suspend qti.form.fullwindow=Display only module, hide LMS -qti.form.limit.attempts=Limit the number of attempts +qti.form.limit.attempts=Limit number of test attempts qti.form.max.score.item=Show questions max. points qti.form.menudisplay=Show menu navigation qti.form.menuenable=Allow menu navigation diff --git a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties index d07e7ebfb893a0f2e540d015a44b10def46f0a45..9772b1fab5756d8d0a7d55d6493eb2c4f0c8b15d 100644 --- a/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/course/nodes/iq/_i18n/LocalStrings_fr.properties @@ -110,7 +110,7 @@ qti.form.date.start.error.mandatory=Il faut indiquer au moins une date de d\u00E qti.form.enablecancel=Permettre abandon qti.form.enablesuspend=Permettre interruption qti.form.fullwindow=Afficher le module seul, masquer le LMS -qti.form.limit.attempts=Limiter le nombre de tentatives +qti.form.limit.attempts=Limiter le nombre de tentatives de test qti.form.max.score.item=Montrer le nombre de points maximum qti.form.menudisplay=Afficher navigation Menu qti.form.menuenable=Autoriser navigation Menu diff --git a/src/main/java/org/olat/course/run/RunMainController.java b/src/main/java/org/olat/course/run/RunMainController.java index 4a69f27582e4e280028c34745dbb162093537d1e..6705c352da43ba5d46619056f1a579637f4c5237 100644 --- a/src/main/java/org/olat/course/run/RunMainController.java +++ b/src/main/java/org/olat/course/run/RunMainController.java @@ -876,8 +876,8 @@ public class RunMainController extends MainLayoutBasicController implements Gene if(entries.size() > 1) { entries = entries.subList(1, entries.size()); } - updateTreeAndContent(ureq, cn, null, entries, firstEntry.getTransientState()); - } else if (currentCourseNode.equals(cn)) { + currentCourseNode = updateTreeAndContent(ureq, cn, null, entries, firstEntry.getTransientState()); + } else { // consume our entry if(entries.size() > 1) { entries = entries.subList(1, entries.size()); diff --git a/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties index 15fb49095febc73813e7361c90d58da7739e19c0..fc0a60d0aca43b14bc6a1f17bfd203920f83c4a7 100644 --- a/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_pt_BR.properties @@ -1,4 +1,4 @@ -#Tue Jun 19 22:51:38 CEST 2018 +#Mon Jul 23 16:24:37 CEST 2018 businessgroup.contact.bodytext=<p></p>---<p>Ir imediatamente para o grupo "{0}"\: {1}</p> businessgroup.contact.subject=Mensagem para grupo {0} contact.all.coaches=Todos os treinadores (coaches) de grupo diff --git a/src/main/java/org/olat/ims/qti/export/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti/export/_i18n/LocalStrings_de.properties index 7ca48c162fc40c0c0daa59459a629a467c825f47..9e12c0cc1400e288ee4fa3fe4f331b6b46e23b71 100644 --- a/src/main/java/org/olat/ims/qti/export/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti/export/_i18n/LocalStrings_de.properties @@ -23,7 +23,7 @@ column.header.vorname=Vorname command.start.exportwizard=Archivierung starten command.start.exportwizard.dummy=Archivierung starten (vorkonfiguriert) dwnld.downloader=Test und Fragebogen -error.select.type.users=Sie m\u00FCssen mindesten einen Benutzertyp ausw\u00E4hlen. +error.select.type.users=Sie m\u00FCssen mindestens einen Benutzertyp ausw\u00E4hlen. finished=Wizard beenden form.carriagereturn=Zeilen getrennt mit form.carriagereturn.ex=default\: \\r\\n diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/FeedbacksEditorController.java b/src/main/java/org/olat/ims/qti21/ui/editor/FeedbacksEditorController.java index 3ec419a9340dbf098b3e60e08c71f2730b2c0802..ffc9d09dcbc2d91e9fee5291b8b37ef2d93bfa74 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/FeedbacksEditorController.java +++ b/src/main/java/org/olat/ims/qti21/ui/editor/FeedbacksEditorController.java @@ -51,6 +51,7 @@ import org.olat.ims.qti21.model.xml.ModalFeedbackCondition; import org.olat.ims.qti21.model.xml.ResponseIdentifierForFeedback; import org.olat.ims.qti21.model.xml.ResponseIdentifierForFeedback.Answer; import org.olat.ims.qti21.model.xml.TestFeedbackBuilder; +import org.olat.ims.qti21.model.xml.interactions.SingleChoiceAssessmentItemBuilder; import org.olat.ims.qti21.ui.ResourcesMapper; import org.olat.ims.qti21.ui.components.FlowFormItem; import org.olat.ims.qti21.ui.editor.events.AssessmentItemEvent; @@ -120,7 +121,9 @@ public class FeedbacksEditorController extends FormBasicController implements Sy addCorrectSolutionButton.setVisible(enable.isEnabled(ModalFeedbackType.correctSolution)); dropdownEl.addElement(addCorrectSolutionButton); - addCorrectButton = uifactory.addFormLink("add.correct.feedback", formLayout, Link.LINK); + boolean sc = (itemBuilder instanceof SingleChoiceAssessmentItemBuilder); + String addCorrectLabel = "add.correct.feedback" + (sc ? ".single" : ""); + addCorrectButton = uifactory.addFormLink("add.correct.feedback", addCorrectLabel, null, formLayout, Link.LINK); addCorrectButton.setElementCssClass("o_sel_add_correct"); addCorrectButton.setVisible(enable.isEnabled(ModalFeedbackType.correct)); dropdownEl.addElement(addCorrectButton); @@ -321,7 +324,12 @@ public class FeedbacksEditorController extends FormBasicController implements Sy formLayout = FormLayoutContainer.createDefaultFormLayout_2_10(feedbackType.name(), getTranslator()); parentFormLayout.add(formLayout); formLayout.setRootForm(mainForm); - formLayout.setFormTitle(translate("form.imd." + feedbackType.name() + ".text")); + + String formTitle = "form.imd." + feedbackType.name(); + if(feedbackType == ModalFeedbackType.correct && itemBuilder instanceof SingleChoiceAssessmentItemBuilder) { + formTitle += ".single"; + } + formLayout.setFormTitle(translate(formTitle + ".text")); String title = feedbackBuilder == null ? "" : feedbackBuilder.getTitle(); titleEl = uifactory.addTextElement("title_".concat(id), "form.imd.feedback.title", -1, title, formLayout); @@ -335,7 +343,12 @@ public class FeedbacksEditorController extends FormBasicController implements Sy textEl.getEditorConfiguration().setSimplestTextModeAllowed(TextMode.oneLine); textEl.setEnabled(!restrictedEdit && !readOnly); textEl.setVisible(!restrictedEdit && !readOnly); - textEl.setHelpTextKey("feedback." + feedbackType.name() + ".help", null); + + String helpText = "feedback." + feedbackType.name(); + if(feedbackType == ModalFeedbackType.correct && itemBuilder instanceof SingleChoiceAssessmentItemBuilder) { + helpText += ".single"; + } + textEl.setHelpTextKey(helpText + ".help", null); textEl.setHelpUrlForManualPage("Test editor QTI 2.1 in detail#details_testeditor_feedback"); textEl.setElementCssClass("o_sel_assessment_item_" + feedbackType.name() + "_feedback"); RichTextConfiguration richTextConfig2 = textEl.getEditorConfiguration(); diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties index 1455ffac3359f7e7a38dbfd28ba7b8e1cad3e3a1..95c122fcaafbae6d03f1d9bd236f2244fc1ce7a9 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_de.properties @@ -5,8 +5,9 @@ add=Hinzuf\u00FCgen add.additional.feedback=Bedingtes Feedback hinzuf\u00FCgen add.answered.feedback=Feedback bei Antwort hinzuf\u00FCgen add.correct.feedback=Feedback bei Wahl aller korrekten Antworten hinzuf\u00FCgen +add.correct.feedback.single=Feedback bei Wahl der korrekten Antwort hinzuf\u00FCgen add.correctSolution.feedback=Korrekte L\u00F6sung hinzuf\u00FCgen -add.empty.feedback=Feedback bei Wahl keiner Antworten hinzuf\u00FCgen +add.empty.feedback=Feedback bei keiner Antwort hinzuf\u00FCgen add.feedback.menu=Feedback hinzuf\u00FCgen add.hint.feedback=L\u00F6sungshinweis add.incorrect.feedback=Feedback bei Wahl einer falschen Antwort hinzuf\u00FCgen @@ -53,6 +54,7 @@ essay.rows=H\u00F6he (Anzahl Zeilen) export.qpool.successful=$org.olat.ims.qti.editor\:export.qpool.successful feedback.answered.help=Feedback bei Antwort\: Dieses Feedback erscheint sobald der Benutzer eine Antwort gibt. feedback.correct.help=Feedback bei Wahl aller korrekten Antworten\: Dieses Feedback erscheint nur dann, wenn alle Antworten korrekt sind. +feedback.correct.single.help=Feedback bei Wahl der korrekten Antwort\: Dieses Feedback erscheint nur dann, wenn die Antwort korrekt sind. feedback.correctSolution.help=Korrekte L\u00F6sung\: Diese L\u00F6sung wird automatisch dann angezeigt, wenn die Antwort falsch ist. feedback.empty.help=Feedback bei leere Antwort\: Dieses Feedback erscheint solange die Antwort leer ist. feedback.hint.help=L\u00F6sungshinweis\: F\u00FCr den Testteilnehmer erscheint eine Schaltfl\u00E4che, welche er aufrufen kann, solange die Antwort noch nicht gesendet worden ist. @@ -98,12 +100,13 @@ form.imd.condition=Bedingung(en) form.imd.correct.kprim=Richtig form.imd.correct.spots=Korrekte Spots form.imd.correct.text=Feedback bei Wahl aller korrekten Antworten +form.imd.correct.single.text=Feedback bei Wahl der korrekten Antwort form.imd.correct.title=Titel form.imd.correctSolution.text=Korrekte L\u00F6sung form.imd.correctSolution.text.word=$\:form.imd.correctSolution.text (nur f\u00FCr Word Export) form.imd.correctSolution.title=Titel form.imd.descr=Frage -form.imd.empty.text=Feedback bei Wahl keiner Antworten +form.imd.empty.text=Feedback bei keiner Antwort form.imd.empty.title=Titel form.imd.feedback.text=Feedback form.imd.feedback.title=Titel diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties index 9981badb5148402de4fee4e71b0285f4167c4a50..907eccead297bbe93764ce89039cbc5b90116827 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_en.properties @@ -3,6 +3,7 @@ add=Add add.additional.feedback=Add feedback with conditions add.answered.feedback=Add feedback by answer add.correct.feedback=Add a feedback for all correct answers +add.correct.feedback.single=Add feedback for correct answer add.correctSolution.feedback=Add correct solution add.empty.feedback=Add feedback by empty answer add.feedback.menu=Add feedback @@ -51,6 +52,9 @@ error.upper.tolerance=The upper bound need to be bigger than the solution. export.qpool.successful=$org.olat.ims.qti.editor\:export.qpool.successful feedback.answered.help=Feedback by answer\: this feedback is shown automatically if the user give an answer. feedback.correct.help=Feedback for all correct answers\: The feedback appears only if all answer are correct. +feedback.correct.help=Feedback for all correct answers\: The feedback appears only if all answer are correct. + + feedback.correctSolution.help=Correct solution\: The solution is shown automatically, if the answer is wrong. feedback.empty.help=Feedback by empty\: this feedback is shown if the user give an empty answer. feedback.hint.help=Hint\: For the hint a button appears, which can be opened, as long as the answer is not submitted yet. @@ -97,6 +101,7 @@ form.imd.condition=Condition(s) form.imd.correct.kprim=True form.imd.correct.spots=Correct spots form.imd.correct.text=Feedback for all correct answers +form.imd.correct.single.text=Feedback for correct answer form.imd.correct.title=Title form.imd.correctSolution.text=Correct solution form.imd.correctSolution.text.word=$\:form.imd.correctSolution.text (only for Word export) diff --git a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_pt_BR.properties index 05c6618598535f32bf5d1cf45be6b49e8a68b72a..98daec103d2aa006dcd5d0172b925767d09b2b62 100644 --- a/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/ims/qti21/ui/editor/_i18n/LocalStrings_pt_BR.properties @@ -1,10 +1,11 @@ -#Fri May 11 23:42:04 CEST 2018 +#Tue Jul 10 14:20:56 CEST 2018 MULTIPLE=M\u00FAltipla escolha SINGLE=Escolha \u00FAnica add=Adicionar add.additional.feedback=Adicionar feedback com condi\u00E7\u00F5es add.answered.feedback=Adicionar feedback por resposta add.correct.feedback=Adicione um feedback para todas as respostas corretas +add.correct.feedback.single=Adicionar feedback para resposta correta add.correctSolution.feedback=Adicionar solu\u00E7\u00E3o correta add.empty.feedback=Adicionar feedback por resposta vazia add.feedback.menu=Adicionar feedback @@ -53,6 +54,7 @@ essay.rows=Altura (n\u00FAmero de linhas) export.qpool.successful=$org.olat.ims.qti.editor\:export.qpool.successful feedback.answered.help=Coment\u00E1rios por resposta\: este coment\u00E1rio \u00E9 mostrado automaticamente se o usu\u00E1rio der uma resposta. feedback.correct.help=Feedback para todas as respostas corretas\: o feedback aparece apenas se toda a resposta estiver correta. +feedback.correct.single.help=Feedback ao escolher a resposta correta\: Esse feedback s\u00F3 aparece se as respostas estiverem corretas. feedback.correctSolution.help=Solu\u00E7\u00E3o correta\: a solu\u00E7\u00E3o \u00E9 mostrada automaticamente, se a resposta for errada. feedback.empty.help=Feedback se vazio\: este feedback \u00E9 mostrado se o usu\u00E1rio der uma resposta vazia. feedback.hint.help=Dica\: para a "dica" aparecer\u00E1 um bot\u00E3o, que pode ser aberto, desde que a resposta ainda n\u00E3o tenha sido enviada. @@ -96,6 +98,7 @@ form.imd.background.resize.no=N\u00E3o mude form.imd.cardinality=Tipo form.imd.condition=Condi\u00E7\u00F5es(s) form.imd.correct.kprim=Verdade +form.imd.correct.single.text=Feedback para resposta correta form.imd.correct.spots=Marca\u00E7\u00E3o correta form.imd.correct.text=Coment\u00E1rios para todas as respostas corretas form.imd.correct.title=T\u00EDtulo diff --git a/src/main/java/org/olat/modules/gotomeeting/ui/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/modules/gotomeeting/ui/_i18n/LocalStrings_pt_BR.properties index 58dc0a24dec1353d9dbf1abcf6a74786bd59613f..c52daa308488287e96de50a9d2eb9b890346ab4a 100644 --- a/src/main/java/org/olat/modules/gotomeeting/ui/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/modules/gotomeeting/ui/_i18n/LocalStrings_pt_BR.properties @@ -1,4 +1,4 @@ -#Tue Jun 19 21:45:31 CEST 2018 +#Tue Jul 10 14:20:58 CEST 2018 add.my.account=Eu tenho uma conta add.organizer=Adicionar um novo organizador add.training=Adicionar novo treinamento diff --git a/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java b/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java index 17f7b92c2d0ae321172910c676d27c5b690a353c..f00c06a7b961f85d6154bea079fe8ca93ab642ac 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/AbstractPageListController.java @@ -194,7 +194,13 @@ implements Activateable2, TooledController, FlexiTableComponentDelegate { timelineSwitchOffButton = uifactory.addFormLink("timeline.switch.off", formLayout, Link.BUTTON_SMALL); timelineSwitchOffButton.setIconLeftCSS("o_icon o_icon-sm o_icon_toggle_off"); timelineSwitchOffButton.setElementCssClass("o_sel_timeline_off"); - doSwitchTimelineOn(); + + Object prefs = ureq.getUserSession().getGuiPreferences().get(this.getClass(), getTimelineSwitchPreferencesName(), "on"); + if("on".equals(prefs)) { + doSwitchTimelineOn(ureq, false); + } else { + doSwitchTimelineOff(ureq, false); + } } else { flc.contextPut("timelineSwitch", Boolean.FALSE); } @@ -627,9 +633,9 @@ implements Activateable2, TooledController, FlexiTableComponentDelegate { } } } else if(timelineSwitchOnButton == source) { - doSwitchTimelineOff(); + doSwitchTimelineOff(ureq, true); } else if(timelineSwitchOffButton == source) { - doSwitchTimelineOn(); + doSwitchTimelineOn(ureq, true); } else if(source instanceof FormLink) { FormLink link = (FormLink)source; String cmd = link.getCmd(); @@ -726,18 +732,26 @@ implements Activateable2, TooledController, FlexiTableComponentDelegate { fireEvent(ureq, Event.CHANGED_EVENT); } - private void doSwitchTimelineOn() { + private void doSwitchTimelineOn(UserRequest ureq, boolean savePreferences) { timelineSwitchOnButton.setVisible(true); timelineSwitchOffButton.setVisible(false); flc.contextPut("timelineSwitch", Boolean.TRUE); + if(savePreferences) { + ureq.getUserSession().getGuiPreferences().putAndSave(this.getClass(), getTimelineSwitchPreferencesName(), "on"); + } } - private void doSwitchTimelineOff() { + private void doSwitchTimelineOff(UserRequest ureq, boolean savePreferences) { timelineSwitchOnButton.setVisible(false); timelineSwitchOffButton.setVisible(true); flc.contextPut("timelineSwitch", Boolean.FALSE); + if(savePreferences) { + ureq.getUserSession().getGuiPreferences().putAndSave(this.getClass(), getTimelineSwitchPreferencesName(), "off"); + } } + protected abstract String getTimelineSwitchPreferencesName(); + protected Assignment doStartAssignment(UserRequest ureq, PortfolioElementRow row) { return doStartAssignment(ureq, row.getAssignment().getKey()); } diff --git a/src/main/java/org/olat/modules/portfolio/ui/BinderPageListController.java b/src/main/java/org/olat/modules/portfolio/ui/BinderPageListController.java index af9a321fe126f45ee8f03b559dca896c5f07c9b1..d4dd694b46eafbf271d95b0116d7818c630f83b5 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/BinderPageListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/BinderPageListController.java @@ -126,6 +126,11 @@ public class BinderPageListController extends AbstractPageListController { initialPanel.setCssClass("o_edit_mode"); } } + + @Override + protected String getTimelineSwitchPreferencesName() { + return "binder-timeline-switch-" + binder.getKey(); + } private String getGuiPrefsKey(OLATResourceable binderOres) { return new StringBuilder() diff --git a/src/main/java/org/olat/modules/portfolio/ui/DeletedPageListController.java b/src/main/java/org/olat/modules/portfolio/ui/DeletedPageListController.java index e04ddf53b8a43f35ab0db742a2fdbba7a54fd2be..1b787abc53aa374ec7a85ffa0a9a01275de064b4 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/DeletedPageListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/DeletedPageListController.java @@ -83,6 +83,11 @@ public class DeletedPageListController extends AbstractPageListController { tableEl.setSelectAllEnable(tableEl.getRendererType() == FlexiTableRendererType.classic); } + @Override + protected String getTimelineSwitchPreferencesName() { + return "del-timeline-switch"; + } + @Override protected void loadModel(UserRequest ureq, String searchString) { Map<Long,Long> numberOfCommentsMap = portfolioService.getNumberOfCommentsOnOwnedPage(getIdentity()); diff --git a/src/main/java/org/olat/modules/portfolio/ui/MyPageListController.java b/src/main/java/org/olat/modules/portfolio/ui/MyPageListController.java index fe38162ea57b2c1ea7ae5d04c79dcb7b991ffcad..8e3145552a65dc24f9cd12fdfda509512860a068 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/MyPageListController.java +++ b/src/main/java/org/olat/modules/portfolio/ui/MyPageListController.java @@ -81,6 +81,11 @@ public class MyPageListController extends AbstractPageListController { newEntryLink.setElementCssClass("o_sel_pf_new_entry"); stackPanel.addTool(newEntryLink, Align.right); } + + @Override + protected String getTimelineSwitchPreferencesName() { + return "entries-timeline-switch"; + } @Override protected void loadModel(UserRequest ureq, String searchString) { @@ -141,6 +146,7 @@ public class MyPageListController extends AbstractPageListController { timelineEl.setPoints(points); disposeRows();//clean up the posters + model.setFlat(true); model.setObjects(rows); tableEl.reset(); tableEl.reloadData(); diff --git a/src/main/java/org/olat/modules/portfolio/ui/PageListDataModel.java b/src/main/java/org/olat/modules/portfolio/ui/PageListDataModel.java index e24a8b81cd811759646340131d84f7a58ef95de9..1972655277e1052bd04cd1c4d2682d46ca783eeb 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/PageListDataModel.java +++ b/src/main/java/org/olat/modules/portfolio/ui/PageListDataModel.java @@ -47,18 +47,26 @@ public class PageListDataModel extends DefaultFlexiTableDataModel<PortfolioEleme private static final OLog log = Tracing.createLoggerFor(PageListDataModel.class); + private boolean flat; private final Locale locale; private List<PortfolioElementRow> backup; - - + public PageListDataModel(FlexiTableColumnModel columnModel, Locale locale) { super(columnModel); this.locale = locale; } + public boolean isFlat() { + return flat; + } + + public void setFlat(boolean flat) { + this.flat = flat; + } + @Override public void sort(SortKey orderBy) { - PageListSortableDataModelDelegate sorter = new PageListSortableDataModelDelegate(orderBy, this, locale); + PageListSortableDataModelDelegate sorter = new PageListSortableDataModelDelegate(orderBy, this, flat, locale); List<PortfolioElementRow> rows; try { rows = sorter.sort(); diff --git a/src/main/java/org/olat/modules/portfolio/ui/PageListSortableDataModelDelegate.java b/src/main/java/org/olat/modules/portfolio/ui/PageListSortableDataModelDelegate.java index ac18370c52475bd0a1beee389d0e991faf4d95be..0c8d6c709d3fd1335fdbc1832bad38bb57d90ff3 100644 --- a/src/main/java/org/olat/modules/portfolio/ui/PageListSortableDataModelDelegate.java +++ b/src/main/java/org/olat/modules/portfolio/ui/PageListSortableDataModelDelegate.java @@ -26,7 +26,6 @@ import java.util.List; import java.util.Locale; import org.olat.core.commons.persistence.SortKey; -import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableDataModel; import org.olat.core.gui.components.form.flexible.impl.elements.table.SortableFlexiTableModelDelegate; import org.olat.modules.portfolio.Page; import org.olat.modules.portfolio.PageStatus; @@ -42,8 +41,11 @@ import org.olat.modules.portfolio.ui.model.PortfolioElementRow; */ public class PageListSortableDataModelDelegate extends SortableFlexiTableModelDelegate<PortfolioElementRow> { - public PageListSortableDataModelDelegate(SortKey orderBy, SortableFlexiTableDataModel<PortfolioElementRow> tableModel, Locale locale) { + private final boolean flat; + + public PageListSortableDataModelDelegate(SortKey orderBy, PageListDataModel tableModel, boolean flat, Locale locale) { super(orderBy, tableModel, locale); + this.flat = flat; } @Override @@ -63,7 +65,11 @@ public class PageListSortableDataModelDelegate extends SortableFlexiTableModelDe comparator = new ReverseComparator(comparator); } - Collections.sort(rows, new ClassicComparator(comparator)); + if(flat) { + Collections.sort(rows, comparator); + } else { + Collections.sort(rows, new ClassicComparator(comparator)); + } } @Override @@ -88,10 +94,12 @@ public class PageListSortableDataModelDelegate extends SortableFlexiTableModelDe private final class CommentsComparator implements Comparator<PortfolioElementRow> { @Override public int compare(PortfolioElementRow o1, PortfolioElementRow o2) { - long c1 = o1.getNumOfComments(); - long c2 = o2.getNumOfComments(); - + long c1 = o1.getCommentFormLink() == null ? 0 : o1.getNumOfComments(); + long c2 = o2.getCommentFormLink() == null ? 0 : o2.getNumOfComments(); int c = Long.compare(c1, c2); + if(c == 0) { + c = Boolean.compare(o1.getCommentFormLink() != null, o2.getCommentFormLink() != null); + } if(c == 0) { c = compareString(o1.getTitle(), o2.getTitle()); } diff --git a/src/main/java/org/olat/modules/webFeed/manager/FeedFileStorge.java b/src/main/java/org/olat/modules/webFeed/manager/FeedFileStorge.java index aaaf8ef56c180d32e09b46f401980e0d106b3b1c..d42fde9dc87c5c1bb691a47eae46f2c0aa02a863 100644 --- a/src/main/java/org/olat/modules/webFeed/manager/FeedFileStorge.java +++ b/src/main/java/org/olat/modules/webFeed/manager/FeedFileStorge.java @@ -109,6 +109,7 @@ public class FeedFileStorge { xstream.omitField(ItemImpl.class, "key"); xstream.omitField(ItemImpl.class, "feed"); xstream.alias("enclosure", Enclosure.class, EnclosureImpl.class); + xstream.ignoreUnknownElements(); } /** @@ -395,9 +396,6 @@ public class FeedFileStorge { } catch (Exception e) { log.warn("Item XML-File could not be read. Item container: " + leaf); } - } else { - log.warn("Item XML-File could not be found on file system." - + " Item container: " + itemContainer.getName()); } } diff --git a/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java b/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java index 77dd85192d3f01b5f4c67deb1ce9c3f4d975cc8a..3f6e29d26d96fb57d6568ec0d088456d516ec5f5 100644 --- a/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java +++ b/src/main/java/org/olat/modules/webFeed/manager/FeedManagerImpl.java @@ -796,13 +796,12 @@ public class FeedManagerImpl extends FeedManager { @Override public void importFeedFromXML(OLATResource ores, boolean removeIdentityKeys) { Feed feedFromXml = feedFileStorage.loadFeedFromXML(ores); - if (feedFromXml == null) return; // Check if the feed already exits or create it. The feed exists // possibly, if a previous migration from an XML feed was not // successful. Feed feed = feedDAO.loadFeed(ores); - if (feed == null) { + if (feed == null && feedFromXml != null) { feedFromXml.setResourceableId(ores.getResourceableId()); // Use the display name instead of the username if (!removeIdentityKeys && feedFromXml.getAuthor() != null) { @@ -815,35 +814,37 @@ public class FeedManagerImpl extends FeedManager { log.info("Feed imported " + "(" + ores.getResourceableTypeName() + "): " + ores.getResourceableId()); } - List<Item> itemsFromXml = feedFileStorage.loadItemsFromXML(ores); - itemsFromXml = fixFeedVersionIssues(feedFromXml, itemsFromXml); - for (Item itemFromXml : itemsFromXml) { - // Check if the item already exits or create it. - Item item = itemDAO.loadItemByGuid(feed.getKey(), itemFromXml.getGuid()); - if (item == null) { - if (removeIdentityKeys) { - itemFromXml.setAuthorKey(null); - itemFromXml.setModifierKey(null); - } else { - // Check if the identity exists - if (itemFromXml.getAuthorKey() != null - && securityManager.loadIdentityShortByKey(itemFromXml.getAuthorKey()) == null) { + if (feed != null) { + List<Item> itemsFromXml = feedFileStorage.loadItemsFromXML(ores); + itemsFromXml = fixFeedVersionIssues(feedFromXml, itemsFromXml); + for (Item itemFromXml : itemsFromXml) { + // Check if the item already exits or create it. + Item item = itemDAO.loadItemByGuid(feed.getKey(), itemFromXml.getGuid()); + if (item == null) { + if (removeIdentityKeys) { itemFromXml.setAuthorKey(null); - } - if (itemFromXml.getModifierKey() != null - && securityManager.loadIdentityShortByKey(itemFromXml.getModifierKey()) == null) { itemFromXml.setModifierKey(null); + } else { + // Check if the identity exists + if (itemFromXml.getAuthorKey() != null + && securityManager.loadIdentityShortByKey(itemFromXml.getAuthorKey()) == null) { + itemFromXml.setAuthorKey(null); + } + if (itemFromXml.getModifierKey() != null + && securityManager.loadIdentityShortByKey(itemFromXml.getModifierKey()) == null) { + itemFromXml.setModifierKey(null); + } } + itemDAO.createItem(feed, itemFromXml); + log.info("Item imported: " + itemFromXml.getGuid()); } - itemDAO.createItem(feed, itemFromXml); - log.info("Item imported: " + itemFromXml.getGuid()); + feedFileStorage.deleteItemXML(itemFromXml); } - feedFileStorage.deleteItemXML(itemFromXml); - } - if (feed.isExternal()) { - saveExternalItems(feed); - saveExternalFeed(feed); + if (feed.isExternal()) { + saveExternalItems(feed); + saveExternalFeed(feed); + } } feedFileStorage.deleteFeedXML(feed); diff --git a/src/main/java/org/olat/repository/handlers/CourseHandler.java b/src/main/java/org/olat/repository/handlers/CourseHandler.java index 0572468a6e0f3dd6567b2ee58c5f2fede57d6ffd..d9947b193dc69bdef92ccc2aacc33b00b0b23272 100644 --- a/src/main/java/org/olat/repository/handlers/CourseHandler.java +++ b/src/main/java/org/olat/repository/handlers/CourseHandler.java @@ -339,7 +339,7 @@ public class CourseHandler implements RepositoryHandler { RepositoryService repositoryService = CoreSpringFactory.getImpl(RepositoryService.class); OLATResource ores = OLATResourceManager.getInstance().findOrPersistResourceable(resource); RepositoryEntry importedRepositoryEntry = repositoryService.create(owner, null, - importExport.getResourceName(), importExport.getDisplayName(), importExport.getDescription(), ores, 0); + importExport.getResourceName(), importExport.getDisplayName(), importExport.getDescription(), ores, RepositoryEntry.ACC_OWNERS); // set the new shared folder reference CourseConfig courseConfig = course.getCourseEnvironment().getCourseConfig(); @@ -373,7 +373,7 @@ public class CourseHandler implements RepositoryHandler { OLATResource ores = OLATResourceManager.getInstance().findOrPersistResourceable(resource); RepositoryEntry importedRepositoryEntry = repositoryService.create(owner, - null, importExport.getResourceName(), importExport.getDisplayName(), importExport.getDescription(), ores, 0); + null, importExport.getResourceName(), importExport.getDisplayName(), importExport.getDescription(), ores, RepositoryEntry.ACC_OWNERS); // set the new glossary reference CourseConfig courseConfig = course.getCourseEnvironment().getCourseConfig(); diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_12_5_3.java b/src/main/java/org/olat/upgrade/OLATUpgrade_12_5_3.java new file mode 100644 index 0000000000000000000000000000000000000000..a195076bacecd0b47a1588ec47a1df17c636597a --- /dev/null +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_12_5_3.java @@ -0,0 +1,109 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <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 the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <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> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.upgrade; + +import java.util.Arrays; +import java.util.List; + +import org.olat.core.commons.persistence.DB; +import org.olat.fileresource.types.BlogFileResource; +import org.olat.fileresource.types.PodcastFileResource; +import org.olat.modules.webFeed.manager.FeedManager; +import org.olat.resource.OLATResource; +import org.olat.resource.OLATResourceManager; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * + * Initial date: 13.07.2018<br> + * @author uhensler, urs.hensler@frentix.com, http://www.frentix.com + * + */ +public class OLATUpgrade_12_5_3 extends OLATUpgrade { + + private static final String VERSION = "OLAT_12.5.3"; + private static final String MIGRATE_WEB_FEED = "MIGRATE WEB FEED"; + + @Autowired + private DB dbInstance; + @Autowired + private FeedManager feedManager; + + public OLATUpgrade_12_5_3() { + super(); + } + + @Override + public String getVersion() { + return VERSION; + } + + @Override + public boolean doPreSystemInitUpgrade(UpgradeManager upgradeManager) { + return false; + } + + @Override + public boolean doPostSystemInitUpgrade(UpgradeManager upgradeManager) { + UpgradeHistoryData uhd = upgradeManager.getUpgradesHistory(VERSION); + if (uhd == null) { + // has never been called, initialize + uhd = new UpgradeHistoryData(); + } else if (uhd.isInstallationComplete()) { + return false; + } + + boolean allOk = true; + allOk &= upgradeBlogXmlToDb(upgradeManager, uhd); + + uhd.setInstallationComplete(allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + if(allOk) { + log.audit("Finished OLATUpgrade_12_5_3 successfully!"); + } else { + log.audit("OLATUpgrade_12_5_3 not finished, try to restart OpenOLAT!"); + } + return allOk; + } + + private boolean upgradeBlogXmlToDb(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { + boolean allOk = true; + if (!uhd.getBooleanDataValue(MIGRATE_WEB_FEED)) { + + List<String> feedTypes = Arrays.asList(BlogFileResource.TYPE_NAME, PodcastFileResource.TYPE_NAME); + List<OLATResource> feeds = OLATResourceManager.getInstance().findResourceByTypes(feedTypes); + log.info("Number of feeds to upgrade: " + feeds.size()); + for (OLATResource ores : feeds) { + log.info("Upgrade feed " + "(" + ores.getResourceableTypeName() + "): " + ores.getResourceableId()); + try { + feedManager.importFeedFromXML(ores, false); + } catch (Exception e) { + allOk &= false; + log.error("", e); + } + dbInstance.commitAndCloseSession(); + } + + uhd.setBooleanDataValue(MIGRATE_WEB_FEED, allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + } + return allOk; + } +} diff --git a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml index 5455c8ef6b2b4945d21db13c1f1e3c9408ded5c2..4fd1198df2cf35aba1df3ecf33476dc3d3c0b035 100644 --- a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml +++ b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml @@ -56,6 +56,7 @@ <bean id="upgrade_12_3_0" class="org.olat.upgrade.OLATUpgrade_12_3_0"/> <bean id="upgrade_12_4_0" class="org.olat.upgrade.OLATUpgrade_12_4_0"/> <bean id="upgrade_12_4_1" class="org.olat.upgrade.OLATUpgrade_12_4_1"/> + <bean id="upgrade_12_5_3" class="org.olat.upgrade.OLATUpgrade_12_5_3"/> </list> </property> </bean> diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties index fd38a1804730b064acbd8a299a218a2b4eb11353..b305a58785e6fd6dd9e6915e1bfc9be36b5dedf1 100644 --- a/src/main/resources/serviceconfig/olat.properties +++ b/src/main/resources/serviceconfig/olat.properties @@ -1126,8 +1126,8 @@ ldap.learningResourceManagerRoleValue= # Build properties ##### application.name=OpenOLAT -build.version=12.5.1 -build.identifier=openolat1251-dev +build.version=12.5.3 +build.identifier=openolat1253-dev build.repo.revision=local-devel ##### diff --git a/src/main/webapp-tomcat/WEB-INF/web.xml b/src/main/webapp-tomcat/WEB-INF/web.xml index 2a2bebd6d47c17c60718039af44e478be99c8448..3cffbb36dd9b0d660f2cd497d201af9cf8e2420e 100644 --- a/src/main/webapp-tomcat/WEB-INF/web.xml +++ b/src/main/webapp-tomcat/WEB-INF/web.xml @@ -199,4 +199,13 @@ <session-config> <session-timeout>60</session-timeout> </session-config> + + <error-page> + <error-code>500</error-code> + <location>/errors/error.html</location> + </error-page> + <error-page> + <exception-type>java.lang.Throwable</exception-type> + <location>/errors/error.html</location> + </error-page> </web-app> diff --git a/src/main/webapp-wildfly/WEB-INF/web.xml b/src/main/webapp-wildfly/WEB-INF/web.xml index ac41009dc671e4be0ac48bbdb2aabfdf36e25071..28a461990f9cf7b9594687480ac5524222d384bb 100644 --- a/src/main/webapp-wildfly/WEB-INF/web.xml +++ b/src/main/webapp-wildfly/WEB-INF/web.xml @@ -165,4 +165,12 @@ <session-timeout>60</session-timeout> </session-config> + <error-page> + <error-code>500</error-code> + <location>/errors/error.html</location> + </error-page> + <error-page> + <exception-type>java.lang.Throwable</exception-type> + <location>/errors/error.html</location> + </error-page> </web-app> diff --git a/src/test/java/org/olat/modules/webFeed/manager/FeedManagerImplTest.java b/src/test/java/org/olat/modules/webFeed/manager/FeedManagerImplTest.java index c9720e3b8cda646ef4cac015929a325f02440a38..d43a1349b30bf649e67c1742bc3a1e6856507608 100644 --- a/src/test/java/org/olat/modules/webFeed/manager/FeedManagerImplTest.java +++ b/src/test/java/org/olat/modules/webFeed/manager/FeedManagerImplTest.java @@ -262,16 +262,6 @@ public class FeedManagerImplTest { SEND_NO_EVENTS); } - @Test - public void importShouldNothingDoIfNoXmlFileIsPresent() { - when(feedFileStorageMock.loadFeedFromXML(any(OLATResource.class))).thenReturn(null); - - sut.importFeedFromXML(any(OLATResource.class), true); - - verifyZeroInteractions(feedDAOMock); - verifyZeroInteractions(itemDAOMock); - } - @Test public void importShouldSaveFeedToDatabase() { when(feedFileStorageMock.loadFeedFromXML(any(OLATResource.class))).thenReturn(internatFeedMock); diff --git a/src/test/java/org/olat/restapi/ForumTest.java b/src/test/java/org/olat/restapi/ForumTest.java index 6b73bb8538dc6e65f81ebdcb52b353a8d0447b56..484217d1b70140bcb8f9a9a8e8fbf50bcac5fa8d 100644 --- a/src/test/java/org/olat/restapi/ForumTest.java +++ b/src/test/java/org/olat/restapi/ForumTest.java @@ -56,7 +56,9 @@ import org.apache.http.util.EntityUtils; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.type.TypeReference; import org.junit.Before; +import org.junit.FixMethodOrder; import org.junit.Test; +import org.junit.runners.MethodSorters; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.Identity; import org.olat.core.util.FileUtils; @@ -75,6 +77,7 @@ import org.olat.test.JunitTestHelper; import org.olat.test.OlatJerseyTestCase; import org.springframework.beans.factory.annotation.Autowired; +@FixMethodOrder(MethodSorters.NAME_ASCENDING) public class ForumTest extends OlatJerseyTestCase { private static Forum forum;