diff --git a/INSTALL.APPSERVER.README b/INSTALL.APPSERVER.README index 59d3eb299cef79cbd60d8c5d87ac396dd8670ac5..6e66b50d3a63f6fe32ce142815a3efd437268fff 100644 --- a/INSTALL.APPSERVER.README +++ b/INSTALL.APPSERVER.README @@ -3,35 +3,77 @@ EXPERIMENTAL: Setting up latest OpenOLAT version on Eclipse With an Application -------------------------------------------------------------------------------------- OpenOLAT supports only Tomcat officially, but it can also run on other application -servers like JBoss AS or Glassfish. +servers like JBoss AS or Glassfish. This README is intended for people who have +some minimal experience with these servers and can install a JDBC driver, set some +JMS resources... The beginning of the installation is the same as Tomcat, it's described in INSTALL.README. To create your eclipse project, use these commands instead of the default one: for JBoss AS: - mvn eclipse:clean eclipse:eclipse -P-tomcat,jbossas + mvn eclipse:clean eclipse:eclipse -P-tomcat,jbossas7 and for Glassfish mvn eclipse:clean eclipse:eclipse -P-tomcat,gae - + + +Configuration JBoss AS 7.1 +-------------------------- + +1. I use a JBoss AS 7.1.1 with Hibernate upgraded to the latest version. +2. Define a JDBC connection pool in your standalone.xml configuration with a jndi-name like: + java:jboss/datasources/OpenOLATDS and set this JNDI name + in olat.local.properties set the following properties: + db.source=jndi + db.jndi=java:jboss/datasources/OpenOLATDS + hibernate.cache=disabled +3. Create a queue with a jndi-name like: + java:jboss/exported/jms/queue/searchQueue + and a topic: + java:jboss/exported/jms/topic/sysbus + in olat.local.properties set the following properties: + jms.provider=jndi + jms.broker.jndi=java:/ConnectionFactory + sysbus.broker.jndi=java:jboss/exported/jms/topic/sysbus + search.broker.jndi=java:jboss/exported/jms/queue/searchQueue -I use a JBoss AS 7.1 with Hibernate upgraded to the latest version and Glassfish 3.1.2.2 -community version. I created in them a JDBC connection Pool, a JMS connection factory -(which already exists in JBoss) and a topic for the sysbus and a queue for the search. +Configuration Glassfish 3.1 +--------------------------- -With this setup, OpenOLAT use the JDBC connection pool of your application server, the JMS -server and its JAX-RS implementation. JBoss delivers Hibernate too. +1. I use the community edition of Glassfish version 3.1.2.2. +2. In the administration console, create a JDBC Resource with a JNDI name like: + jdbc/OpenOLATDS + and drop the driver.jar at the right place. + In olat.local.properties, set the following properties: + db.source=jndi + db.jndi=jdbc/OpenOLATDS +3. In the administration console, create in JMS Resources > Connection factories: + -A resource of type javax.jms.ConnectionFactory with a JNDI name like: + OpenOLATConnectionFactory + In JMS Resources > Destination factories: + -A queue of type javax.jms.Queue and a JNDI name like; + queue/searchQueue + -A topic of type javax.jms.Topic and a JNDI name like; + topic/sysbus + in olat.local.properties set the following properties: + jms.provider=jndi + jms.broker.jndi=OpenOLATConnectionFactory + sysbus.broker.jndi=topic/sysbus + search.broker.jndi=queue/searchQueue -Features located on the application server: -OK JDBC Connections -OK JMS -OK JAX-RS (restapi) -x JAX-WS (onyx, vitero) -x Mail -x LDAP Connection --- Hibernate/JPA (only JBoss because we depend on Hibernate) -x Infinispan for caching +Features located on the application server +------------------------------------------ +State Feature +------------------------------------------ +OK JDBC Connections +OK JMS +OK JAX-RS (restapi) +x JAX-WS (onyx, vitero) +x Mail +x LDAP Connection +OK (only JBoss) Hibernate/JPA (only JBoss AS, we depend on Hibernate) +x Caching (for JPA second level cache for example) diff --git a/NOTICE.TXT b/NOTICE.TXT index 95e6eb474d1bc71c24fa2512c73b9c79d7191c08..dcfd76f347416732e1b979918056771c96113bfc 100644 --- a/NOTICE.TXT +++ b/NOTICE.TXT @@ -23,7 +23,7 @@ Contributors and copy right holders of openolat.org codebase since 2011: Michael Enz, Christian Franck, Florian Gnägi, Roman Haag, Joël Krähemann, Matthai Kurian, Stéphane Rossé, Kirsten Scherer, Sergio Trentini - BPS Bildungsportal Sachsen GmbH, Germany [http://www.bildungsportal.sachsen.de]: - Armin Blawitzki, Stefan Köber, Sven Morgener + Armin Blawitzki, Stefan Köber, Sven Morgner - VCRP Virtueller Campus Rheinland-Pfalz [http://www.vcrp.de] Stephan Clemenz - Rain and Hail Agricultural Insurance [http://www.rainhail.com] diff --git a/src/main/java/de/bps/course/nodes/den/DENManageParticipantsController.java b/src/main/java/de/bps/course/nodes/den/DENManageParticipantsController.java index f159535bb1d0361cdb1e4c95c82a9a4d37c1d4d3..a1d822992720b01485b42c9cb8a5e476d44f4737 100644 --- a/src/main/java/de/bps/course/nodes/den/DENManageParticipantsController.java +++ b/src/main/java/de/bps/course/nodes/den/DENManageParticipantsController.java @@ -305,7 +305,7 @@ public class DENManageParticipantsController extends BasicController { private void createAddedNotificationMail(UserRequest ureq, String subjectStr) { MailTemplate mailTempl = denManager.getAddedMailTemplate(ureq, subjectStr, getTranslator()); removeAsListenerAndDispose(addedNotificationCtr); - //TODO memail + addedNotificationCtr = new MailNotificationEditController(getWindowControl(), ureq, mailTempl, false, false); listenTo(addedNotificationCtr); diff --git a/src/main/java/de/bps/olat/user/ChangeEMailController.java b/src/main/java/de/bps/olat/user/ChangeEMailController.java index 1d9a28a2f8334665162fd885e1be35e0da6f4024..e90be1c46047289aa0ad66c91df4fe4be87304f4 100644 --- a/src/main/java/de/bps/olat/user/ChangeEMailController.java +++ b/src/main/java/de/bps/olat/user/ChangeEMailController.java @@ -52,7 +52,7 @@ public class ChangeEMailController extends DefaultController { protected static final String PACKAGE = ProfileAndHomePageEditController.class.getPackage().getName(); protected static final String CHANGE_EMAIL_ENTRY = "change.email.login"; - public static int TIME_OUT = 3; + public static int TIME_OUT = 30; protected Translator pT; protected String emKey; diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties index 9e9d54ffe59e73a8f19f7543df9777c7febc7dcb..c33302ad6a9ddee0be9ecff4eedb3176b490e077 100644 --- a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties @@ -1,10 +1,10 @@ -#Fri Aug 13 18:17:56 CEST 2010 -main.menu.title=Administration -main.menu.title.alt=Administration +#Tue Dec 18 22:37:34 CET 2012 bulkuserreplay.chkbx.onoff='Check box on' means 'Replay ON' and 'AJAX OFF' bulkuserreplay.tt=User names in separate lines (no comma, etc.) data.no.save=Attention\: your modifications will be lost after an OLAT reboot\! To save your changes permanently you have to adapt the file <code>olat.properties</code>. Future releases will provide you with the possibility to save modifications automatically. error.deleteworkflow.locked.by=The workflow regarding the deletion of users is being edited by user {0}. Please try again later. +main.menu.title=Administration +main.menu.title.alt=Administration manu.config.alt=Please configure your system menu.admin=Administration menu.admin.alt=Administration @@ -18,6 +18,8 @@ menu.anonymousgroup=Anonymous users/guests menu.anonymousgroup.alt=Manage anonymous user group (guests) menu.authorgroup=Authors menu.authorgroup.alt=Manage author group +menu.caches=Caches +menu.caches.alt=Caches menu.coauthors=Co-authors menu.coauthors.alt=Manage all co-authors that are not part of the author group menu.config=Core functions @@ -32,26 +34,38 @@ menu.created.sixmonth=New since the last six months menu.created.sixmonth.alt=Users that have been created within the last six months menu.deletedusers=Deleted users menu.deletedusers.alt=Users deleted in OLAT +menu.devel=Development +menu.devel.alt=Development tools +menu.errors=Errors +menu.errors.alt=Errors and log levels menu.extensions=Software modules menu.extensions.alt=List of uploaded software modules menu.groupmanagergroup=Group administrator menu.groupmanagergroup.alt=Manage group administrators course-comprehensively -menu.userproperties=User Properties -menu.userproperties.alt=Manage User Properties +menu.hibernate=Database ORM +menu.hibernate.alt=Database ORM / Hibernate menu.i18n=Languages menu.i18n.alt=Configuration of default and enabled system languages menu.imadmin=Instant Messaging menu.imadmin.alt=Administer Instant Messaging +menu.infomsg=Info messages +menu.infomsg.alt=Info messages +menu.javavm=Java VM Infos +menu.javavm.alt=Java Virtual Machine informations menu.jmx=JMX menu.jmx.alt=View JMX values menu.layout=Layout menu.layout.alt=Modify layout within the entire system +menu.lock=Locks +menu.lock.alt=Locks menu.logondeniedgroup=Blocked users menu.logondeniedgroup.alt=Users not allowed to log in into OLAT menu.menuaccess=Access and rights menu.menuaccess.alt=Manage users by access and rights menu.menuqueries=Predefined searches menu.menuqueries.alt=Manage user by predefined search lists +menu.module=Modules +menu.module.alt=Modules menu.noauthentication=Authentication missing menu.noauthentication.alt=Users that are not correctly set up (no password) menu.notifications=Notifications @@ -60,6 +74,10 @@ menu.onlinetranslation=Translation tool menu.onlinetranslation.alt=Translate OLAT into your language menu.onlinetranslation.customize=Language adaption tool menu.onlinetranslation.customize.alt=Please adapt all language elements of your OLAT installation using the language adaption tool +menu.parent.customizing=Customizing +menu.parent.customizing.alt=Customize your OLAT deeply +menu.parent.maintenance=System maintenance +menu.parent.maintenance.alt=System maintenance and extended setup menu.quota=Quota management menu.quota.alt=Quota management menu.registration=System registration @@ -70,10 +88,16 @@ menu.restapi=REST API menu.restapi.alt=REST API settings menu.search=Full-text search menu.search.alt=Administration of full-text search +menu.session=User sessions +menu.session.alt=Benutzer sessions +menu.snoop=Snoop user request +menu.snoop.alt=Snoop user requests menu.statistics=Statistics menu.statistics.alt=Log file statistics menu.sysinfo=System information menu.sysinfo.alt=System information +menu.system=System +menu.system.alt=System menu.ucreate=Create user menu.ucreate.alt=Create user menu.umgmt=User management @@ -92,13 +116,11 @@ menu.usergroup=All system users menu.usergroup.alt=Manage system user group menu.usermanagergroup=User manager menu.usermanagergroup.alt=Administer user managers +menu.userproperties=User Properties +menu.userproperties.alt=Manage User Properties menu.usersimport=Import users menu.usersimport.alt=Import users by means of Excel lists menu.versions=Versioning menu.versions.alt=Versioning settings queries.intro=In the menu <i>Predefined searches</i> you will find often used search queries. You can specify your queries by means of the user search. sysroles.intro=In the menu <i>Access and rights</i> you get an overview of access and rights in OLAT you can administer. -menu.parent.maintenance=System maintenance -menu.parent.maintenance.alt=System maintenance and extended setup -menu.parent.customizing=Customizing -menu.parent.customizing.alt=Customize your OLAT deeply \ No newline at end of file diff --git a/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java b/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java index 1362bf3fcf85f2f0313038f2b533610d783b08a1..2e33fbdee0dcf8689b6f5129e1deee7017ed1ef2 100644 --- a/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java +++ b/src/main/java/org/olat/admin/notifications/NotificationsEmailAdminController.java @@ -33,9 +33,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.olat.core.util.notifications.NotificationsManager; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; import org.springframework.scheduling.quartz.CronTriggerBean; + /** * Description:<br> * Manually trigger sending of notification email which are normally sent only once a day. @@ -74,12 +77,17 @@ public class NotificationsEmailAdminController extends BasicController { * org.olat.core.gui.control.Event) */ @Override - @SuppressWarnings("unused") public void event(UserRequest ureq, Component source, Event event) { if (source == startNotifyButton) { - NotificationsManager.getInstance().notifyAllSubscribersByEmail(); + //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()); + } catch (SchedulerException e) { + logError("", e); + } } - } /** diff --git a/src/main/java/org/olat/admin/search/SearchAdminController.java b/src/main/java/org/olat/admin/search/SearchAdminController.java index 367170b5b2c66b70632e2e6492d4fd043f05eded..f8dc8cbaf03f9fc978cfca5e33e954250c591fc7 100644 --- a/src/main/java/org/olat/admin/search/SearchAdminController.java +++ b/src/main/java/org/olat/admin/search/SearchAdminController.java @@ -100,17 +100,19 @@ public class SearchAdminController extends BasicController { putInitialPanel(main); } + protected void doDispose() { + // + } + /** * @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) */ public void event(UserRequest ureq, Component source, Event event) { if (source == startIndexingButton) { - SearchServiceFactory.getService().startIndexing(); - logInfo("Indexing started via Admin", SearchAdminController.class.getName()); + doStartIndexer(); myContent.setDirty(true); } else if (source == stopIndexingButton) { - SearchServiceFactory.getService().stopIndexing(); - logInfo("Indexing stopped via Admin", SearchAdminController.class.getName()); + doStopIndexer(); myContent.setDirty(true); } } @@ -133,11 +135,13 @@ public class SearchAdminController extends BasicController { } } - /** - * - * @see org.olat.core.gui.control.DefaultController#doDispose(boolean) - */ - protected void doDispose() { - // + private void doStartIndexer() { + SearchServiceFactory.getService().startIndexing(); + logInfo("Indexing started via Admin", SearchAdminController.class.getName()); + } + + private void doStopIndexer() { + SearchServiceFactory.getService().stopIndexing(); + logInfo("Indexing started via Admin", SearchAdminController.class.getName()); } } diff --git a/src/main/java/org/olat/admin/sysinfo/UserSessionConfigAdminController.java b/src/main/java/org/olat/admin/sysinfo/UserSessionConfigAdminController.java index cf488a7504fa5ca1edc02487a960306277fa9579..425001d3f7ecf09e3e73660a5d1da2d441389ecd 100644 --- a/src/main/java/org/olat/admin/sysinfo/UserSessionConfigAdminController.java +++ b/src/main/java/org/olat/admin/sysinfo/UserSessionConfigAdminController.java @@ -19,6 +19,7 @@ */ package org.olat.admin.sysinfo; +import org.apache.commons.lang.math.NumberUtils; import org.olat.admin.AdminModule; import org.olat.basesecurity.AuthHelper; import org.olat.core.CoreSpringFactory; @@ -137,14 +138,22 @@ public class UserSessionConfigAdminController extends FormBasicController { @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == saveLink) { + // make sure the value is really an integer, user current value as default + sessionTimeoutEl.setIntValue(NumberUtils.toInt(sessionTimeoutEl.getValue(), sessionModule.getSessionTimeout())); int sessionTimeout = sessionTimeoutEl.getIntValue(); sessionModule.setSessionTimeout(sessionTimeout); + // make sure the value is really an integer, user current value as default + sessionTimeoutAuthEl.setIntValue(NumberUtils.toInt(sessionTimeoutAuthEl.getValue(), sessionModule.getSessionTimeoutAuthenticated())); int sessionTimeoutAuth = sessionTimeoutAuthEl.getIntValue(); sessionModule.setSessionTimeoutAuthenticated(sessionTimeoutAuth); + // make sure the value is really an integer, user 0 as default to indicate no limitation + maxSessionsEl.setIntValue(NumberUtils.toInt(maxSessionsEl.getValue(), 0)); int maxSessions = maxSessionsEl.getIntValue(); adminModule.setMaxSessions(maxSessions); sessionManager.setGlobalSessionTimeout(sessionTimeoutAuth); } else if(source == invalidateOldSessionLink) { + // make sure the value is really an integer, user 0 as default + nbrSessionsEl.setIntValue(NumberUtils.toInt(nbrSessionsEl.getValue(), 0)); int nbrSessions = nbrSessionsEl.getIntValue(); int nbrOfInvalidatedSessions = sessionManager.invalidateOldestSessions(nbrSessions); showInfo("invalidate.session.done", Integer.toString(nbrOfInvalidatedSessions)); diff --git a/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_de.properties index 6363b92a4ce429718787c35c64f02c99dc0d5c9f..b8a00149fdaecb4b2054f9f4f46f9b7d8211b67b 100644 --- a/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_de.properties @@ -2,15 +2,15 @@ allow.login.done=Loginsperrung ist wieder aufgehoben. block.login.done=Neue Logins sind ab jetzt gesperrt. block.login.title=Login sperren -block.login.sure=Sind Sie sicher, dass Sie für alle neuen Benutzer das Login sperren wollen? -block.login.info=Sie können den "Login sperren" speichern so dass er noch gultig ist nach dem Restart. -block.login.options=Persistieren +block.login.sure=Sind Sie sicher, dass Sie für alle neuen Benutzer das Login sperren wollen? Benutzer mit der Rolle Systemadministration sind von der Sperre nicht betroffen. +block.login.info=Sie können die Einstellung "$\:block.login.title" speichern, so dass diese auch nach einem Neustart noch bestehen bleibt bis die Sperrung wieder aufgehoben wird. +block.login.options=Speichern persist.block.login=ein buildinfo=Build Information clear.hibernate.statistics=Hibernate Statistik l\u00F6schen disable.hibernate.statistics=Hibernate Statistik ausschalten enable.hibernate.statistics=Hibernate Statistik einschalten -core.functions=Funktionen Ubersicht +core.functions=Funktionsübersicht core.webdav=WebDAV core.jsMath=JS Math core.restapi=REST API @@ -30,7 +30,7 @@ infomsgEditCluster=Info Meldung editieren infomsgClear=Info Meldung löschen infomsgClearCluster=Info Meldung löschen invalidate.all.sure=Sind Sie sicher, dass Sie alle Benutzersession invalidieren m\u00F6chten? -invalidate.session.done=Alle Sessions wurden invaliert. +invalidate.session.done=Die Sessions wurden invaliert. locks.title=Durch Benutzer gesperrte Objekte loglevels=Loglevels loglevels.title=Log4J Loglevels @@ -48,18 +48,18 @@ oldest.session.button=Sessions invalidieren loglevels=Log levels loglevels.title=Log4J log levels resetloglevels=Alle loglevels auf INFO zur\u00FCcksetzen -run.gc=Run garbage collection -java.memory=Memory +run.gc=Java Garbage Collection jetzt starten +java.memory=Speicher java.threads=Threads -java.threads.title=Current threads +java.threads.title=Gleichzeitige Threads java.thread.name=Name java.thread.group=Gruppe -java.thread.alive=Alive -java.thread.interrupted=Interrupted +java.thread.alive=Aktiv +java.thread.interrupted=Unterbrochen java.thread.cpu.percent=CPU % java.thread.cpu.time=CPU Zeit -java.envProps=Environment properties -java.envProps.title=Java Environment properties +java.envProps=Umgebungsvariablen +java.envProps.title=Java Umgebungsvariablen java.envprops.name=Name java.envprops.value=Wert sess.access=Letzter Zugriff @@ -104,8 +104,8 @@ reject.dmz.requests.sure=Sind Sie sicher, dass Sie alle Requests auf DMZ auf and reject.dmz.requests.done=Alle Requests auf DMZ werden ab jetzt auf andere Nodes umgeleitet allow.dmz.requests.done=Alle Requests auf DMZ werden ab jetzt wieder zugelassen session.admin.invalidate.all.link=Alle Sessions invalidieren -session.timeout.label=Session timeout in sec -session.timeout.auth.label=Authenticated session timeout in sec +session.timeout.label=DMZ Session Timeout in Sekunden +session.timeout.auth.label=Authentifiziert Session Timeout in Sekunden sessionadministration.title=Session Administration sessions=Sessions snoop=Snoop @@ -116,41 +116,41 @@ sysinfo.version=Version sysinfo.version.hg=Mercurial Version sysinfo.version.date=Build Datum sysinfo.cluster=Cluster -sysinfo.basedir=Root Ordner +sysinfo.basedir=Wurzelordner sysinfo.node=Node -runtime=Runtime infos -runtime.startup=Startup -runtime.users.lastmonth=Active users within last month -runtime.users.last6months=Active users within last six months -runtime.users.lastday=Active users within last day -runtime.users.lastweek=Active users within last week -runtime.controllercount=Controllers (active and not disposed) -runtime.dispatchingthreads=Concurrent Dispatching Threads -runtime.memory=Memory -runtime.memory.permGen=Memory (Perm. gen.) -runtime.memory.tooltip={0} MB von {1} MB available +runtime=Runtime Informationen +runtime.startup=System Start +runtime.users.lastmonth=Aktive Benutzer innerhalb des letzten Monates +runtime.users.last6months=Aktive Benutzer innerhalb des letzten halben Jahres +runtime.users.lastday=Aktive Benutzer innerhalb der letzten 24 Stunden +runtime.users.lastweek=Aktive Benutzer innerhalb innerhalb der letzten 7 Tage +runtime.controllercount=Controllers (Aktiv und nicht aufgeräumt) +runtime.dispatchingthreads=Gleichzeitige arbeitende Threads +runtime.memory=Speicher +runtime.memory.permGen=Speicher (Permanent Generation) +runtime.memory.tooltip={0} MB von {1} MB verfügbar title.hibernate.statistics=Hibernate Datenbank Zugriff Statistik usersession.title=Information \u00FCber Benutzer-Sessions -filesystemtest=File System Test (Verteilte File Tests mit write/read für clustering). Wichtig nicht auf produktiven Systemen starten, kann zu Performance Problemen führen! +filesystemtest=Dateisystem Test (Verteilte File Tests mit write/read für clustering). Wichtig nicht auf produktiven Systemen starten, kann zu Performance Problemen führen! filesystemtest.start=Start Test -filesystemtest.cleanup.testdir=Test Dir löschen +filesystemtest.cleanup.testdir=Test Verzeichnis löschen filesystemtest.loops.label=Anzahl Durchgänge -filesystemtest.maxnbr.dirs.label=Anzahl Test Directories -filesystemtest.maxnbr.files.label=Anzahl Test Files pro Directory -filesystemtest.nbrCharInFile.label=Anzahl Zeichen im File, aufgerundet auf ein Vielfaches von 15 [0=leere Files] +filesystemtest.maxnbr.dirs.label=Anzahl Testverzeichnisse +filesystemtest.maxnbr.files.label=Anzahl Testdateien pro Verzeichnis +filesystemtest.nbrCharInFile.label=Anzahl Zeichen in Datei, aufgerundet auf ein Vielfaches von 15 [0=leere Dateien] filesystemtest.call.fs.sync.label=Aufruf von 'File-Descriptor.sync( )' nach File.close( ) -filesystemtest.check.with.retries.label=Mehrere Versuche beim File-Check erlaubt (Warten bis File vorhanden, max ...) -filesystemtest.intro=WICHTIG: Der File-System Test darf nur für System-Tests aktiviert werden! -filesystemtest.on=File-System Test aktivieren -filesystemtest.reload=Reload -lock.key=Lock -lock.owner=Lock Benutzer -lock.aquiretime=Lock Zeit +filesystemtest.check.with.retries.label=Mehrere Versuche beim Datei-Check erlaubt (Warten bis Datei vorhanden, max ...) +filesystemtest.intro=WICHTIG: Der Dateisystem Test darf nur für System-Tests aktiviert werden! +filesystemtest.on=Dateisystem Test aktivieren +filesystemtest.reload=Ausführen +lock.key=Sperrung +lock.owner=Benutzersperrung +lock.aquiretime=Zeitsperrung lock.release=freigeben -lock.release.sure=Sind Sie sicher, dass Sie den Lock freigeben m\u00F6chten? -requestloglevel.title=Log level per request +lock.release.sure=Sind Sie sicher, dass Sie die Sperrung freigeben m\u00F6chten? +requestloglevel.title=Log Level pro Anfrage requestloglevel.format.label=Format requestloglevel.format.text=127.0.0.1=DEBUG<br>192.168.0.1=DEBUG,DebugLog (DebugLog = log4j Appender)<br>administrator=INFO requestloglevel.ips=IP-Adressen -requestloglevel.usernames=Usernamen -requestloglevel.disabled=Dieses Feature ist auf diesem Node nicht konfiguriert. \ No newline at end of file +requestloglevel.usernames=Benutzernamen +requestloglevel.disabled=Diese Funktion ist auf diesem Node nicht konfiguriert. \ No newline at end of file diff --git a/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_en.properties index b698b77486a82f1c1411c35107b8f5428f668e4d..758133ea2fc4aef17fbd53fadd7729cc8bef3fe1 100644 --- a/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/sysinfo/_i18n/LocalStrings_en.properties @@ -1,10 +1,17 @@ -#Fri Feb 24 12:02:45 CET 2012 +#Tue Dec 18 22:45:27 CET 2012 allow.dmz.requests.done=All requests on DMZ will be allowed again from now on allow.login.done=Blocking of login cancelled. block.login.done=New logins blocked from now on. +block.login.info=You can persist the setting "$\:block.login.title" so that it it remains active even after a system restart until you manually remove the setting. +block.login.options=Persist block.login.sure=Do you really want to block the login for all new users? +block.login.title=Block logins buildinfo=Build information clear.hibernate.statistics=Delete hibernate statistics +core.functions=Function overview +core.jsMath=JS Math +core.restapi=REST API +core.webdav=WebDAV disable.hibernate.statistics=Disable hibernate statistics enable.hibernate.statistics=Enable hibernate statistics error.date=Date @@ -36,6 +43,19 @@ infomsgEdit=Edit message infomsgEditCluster=Edit information invalidate.all.sure=Do you really want to invalidate all user sessions? invalidate.session.done=All sessions invalidated. +java.envProps=Environment properties +java.envProps.title=Java Environment properties +java.envprops.name=Name +java.envprops.value=Value +java.memory=Memory +java.thread.alive=Alive +java.thread.cpu.percent=CPU % +java.thread.cpu.time=CPU time +java.thread.group=Group +java.thread.interrupted=Interrupted +java.thread.name=Name +java.threads=Threads +java.threads.title=Current threads lock.aquiretime=Lock time lock.key=Lock lock.owner=Lock user @@ -55,15 +75,28 @@ max.sessions.label=Maximum number of sessions multiuser.title=Information on multi-user events nbr.session.label=Number of sessions to be invalidated (ordered by last access) oldest.session.button=Invalidate sessions +persist.block.login=on reject.dmz.requests.done=All requests on DMZ will be redirected to other nodes from now on reject.dmz.requests.sure=Are you sure you want to redirect all requests on DMZ to other nodes?<br/><br/><b>Important\:</b> this node has to be <b>disabled</b>in mod_jk\! requestloglevel.disabled=This feature is not configured on this node. requestloglevel.format.label=Format requestloglevel.format.text=127.0.0.1\=DEBUG<br>192.168.0.1\=DEBUG,DebugLog (DebugLog \= log4j Appender)<br>administrator\=INFO requestloglevel.ips=IP addresses +requestloglevel.title=Log level per request requestloglevel.usernames=User names resetloglevels=Reset all log levels to INFO run.gc=Run garbage collection +runtime=Runtime infos +runtime.controllercount=Controllers (active and not disposed) +runtime.dispatchingthreads=Concurrent dispatching threads +runtime.memory=Memory +runtime.memory.permGen=Memory (Permanent Generation) +runtime.memory.tooltip={0} MB of {1} MB available +runtime.startup=Startup +runtime.users.last6months=Active users within last six month +runtime.users.lastday=Active users within last 24 hours +runtime.users.lastmonth=Active users within last month +runtime.users.lastweek=Active users within last 7 days sess.access=Last access sess.active=Number of users which have clicked within the last {0} minutes sess.attributes.title=Attributes @@ -100,12 +133,21 @@ session.admin.block.login.link=Block new logins session.admin.invalidate.all.link=Invalidate all sessions session.admin.reject.dmz.requests.intro=Redirect all requests on DMZ to other nodes available in mod_jk. Exception\: admin user via cluster tab 'Switch to node' session.admin.reject.dmz.requests.link=Lock all requests on DMZ to redirect new logins to other nodes -session.timeout.label=Session timeout in sec +session.configuration=Configuration +session.list=User sessions +session.timeout.auth.label=Authenticated session timeout in seconds +session.timeout.label=DMZ session timeout in seconds sessionadministration.title=Session administration sessions=Sessions snoop=Snoop sysinfo=System information +sysinfo.basedir=Root folder +sysinfo.cluster=Cluster sysinfo.memory=Memory information +sysinfo.node=Node sysinfo.startuptime=Server startup time +sysinfo.version=Version +sysinfo.version.date=Build date +sysinfo.version.hg=Mercurial version title.hibernate.statistics=Hibernate database access statistics usersession.title=Information on user sessions diff --git a/src/main/java/org/olat/admin/user/SystemRolesAndRightsController.java b/src/main/java/org/olat/admin/user/SystemRolesAndRightsController.java index 0335af9bf6443a170a23ca6d1ab34a38f5a5b404..85c05bd0453b3d3ce8f3f7ac74e4e7584a98a1c8 100644 --- a/src/main/java/org/olat/admin/user/SystemRolesAndRightsController.java +++ b/src/main/java/org/olat/admin/user/SystemRolesAndRightsController.java @@ -179,8 +179,7 @@ public class SystemRolesAndRightsController extends BasicController { updateSecurityGroup(myIdentity, secMgr, adminGroup, hasBeenAdmin, isAdmin); } if (iAmOlatAdmin && !myIdentity.getStatus().equals(form.getStatus()) ) { - secMgr.saveIdentityStatus(myIdentity, form.getStatus()); - identity.setStatus(form.getStatus()); + identity = secMgr.saveIdentityStatus(myIdentity, form.getStatus()); } } diff --git a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java index d375d3831d9cbb90ba54e9cc22ec34675e11fa4c..327ca480f81038dedf26a8feee64ac5f3dab075f 100644 --- a/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java +++ b/src/main/java/org/olat/admin/user/bulkChange/UserBulkChangeManager.java @@ -191,8 +191,7 @@ public class UserBulkChangeManager extends BasicManager { // set status if (roleChangeMap.containsKey("Status")) { Integer status = Integer.parseInt(roleChangeMap.get("Status")); - secMgr.saveIdentityStatus(identity, status); - identity = (Identity) db.loadObject(identity); + identity = secMgr.saveIdentityStatus(identity, status); } // persist changes: @@ -232,25 +231,8 @@ public class UserBulkChangeManager extends BasicManager { BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); MailPackage mailing = new MailPackage(); - bgs.updateMemberships(addingIdentity, changes, mailing);//TODO memail + bgs.updateMemberships(addingIdentity, changes, mailing); DBFactory.getInstance().commit(); - - //TODO memail not needed anymore - /*if(mailGroups != null && !mailGroups.isEmpty()) { - List<BusinessGroup> notifGroups = bgs.loadBusinessGroups(mailGroups); - for (BusinessGroup group : notifGroups) { - for(Identity selIdentity:selIdentities) { - - MailTemplate mailTemplate = BGMailHelper.createAddParticipantMailTemplate(group, addingIdentity); - MailerWithTemplate mailer = MailerWithTemplate.getInstance(); - MailerResult mailerResult = mailer.sendMailAsSeparateMails(null, Collections.singletonList(selIdentity), null, mailTemplate, null); - if (mailerResult.getReturnCode() != MailerResult.OK && isLogDebugEnabled()) { - logDebug("Problems sending Group invitation mail for identity: " + selIdentity.getName() + " and group: " - + group.getName() + " key: " + group.getKey() + " mailerresult: " + mailerResult.getReturnCode(), null); - } - } - } - }*/ } } diff --git a/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java b/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java index cf16fb278c4ea60cccdae5574ac1aa6cf054eb95..1dba1513ceddad19f1e5f969e2675fa08e2e7a6a 100644 --- a/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java +++ b/src/main/java/org/olat/admin/user/delete/service/UserDeletionManager.java @@ -70,6 +70,7 @@ import org.olat.repository.delete.service.DeletionModule; import org.olat.user.UserDataDeletable; import org.olat.user.UserManager; import org.olat.user.propertyhandlers.UserPropertyHandler; +import org.springframework.beans.factory.annotation.Autowired; /** @@ -101,6 +102,9 @@ public class UserDeletionManager extends BasicManager { private boolean managersInitialized = false; private DeletionModule deletionModule; private CoordinatorManager coordinatorManager; + + @Autowired + private BaseSecurity securityManager; /** * [used by spring] @@ -166,9 +170,7 @@ public class UserDeletionManager extends BasicManager { } private void markSendEmailEvent(Identity identity) { - identity = (Identity)DBFactory.getInstance().loadObject(identity); LifeCycleManager.createInstanceFor(identity).markTimestampFor(SEND_DELETE_EMAIL_ACTION); - DBFactory.getInstance().updateObject(identity); } /** @@ -297,7 +299,7 @@ public class UserDeletionManager extends BasicManager { logInfo("deleteUserProperties user=" + identity.getUser()); UserManager.getInstance().deleteUserProperties(identity.getUser()); // Delete all authentications for certain identity - List<Authentication> authentications = BaseSecurityManager.getInstance().getAuthentications(identity); + List<Authentication> authentications = securityManager.getAuthentications(identity); for (Iterator<Authentication> iter = authentications.iterator(); iter.hasNext();) { Authentication auth = iter.next(); logInfo("deleteAuthentication auth=" + auth); @@ -306,10 +308,9 @@ public class UserDeletionManager extends BasicManager { } //remove identity from its security groups - BaseSecurity secMgr = BaseSecurityManager.getInstance(); - List<SecurityGroup> securityGroups = BaseSecurityManager.getInstance().getSecurityGroupsForIdentity(identity); + List<SecurityGroup> securityGroups = securityManager.getSecurityGroupsForIdentity(identity); for (SecurityGroup secGroup : securityGroups) { - secMgr.removeIdentityFromSecurityGroup(identity, secGroup); + securityManager.removeIdentityFromSecurityGroup(identity, secGroup); logInfo("Removing user=" + identity + " from security group=" + secGroup.toString()); } @@ -321,47 +322,39 @@ public class UserDeletionManager extends BasicManager { rm.deleteTemporaryKey(tempKey); } - // can be used, if there is once the possibility to delete identities without db-constraints... - //if neither email nor login should be kept, REALLY DELETE Identity - /*if (!keepUserEmailAfterDeletion & !keepUserLoginAfterDeletion){ - identity = (Identity)DBFactory.getInstance().loadObject(identity); - DBFactory.getInstance().deleteObject(identity.getUser()); - DBFactory.getInstance().deleteObject(identity); - } - else { */ - identity = (Identity)DBFactory.getInstance().loadObject(identity); - //keep login-name only -> change email - if (!keepUserEmailAfterDeletion){ - List<UserPropertyHandler> userPropertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor("org.olat.admin.user.UsermanagerUserSearchForm", true); - User persistedUser = identity.getUser(); - String actualProperty; - for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) { - actualProperty = userPropertyHandler.getName(); - if (actualProperty.equals(UserConstants.EMAIL)){ - String oldEmail = userPropertyHandler.getUserProperty(persistedUser, null); - String newEmail = ""; - if (StringHelper.containsNonWhitespace(oldEmail)){ - newEmail = getBackupStringWithDate(oldEmail); - } - logInfo("Update user-property user=" + persistedUser); - userPropertyHandler.setUserProperty(persistedUser, newEmail); + + identity = securityManager.loadIdentityByKey(identity.getKey()); + //keep login-name only -> change email + if (!keepUserEmailAfterDeletion){ + List<UserPropertyHandler> userPropertyHandlers = UserManager.getInstance().getUserPropertyHandlersFor("org.olat.admin.user.UsermanagerUserSearchForm", true); + User persistedUser = identity.getUser(); + String actualProperty; + for (UserPropertyHandler userPropertyHandler : userPropertyHandlers) { + actualProperty = userPropertyHandler.getName(); + if (actualProperty.equals(UserConstants.EMAIL)){ + String oldEmail = userPropertyHandler.getUserProperty(persistedUser, null); + String newEmail = ""; + if (StringHelper.containsNonWhitespace(oldEmail)){ + newEmail = getBackupStringWithDate(oldEmail); } + logInfo("Update user-property user=" + persistedUser); + userPropertyHandler.setUserProperty(persistedUser, newEmail); } } - - //keep email only -> change login-name - if (!keepUserLoginAfterDeletion){ - identity.setName(newName); - } - - //keep everything, change identity.status to deleted - logInfo("Change stater identity=" + identity); - identity.setStatus(Identity.STATUS_DELETED); - DBFactory.getInstance().updateObject(identity); - LifeCycleManager.createInstanceFor(identity).deleteTimestampFor(SEND_DELETE_EMAIL_ACTION); - LifeCycleManager.createInstanceFor(identity).markTimestampFor(USER_DELETED_ACTION, createLifeCycleLogDataFor(identity)); - // } + } + //keep email only -> change login-name + if (!keepUserLoginAfterDeletion){ + identity.setName(newName); + } + + //keep everything, change identity.status to deleted + logInfo("Change stater identity=" + identity); + identity = securityManager.saveIdentityStatus(identity, Identity.STATUS_DELETED); + + LifeCycleManager.createInstanceFor(identity).deleteTimestampFor(SEND_DELETE_EMAIL_ACTION); + LifeCycleManager.createInstanceFor(identity).markTimestampFor(USER_DELETED_ACTION, createLifeCycleLogDataFor(identity)); + // TODO: chg: ev. logAudit at another place logAudit("User-Deletion: Delete all userdata for identity=" + identity); } @@ -387,24 +380,22 @@ public class UserDeletionManager extends BasicManager { * Re-activate an identity, lastLogin = now, reset deleteemaildate = null. * @param identity */ - public void setIdentityAsActiv(final Identity anIdentity) { + public Identity setIdentityAsActiv(final Identity anIdentity) { + final Identity reloadedIdentity = securityManager.setIdentityLastLogin(anIdentity); + coordinatorManager.getCoordinator().getSyncer().doInSync(OresHelper.createOLATResourceableInstance(anIdentity.getClass(), anIdentity.getKey()) , new SyncerExecutor(){ public void execute() { //o_clusterOK by:fj : must be fast - Identity identity = (Identity)DBFactory.getInstance().loadObject(anIdentity, true); - if (isLogDebugEnabled()) logDebug("setIdentityAsActiv beginSingleTransaction identity=" + identity); - identity.setLastLogin(new Date()); - LifeCycleManager lifeCycleManagerForIdenitiy = LifeCycleManager.createInstanceFor(identity); + LifeCycleManager lifeCycleManagerForIdenitiy = LifeCycleManager.createInstanceFor(reloadedIdentity); if (lifeCycleManagerForIdenitiy.lookupLifeCycleEntry(SEND_DELETE_EMAIL_ACTION) != null) { - logAudit("User-Deletion: Remove from delete-list identity=" + identity); + logAudit("User-Deletion: Remove from delete-list identity=" + reloadedIdentity); lifeCycleManagerForIdenitiy.deleteTimestampFor(SEND_DELETE_EMAIL_ACTION); } - if (isLogDebugEnabled()) logDebug("setIdentityAsActiv updateObject identity=" + identity); - DBFactory.getInstance().updateObject(identity); - if (isLogDebugEnabled()) logDebug("setIdentityAsActiv committed identity=" + identity); } }); + + return reloadedIdentity; } /** diff --git a/src/main/java/org/olat/admin/user/delete/service/UserFileDeletionManager.java b/src/main/java/org/olat/admin/user/delete/service/UserFileDeletionManager.java index 3169ac956fc33c33212d2d9d5e9eff2bbecca761..3b958c7ae28e672216530f0fd1c3ab7637fc996c 100644 --- a/src/main/java/org/olat/admin/user/delete/service/UserFileDeletionManager.java +++ b/src/main/java/org/olat/admin/user/delete/service/UserFileDeletionManager.java @@ -114,7 +114,7 @@ public class UserFileDeletionManager extends BasicManager implements UserDataDel private void deleteAllTempQtiEditorFilesOf(Identity identity) { // Temp QTI-editor File path e.g. /usr/local/olatfs/olat/olatdata/tmp/qtieditor/schuessler - File userTempQtiEditorDir = new File(QTIEditorPackage.getTmpBaseDir(),identity.getName()); + File userTempQtiEditorDir = new File(QTIEditorPackage.getQTIEditorBaseDir(),identity.getName()); if (userTempQtiEditorDir.exists()) { FileUtils.deleteDirsAndFiles(userTempQtiEditorDir, true, true); logAudit("User-Deletion: identity=" + identity.getName() +" : QTI editor temp files deleted under dir=" + userTempQtiEditorDir.getAbsolutePath()); diff --git a/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java b/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java index 0837b6c77bef2e3ed5623294295442690074f010..cbef349ce723c6bd14c9921dab918aadc7e28e6a 100644 --- a/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java +++ b/src/main/java/org/olat/admin/user/groups/GroupOverviewController.java @@ -267,22 +267,9 @@ public class GroupOverviewController extends BasicController { } } - MailPackage mailing = new MailPackage();//TODO memail + MailPackage mailing = new MailPackage(); businessGroupService.updateMemberships(getIdentity(), changes, mailing); DBFactory.getInstance().commit(); - - /*if(e.getMailForGroupsList() != null && !e.getMailForGroupsList().isEmpty()) { - List<BusinessGroup> notifGroups = businessGroupService.loadBusinessGroups(e.getMailForGroupsList()); - for (BusinessGroup group : notifGroups) { - MailTemplate mailTemplate = BGMailHelper.createAddParticipantMailTemplate(group, getIdentity()); - MailerWithTemplate mailer = MailerWithTemplate.getInstance(); - MailerResult mailerResult = mailer.sendMailAsSeparateMails(null, Collections.singletonList(identity), null, mailTemplate, null); - if (mailerResult.getReturnCode() != MailerResult.OK && isLogDebugEnabled()) { - logDebug("Problems sending Group invitation mail for identity: " + identity.getName() + " and group: " - + group.getName() + " key: " + group.getKey() + " mailerresult: " + mailerResult.getReturnCode(), null); - } - } - }*/ } private void doLeave(UserRequest ureq, List<BusinessGroup> groupsToLeave) { diff --git a/src/main/java/org/olat/admin/user/imp/UserImportController.java b/src/main/java/org/olat/admin/user/imp/UserImportController.java index c7922d4fc28102ca2969011c2b48590120e0d71b..ff1b71eb56db4949e7512f3ba292d3e35da8d211 100644 --- a/src/main/java/org/olat/admin/user/imp/UserImportController.java +++ b/src/main/java/org/olat/admin/user/imp/UserImportController.java @@ -249,7 +249,7 @@ public class UserImportController extends BasicController { } } } - businessGroupService.updateMemberships(getIdentity(), changes, null);//TODO memail + businessGroupService.updateMemberships(getIdentity(), changes, null); DBFactory.getInstance().commit(); if(mailGroups != null && !mailGroups.isEmpty()) { diff --git a/src/main/java/org/olat/admin/version/OrphanVersionsController.java b/src/main/java/org/olat/admin/version/OrphanVersionsController.java index 3ef52c95d40e641e67ff24cdbeef0d92939a237c..8f13097dc251c11aa63b693182c794df3d0a6edf 100644 --- a/src/main/java/org/olat/admin/version/OrphanVersionsController.java +++ b/src/main/java/org/olat/admin/version/OrphanVersionsController.java @@ -135,7 +135,7 @@ public class OrphanVersionsController extends BasicController { } } - private class OrphanTableModel implements TableDataModel { + private class OrphanTableModel implements TableDataModel<OrphanVersion> { private List<OrphanVersion> orphanList; @@ -186,7 +186,7 @@ public class OrphanVersionsController extends BasicController { } @Override - public void setObjects(List objects) { + public void setObjects(List<OrphanVersion> objects) { orphanList = objects; } diff --git a/src/main/java/org/olat/admin/version/VersionMaintenanceForm.java b/src/main/java/org/olat/admin/version/VersionMaintenanceForm.java index b8fad2314bc727aada7a598f1415473a8357f2de..030443a16f3ab01cf1e8e3ac3b45393eb2c99614 100644 --- a/src/main/java/org/olat/admin/version/VersionMaintenanceForm.java +++ b/src/main/java/org/olat/admin/version/VersionMaintenanceForm.java @@ -25,6 +25,7 @@ import java.util.List; import java.util.Locale; import org.olat.admin.SystemAdminMainController; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.taskExecutor.TaskExecutorManager; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; @@ -35,11 +36,17 @@ import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormEvent; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.progressbar.ProgressController; import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +import org.olat.core.gui.control.generic.modal.DialogBoxController; +import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.util.Util; +import org.olat.core.util.async.ProgressDelegate; import org.olat.core.util.vfs.version.OrphanVersion; +import org.olat.core.util.vfs.version.SimpleVersionConfig; import org.olat.core.util.vfs.version.VFSRevision; import org.olat.core.util.vfs.version.VersionsManager; @@ -55,18 +62,24 @@ import org.olat.core.util.vfs.version.VersionsManager; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ //fxdiff FXOLAT-127: file versions maintenance tool -public class VersionMaintenanceForm extends FormBasicController { +public class VersionMaintenanceForm extends FormBasicController implements ProgressDelegate { - private FormLink cleanUp, orphanSize; + private FormLink cleanUpLink, pruneLink, showOrphanLink, orphanSize; private StaticTextElement orphanSizeEl; private CloseableModalController cmc; private OrphanVersionsController orphansController; + private DialogBoxController confirmPrunehistoryBox; + private DialogBoxController confirmDeleteOrphansBox; + private ProgressController progressCtrl; + + private final VersionsManager versionsManager; public VersionMaintenanceForm(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); // use combined translator from system admin main setTranslator(Util.createPackageTranslator(SystemAdminMainController.class, ureq.getLocale(), getTranslator())); - + versionsManager = CoreSpringFactory.getImpl(VersionsManager.class); + initForm(ureq); } @@ -79,11 +92,17 @@ public class VersionMaintenanceForm extends FormBasicController { orphanSizeEl = uifactory.addStaticTextElement("version.orphan.size", "version.orphan.size", "???", formLayout); - FormLayoutContainer buttonsLayout = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + FormLayoutContainer buttonsLayout = FormLayoutContainer.createHorizontalFormLayout("buttons", getTranslator()); formLayout.add(buttonsLayout); orphanSize = uifactory.addFormLink("version.orphan.size.calc", buttonsLayout, Link.BUTTON); - cleanUp = uifactory.addFormLink("version.clean.up", buttonsLayout, Link.BUTTON); + showOrphanLink = uifactory.addFormLink("version.show.orphans", buttonsLayout, Link.BUTTON); + cleanUpLink = uifactory.addFormLink("version.clean.up", buttonsLayout, Link.BUTTON); + + FormLayoutContainer buttons2Layout = FormLayoutContainer.createHorizontalFormLayout("buttons2", getTranslator()); + formLayout.add(buttons2Layout); + + pruneLink = uifactory.addFormLink("version.prune.history", buttons2Layout, Link.BUTTON); } @Override @@ -91,6 +110,32 @@ public class VersionMaintenanceForm extends FormBasicController { // } + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if(source == orphansController) { + cmc.deactivate(); + cleanup(); + } else if(source == confirmDeleteOrphansBox) { + if (DialogBoxUIFactory.isYesEvent(event)) { + doDeleteOrphans(ureq); + } + } else if(source == confirmPrunehistoryBox) { + if (DialogBoxUIFactory.isYesEvent(event)) { + doPruneHistory(ureq); + } + } else if(source == cmc) { + cleanup(); + } + super.event(ureq, source, event); + } + + private void cleanup() { + removeAsListenerAndDispose(orphansController); + removeAsListenerAndDispose(cmc); + orphansController = null; + cmc = null; + } + @Override protected void formOK(UserRequest ureq) { // @@ -98,13 +143,19 @@ public class VersionMaintenanceForm extends FormBasicController { @Override protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { - if(source == cleanUp) { - List<OrphanVersion> orphans = VersionsManager.getInstance().orphans(); + if(source == showOrphanLink) { + List<OrphanVersion> orphans = versionsManager.orphans(); orphansController = new OrphanVersionsController(ureq, getWindowControl(), orphans); listenTo(orphansController); cmc = new CloseableModalController(getWindowControl(), "close", orphansController.getInitialComponent()); cmc.insertHeaderCss(); cmc.activate(); + } else if(source == cleanUpLink) { + String text = translate("confirm.delete.orphans"); + confirmDeleteOrphansBox = activateYesNoDialog(ureq, null, text, confirmDeleteOrphansBox); + } else if(source == pruneLink) { + String text = translate("confirm.prune.history"); + confirmPrunehistoryBox = activateYesNoDialog(ureq, null, text, confirmPrunehistoryBox); } else if (source == orphanSize) { orphanSizeEl.setValue(translate("version.orphan.size.calculating")); TaskExecutorManager.getInstance().runTask(new Runnable() { @@ -116,9 +167,72 @@ public class VersionMaintenanceForm extends FormBasicController { super.formInnerEvent(ureq, source, event); } + private void doDeleteOrphans(UserRequest ureq) { + progressCtrl = new ProgressController(ureq, getWindowControl()); + progressCtrl.setMessage(translate("version.clean.up")); + progressCtrl.setPercentagesEnabled(false); + progressCtrl.setUnitLabel(""); + progressCtrl.setActual(0.0f); + progressCtrl.setMax(100.0f); + listenTo(progressCtrl); + + TaskExecutorManager.getInstance().runTask(new Runnable() { + public void run() { + waitASecond(); + versionsManager.deleteOrphans(VersionMaintenanceForm.this); + } + }); + + synchronized(this) { + if(progressCtrl != null) { + cmc = new CloseableModalController(getWindowControl(), null, progressCtrl.getInitialComponent(), true, null, false); + cmc.activate(); + listenTo(cmc); + } + } + } + + private void doPruneHistory(UserRequest ureq) { + progressCtrl = new ProgressController(ureq, getWindowControl()); + progressCtrl.setMessage(translate("version.prune.history")); + progressCtrl.setPercentagesEnabled(false); + progressCtrl.setUnitLabel(""); + progressCtrl.setMax(versionsManager.countDirectories()); + listenTo(progressCtrl); + + TaskExecutorManager.getInstance().runTask(new Runnable() { + public void run() { + waitASecond(); + Long numOfVersions = getNumOfVersions(); + versionsManager.pruneHistory(numOfVersions.longValue(), VersionMaintenanceForm.this); + } + }); + + synchronized(this) { + if(progressCtrl != null) { + cmc = new CloseableModalController(getWindowControl(), null, progressCtrl.getInitialComponent(), true, null, false); + cmc.activate(); + listenTo(cmc); + } + } + } + + private final void waitASecond() { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + logError("Can't wait", e); + } + } + + public Long getNumOfVersions() { + SimpleVersionConfig config = (SimpleVersionConfig) CoreSpringFactory.getBean(SimpleVersionConfig.class); + return config.getMaxNumberOfVersionsProperty(); + } + public final void calculateOrphanSize() { long size = 0l; - List<OrphanVersion> orphans = VersionsManager.getInstance().orphans(); + List<OrphanVersion> orphans = versionsManager.orphans(); for(OrphanVersion orphan:orphans) { List<VFSRevision> revisions = orphan.getVersions().getRevisions(); if(revisions != null) { @@ -141,4 +255,33 @@ public class VersionMaintenanceForm extends FormBasicController { orphanSizeEl.setValue(readableSize); } } + + @Override + public void setMax(float max) { + if(progressCtrl != null && !progressCtrl.isDisposed()) { + progressCtrl.setMax(max); + } + } + + @Override + public void setActual(float value) { + if(progressCtrl != null && !progressCtrl.isDisposed()) { + progressCtrl.setActual(value); + } + } + + @Override + public void setInfo(String message) { + if(progressCtrl != null && !progressCtrl.isDisposed()) { + progressCtrl.setInfo(message); + } + } + + @Override + public synchronized void finished() { + if(cmc != null && !cmc.isDisposed()) { + cmc.deactivate(); + } + cleanup(); + } } diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_de.properties index 8cd177d3ea9bbd5cb7a88c1b5105295ff90b770c..fc679e2c5ee128c035c6bafa9a0987efee8f2c83 100644 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_de.properties @@ -10,6 +10,8 @@ version.clean.up=Orphan Versionen l version.orphan.size=Orphan Versionen Grösse version.orphan.size.calc=Grösse rechnen version.orphan.size.calculating=Grösse am rechnen... +version.show.orphans=Orphan Versionen auflisten +version.prune.history=Versionen aufräumen version.maintenance.title=Verwaltung version.maintenance.intro=Verwaltung von Versionen table.header.file=Datei @@ -23,4 +25,6 @@ chelp.version.scope=Die Versionierung ist in allen Ordnern des Systems vorhanden chelp.version.enable=Um die Versionierung auf diesem System global einzuschalten, wählen Sie aus der Liste die Anzahl der jeweils erlaubten Versionen pro Datei aus oder wählen Sie unlimitiert, um beliebig viele Versionen eines Dokuments zuzulassen. Eine Beschränkung kann sinnvoll sein, um den benötigten Speicherplatz zu limitieren. chelp.version.disable=Um die Versionierung auf diesem System global auszuschalten wählen Sie den entsprechenden Eintrag in der Liste. chelp.version.maintenance=Versionen von gelöschten Dateien werden aus WebDAV Kompatibilitätsgründen nicht automatisch gelöscht. Sie können diese manuell löschen. -chelp.maintenance.title=Dateiversionierung: Verwaltung \ No newline at end of file +chelp.maintenance.title=Dateiversionierung: Verwaltung +confirm.delete.orphans=Wollen Sie wirklich alle Orphan Versionen löschen? +confirm.prune.history=Wollen Sie wirklich die überflüssige Versionen löschen? \ No newline at end of file diff --git a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_en.properties index be83a12011de90e2536f21fa9598e7ed4b94eb6b..c447071c9dfeffb0097b31d7eb3b15e755af14c4 100644 --- a/src/main/java/org/olat/admin/version/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/version/_i18n/LocalStrings_en.properties @@ -1,26 +1,30 @@ -#Thu May 26 10:39:08 CEST 2011 +#Tue Dec 18 22:46:41 CET 2012 +chelp.maintenance.title=Maintenance of file versioning chelp.version.disable=In order to deactivate versioning on this system globally please select the corresponding entry from the list. chelp.version.enable=In order to activate versioning on this system globally please select from the list the number of allowed versions per file or choose the option "Unlimited" to allow any number of versions for one document. Some restricting might be reasonable to limit the necessary storage space. chelp.version.intro=In this form you can activate or deactivate file versioning of the folder module. If versioning is active files will not be overwritten but saved as a new version (commonly known as revision). Older versions of a document can be downloaded or restored if necessary. Deleted files will appear in a corresponding list and can be restored as well. If the versioning feature is activated files can also be locked, e.g. in case someone editing a document wants to prevent others from creating a new version in the meantime. chelp.version.maintenance=Versions of deleted files will not automatically deleted because of compatibility issues with WebDAV. You can delete them manually. chelp.version.scope=Versioning is available in all system folders\: personal folders, group folders, course folders, resource folders, as well as in the course elements 'Folder'. chelp.version.title=Configure file versioning -chelp.maintenance.title=Maintenance of file versioning +confirm.delete.orphans=Do you really want to delete all orphan versions? +confirm.prune.history=Do you really want to delete all versions that exceed the configured version limit? form.version=Versioning help.hover.version=Help regarding the configuration of file versioning table.empty=No orphan version left table.header.file=File -table.header.versions=Number of versions table.header.size=Size +table.header.versions=Number of versions version.clean.up=Delete orphan version -version.orphan.size=Orphan versions size -version.orphan.size.calc=Calculate size -version.orphan.size.calculating=Calculating... version.intro=Please set the maximum number of versions for a folder component file (group folder, course folder, etc.). version.maintenance.intro=File versions management version.maintenance.title=Management version.notANumber=No number selected version.numOfVersions=Number of versions version.off=Versioning deactivated +version.orphan.size=Orphan versions size +version.orphan.size.calc=Calculate size +version.orphan.size.calculating=Calculating... +version.prune.history=Cleanup versions +version.show.orphans=List orphan versions version.title=Versioning version.unlimited=Unlimited diff --git a/src/main/java/org/olat/basesecurity/BaseSecurity.java b/src/main/java/org/olat/basesecurity/BaseSecurity.java index b4b2350d812828d331247c9ee8b4a70361528fb0..dbe4ef76df39da9a1bb715bd28a8a5635e4d2ba9 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurity.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurity.java @@ -573,7 +573,14 @@ public interface BaseSecurity { /** Save an identity * @param identity Save this identity */ - public void saveIdentityStatus(Identity identity, Integer status); + public Identity saveIdentityStatus(Identity identity, Integer status); + + /** + * Set the date of the last login + * @param identity + * @return + */ + public Identity setIdentityLastLogin(Identity identity); /** * Check if identity is visible. Deleted or login-denied users are not visible. diff --git a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java index 098ed788f5509b11b460eebf513f5a5fa160ffa1..5c23cae531073f3aa76e14b9106aefe73dfdbcee 100644 --- a/src/main/java/org/olat/basesecurity/BaseSecurityManager.java +++ b/src/main/java/org/olat/basesecurity/BaseSecurityManager.java @@ -36,6 +36,7 @@ import java.util.Locale; import java.util.Map; import java.util.UUID; +import javax.persistence.LockModeType; import javax.persistence.TypedQuery; import org.hibernate.type.StandardBasicTypes; @@ -69,6 +70,7 @@ import org.olat.resource.OLATResourceManager; import org.olat.user.ChangePasswordController; import org.olat.user.PersonalSettingsController; import org.olat.user.UserManager; +import org.springframework.beans.factory.annotation.Autowired; /** * <h3>Description:</h3> @@ -86,6 +88,9 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { private static String GUEST_USERNAME_PREFIX = "guest_"; public static final OLATResourceable IDENTITY_EVENT_CHANNEL = OresHelper.lookupType(Identity.class); + @Autowired + private DB dbInstance; + /** * [used by spring] */ @@ -331,42 +336,6 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { .setParameter("resname", oresName) .getSingleResult(); return count.longValue() > 0; - - - -/* - String queryString; - if (checkTypeRight) { - queryString = - "select count(poi) from" - + " org.olat.basesecurity.SecurityGroupMembershipImpl as sgmsi," - + " org.olat.basesecurity.PolicyImpl as poi," - + " org.olat.resource.OLATResourceImpl as ori" - + " where sgmsi.identity = :identitykey and sgmsi.securityGroup = poi.securityGroup" - + " and poi.permission = :permission and poi.olatResource = ori" - + " and (ori.resId = :resid or ori.resId = 0) and ori.resName = :resname"; - } else { - queryString = - "select count(poi) from" - + " org.olat.basesecurity.SecurityGroupMembershipImpl as sgmsi," - + " org.olat.basesecurity.PolicyImpl as poi," - + " org.olat.resource.OLATResourceImpl as ori" - + " where sgmsi.identity = :identitykey and sgmsi.securityGroup = poi.securityGroup" - + " and poi.permission = :permission and poi.olatResource = ori" - + " and (ori.resId = :resid) and ori.resName = :resname"; - } - - DBQuery query = DBFactory.getInstance().createQuery(queryString); - query.setLong("identitykey", iimpl.getKey()); - query.setString("permission", permission); - query.setLong("resid", oresid); - query.setString("resname", oresName); - query.setCacheable(true); - List res = query.list(); - Long cntL = (Long) res.get(0); - return (cntL.longValue() > 0); // can be > 1 if identity is in more the one group having - // the permission on the olatresourceable - */ } /** @@ -893,7 +862,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { */ public Identity createAndPersistIdentity(String username, User user, String provider, String authusername, String credential) { IdentityImpl iimpl = new IdentityImpl(username, user); - DBFactory.getInstance().saveObject(iimpl); + dbInstance.getCurrentEntityManager().persist(iimpl); if (provider != null) { createAndPersistAuthentication(iimpl, provider, authusername, credential); } @@ -912,9 +881,9 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { * @return Identity */ public Identity createAndPersistIdentityAndUser(String username, User user, String provider, String authusername, String credential) { - DBFactory.getInstance().saveObject(user); + dbInstance.getCurrentEntityManager().persist(user); IdentityImpl iimpl = new IdentityImpl(username, user); - DBFactory.getInstance().saveObject(iimpl); + dbInstance.getCurrentEntityManager().persist(iimpl); if (provider != null) { createAndPersistAuthentication(iimpl, provider, authusername, credential); } @@ -1260,7 +1229,7 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { */ public Authentication createAndPersistAuthentication(Identity ident, String provider, String authUserName, String credential) { AuthenticationImpl authImpl = new AuthenticationImpl(ident, provider, authUserName, credential); - DBFactory.getInstance().saveObject(authImpl); + dbInstance.getCurrentEntityManager().persist(authImpl); return authImpl; } @@ -1737,11 +1706,36 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { /** * @see org.olat.basesecurity.Manager#saveIdentityStatus(org.olat.core.id.Identity) */ - public void saveIdentityStatus(Identity identity, Integer status) { - //FIXME: cg: would be nice if the updated identity is returned. no loading required afterwards. - identity = (Identity)DBFactory.getInstance().loadObject(identity.getClass(), identity.getKey()); - identity.setStatus(status); - DBFactory.getInstance().updateObject(identity); + @Override + public Identity saveIdentityStatus(Identity identity, Integer status) { + Identity reloadedIdentity = loadForUpdate(identity.getKey()); + reloadedIdentity.setStatus(status); + return dbInstance.getCurrentEntityManager().merge(reloadedIdentity); + } + + @Override + public Identity setIdentityLastLogin(Identity identity) { + Identity reloadedIdentity = loadForUpdate(identity.getKey()); + reloadedIdentity.setLastLogin(new Date()); + return dbInstance.getCurrentEntityManager().merge(reloadedIdentity); + } + + private IdentityImpl loadForUpdate(Long identityKey) { + StringBuilder sb = new StringBuilder(); + sb.append("select id from ").append(IdentityImpl.class.getName()).append(" as id") + .append(" inner join fetch id.user user ") + .append(" where id.key=:identityKey"); + + List<IdentityImpl> identity = dbInstance.getCurrentEntityManager() + .createQuery(sb.toString(), IdentityImpl.class) + .setParameter("identityKey", identityKey) + .setLockMode(LockModeType.PESSIMISTIC_WRITE) + .getResultList(); + + if(identity.isEmpty()) { + return null; + } + return identity.get(0); } @Override @@ -1774,15 +1768,12 @@ public class BaseSecurityManager extends BasicManager implements BaseSecurity { guestIdentity = createAndPersistIdentityAndUser(guestUsername, guestUser, null, null, null); SecurityGroup anonymousGroup = findSecurityGroupByName(Constants.GROUP_ANONYMOUS); addIdentityToSecurityGroup(guestIdentity, anonymousGroup); - return guestIdentity; - } else { - // Check if guest name has been updated in the i18n tool - if ( ! guestIdentity.getUser().getProperty(UserConstants.FIRSTNAME, locale).equals(trans.translate("user.guest"))) { - guestIdentity.getUser().setProperty(UserConstants.FIRSTNAME, trans.translate("user.guest")); - DBFactory.getInstance().updateObject(guestIdentity); - } - return guestIdentity; + } else if (!guestIdentity.getUser().getProperty(UserConstants.FIRSTNAME, locale).equals(trans.translate("user.guest"))) { + //Check if guest name has been updated in the i18n tool + guestIdentity.getUser().setProperty(UserConstants.FIRSTNAME, trans.translate("user.guest")); + guestIdentity = dbInstance.getCurrentEntityManager().merge(guestIdentity); } + return guestIdentity; } diff --git a/src/main/java/org/olat/collaboration/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/collaboration/_i18n/LocalStrings_en.properties index 345dfc66d3f24c4f7a0efdc34a9d339505457a8a..2adaa265c3ce1867b5a701741c973c86912abfb0 100644 --- a/src/main/java/org/olat/collaboration/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/collaboration/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Mon May 16 17:33:28 CEST 2011 +#Tue Dec 18 17:59:51 CET 2012 calendar.access=Calendar write permission calendar.access.all=All members calendar.access.owners=Coaches @@ -9,6 +9,7 @@ collabtools.named.hasContactForm=E-mail collabtools.named.hasFolder=Folder collabtools.named.hasForum=Forum collabtools.named.hasNews=Information for members +collabtools.named.hasOpenMeetings=OpenMeetings collabtools.named.hasPortfolio=ePortfolio collabtools.named.hasWiki=Wiki folder=Folder diff --git a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java index d745d776bc6280aafc4312614779069112492216..70c587d289fbd29492475c0387d566d842a6e3ac 100644 --- a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java +++ b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java @@ -707,8 +707,7 @@ public class ICalFileCalendarManager extends BasicManager implements CalendarMan java.util.Calendar recurStartCal = java.util.Calendar.getInstance(); recurStartCal.clear(); - recurStartCal.setTimeInMillis(date.getTime()); - + recurStartCal.setTimeInMillis(date.getTime()-tz.getOffset(date.getTime())); long duration = kEvent.getEnd().getTime() - kEvent.getBegin().getTime(); java.util.Calendar beginCal = java.util.Calendar.getInstance(); diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties index ab1eb09a0c017e7b3163e5881c49e4878e7fc8ec..68300205ca1e219d3e32b29743e3f4c6555065d6 100644 --- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Mon Apr 02 14:41:11 CEST 2012 +#Tue Dec 18 22:46:45 CET 2012 cal.add.event=Add event cal.add.readonly=(Read only) cal.color.choose=Choose color diff --git a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pl.properties index 6788f111a721303a1cf903d59741ce09b72fc321..4d745a428aa6979dca346fddb623c483098ffc78 100644 --- a/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/commons/calendar/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Tue Sep 07 13:31:29 CEST 2010 +#Wed Dec 05 14:41:01 CET 2012 cal.add.event=Dodaj zdarzenie cal.add.readonly=(Tylko do odczytu) cal.color.choose=Wybierz kolor @@ -167,5 +167,12 @@ error.goto.date=Z\u0142y format daty (dd.mm.rrrr) help.hover.cal=Pomoc - Kalendarz tab.event=Szczeg\u00F3\u0142y zdarzenia tab.links=Linki +tab.links.extern=Dokumenty zewn\u0119trzne +tab.links.extern.name=Nazwa +tab.links.extern.new=Nowy dokument zewn\u0119trzny +tab.links.extern.url=URL +tab.links.extern.url.invalid=Ten URL jest niew\u0142a\u015Bciwy +table.add=+ +table.delete=- ul.select=Wybierz plik uncheckall=Usu\u0144 selekcj\u0119 wszystkich element\u00F3w diff --git a/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java b/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java index b01d219de8a8e545b7ac6fee6e8cdd1112600b17..ef5d01ed86a81e6f5aaebaaa003edf7ca842e3c6 100644 --- a/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java +++ b/src/main/java/org/olat/commons/file/filechooser/FileChooseCreateEditController.java @@ -556,7 +556,7 @@ public class FileChooseCreateEditController extends BasicController{ } protected Controller createWysiwygController(UserRequest ureq, WindowControl windowControl, VFSContainer rootContainer, String chosenFile) { - return WysiwygFactory.createWysiwygController(ureq, windowControl, rootContainer, chosenFile, true); + return WysiwygFactory.createWysiwygController(ureq, windowControl, rootContainer, chosenFile, true, true); } /** diff --git a/src/main/java/org/olat/commons/file/filechooser/FileChooserController.java b/src/main/java/org/olat/commons/file/filechooser/FileChooserController.java index 28689fd0a1467f057cdb119397ba5590709f2b8c..e2cb0734ef8ed3130ca433a644688be5d474c361 100644 --- a/src/main/java/org/olat/commons/file/filechooser/FileChooserController.java +++ b/src/main/java/org/olat/commons/file/filechooser/FileChooserController.java @@ -32,7 +32,6 @@ import java.util.List; import org.olat.core.commons.controllers.filechooser.FileChoosenEvent; import org.olat.core.commons.controllers.filechooser.FileChooserUIFactory; import org.olat.core.commons.modules.bc.FileUploadController; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.FolderEvent; import org.olat.core.commons.modules.bc.FolderModule; import org.olat.core.gui.UserRequest; @@ -42,13 +41,13 @@ import org.olat.core.gui.components.link.LinkFactory; import org.olat.core.gui.components.panel.Panel; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.Controller; -import org.olat.core.gui.control.ControllerEventListener; 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.CodeHelper; import org.olat.core.util.FileUtils; import org.olat.core.util.Util; +import org.olat.core.util.WebappHelper; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.Quota; @@ -123,7 +122,7 @@ public class FileChooserController extends BasicController { uploadButton = LinkFactory.createButton("upload", main, this); cancelButton = LinkFactory.createButton("cancel", main, this); // tmp upload container - uploadDir = new File(FolderConfig.getCanonicalTmpDir() + "/" + CodeHelper.getGlobalForeverUniqueID()); + uploadDir = new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID()); uploadContainer = new LocalFolderImpl(uploadDir); folderNames = new ArrayList<String>(3); diff --git a/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java b/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java index a7660589f3c82044fdc78ffa5522e56835eda5c8..b54975c1268b49f42edfb74c62b25a68d61b2150 100644 --- a/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java +++ b/src/main/java/org/olat/commons/info/notification/InfoMessageNotificationHandler.java @@ -105,7 +105,8 @@ public class InfoMessageNotificationHandler extends LogDelegator implements Noti @Override public String createTitleInfo(Subscriber subscriber, Locale locale) { Translator translator = Util.createPackageTranslator(this.getClass(), locale); - return translator.translate("notification.title"); + String displayName = RepositoryManager.getInstance().lookupDisplayNameByOLATResourceableId(subscriber.getPublisher().getResId()); + return translator.translate("notification.title", new String[]{displayName}); } @Override diff --git a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_de.properties index 7a33984a33942c328fb9a96a08a6f239b35707b1..278e4dd705d084f6b3cd46acfda38ef52d191525 100644 --- a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_de.properties @@ -1,2 +1,2 @@ #Mon Mar 02 09:54:04 CET 2009 -notification.title=Mitteilungen \ No newline at end of file +notification.title=Mitteilungen im Kurs "{0}" \ No newline at end of file diff --git a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_en.properties index 7dfb838a098f096970ce42755de5375a14a14751..402bb7c8fa20965b6ea90fca77a2472a70377625 100644 --- a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_en.properties @@ -1,2 +1,2 @@ #Wed Jan 05 12:23:37 CET 2011 -notification.title=Notifications +notification.title=Notifications in course "{0}" diff --git a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_fr.properties index 931ecc30f30701dd903959154628efa37662bac3..af78d6445f8322de78f57868e26202891d6082b6 100644 --- a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_fr.properties @@ -1,2 +1,2 @@ #Sun Jan 16 16:21:29 CET 2011 -notification.title=Communications +notification.title=Communications dans le cours "{0}" diff --git a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_it.properties index 391fc891fb7aae15232781f91e02b83f63835430..8949657f20defe377b7399e93ae3529ec957b039 100644 --- a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_it.properties +++ b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_it.properties @@ -1,2 +1,2 @@ #Sun Jan 09 15:17:42 CET 2011 -notification.title=Comunicazioni +notification.title=Comunicazioni nel corso "{0}" diff --git a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_nl_NL.properties index 2aad98dbdaa0e00cd4e3a19fc20676c189fe9067..873a966b92264c45c390a45a9c431dbe761a25a2 100644 --- a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_nl_NL.properties +++ b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_nl_NL.properties @@ -1,2 +1,2 @@ #Thu Sep 08 16:42:42 CEST 2011 -notification.title=Mededelingen +notification.title=Mededelingen in cursus "{0}" diff --git a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pl.properties index 4463344cd4837b338758e5e44495f3652f062293..f64a29c268344687be7f2669f9d76707222290d9 100644 --- a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pl.properties @@ -1,2 +1,2 @@ #Thu Sep 08 16:42:41 CEST 2011 -notification.title=Powiadomienia +notification.title=Powiadomienia w kursie "{0}" diff --git a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pt_BR.properties index f3bd5c9d2340a367041cc7fb306ab95223120d61..1c0dd5e83bc9a80c5c7b03116166617eb4234c68 100644 --- a/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/commons/info/notification/_i18n/LocalStrings_pt_BR.properties @@ -1,2 +1,2 @@ #Thu Sep 08 16:42:37 CEST 2011 -notification.title=Notifica\u00E7\u00F5es +notification.title=Notifica\u00E7\u00F5es no curso "{0}" diff --git a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java index 6828ad6c7f1c70818c77a180cf0b4daf4d67c8ba..399ad60c6233da7ff6068d1e816bf8aea2176f83 100644 --- a/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java +++ b/src/main/java/org/olat/core/commons/editor/htmleditor/HTMLEditorController.java @@ -108,6 +108,7 @@ public class HTMLEditorController extends FormBasicController { private boolean editable = true; private boolean newFile = true; private boolean editorCheckEnabled = true; // default + private boolean versions = true; private String fileToLargeError = null; /** @@ -132,11 +133,12 @@ public class HTMLEditorController extends FormBasicController { * @return Controller with internal-link selector */ protected HTMLEditorController(UserRequest ureq, WindowControl wControl, VFSContainer baseContainer, String relFilePath, - CustomLinkTreeModel customLinkTreeModel, boolean editorCheckEnabled) { + CustomLinkTreeModel customLinkTreeModel, boolean editorCheckEnabled, boolean versions) { super(ureq, wControl, "htmleditor"); // set some basic variables this.baseContainer = baseContainer; this.fileRelPath = relFilePath; + this.versions = versions; this.customLinkTreeModel = customLinkTreeModel; this.editorCheckEnabled = editorCheckEnabled; // make sure the filename doesn't start with a slash @@ -390,7 +392,7 @@ public class HTMLEditorController extends FormBasicController { } // save the file - if(fileLeaf instanceof Versionable && ((Versionable)fileLeaf).getVersions().isVersioned()) { + if(versions && fileLeaf instanceof Versionable && ((Versionable)fileLeaf).getVersions().isVersioned()) { InputStream inStream = FileUtils.getInputStream(fileContent.toString(), charSet); ((Versionable)fileLeaf).getVersions().addVersion(getIdentity(), "", inStream); } else { diff --git a/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java b/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java index cb17a8ebb70d985e36d6026501f4f134841c455b..1df36fb6cac73f910804b2a522d26d71829738f6 100644 --- a/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java +++ b/src/main/java/org/olat/core/commons/editor/htmleditor/WysiwygFactory.java @@ -29,7 +29,6 @@ package org.olat.core.commons.editor.htmleditor; import org.olat.core.commons.controllers.linkchooser.CustomLinkTreeModel; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.WindowControl; -import org.olat.core.logging.activity.IUserActivityLogger; import org.olat.core.util.vfs.VFSContainer; /** @@ -66,9 +65,9 @@ public class WysiwygFactory { */ public static HTMLEditorController createWysiwygController( UserRequest ureq, WindowControl wControl, VFSContainer rootDir, - String filePath, boolean editorCheckEnabled) { + String filePath, boolean editorCheckEnabled, boolean versions) { return new HTMLEditorController(ureq, wControl, rootDir, filePath, - null, editorCheckEnabled); + null, editorCheckEnabled, versions); } /** @@ -100,7 +99,7 @@ public class WysiwygFactory { String relFilePath, boolean editorCheckEnabled, CustomLinkTreeModel customLinkTreeModel) { return new HTMLEditorController(ureq, wControl, baseContainer, relFilePath, - customLinkTreeModel, editorCheckEnabled); + customLinkTreeModel, editorCheckEnabled, true); } /** diff --git a/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java b/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java index 7ce2824dbaf9935f03a1faf92b7ea5876cd2260b..7656ec34b935b096dcaf89c3572449af3a023ae0 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FileUploadController.java @@ -77,7 +77,6 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.version.Versionable; import org.olat.core.util.vfs.version.Versions; -import org.olat.core.util.vfs.version.VersionsManager; /** * <h3>Description</h3> @@ -539,8 +538,7 @@ public class FileUploadController extends FormBasicController { } else if (buttonClickedEvent.getPosition() == 2) { // cancel // Cancel. Remove the new file since it has already been uploaded. Note that we don't have to explicitly close the // dialog box since it closes itself whenever something gets clicked. - newFile.delete(); - VersionsManager.getInstance().delete(newFile, true);//force delete the auto-versioning of this temp. file + newFile.deleteSilently(); } else { throw new RuntimeException("Unknown button number " + buttonClickedEvent.getPosition()); } @@ -558,8 +556,7 @@ public class FileUploadController extends FormBasicController { break; } case 1: {//cancel - newFile.delete(); - VersionsManager.getInstance().delete(newFile, true);//force delete the auto-versioning of this temp. file + newFile.deleteSilently(); fireEvent(ureq, Event.CANCELLED_EVENT); break; } @@ -586,8 +583,7 @@ public class FileUploadController extends FormBasicController { Versionable existingVersionableItem = (Versionable)existingVFSItem; boolean ok = existingVersionableItem.getVersions().addVersion(ureq.getIdentity(), comment, newFile.getInputStream()); if(ok) { - newFile.delete(); - VersionsManager.getInstance().delete(newFile, true); + newFile.deleteSilently(); //what can i do if existingVFSItem is a container if(existingVFSItem instanceof VFSLeaf) { newFile = (VFSLeaf)existingVFSItem; @@ -619,8 +615,7 @@ public class FileUploadController extends FormBasicController { revisionListDialogBox = null; //remove the file - newFile.delete(); - VersionsManager.getInstance().delete(newFile, true); + newFile.deleteSilently(); } else if (source == revisionListCtr) { if(FolderCommandStatus.STATUS_CANCELED == revisionListCtr.getStatus()) { @@ -630,8 +625,7 @@ public class FileUploadController extends FormBasicController { //don't want to delete revisions, clean the temporary file if(newFile != null) { - newFile.delete(); - VersionsManager.getInstance().delete(newFile, true); + newFile.deleteSilently(); } } else { if (existingVFSItem instanceof Versionable && ((Versionable)existingVFSItem).getVersions().isVersioned()) { diff --git a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java index fa9e71e41a3ea5541374520dc9f052a085bd716c..567c1778897ed8980645c80c415967f812197f72 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java +++ b/src/main/java/org/olat/core/commons/modules/bc/FolderRunController.java @@ -457,9 +457,9 @@ public class FolderRunController extends BasicController implements Activateable * @return The action triggered by the user. */ private String getFormAction(UserRequest ureq) { - Enumeration params = ureq.getHttpReq().getParameterNames(); + Enumeration<String> params = ureq.getHttpReq().getParameterNames(); while (params.hasMoreElements()) { - String key = (String) params.nextElement(); + String key = params.nextElement(); if (key.startsWith(ACTION_PRE)) { return key.substring(ACTION_PRE.length()); } diff --git a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pl.properties index d1605be768486f9c9d6705693772e563bf13b900..1131af900149f84cc1b34789e41468104391986d 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/core/commons/modules/bc/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Thu Sep 08 16:42:41 CEST 2011 +#Wed Dec 05 14:54:32 CET 2012 Directory=Folder FileDeleteFailed=Pliki/foldery <b>{0}</b> nie mog\u0142y zosta\u0107 usuni\u0119te. FileDeleted=Pliki/foldery <b>{0}</b> zosta\u0142y usuni\u0119te. @@ -127,6 +127,7 @@ notifications.entry=Plik "{0}" od u\u017Cytkownika {1} zmodyfikowany {2} notifications.header=S\u0105 nowe pliki w subskrybowanym przez ciebie folderze\: resize_image=Optymalizuj rozmiar obraz\u00F3w dla sieci Web (1280 x 1280) searchfile=Znajd\u017A +send=Wy\u015Blij e-mail success=Operacja powiod\u0142a si\u0119 text.element.error.notlongerthan=Nazwy plik\u00F3w i folder\u00F3w nie mog\u0105 przekracza\u0107 20 znak\u00F3w ul=Za\u0142aduj plik diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java index 20970ebd63c52b5e7e2a4d09bc8e914ed3b4963f..712e8d6b2c6a96a3f9e7477a91a5374f98f351e8 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdCreateFile.java @@ -166,7 +166,7 @@ public class CmdCreateFile extends BasicController implements FolderCommand { writableRootContainer = folderComponent.getCurrentContainer(); } if (relFilePath.endsWith(".html") || relFilePath.endsWith(".htm")) { - editorCtr = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), writableRootContainer, relFilePath, true); + editorCtr = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), writableRootContainer, relFilePath, true, true); ((HTMLEditorController)editorCtr).setNewFile(true); } else { diff --git a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditContent.java b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditContent.java index b75e68c6c2abf0b466dbaef164670388484497f8..4e2f1bb26a3789ee4637c0bb5f67b26cceae0c7e 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditContent.java +++ b/src/main/java/org/olat/core/commons/modules/bc/commands/CmdEditContent.java @@ -140,7 +140,7 @@ public class CmdEditContent extends BasicController implements FolderCommand { editorc = WysiwygFactory.createWysiwygControllerWithInternalLink(ureq, getWindowControl(), writableRootContainer, relFilePath, true, customLinkTreeModel); ((HTMLEditorController)editorc).setNewFile(false); } else { - editorc = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), writableRootContainer, relFilePath, true); + editorc = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), writableRootContainer, relFilePath, true, true); ((HTMLEditorController)editorc).setNewFile(false); } } diff --git a/src/main/java/org/olat/core/commons/modules/bc/meta/tagged/TitleComparator.java b/src/main/java/org/olat/core/commons/modules/bc/meta/tagged/TitleComparator.java index f2bac687cba21f2a6c063385f61e785aba72c710..d54d24fa3258fbcc0de36568960a9372856e3d34 100644 --- a/src/main/java/org/olat/core/commons/modules/bc/meta/tagged/TitleComparator.java +++ b/src/main/java/org/olat/core/commons/modules/bc/meta/tagged/TitleComparator.java @@ -24,21 +24,18 @@ import java.util.Comparator; import java.util.Locale; import org.olat.core.commons.modules.bc.meta.MetaInfo; -import org.olat.core.commons.modules.bc.meta.MetaTitleComparator; import org.olat.core.util.vfs.VFSItem; /** - * Compare the title or the filename + * Compare the title, the filename and the last modification date * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class TitleComparator implements Comparator<VFSItem> { private final Collator collator; - private final MetaTitleComparator comparator; public TitleComparator(Collator collator) { this.collator = collator; - comparator = new MetaTitleComparator(collator); } public TitleComparator(Locale locale) { @@ -46,14 +43,32 @@ public class TitleComparator implements Comparator<VFSItem> { } public int compare(VFSItem i1, VFSItem i2) { + int result = 0; if(i1 instanceof MetaTagged && i2 instanceof MetaTagged) { MetaInfo m1 = ((MetaTagged)i1).getMetaInfo(); MetaInfo m2 = ((MetaTagged)i2).getMetaInfo(); - return comparator.compare(m1, m2); + if(m1 != null && m2 != null) { + String t1 = m1.getTitle(); + String t2 = m2.getTitle(); + if(t1 != null && t2 != null) { + result = collator.compare(t1, t2); + } + } } - String t1 = i1.getName(); - String t2 = i2.getName(); - return collator.compare(t1, t2); + if(result == 0) { + String n1 = i1.getName(); + String n2 = i2.getName(); + if(n1 != null && n2 != null) { + result = collator.compare(n1, n2); + } + } + + if(result == 0) { + long l1 = i1.getLastModified(); + long l2 = i2.getLastModified(); + result = l1<l2 ? -1 : (l1==l2 ? 0 : 1); + } + return result; } } diff --git a/src/main/java/org/olat/core/commons/modules/singlepage/SinglePageController.java b/src/main/java/org/olat/core/commons/modules/singlepage/SinglePageController.java index 4bb842c5021d62a05bf8c64a158c505f8f97e675..758604aeb31764dd2eaebcb6687e8bd63f1106ce 100644 --- a/src/main/java/org/olat/core/commons/modules/singlepage/SinglePageController.java +++ b/src/main/java/org/olat/core/commons/modules/singlepage/SinglePageController.java @@ -354,7 +354,7 @@ public class SinglePageController extends BasicController implements CloneableCo removeAsListenerAndDispose(htmlEditorController); if (customLinkTreeModel == null) { - htmlEditorController = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), g_new_rootContainer, g_curURI, true); + htmlEditorController = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), g_new_rootContainer, g_curURI, true, true); } else { htmlEditorController = WysiwygFactory.createWysiwygControllerWithInternalLink(ureq, getWindowControl(), g_new_rootContainer, g_curURI, true, customLinkTreeModel); diff --git a/src/main/java/org/olat/core/commons/portlets/didYouKnow/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/core/commons/portlets/didYouKnow/_i18n/LocalStrings_pl.properties index 4f6b8bd622ae6e3572d7ee6105c2625ff3eec8b3..57aa0415dede00bf83ee7d0d6c5b41341b66d052 100644 --- a/src/main/java/org/olat/core/commons/portlets/didYouKnow/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/core/commons/portlets/didYouKnow/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Mon Mar 02 09:54:16 CET 2009 +#Wed Dec 05 14:07:26 CET 2012 A-0=U\u017Cywaj\u0105c zak\u0142adki "Grupy" mo\u017Cesz utworzy\u0107 tzw. grup\u0119 projekt\u00F3w i umie\u015Bci\u0107 w niej narz\u0119dzia wsp\u00F3\u0142pracy jak np. folder, forum czy portal Wiki. A-1=Na stronie g\u0142\u00F3wnej ka\u017Cdego forum widnieje link "Subskrybuj". Aktywuj\u0105c subskrypcj\u0119 b\u0119dziesz informowany o zmianach na tym forum m.in. poprzez e-mail. A-10=U\u017Cywaj\u0105c zak\u0142adki "Grupy" mo\u017Cesz utworzy\u0107 tzw. grup\u0119 projekt\u00F3w i umie\u015Bci\u0107 w niej narz\u0119dzie wsp\u00F3\u0142pracy jak np. folder, forum czy portal Wiki. @@ -7,12 +7,12 @@ A-12=OpenOLAT jest aplikacj\u0105 dzia\u0142aj\u0105c\u0105 w przegl\u0105darce A-13=Kliknij w tym celu ikon\u0119 ze znakiem zapytania, a otrzymasz niezb\u0119dne informacje. A-2=Na stronie g\u0142\u00F3wnej ka\u017Cdego folderu widnieje link "Subskrybuj". Aktywuj\u0105c subskrypcj\u0119 b\u0119dziesz informowany o zmianach w tym folderze m.in. poprzez e-mail. A-3=Kliknij link RSS na swojej stronie g\u0142\u00F3wnej w OpenOLAT i dodaj go do zak\u0142adek. B\u0105d\u017A zawsze na bie\u017C\u0105co. - +A-4=OpenOLAT oferuje kompleksowe rozwi\u0105zania e-portfolio. Z kreatorem mo\u017Cna zebra\u0107 wszystkie osobiste "artefakty" i wykorzysta\u0107 je do stworzenia "teczki" dla innych u\u017Cytkownik\u00F3w. Mo\u017Cliwe jest r\u00F3wnie\u017C tworzenie portfolio grupowych lub zada\u0144 portfolio w kursach. A-5=Na stronie g\u0142\u00F3wnej, w lewym menu wybierz "Ustawienia", a nast\u0119pnie kliknij w zak\u0142adk\u0119 "Wizyt\u00F3wka". Mo\u017Cesz tam wybra\u0107 dane, kt\u00F3re b\u0119d\u0105 widoczne dla innych u\u017Cytkownik\u00F3w. Ponadto mo\u017Cesz za\u0142adowa\u0107 tam sw\u00F3j obrazek i wpisa\u0107 kr\u00F3tki tekst. A-6=Mo\u017Cesz przechowywa\u0107 dokumenty w swoim folderze osobistym i mie\u0107 do nich dost\u0119p w ka\u017Cdej chwili. A-7=Kliknij link "Inni u\u017Cytkownicy" na stronie domowej i wyszukaj interesuj\u0105c\u0105 Ci\u0119 osob\u0119. Opr\u00F3cz wizyt\u00F3wki, mo\u017Cesz tak\u017Ce obejrze\u0107 zawarto\u015B\u0107 folderu publicznego danego u\u017Cytkownika i skontaktowa\u0107 si\u0119 z nim za pomoc\u0105 formularza kontaktowego. A-8=Umie\u015B\u0107 dokumenty w swoim osobistym folderze, w sekcji "public". Od tej chwili pozostali u\u017Cytkownicy b\u0119d\u0105 mogli je przegl\u0105da\u0107. -A-9=OpenOLAT jest aplikacj\u0105 dzia\u0142aj\u0105c\u0105 w przegl\u0105darce internetowej i posiada w\u0142asny system nawigacji, dlatego u\u017Cywanie przycisk\u00F3w "Wstecz" i "Od\u015Bwie\u017C" przegl\u0105darki internetowej mo\u017Ce powodowa\u0107 problemy w trakcie pracy. +A-9=Mo\u017Cesz przechowywa\u0107 dokumenty w folderze osobistym, kt\u00F3ry mo\u017Cna wykorzysta\u0107 w ka\u017Cdej chwili. OpenOLAT zapewnia 20 MB przestrzeni dla tego celu. Q-0=...OpenOLAT to skr\u00F3t? Q-1=... mo\u017Cesz by\u0107 powiadamiany o zmianach zachodz\u0105cych na forum? Q-10=... OpenOLAT mo\u017Ce by\u0107 wykorzystywany jako narz\u0119dzie do wsp\u00F3lnego przygotowywania dokument\u00F3w? @@ -21,7 +21,6 @@ Q-12=... nie powiniene\u015B u\u017Cywa\u0107 przycisk\u00F3w "Wstecz" i "Od\u01 Q-13=... mo\u017Cesz zawsze skorzysta\u0107 z pomocy online? Q-2=... mo\u017Cesz by\u0107 powiadamiany o zmianach zachodz\u0105cych w folderach? Q-3=... wszystkie powiadomienia mo\u017Cesz przegl\u0105da\u0107 w czytniku kana\u0142\u00F3w RSS? - Q-5=... mo\u017Cesz skomponowa\u0107 swoj\u0105 wizyt\u00F3wk\u0119 w OpenOLAT? Q-6=... mo\u017Cesz przechowywa\u0107 swoje osobiste dokumenty w OpenOLAT? Q-7=... mo\u017Cesz ogl\u0105da\u0107 wizyt\u00F3wki innych u\u017Cytkownik\u00F3w OpenOLAT? diff --git a/src/main/java/org/olat/core/commons/portlets/iframe/IframePortletRunController.java b/src/main/java/org/olat/core/commons/portlets/iframe/IframePortletRunController.java index 16ac69b2f5821cdf038a88f23f1396e741734f41..abdf97f90ff3306be4c72dff5c00226e01c7e0db 100644 --- a/src/main/java/org/olat/core/commons/portlets/iframe/IframePortletRunController.java +++ b/src/main/java/org/olat/core/commons/portlets/iframe/IframePortletRunController.java @@ -172,8 +172,8 @@ public class IframePortletRunController extends BasicController { if (editorCtr != null) editorCtr.dispose(); editorCtr = WysiwygFactory.createWysiwygController(ureq, - getWindowControl(), rootDir, fileName, true); - this.listenTo(editorCtr); + getWindowControl(), rootDir, fileName, true, true); + listenTo(editorCtr); cmc = new CloseableModalController(getWindowControl(), translate("close"), editorCtr.getInitialComponent()); cmc.activate(); } diff --git a/src/main/java/org/olat/core/commons/services/mark/impl/ui/MarkController.java b/src/main/java/org/olat/core/commons/services/mark/impl/ui/MarkController.java index 5f5f1c7c879c38801ab36b69ca8e5091188a26c3..ff41acd5003162d77ae7b898c4e215dd5ef5d3fd 100644 --- a/src/main/java/org/olat/core/commons/services/mark/impl/ui/MarkController.java +++ b/src/main/java/org/olat/core/commons/services/mark/impl/ui/MarkController.java @@ -103,6 +103,7 @@ public class MarkController extends FormBasicController { protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { markLink = uifactory.addFormLink("mark", " ", " ", formLayout, Link.NONTRANSLATED + Link.LINK_CUSTOM_CSS); markLink.setCustomEnabledLinkCSS(marked ? "b_mark_set" : "b_mark_not_set"); + markLink.setEnabled(!ureq.getUserSession().getRoles().isGuestOnly()); String tooltip; if(stat == null) { diff --git a/src/main/java/org/olat/core/commons/services/search/SearchModule.java b/src/main/java/org/olat/core/commons/services/search/SearchModule.java index 70bc5e86bc18230326203d172756cd1bdd3867aa..a2453eaca62ead938ceb4793fe8d93fbdc48d313 100644 --- a/src/main/java/org/olat/core/commons/services/search/SearchModule.java +++ b/src/main/java/org/olat/core/commons/services/search/SearchModule.java @@ -54,7 +54,6 @@ public class SearchModule extends AbstractOLATModule { public final static String CONF_TEMP_INDEX_PATH = "tempIndexPath"; public final static String CONF_TEMP_SPELL_CHECK_PATH = "tempSpellCheckPath"; public final static String CONF_GENERATE_AT_STARTUP = "generateIndexAtStartup"; - private static final String CONF_RESTART_INTERVAL = "restartInterval"; private static final String CONF_INDEX_INTERVAL = "indexInterval"; private static final String CONF_MAX_HITS = "maxHits"; private static final String CONF_MAX_RESULTS = "maxResults"; @@ -77,7 +76,6 @@ public class SearchModule extends AbstractOLATModule { private static final String CONF_FILE_BLACK_LIST = "fileBlackList"; // Default values - private static final int DEFAULT_RESTART_INTERVAL = 0; private static final int DEFAULT_INDEX_INTERVAL = 0; private static final int DEFAULT_MAX_HITS = 1000; private static final int DEFAULT_MAX_RESULTS = 100; @@ -94,7 +92,6 @@ public class SearchModule extends AbstractOLATModule { private String fullTempIndexPath; private String fullTempSpellCheckPath; private long indexInterval; - private long restartInterval; private boolean generateAtStartup; private int maxHits; private int maxResults; @@ -113,7 +110,7 @@ public class SearchModule extends AbstractOLATModule { private boolean pdfFileEnabled; private boolean pdfTextBuffering; private boolean isSpellCheckEnabled; - private String fullTempPdfTextBufferPath; + private String fullPdfTextBufferPath; private List<String> fileSizeSuffixes; private long maxFileSize; @@ -163,13 +160,13 @@ public class SearchModule extends AbstractOLATModule { String tempIndexPath = getStringConfigParameter(CONF_TEMP_INDEX_PATH, "/tmp", false); String tempSpellCheckPath = getStringConfigParameter(CONF_TEMP_SPELL_CHECK_PATH, "/tmp",false); String tempPdfTextBufferPath = getStringConfigParameter(CONF_TEMP_PDF_TEXT_BUF_PATH, "/tmp", false); - fullIndexPath = FolderConfig.getCanonicalTmpDir() + File.separator + indexPath; - fullTempIndexPath = FolderConfig.getCanonicalTmpDir() + File.separator + tempIndexPath; - fullTempSpellCheckPath = FolderConfig.getCanonicalTmpDir() + File.separator + tempSpellCheckPath; - fullTempPdfTextBufferPath = FolderConfig.getCanonicalTmpDir() + File.separator + tempPdfTextBufferPath; + + fullIndexPath = buildPath(indexPath); + fullTempIndexPath = buildPath(tempIndexPath); + fullTempSpellCheckPath = buildPath(tempSpellCheckPath); + fullPdfTextBufferPath = buildPath(tempPdfTextBufferPath); generateAtStartup = getBooleanConfigParameter(CONF_GENERATE_AT_STARTUP, true); - restartInterval = getIntConfigParameter(CONF_RESTART_INTERVAL, DEFAULT_RESTART_INTERVAL); indexInterval = getIntConfigParameter(CONF_INDEX_INTERVAL, DEFAULT_INDEX_INTERVAL); maxHits = getIntConfigParameter(CONF_MAX_HITS, DEFAULT_MAX_HITS); maxResults = getIntConfigParameter(CONF_MAX_RESULTS, DEFAULT_MAX_RESULTS); @@ -190,6 +187,14 @@ public class SearchModule extends AbstractOLATModule { useCompoundFile = getBooleanConfigParameter(CONF_USE_COMPOUND_FILE, false); } + private String buildPath(String path) { + File f = new File(path); + if(f.isAbsolute() && (f.exists() || f.mkdirs())) { + return path; + } + return FolderConfig.getCanonicalTmpDir() + File.separator + path; + } + @Override public void init() { //black list @@ -271,13 +276,6 @@ public class SearchModule extends AbstractOLATModule { return generateAtStartup; } - /** - * @return Time in millisecond between restart generation of a full-index. - */ - public long getRestartInterval() { - return restartInterval; - } - /** * @return Sleep time in millisecond between indexing documents. */ @@ -414,7 +412,7 @@ public class SearchModule extends AbstractOLATModule { } public String getPdfTextBufferPath() { - return fullTempPdfTextBufferPath; + return fullPdfTextBufferPath; } public List<String> getFileSizeSuffixes() { diff --git a/src/main/java/org/olat/core/commons/services/search/SearchService.java b/src/main/java/org/olat/core/commons/services/search/SearchService.java index d22b89955c73c181b01beca235eac512bb86a662..34feb9ed880f2964e20842887d3aab9b225b59c3 100644 --- a/src/main/java/org/olat/core/commons/services/search/SearchService.java +++ b/src/main/java/org/olat/core/commons/services/search/SearchService.java @@ -28,7 +28,6 @@ package org.olat.core.commons.services.search; import java.util.List; import java.util.Set; -import org.apache.lucene.document.Document; import org.apache.lucene.queryParser.ParseException; import org.olat.core.id.Identity; import org.olat.core.id.Roles; @@ -77,18 +76,6 @@ public interface SearchService { * @return */ public SearchServiceStatus getStatus(); - - /** - * Add a document to existing index. - * @param document New document. - */ - public void addToIndex(Document document); - - /** - * Delete a document in existing index. - * @param document Delete this document. - */ - public void deleteFromIndex(Document document); /** * Get index-interval of running system diff --git a/src/main/java/org/olat/core/dispatcher/DispatcherAction.java b/src/main/java/org/olat/core/dispatcher/DispatcherAction.java index 5c0d31057be2dfe751239ed310cf6f1c709df5aa..0333af22cead1cb400a2f9031c6854497cd46abd 100644 --- a/src/main/java/org/olat/core/dispatcher/DispatcherAction.java +++ b/src/main/java/org/olat/core/dispatcher/DispatcherAction.java @@ -36,7 +36,6 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.olat.core.commons.persistence.DBFactory; -import org.olat.core.defaults.dispatcher.StaticMediaDispatcher; import org.olat.core.dispatcher.mapper.GlobalMapperRegistry; import org.olat.core.dispatcher.mapper.MapperDispatcher; import org.olat.core.logging.OLog; @@ -334,9 +333,16 @@ public class DispatcherAction implements Dispatcher { } + /** + * Sent to standard 503 if not available + * @param response + */ public static void redirectToServiceNotAvailable(HttpServletResponse response) { - String pathStaticDir = StaticMediaDispatcher.getStaticMapperPath(); - redirectTo(response, WebappHelper.getServletContextPath() + pathStaticDir + "msg/en/service_not_available.html"); + try { + response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE); + } catch (IOException e) { + log.error("Send 503 failed", e); + } } } diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/Form.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/Form.java index 89eeed31cd6716ee980343af76d6832a05f109c0..c5ce1e1e8fddb12566b6cf4de654f92677eb9b9e 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/Form.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/Form.java @@ -59,6 +59,7 @@ import org.olat.core.util.CodeHelper; import org.olat.core.util.FileUtils; import org.olat.core.util.ValidationStatus; import org.olat.core.util.ValidationStatusHelper; +import org.olat.core.util.WebappHelper; import org.olat.core.util.component.FormComponentTraverser; import org.olat.core.util.component.FormComponentVisitor; @@ -350,7 +351,7 @@ public class Form extends LogDelegator { slashpos = fileName.lastIndexOf("\\"); if (slashpos != -1) fileName = fileName.substring(slashpos + 1); - File tmpFile = new File(System.getProperty("java.io.tmpdir") + File.separator + "upload-" + CodeHelper.getGlobalForeverUniqueID()); + File tmpFile = new File(WebappHelper.getTmpDir() + File.separator + "upload-" + CodeHelper.getGlobalForeverUniqueID()); try { FileUtils.save(itemStream, tmpFile); @@ -678,7 +679,7 @@ public class Form extends LogDelegator { } - private class FormDependencyRulesInitComponentVisitor implements FormComponentVisitor { + private static class FormDependencyRulesInitComponentVisitor implements FormComponentVisitor { public boolean visit(FormItem comp, UserRequest ureq) { if (comp instanceof FormItemContainer) { @@ -697,18 +698,8 @@ public class Form extends LogDelegator { } - - /** - * Description:<br> - * TODO: patrickb Class Description for ValidatingFormComponentVisitor - * <P> - * Initial Date: 07.12.2006 <br> - * - * @author patrickb - */ - private class ValidatingFormComponentVisitor implements FormComponentVisitor { - - List tmp = new ArrayList(); + private static class ValidatingFormComponentVisitor implements FormComponentVisitor { + final List<ValidationStatus> tmp = new ArrayList<ValidationStatus>(); public ValidationStatus[] getStatus() { return ValidationStatusHelper.sort(tmp); @@ -722,15 +713,8 @@ public class Form extends LogDelegator { return true; } } - /** - * Description:<br> - * TODO: patrickb Class Description for ValidatingFormComponentVisitor - * <P> - * Initial Date: 07.12.2006 <br> - * - * @author patrickb - */ - private class ResettingFormComponentVisitor implements FormComponentVisitor { + + private static class ResettingFormComponentVisitor implements FormComponentVisitor { public boolean visit(FormItem comp, UserRequest ureq) { //reset all fields including also non visible and disabled form items! diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java index e2598ce7f006ef525e685d1ebdf2e833c2da9ba8..63db270ae1ac977cd6223630f89f46eeed3e6f3d 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/FileElementImpl.java @@ -108,7 +108,7 @@ public class FileElementImpl extends FormItemImpl implements FileElement, Dispos // with a // temporary form item scope. The file must be moved later using the // moveUploadFileTo() method to the final destination. - tempUploadFile = new File(WebappHelper.getUserDataRoot() + "/tmp/" + CodeHelper.getGlobalForeverUniqueID()); + tempUploadFile = new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID()); File tmpRequestFile = getRootForm().getRequestMultipartFile(component.getFormDispatchId()); // Move file to internal temp location boolean success = tmpRequestFile.renameTo(tempUploadFile); diff --git a/src/main/java/org/olat/core/gui/components/panel/LayeredPanel.java b/src/main/java/org/olat/core/gui/components/panel/LayeredPanel.java index 70dcf0337b506513d137da128871e1b3a5872e83..84ef2776f6731cf40b57e85ee9fc1554694325c3 100644 --- a/src/main/java/org/olat/core/gui/components/panel/LayeredPanel.java +++ b/src/main/java/org/olat/core/gui/components/panel/LayeredPanel.java @@ -19,6 +19,7 @@ */ package org.olat.core.gui.components.panel; +import java.util.ArrayList; import java.util.List; import org.olat.core.gui.components.Component; @@ -73,7 +74,9 @@ public class LayeredPanel extends Panel { * @return The list of layers in this panel */ List<Component> getLayers() { - return super.stackList; + synchronized(stackList) { + return new ArrayList<Component>(stackList); + } } /** diff --git a/src/main/java/org/olat/core/gui/components/progressbar/ProgressBar.java b/src/main/java/org/olat/core/gui/components/progressbar/ProgressBar.java index 853420310faac46f99f805498ffe5a5aace79067..fb814a00f2919e46f53cdbba510bfc7a9f6e615c 100644 --- a/src/main/java/org/olat/core/gui/components/progressbar/ProgressBar.java +++ b/src/main/java/org/olat/core/gui/components/progressbar/ProgressBar.java @@ -46,6 +46,7 @@ public class ProgressBar extends Component { private boolean isNoMax = false; private String unitLabel; private boolean percentagesEnabled = true; // default + private String info; /** * @param name @@ -83,6 +84,11 @@ public class ProgressBar extends Component { setDirty(true); actual = i; } + + public void setInfo(String info) { + this.info = info; + setDirty(true); + } /** * @param i @@ -125,6 +131,10 @@ public class ProgressBar extends Component { float getActual() { return actual; } + + String getInfo() { + return info; + } /** * @return diff --git a/src/main/java/org/olat/core/gui/components/progressbar/ProgressBarRenderer.java b/src/main/java/org/olat/core/gui/components/progressbar/ProgressBarRenderer.java index 3228bac13d661d2ae9df29772bbaefef6b4fe6a8..c79dd9179db28426117093e902e97bc06a91caa0 100644 --- a/src/main/java/org/olat/core/gui/components/progressbar/ProgressBarRenderer.java +++ b/src/main/java/org/olat/core/gui/components/progressbar/ProgressBarRenderer.java @@ -34,6 +34,7 @@ import org.olat.core.gui.render.RenderingState; import org.olat.core.gui.render.StringOutput; import org.olat.core.gui.render.URLBuilder; import org.olat.core.gui.translator.Translator; +import org.olat.core.util.StringHelper; /** * Initial Date: Feb 2, 2004 A <b>ChoiceRenderer </b> is @@ -65,13 +66,13 @@ public class ProgressBarRenderer implements ComponentRenderer { if (!ubar.getIsNoMax()) percent = 100 * ubar.getActual() / ubar.getMax(); if (percent < 0) percent = 0; if (percent > 100) percent = 100; - target.append("<div class=\"b_progress\"><div class=\"b_progress_bar\" style=\"width:"); - target.append(ubar.getWidth()); - target.append("px;\"><div style=\"width:"); - target.append(Math.round(percent * ubar.getWidth() / 100)); - target.append("px\" title=\""); - target.append(Math.round(percent * ubar.getWidth() / 100)); - target.append("%\"></div></div>"); + target.append("<div class=\"b_progress\"><div class=\"b_progress_bar\" style=\"width:") + .append(ubar.getWidth()) + .append("px;\"><div style=\"width:") + .append(Math.round(percent * ubar.getWidth() / 100)) + .append("px\" title=\"") + .append(Math.round(percent * ubar.getWidth() / 100)) + .append("%\"></div></div>"); if (renderLabels) { target.append("<div class=\"b_progress_label\">"); if (ubar.isPercentagesEnabled()) { @@ -89,8 +90,13 @@ public class ProgressBarRenderer implements ComponentRenderer { } target.append("</div>"); } + String info = ubar.getInfo(); + if(StringHelper.containsNonWhitespace(info)) { + target.append("<div class=\"b_progress_label\">") + .append(info) + .append("</div>"); + } target.append("</div>"); - } /** diff --git a/src/main/java/org/olat/core/gui/components/progressbar/ProgressController.java b/src/main/java/org/olat/core/gui/components/progressbar/ProgressController.java index 77a9c0d593ff8f9b204bf4d10ff9a3a7a7225ccc..b07f7c919978d7767757d314d850ebd8452edca6 100644 --- a/src/main/java/org/olat/core/gui/components/progressbar/ProgressController.java +++ b/src/main/java/org/olat/core/gui/components/progressbar/ProgressController.java @@ -58,11 +58,28 @@ public class ProgressController extends BasicController implements ProgressDeleg mainVC.contextPut("msg", translatedMsg); } + public void setMax(float i) { + progressBar.setMax(i); + } + + public void setPercentagesEnabled(boolean percentagesEnabled) { + progressBar.setPercentagesEnabled(percentagesEnabled); + } + @Override public void setActual(float i) { progressBar.setActual(i); } + @Override + public void setInfo(String message) { + progressBar.setInfo(message); + } + + public void setUnitLabel(String label) { + progressBar.setUnitLabel(label); + } + @Override public void finished() { progressBar.setActual(0.0f); diff --git a/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java b/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java index 0d4454b1c466a34bf53750a12cb7481b8043eda6..5d52e163b7f5c16d92b7025c4462d2b050b4bc16 100644 --- a/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java +++ b/src/main/java/org/olat/core/gui/components/table/DefaultXlsTableExporter.java @@ -35,7 +35,6 @@ import org.apache.poi.ss.usermodel.Font; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.gui.media.CleanupAfterDeliveryFileMediaResource; import org.olat.core.gui.media.MediaResource; import org.olat.core.gui.render.StringOutput; @@ -43,6 +42,7 @@ import org.olat.core.gui.translator.Translator; import org.olat.core.logging.AssertException; import org.olat.core.util.CodeHelper; import org.olat.core.util.StringHelper; +import org.olat.core.util.WebappHelper; import org.olat.core.util.filter.FilterFactory; /** @@ -119,8 +119,7 @@ public class DefaultXlsTableExporter implements TableExporter { private MediaResource createMediaResourceFromDocument(final Workbook wb) { FileOutputStream fos = null; try { - String tmpFilePath = FolderConfig.getCanonicalTmpDir()+File.separator+"TableExport"+CodeHelper.getRAMUniqueID()+".xls"; - File f = new File(tmpFilePath); + File f = new File(WebappHelper.getTmpDir(), "TableExport" + CodeHelper.getUniqueID() + ".xls"); fos = new FileOutputStream(f); wb.write(fos); fos.close(); diff --git a/src/main/java/org/olat/core/id/IdentityEnvironment.java b/src/main/java/org/olat/core/id/IdentityEnvironment.java index c075d21879cbb2667c9313fa134db220f60ca3e9..dfa8a2e480cd222c390a012ff42bb8231f4493a4 100644 --- a/src/main/java/org/olat/core/id/IdentityEnvironment.java +++ b/src/main/java/org/olat/core/id/IdentityEnvironment.java @@ -100,7 +100,9 @@ public class IdentityEnvironment extends LogDelegator implements Serializable { * @param roles */ public void setRoles(Roles roles) { - if (this.roles != null) throw new AssertException("can only set Roles once"); + if (this.roles != null && !this.roles.equals(roles)) { + throw new AssertException("can only set Roles once"); + } this.roles = roles; } diff --git a/src/main/java/org/olat/core/id/Roles.java b/src/main/java/org/olat/core/id/Roles.java index bd88a2567fd8a29c6adf97c4ec7797687790fffc..80839e8598fb4762851ab57a56dbe32408a22893 100644 --- a/src/main/java/org/olat/core/id/Roles.java +++ b/src/main/java/org/olat/core/id/Roles.java @@ -33,6 +33,7 @@ import java.io.Serializable; * @author Felix Jost */ public class Roles implements Serializable { + private static final long serialVersionUID = 4726449291059674346L; private boolean isOLATAdmin; private boolean isUserManager; private boolean isGroupManager; @@ -111,8 +112,45 @@ public class Roles implements Serializable { /** * @see java.lang.Object#toString() */ + @Override public String toString() { return "admin:"+isOLATAdmin+", usermanager:"+isUserManager+", groupmanager:"+isGroupManager+", author:"+isAuthor+", guestonly:"+isGuestOnly+", isInstitutionalResourceManager:"+isInstitutionalResourceManager+", isInvitee:"+isInvitee+", "+super.toString(); } + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + (isAuthor ? 1231 : 1237); + result = prime * result + (isGroupManager ? 1231 : 1237); + result = prime * result + (isGuestOnly ? 1231 : 1237); + result = prime * result + (isInstitutionalResourceManager ? 1231 : 1237); + result = prime * result + (isInvitee ? 1231 : 1237); + result = prime * result + (isOLATAdmin ? 1231 : 1237); + result = prime * result + (isUserManager ? 1231 : 1237); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + + Roles other = (Roles) obj; + if (isAuthor != other.isAuthor) return false; + if (isGroupManager != other.isGroupManager) return false; + if (isGuestOnly != other.isGuestOnly) return false; + if (isInstitutionalResourceManager != other.isInstitutionalResourceManager) return false; + if (isInvitee != other.isInvitee) return false; + if (isOLATAdmin != other.isOLATAdmin) return false; + if (isUserManager != other.isUserManager) return false; + return true; + } } diff --git a/src/main/java/org/olat/core/util/CodeHelper.java b/src/main/java/org/olat/core/util/CodeHelper.java index 2b40670c9e866cfff7db7bd9de347b6470dda685..a4708878d4fd3c60e1dc8bf258974d9068b679e3 100644 --- a/src/main/java/org/olat/core/util/CodeHelper.java +++ b/src/main/java/org/olat/core/util/CodeHelper.java @@ -26,6 +26,7 @@ package org.olat.core.util; +import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; @@ -98,5 +99,9 @@ public class CodeHelper { public static long getRAMUniqueID() { return ramid.incrementAndGet(); } + + public static String getUniqueID() { + return UUID.randomUUID().toString(); + } } diff --git a/src/main/java/org/olat/core/util/WebappHelper.java b/src/main/java/org/olat/core/util/WebappHelper.java index b84eca690a105e261b8549a3731a75f3fbe8714c..4c24b6a96bd541ad90fc818b181dc80ad79daa56 100644 --- a/src/main/java/org/olat/core/util/WebappHelper.java +++ b/src/main/java/org/olat/core/util/WebappHelper.java @@ -270,14 +270,18 @@ public class WebappHelper implements Initializable, Destroyable, ServletContextA public static String getUserDataRoot() { return userDataRoot; } + + public static String getTmpDir() { + return System.getProperty("java.io.tmpdir"); + } /** * [spring] * @param userDataRoot */ public void setUserDataRoot(String userDataRoot) { - if (! StringHelper.containsNonWhitespace(userDataRoot)) { - userDataRoot = System.getProperty("java.io.tmpdir")+"/olatdata"; + if (!StringHelper.containsNonWhitespace(userDataRoot)) { + userDataRoot = System.getProperty("java.io.tmpdir") + "/olatdata"; log.info("using java.io.tmpdir as userdata. this is the default if userdata.dir is not set"); } File fUserData = new File(userDataRoot); @@ -286,7 +290,6 @@ public class WebappHelper implements Initializable, Destroyable, ServletContextA } //fxdiff: reset tmp-dir from within application to circumvent startup-params. //do not write to system default (/var/tmp) as this leads to permission problems with multiple instances on one host! - System.setProperty("java.io.tmpdir", userDataRoot+"/tmp"); log.info("Setting userdata root to: "+userDataRoot); WebappHelper.userDataRoot = userDataRoot; } diff --git a/src/main/java/org/olat/core/util/WorkThreadInformations.java b/src/main/java/org/olat/core/util/WorkThreadInformations.java index 8a5c8cc49d65ee320e31703d188357cd8685d095..1c43c9d0ae0531dd9a34bc66b4b1fbe9a80d430d 100644 --- a/src/main/java/org/olat/core/util/WorkThreadInformations.java +++ b/src/main/java/org/olat/core/util/WorkThreadInformations.java @@ -75,7 +75,7 @@ public class WorkThreadInformations { public static void setInfoFiles(String filePath, VFSLeaf leaf) { try { - File file = new File(FolderConfig.getCanonicalTmpDir(), "threadInfos"); + File file = new File(WebappHelper.getUserDataRoot(), "threadInfos"); if(!file.exists()) { file.mkdirs(); } diff --git a/src/main/java/org/olat/core/util/ZipUtil.java b/src/main/java/org/olat/core/util/ZipUtil.java index f63991971c2fe9c8678e40276937b581ae4e2e1f..36f4e3c851ff66bc70ff0a9e89cc0e291867be46 100644 --- a/src/main/java/org/olat/core/util/ZipUtil.java +++ b/src/main/java/org/olat/core/util/ZipUtil.java @@ -59,7 +59,6 @@ import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.VersionsFileManager; /** * Initial Date: 04.12.2002 @@ -73,7 +72,7 @@ public class ZipUtil { private static final String DIR_NAME__MACOSX = "__MACOSX/"; - private static final OLog log = Tracing.createLoggerFor(VersionsFileManager.class); + private static final OLog log = Tracing.createLoggerFor(ZipUtil.class); /** * Constructor for ZipUtil. 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 65fa87b0279e6d2ec5db90478e2ddc407a3f8dd3..f49b934915e68840f05a245c56fd2ba96784987e 100644 --- a/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml +++ b/src/main/java/org/olat/core/util/_spring/utilCorecontext.xml @@ -41,6 +41,7 @@ <property name="arguments"> <value> session.timeout=${session.timeout} + session.timeout.authenticated=${session.timeout.authenticated} </value> </property> </bean> diff --git a/src/main/java/org/olat/core/util/async/ProgressDelegate.java b/src/main/java/org/olat/core/util/async/ProgressDelegate.java index 2e060fef0236a1de075019e26b43cc5b63c55f0b..ade4a982e90cd9575edc2b6f364b9cc2e7febe14 100644 --- a/src/main/java/org/olat/core/util/async/ProgressDelegate.java +++ b/src/main/java/org/olat/core/util/async/ProgressDelegate.java @@ -27,8 +27,12 @@ package org.olat.core.util.async; */ public interface ProgressDelegate { + public void setMax(float max); + public void setActual(float value); + public void setInfo(String message); + public void finished(); } 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 8dc2ee4ae76bdee0bef4b5bd01e189c936f1ee06..2eadd5fca2e9247806cb33abe42605916146650c 100644 --- a/src/main/java/org/olat/core/util/i18n/I18nManager.java +++ b/src/main/java/org/olat/core/util/i18n/I18nManager.java @@ -1988,7 +1988,7 @@ public class I18nManager extends BasicManager { */ public File createLanguageJarFile(Set<String> languageKeys, String fileName) { // Create file olatdata temporary directory - File file = new File(WebappHelper.getUserDataRoot() + "/tmp/" + fileName); + File file = new File(WebappHelper.getTmpDir() + "/" + fileName); file.getParentFile().mkdirs(); FileOutputStream stream = null; 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 2ffee1c510523d72f82b09bccddcfed51c2d5a60..e937514971f25e9c38c7fda9968775b96e1b04ad 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 @@ -28,8 +28,6 @@ import java.util.HashSet; import java.util.Locale; import java.util.Set; -import org.olat.core.commons.persistence.DB; -import org.olat.core.commons.persistence.DBFactory; import org.olat.core.dispatcher.DispatcherAction; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; @@ -52,6 +50,7 @@ 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.user.UserManager; /** * Description:<br> @@ -213,10 +212,9 @@ class I18nConfigSubNewLangController extends FormBasicController { User currUser = ureq.getIdentity().getUser(); // direct DB calls have to be made here because the // user manager is not available in the core - DB db = DBFactory.getInstance(); - currUser = (User) db.loadObject(currUser); + currUser = UserManager.getInstance().loadUserByKey(currUser.getKey()); currUser.getPreferences().setLanguage(localeKey); - db.saveObject(currUser); + UserManager.getInstance().updateUser(currUser); DispatcherAction.redirectToDefaultDispatcher(ureq.getHttpResp()); } diff --git a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_pl.properties index 10c610be116af7559ac3650bcbdd5b2fda26f43c..e85697be9d2f88a1aa961400fafe1c356fdfd408 100644 --- a/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/core/util/mail/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Tue Jul 31 15:54:11 CEST 2012 +#Wed Dec 05 15:23:43 CET 2012 chelp.mail-templ.title=$\:mailnotification.title chelp.mailtemplateformbody=Domy\u015Blnie, ka\u017Cda wiadomo\u015B\u0107 zawiera standardowy tekst, kt\u00F3ry mo\u017Cesz dopasowa\u0107 do w\u0142asnych potrzeb. chelp.mailtempsubject=Tematy wiadomo\u015Bci s\u0105 wst\u0119pnie ustawione, lecz mo\u017Cesz zmienia\u0107 je wed\u0142ug uznania. @@ -12,6 +12,8 @@ contact.cp.from=Kopia wys\u0142ana do nadawcy footer.no.userdata=\n\n--- \n Wiadomo\u015B\u0107 zosta\u0142a automatycznie wys\u0142ana z systemu OpenOLAT\n{0} footer.with.userdata=\n\n--- \n{2} {3} ({0})\n{4}\n\n Wiadomo\u015B\u0107 zosta\u0142a wys\u0142ana z systemu OpenOLAT\n{1} help.hover.mail-templ=Pomoc dla szablonu u\u017Cycia poczty +mail.action.open=Otw\u00F3rz +mail.context=Kontekst mail.empty.box=Skrzynka nie zawiera e-maili. mail.from=Nadawca mail.from.miscellaneous=R\u00F3\u017Cni diff --git a/src/main/java/org/olat/core/util/notifications/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/core/util/notifications/_i18n/LocalStrings_pl.properties index fbe7d587f404ab3d03eb38bbd6fec53380b9819d..2397ed1372c22f75375ac0279233f95349edbe6e 100644 --- a/src/main/java/org/olat/core/util/notifications/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/core/util/notifications/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Fri Dec 17 17:13:24 CET 2010 +#Wed Dec 05 14:47:08 CET 2012 actions.title=Modyfikacje chelp.del=<i>$org.olat.notifications\:subs.deleted</i> chelp.home=<i>$org.olat.home\:main.menu.title</i> @@ -20,8 +20,11 @@ chelp.notif7=Po wybraniu "Powiadomienia" uzyskasz list\u0119 wszystkich subskryb chelp.notif8=Ponadto, otrzymasz nast\u0119puj\u0105ce informacje\: chelp.notif9=Wpis $\:chelp.ok poajwi si\u0119, je\u015Bli masz dost\u0119p do odpowiedniego fora lub folderu i czy nadal jest to aktualne (warunki dost\u0119pu mog\u0142y si\u0119 zmieni\u0107 w mi\u0119dzyczasie). chelp.ok=<i>$org.olat.notifications\:subs.ok</i> +chelp.resname=W tej kolumnie jest wy\u015Bwietlany rodzaj obiektu. chelp.rss=RSS-Feed +chelp.subidentifier=W tej kolumnie jest wy\u015Bwietlana nazwa obiektu. chelp.subs=<i>$org.olat.core.util.notifications\:command.subscribe</i> +chelp.type=W tej kolumnie jest wy\u015Bwietlany typ subskrybowanego obiektu - jest to od razu link do tego obiektu, kt\u00F3ry mo\u017Cesz "klikn\u0105\u0107". chelp.unsubs=<i>$org.olat.core.util.notifications\:command.unsubscribe</i> command.subscribe=Subskrybuj command.unsubscribe=Cofnij subskrypcj\u0119 diff --git a/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java b/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java index b3b6d12f41f83f2912ee1dfefb3be2b0514b79dc..626fe8a2b341df994decf3bd574fc70ce1ff1608 100644 --- a/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java +++ b/src/main/java/org/olat/core/util/vfs/AbstractVirtualContainer.java @@ -115,6 +115,11 @@ public abstract class AbstractVirtualContainer implements VFSContainer { throw new RuntimeException("unsupported"); } + @Override + public VFSStatus deleteSilently() { + throw new RuntimeException("unsupported"); + } + /** * @see org.olat.core.util.vfs.VFSContainer#createChildContainer(java.lang.String) */ diff --git a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java index 5107635c05f80887f9d05e67f4f4085e62608435..4b63c7916124e1e78d6f0d5b4b8d872a6c24ed40 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalFileImpl.java @@ -154,6 +154,11 @@ public class LocalFileImpl extends LocalImpl implements VFSLeaf, Versionable { } return getBasefile().delete() ? VFSConstants.YES : VFSConstants.NO; } + + @Override + public VFSStatus deleteSilently() { + return getBasefile().delete() ? VFSConstants.YES : VFSConstants.NO; + } /** * @see org.olat.core.util.vfs.VFSItem#resolveFile(java.lang.String) diff --git a/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java b/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java index 35b837c946ffc87b7002549ed66d2042efc5005b..601c62774bf3f130ecf16af27ad5bf2058e2767f 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalFolderImpl.java @@ -249,6 +249,25 @@ public class LocalFolderImpl extends LocalImpl implements VFSContainer { boolean del = getBasefile().delete(); return del ? VFSConstants.YES : VFSConstants.NO; } + + + + @Override + public VFSStatus deleteSilently() { + if(!getBasefile().exists()){ + return VFSConstants.YES; // already non-existent + } + // we must empty the folders and subfolders first + for (Iterator<VFSItem> it_chd = getItems().iterator(); it_chd.hasNext();) { + it_chd.next().deleteSilently(); // TODO status + } + + VersionsManager.getInstance().delete(this, true); + + // now delete the directory itself + boolean del = getBasefile().delete(); + return del ? VFSConstants.YES : VFSConstants.NO; + } /** * @see org.olat.core.util.vfs.VFSItem#resolveFile(java.lang.String) diff --git a/src/main/java/org/olat/core/util/vfs/LocalImpl.java b/src/main/java/org/olat/core/util/vfs/LocalImpl.java index 9c0520beed23aadd75ad7c3cc66517e8e096f8b1..1ceab9611030682f31bfe9aeb1b2d4b07472d6d4 100644 --- a/src/main/java/org/olat/core/util/vfs/LocalImpl.java +++ b/src/main/java/org/olat/core/util/vfs/LocalImpl.java @@ -104,7 +104,12 @@ public abstract class LocalImpl implements VFSItem { public VFSStatus canWrite() { return VFSConstants.NO; } - + + @Override + public boolean exists() { + return basefile != null && basefile.exists(); + } + /** * @see org.olat.core.util.vfs.VFSItem#getName() */ diff --git a/src/main/java/org/olat/core/util/vfs/MergeSource.java b/src/main/java/org/olat/core/util/vfs/MergeSource.java index c32cd925aae1b3b32466911978c203c8a0a6712e..8a26fc43e63c6a59f6a407a1c1a523fec3fb476f 100644 --- a/src/main/java/org/olat/core/util/vfs/MergeSource.java +++ b/src/main/java/org/olat/core/util/vfs/MergeSource.java @@ -61,6 +61,11 @@ public class MergeSource extends AbstractVirtualContainer { this.mergedContainersChildren = new ArrayList<VFSContainer>(); } + @Override + public boolean exists() { + return true; + } + /** * Add container to this merge source. container will show up as its name as a childe of MergeSource. * diff --git a/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java b/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java index ad7ab98086fa4545262db5b5ec90b379ee24580a..cb3c5894d42b50fa041be9ec73fdcf59d45a2ba5 100644 --- a/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java +++ b/src/main/java/org/olat/core/util/vfs/NamedContainerImpl.java @@ -52,7 +52,12 @@ public class NamedContainerImpl extends AbstractVirtualContainer { super(name); this.delegate = delegate; } - + + @Override + public boolean exists() { + return delegate != null && delegate.exists(); + } + public VFSContainer getDelegate() { return delegate; } diff --git a/src/main/java/org/olat/core/util/vfs/NamedLeaf.java b/src/main/java/org/olat/core/util/vfs/NamedLeaf.java index 8cbee6e84e01ef38fa85f08be8eaae3e0c1f2764..7c634047e6c56dde4025654a75bd6050a7c649fa 100644 --- a/src/main/java/org/olat/core/util/vfs/NamedLeaf.java +++ b/src/main/java/org/olat/core/util/vfs/NamedLeaf.java @@ -48,6 +48,11 @@ public class NamedLeaf implements VFSLeaf { this.delegate = delegate; } + @Override + public boolean exists() { + return delegate != null && delegate.exists(); + } + //fxdiff FXOLAT-125: virtual file system for CP public VFSLeaf getDelegate() { return delegate; @@ -107,7 +112,12 @@ public class NamedLeaf implements VFSLeaf { * @see org.olat.core.util.vfs.VFSItem#delete() */ public VFSStatus delete() { - return delegate.canDelete(); + return delegate.delete(); + } + + @Override + public VFSStatus deleteSilently() { + return delegate.deleteSilently(); } /** diff --git a/src/main/java/org/olat/core/util/vfs/VFSItem.java b/src/main/java/org/olat/core/util/vfs/VFSItem.java index c20c4cc3acda266b794371e0ae2f64ec0fce4a1f..8ff89b5c316979006a869f9b33afdb750359c2cd 100644 --- a/src/main/java/org/olat/core/util/vfs/VFSItem.java +++ b/src/main/java/org/olat/core/util/vfs/VFSItem.java @@ -72,12 +72,21 @@ public interface VFSItem { public VFSStatus rename(String newname); /** - * deltes the item. if the item is a container, all children will be deleted recursively + * Deletes the item. If the item is a container, all children will be deleted recursively * @return status */ public VFSStatus delete(); - + /** + * Delete the items and by pass versioning if enabled + * @return + */ + public VFSStatus deleteSilently(); + + /** + * @return True if the file exists + */ + public boolean exists(); /** * @return if can write diff --git a/src/main/java/org/olat/core/util/vfs/VirtualContainer.java b/src/main/java/org/olat/core/util/vfs/VirtualContainer.java index fa5b92d87bc0626f7283c2c4025e890e52f673f4..1cfdf3a659da444ece2173aed895eb88e633fbad 100644 --- a/src/main/java/org/olat/core/util/vfs/VirtualContainer.java +++ b/src/main/java/org/olat/core/util/vfs/VirtualContainer.java @@ -35,15 +35,20 @@ import org.olat.core.util.vfs.filters.VFSItemFilter; public class VirtualContainer extends AbstractVirtualContainer { - private List children; + private List<VFSItem> children; private VFSSecurityCallback secCallback = null; private VFSContainer parentContainer; public VirtualContainer(String name) { super(name); - children = new ArrayList(); - } + children = new ArrayList<VFSItem>(); + } + @Override + public boolean exists() { + return true; + } + /** * Add a VFSItem to this CirtualContainer. * @param vfsItem @@ -52,15 +57,15 @@ public class VirtualContainer extends AbstractVirtualContainer { children.add(vfsItem); } - public List getItems() { + public List<VFSItem> getItems() { return getItems(null); } - public List getItems(VFSItemFilter filter) { + public List<VFSItem> getItems(VFSItemFilter filter) { if (filter == null) return children; else { - List filtered = new ArrayList(); - for (Iterator iter = children.iterator(); iter.hasNext();) { + List<VFSItem> filtered = new ArrayList<VFSItem>(); + for (Iterator<VFSItem> iter = children.iterator(); iter.hasNext();) { VFSItem vfsItem = (VFSItem) iter.next(); if (filter.accept(vfsItem)) filtered.add(vfsItem); } diff --git a/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java b/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java index e95c22e3c66a87b0fee6d8a7e866f869e3ae0877..45559de0e7e5b2db78ba97f58b2ebfd90a888275 100644 --- a/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java +++ b/src/main/java/org/olat/core/util/vfs/version/SimpleVersionConfig.java @@ -20,11 +20,14 @@ package org.olat.core.util.vfs.version; import java.io.IOException; +import java.util.ArrayList; +import java.util.List; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.configuration.PersistedProperties; import org.olat.core.configuration.PersistedPropertiesChangedEvent; import org.olat.core.gui.control.Event; +import org.olat.core.util.StringHelper; import org.olat.core.util.coordinate.CoordinatorManager; import org.olat.core.util.event.GenericEventListener; import org.olat.core.util.vfs.LocalFolderImpl; @@ -60,13 +63,12 @@ public class SimpleVersionConfig implements GenericEventListener, FolderVersioni private PersistedProperties persistedProperties; private String courseRoot; + private List<String> excludedRoots; - /** * [used by spring] */ private SimpleVersionConfig() { - // } public void event(Event event) { @@ -128,10 +130,23 @@ public class SimpleVersionConfig implements GenericEventListener, FolderVersioni } public int versionAllowed(String relPath) { + if(StringHelper.containsNonWhitespace(relPath)) { + if(relPath.startsWith("/tmp/")//no versioning in tmp + || relPath.startsWith("/scorm/")//there is already a versioning in assessment tool + || relPath.startsWith("/portfolio/")//portfolio is not a folder + || relPath.startsWith("/forum/")) {//forum is not a folder + return 0; + } + } return getVersionAllowed() ; } public boolean versionEnabled(VFSContainer container) { + int versionsAllowed = getVersionAllowed(); + if(versionsAllowed == 0) { + return false; + } + if (container instanceof NamedContainerImpl) { container = ((NamedContainerImpl) container).getDelegate(); } @@ -143,6 +158,13 @@ public class SimpleVersionConfig implements GenericEventListener, FolderVersioni try { LocalFolderImpl folderImpl = (LocalFolderImpl)container; String path = folderImpl.getBasefile().getCanonicalPath(); + List<String> excludedRoots = getExcludedRoots(); + for(String excludedRoot:excludedRoots) { + if(path.startsWith(excludedRoot)) { + return false; + } + } + String root = getCourseRoot(); if (path.startsWith(root)) { for(String exclusion:EXCLUSIONS_IN_COURSE_PATH) { @@ -186,4 +208,16 @@ public class SimpleVersionConfig implements GenericEventListener, FolderVersioni } return courseRoot; } + + private List<String> getExcludedRoots() { + if(excludedRoots == null) { + excludedRoots = new ArrayList<String>(); + excludedRoots.add(FolderConfig.getCanonicalTmpDir()); + String bcroot = FolderConfig.getCanonicalRoot(); + excludedRoots.add(bcroot + "/forum"); + excludedRoots.add(bcroot + "/portfolio"); + excludedRoots.add(bcroot + "/scorm"); + } + return excludedRoots; + } } diff --git a/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java b/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java index d51544451c902644410116870ebb74de826d0973..bdea2482e80d0b9a620ed8920741a4ed3b6acab2 100644 --- a/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java +++ b/src/main/java/org/olat/core/util/vfs/version/VersionsFileManager.java @@ -25,12 +25,20 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; +import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; +import java.util.Scanner; import java.util.Set; import java.util.UUID; +import java.util.regex.Pattern; +import java.util.zip.Adler32; +import java.util.zip.Checksum; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.meta.MetaInfo; import org.olat.core.commons.modules.bc.meta.tagged.MetaTagged; @@ -40,6 +48,7 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.StringHelper; +import org.olat.core.util.async.ProgressDelegate; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.LocalImpl; @@ -53,6 +62,7 @@ import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.VFSManager; import org.olat.core.util.vfs.filters.VFSItemSuffixFilter; import org.olat.core.util.vfs.filters.VFSLeafFilter; +import org.olat.core.util.vfs.restapi.SystemItemFilter; import org.olat.core.util.xml.XStreamHelper; import com.thoughtworks.xstream.XStream; @@ -74,6 +84,7 @@ public class VersionsFileManager extends VersionsManager implements Initializabl private static final OLog log = Tracing.createLoggerFor(VersionsFileManager.class); private static final Versions NOT_VERSIONED = new NotVersioned(); + private static final Pattern TAG_PATTERN = Pattern.compile("\\s*[<>]\\s*"); private static XStream mystream; @@ -118,11 +129,14 @@ public class VersionsFileManager extends VersionsManager implements Initializabl List<VFSItem> versionItems = versionContainer.getItems(new VFSItemSuffixFilter(new String[] { "xml" })); for (VFSItem versionItem : versionItems) { - if (versionItem instanceof VFSLeaf && !currentNames.contains(versionItem.getName())) { + String name = versionItem.getName(); + if (versionItem instanceof VFSLeaf && !currentNames.contains(name) && isVersionsXmlFile((VFSLeaf)versionItem)) { Versions versions = readVersions(null, (VFSLeaf) versionItem); - List<VFSRevision> revisions = versions.getRevisions(); - if (!revisions.isEmpty()) { - deletedRevisions.add(versions); + if(versions != null) { + List<VFSRevision> revisions = versions.getRevisions(); + if (!revisions.isEmpty()) { + deletedRevisions.add(versions); + } } } } @@ -141,23 +155,54 @@ public class VersionsFileManager extends VersionsManager implements Initializabl } return readVersions(leaf, fVersions); } + + private boolean isVersionsXmlFile(VFSLeaf fVersions) { + if(fVersions == null || !fVersions.exists()) { + return false; + } + InputStream in = fVersions.getInputStream(); + if(in == null) { + return false; + } + + Scanner scanner = new Scanner(in); + scanner.useDelimiter(TAG_PATTERN); + + boolean foundVersionsTag = false; + while (scanner.hasNext()) { + String tag = scanner.next(); + if("versions".equals(tag)) { + foundVersionsTag = true; + break; + } + } + + scanner.close(); + IOUtils.closeQuietly(in); + return foundVersionsTag; + } private Versions readVersions(VFSLeaf leaf, VFSLeaf fVersions) { if (fVersions == null) { return new NotVersioned(); } - VFSContainer fVersionContainer = fVersions.getParentContainer(); - VersionsFileImpl versions = (VersionsFileImpl) XStreamHelper.readObject(mystream, fVersions); - versions.setVersionFile(fVersions); - versions.setCurrentVersion((Versionable) leaf); - if (versions.getRevisionNr() == null || versions.getRevisionNr().length() == 0) { - versions.setRevisionNr(getNextRevisionNr(versions)); - } + try { + VFSContainer fVersionContainer = fVersions.getParentContainer(); + VersionsFileImpl versions = (VersionsFileImpl) XStreamHelper.readObject(mystream, fVersions); + versions.setVersionFile(fVersions); + versions.setCurrentVersion((Versionable) leaf); + if (versions.getRevisionNr() == null || versions.getRevisionNr().length() == 0) { + versions.setRevisionNr(getNextRevisionNr(versions)); + } - for (VFSRevision revision : versions.getRevisions()) { - RevisionFileImpl revisionImpl = (RevisionFileImpl) revision; - revisionImpl.setContainer(fVersionContainer); + for (VFSRevision revision : versions.getRevisions()) { + RevisionFileImpl revisionImpl = (RevisionFileImpl) revision; + revisionImpl.setContainer(fVersionContainer); + } + return versions; + } catch (Exception e) { + log.warn("This file is not a versions XML file: " + fVersions, e); + return null; } - return versions; } @Override @@ -328,6 +373,7 @@ public class VersionsFileManager extends VersionsManager implements Initializabl Versions versions = readVersions(currentFile, true); List<VFSRevision> allVersions = versions.getRevisions(); + Map<String,VFSLeaf> filenamesToDelete = new HashMap<String,VFSLeaf>(allVersions.size()); for (VFSRevision versionToDelete : versionsToDelete) { RevisionFileImpl versionImpl = (RevisionFileImpl) versionToDelete; for (Iterator<VFSRevision> allVersionIt = allVersions.iterator(); allVersionIt.hasNext();) { @@ -340,9 +386,21 @@ public class VersionsFileManager extends VersionsManager implements Initializabl VFSLeaf fileToDelete = versionImpl.getFile(); if (fileToDelete != null) { - fileToDelete.delete(); + filenamesToDelete.put(fileToDelete.getName(), fileToDelete); + } + } + + for(VFSRevision survivingVersion:allVersions) { + RevisionFileImpl survivingVersionImpl = (RevisionFileImpl)survivingVersion; + VFSLeaf revFile = survivingVersionImpl.getFile(); + if(filenamesToDelete.containsKey(revFile.getName())) { + filenamesToDelete.remove(revFile.getName()); } } + + for(VFSLeaf fileToDelete:filenamesToDelete.values()) { + fileToDelete.deleteSilently(); + } VFSLeaf versionFile = getCanonicalVersionXmlFile(currentFile, true); XStreamHelper.writeObject(mystream, versionFile, versions); @@ -360,13 +418,13 @@ public class VersionsFileManager extends VersionsManager implements Initializabl VFSLeaf versionFile = versionsImpl.getVersionFile(); if(versionFile != null) { //robust against manual file system manipulation - versionFile.delete(); + versionFile.deleteSilently(); } for (VFSRevision revisionToDelete : versionsImpl.getRevisions()) { RevisionFileImpl versionImpl = (RevisionFileImpl)revisionToDelete; VFSLeaf fileToDelete = versionImpl.getFile(); if (fileToDelete != null) { - fileToDelete.delete(); + fileToDelete.deleteSilently(); } } } @@ -503,8 +561,10 @@ public class VersionsFileManager extends VersionsManager implements Initializabl return false; } VersionsFileImpl versions = (VersionsFileImpl) v; - - String uuid = UUID.randomUUID().toString() + "_" + name; + boolean sameFile = isSameFile(currentFile, versions); + String uuid = sameFile ? getLastRevisionFilename(versions) + : UUID.randomUUID().toString() + "_" + name; + String versionNr = getNextRevisionNr(versions); String currentAuthor = versions.getAuthor(); long lastModifiedDate = 0; @@ -539,8 +599,7 @@ public class VersionsFileManager extends VersionsManager implements Initializabl versions.setCreator(metaTagged.getMetaInfo().getAuthor()); } - VFSLeaf target = versionContainer.createChildLeaf(uuid); - if (VFSManager.copyContent(currentFile, target)) { + if (sameFile || VFSManager.copyContent(currentFile, versionContainer.createChildLeaf(uuid))) { if (identity != null) { versions.setAuthor(identity.getName()); } @@ -557,6 +616,31 @@ public class VersionsFileManager extends VersionsManager implements Initializabl } return false; } + + private boolean isSameFile(VFSLeaf currentFile, VersionsFileImpl versions) { + boolean same = false; + if(versions.getRevisions() != null && !versions.getRevisions().isEmpty()) { + VFSRevision lastRevision = versions.getRevisions().get(versions.getRevisions().size() -1); + + long lastSize = lastRevision.getSize(); + long currentSize = currentFile.getSize(); + if(currentSize == lastSize && currentSize > 0 + && lastRevision instanceof RevisionFileImpl + && currentFile instanceof LocalFileImpl) { + RevisionFileImpl lastRev = ((RevisionFileImpl)lastRevision); + LocalFileImpl current = (LocalFileImpl)currentFile; + //can be the same file + try { + Checksum cm1 = FileUtils.checksum(((LocalFileImpl)((RevisionFileImpl)lastRev).getFile()).getBasefile() , new Adler32()); + Checksum cm2 = FileUtils.checksum(current.getBasefile() , new Adler32()); + same = cm1.getValue() == cm2.getValue(); + } catch (IOException e) { + log.debug("Error calculating the checksum of files"); + } + } + } + return same; + } public String getNextRevisionNr(Versions versions) { int maxNumber = 0; @@ -573,6 +657,18 @@ public class VersionsFileManager extends VersionsManager implements Initializabl } return Integer.toString(maxNumber + 1); } + + private String getLastRevisionFilename(Versions versions) { + if(versions.getRevisions() == null || versions.getRevisions().isEmpty()) { + return null; + } + + VFSRevision revision = versions.getRevisions().get(versions.getRevisions().size() - 1); + if(revision instanceof RevisionFileImpl) { + return ((RevisionFileImpl)revision).getFilename(); + } + return null; + } /** * Get the canonical path to the file's meta file. @@ -611,7 +707,7 @@ public class VersionsFileManager extends VersionsManager implements Initializabl return null; } - private VFSContainer getCanonicalVersionFolder(VFSContainer container, boolean create) { + protected VFSContainer getCanonicalVersionFolder(VFSContainer container, boolean create) { String relPath = getRelPath(container); File fVersion = new File(getRootVersionsFile(), relPath); if (fVersion.exists()) { return new LocalFolderImpl(fVersion); } @@ -702,9 +798,106 @@ public class VersionsFileManager extends VersionsManager implements Initializabl } return rootVersionsContainer; } + + @Override + public int countDirectories() { + VFSContainer versionsContainer = getRootVersionsContainer(); + if(versionsContainer.exists()) { + return countDirectories(versionsContainer); + } + return 0; + } + + private int countDirectories(VFSContainer container) { + int count = 1;//itself + List<VFSItem> children = container.getItems(new SystemItemFilter()); + for(VFSItem child:children) { + if(child instanceof VFSContainer) { + count += countDirectories((VFSContainer)child); + } + } + return count; + } + + @Override + public void pruneHistory(long maxHistoryLength, ProgressDelegate progress) { + VFSContainer versionsContainer = getRootVersionsContainer(); + if(!versionsContainer.exists()) { + return; + } + //delete folder without versioning first + + int count = 0; + String[] excludedRootFolders = new String[]{"tmp","scorm","forum","portfolio"}; + for(String excludedRootFolder:excludedRootFolders) { + VFSItem excludedContainer = versionsContainer.resolve(excludedRootFolder); + if(excludedContainer instanceof LocalFolderImpl) { + File excludedFile = ((LocalFolderImpl)excludedContainer).getBasefile(); + FileUtils.deleteQuietly(excludedFile); + if(progress != null) progress.setInfo(excludedContainer.getName()); + } + if(progress != null) progress.setActual(++count); + } + + if(maxHistoryLength < 0) { + //nothing to do + } else if(maxHistoryLength == 0 && versionsContainer instanceof LocalFolderImpl) { + //delete all the stuff + FileUtils.deleteQuietly(((LocalFolderImpl)versionsContainer).getBasefile()); + } else { + pruneVersionHistory(versionsContainer, maxHistoryLength, progress, count); + } + + if(progress != null) progress.finished(); + } + + private void pruneVersionHistory(VFSContainer container, long maxHistoryLength, ProgressDelegate progress, int count) { + List<VFSItem> children = container.getItems(new SystemItemFilter()); + for(VFSItem child:children) { + if(child instanceof VFSContainer) { + if(progress != null) progress.setActual(++count); + pruneVersionHistory((VFSContainer)child, maxHistoryLength, progress, count); + } + if(child instanceof VFSLeaf) { + VFSLeaf versionsLeaf = (VFSLeaf)child; + pruneVersionHistory(versionsLeaf, maxHistoryLength, progress); + } + } + } + + private void pruneVersionHistory(VFSLeaf versionsLeaf, long maxHistoryLength, ProgressDelegate progress) { + if(versionsLeaf.getName().endsWith(".xml") && isVersionsXmlFile(versionsLeaf)) { + File originalFile = reversedOriginFile(versionsLeaf); + if(originalFile.exists()) { + VFSLeaf original = new LocalFileImpl(originalFile); + if(progress != null) progress.setInfo(original.getName()); + Versions versions = readVersions(original, versionsLeaf); + List<VFSRevision> revisions = versions.getRevisions(); + if(revisions.size() > maxHistoryLength) { + List<VFSRevision> revisionsToDelete = revisions.subList(0, revisions.size() - (int)maxHistoryLength); + deleteRevisions((Versionable)original, revisionsToDelete); + } + } + } + } + + @Override + public boolean deleteOrphans(ProgressDelegate progress) { + List<OrphanVersion> orphans = orphans(); + if(progress != null) progress.setMax(orphans.size()); + int count = 0; + for(OrphanVersion orphan:orphans) { + delete(orphan); + if(progress != null) { + progress.setActual(++count); + progress.setInfo(orphan.getOriginalFilePath()); + } + } + if(progress != null) progress.finished(); + return true; + } @Override - //fxdiff FXOLAT-127: file versions maintenance tool public boolean delete(OrphanVersion orphan) { VFSLeaf versionLeaf = orphan.getVersionsLeaf(); @@ -723,14 +916,13 @@ public class VersionsFileManager extends VersionsManager implements Initializabl } @Override - //fxdiff FXOLAT-127: file versions maintenance tool public List<OrphanVersion> orphans() { List<OrphanVersion> orphans = new ArrayList<OrphanVersion>(); VFSContainer versionsContainer = getRootVersionsContainer(); crawlForOrphans(versionsContainer, orphans); return orphans; } - //fxdiff FXOLAT-127: file versions maintenance tool + private void crawlForOrphans(VFSContainer container, List<OrphanVersion> orphans) { List<VFSItem> children = container.getItems(); for(VFSItem child:children) { @@ -762,16 +954,19 @@ public class VersionsFileManager extends VersionsManager implements Initializabl } } } - //fxdiff FXOLAT-127: file versions maintenance tool + private Versions isOrphan(VFSLeaf potentialOrphan) { try { - VersionsFileImpl versions = (VersionsFileImpl) XStreamHelper.readObject(mystream, potentialOrphan); - return versions; + if(potentialOrphan.exists()) { + VersionsFileImpl versions = (VersionsFileImpl) XStreamHelper.readObject(mystream, potentialOrphan); + return versions; + } + return null; } catch (Exception e) { return null; } } - //fxdiff FXOLAT-127: file versions maintenance tool + private File reversedOriginFile(VFSItem versionXml) { String path = File.separatorChar + versionXml.getName().substring(0, versionXml.getName().length() - 4); for(VFSContainer parent=versionXml.getParentContainer(); parent != null && !parent.isSame(getRootVersionsContainer()); parent = parent.getParentContainer()) { diff --git a/src/main/java/org/olat/core/util/vfs/version/VersionsManager.java b/src/main/java/org/olat/core/util/vfs/version/VersionsManager.java index 2cced4eaaadec8be4d960d0d2e43fe8639a24de3..4049f5b6809d8107693ab2715119cdc52e43b199 100644 --- a/src/main/java/org/olat/core/util/vfs/version/VersionsManager.java +++ b/src/main/java/org/olat/core/util/vfs/version/VersionsManager.java @@ -24,6 +24,7 @@ import java.util.List; import org.olat.core.id.Identity; import org.olat.core.manager.BasicManager; +import org.olat.core.util.async.ProgressDelegate; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; @@ -166,10 +167,26 @@ public abstract class VersionsManager extends BasicManager { */ public abstract boolean rename(VFSItem item, String newname); - //fxdiff FXOLAT-127: file versions maintenance tool + /** + * @return The list of orphans + */ public abstract List<OrphanVersion> orphans(); - //fxdiff FXOLAT-127: file versions maintenance tool + /** + * @param orphan + * @return + */ public abstract boolean delete(OrphanVersion orphan); + + /** + * Delete the orphans + * @return + */ + public abstract boolean deleteOrphans(ProgressDelegate progress); + + + public abstract void pruneHistory(long historyLength, ProgressDelegate progress); + + public abstract int countDirectories(); } diff --git a/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml b/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml index 8a98892bab684a99b5afb4a27d85c0c906d833f8..e90c113ca672285588202ae8b29227e625124fd2 100644 --- a/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml +++ b/src/main/java/org/olat/core/util/vfs/version/_spring/versioningCorecontext.xml @@ -3,18 +3,12 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> -<bean id="versionsManager" class="org.olat.core.util.vfs.version.VersionsFileManager" init-method="init"/> + <bean id="versionsManager" class="org.olat.core.util.vfs.version.VersionsFileManager" init-method="init"/> - -<!-- - *********************************************** - *** Define the Version Manager Configurator *** - *********************************************** ---> - - <bean id="versioningConfigurator" class="org.olat.core.util.vfs.version.SimpleVersionConfig" depends-on="coordinatorManager,org.olat.core.util.WebappHelper"> + <bean id="versioningConfigurator" class="org.olat.core.util.vfs.version.SimpleVersionConfig" + depends-on="coordinatorManager,org.olat.core.util.WebappHelper,folderModule"> <property name="coordinator" ref="coordinatorManager" /> <property name="persistedProperties"> <bean class="org.olat.core.configuration.PersistedProperties" scope="prototype" init-method="init" destroy-method="destroy" @@ -27,6 +21,6 @@ </property> </bean> </property> - </bean> + </bean> </beans> \ No newline at end of file diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java index d7cdbe39f2af6ff75a80040af70ea427f9404b9d..4a9bb169bdb9172ffc51d8a413546ba9fedef577 100644 --- a/src/main/java/org/olat/course/CourseFactory.java +++ b/src/main/java/org/olat/course/CourseFactory.java @@ -75,6 +75,7 @@ import org.olat.core.util.ObjectCloner; import org.olat.core.util.StringHelper; import org.olat.core.util.UserSession; import org.olat.core.util.Util; +import org.olat.core.util.WebappHelper; import org.olat.core.util.ZipUtil; import org.olat.core.util.cache.CacheWrapper; import org.olat.core.util.coordinate.CoordinatorManager; @@ -520,7 +521,7 @@ public class CourseFactory extends BasicManager { PersistingCourseImpl sourceCourse = (PersistingCourseImpl) loadCourse(sourceRes); // add files to ZIP - File fExportDir = new File(System.getProperty("java.io.tmpdir")+File.separator+CodeHelper.getRAMUniqueID()); + File fExportDir = new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID()); fExportDir.mkdirs(); synchronized (sourceCourse) { //o_clusterNOK - cannot be solved with doInSync since could take too long (leads to error: "Lock wait timeout exceeded") OLATResource courseResource = sourceCourse.getCourseEnvironment().getCourseGroupManager().getCourseResource(); diff --git a/src/main/java/org/olat/course/DeployableCourseExport.java b/src/main/java/org/olat/course/DeployableCourseExport.java index b9fce63b2c734bdbd5148ceda7803c91c961dfc9..4ade9516c11f0e6e222bf319e0aa0537e3b0173a 100644 --- a/src/main/java/org/olat/course/DeployableCourseExport.java +++ b/src/main/java/org/olat/course/DeployableCourseExport.java @@ -36,6 +36,7 @@ import java.net.URLConnection; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; +import org.olat.core.util.WebappHelper; /** * Description:<br> @@ -138,7 +139,7 @@ public class DeployableCourseExport { if (offset != contentLength) { throw new IOException("Only read " + offset + " bytes; Expected " + contentLength + " bytes"); } String filename = url.getFile().substring(url.getFile().lastIndexOf('/') + 1); - filename = System.getProperty("java.io.tmpdir")+"/"+filename; + filename = WebappHelper.getTmpDir() + "/" + filename; FileOutputStream out = new FileOutputStream(filename); out.write(data); out.flush(); diff --git a/src/main/java/org/olat/course/_spring/courseContext.xml b/src/main/java/org/olat/course/_spring/courseContext.xml index b3425610a941f0ec96d48fb8ecfa1f59f0df45db..b9e50f7792ce8f3857d96b0ff352fad42a59effb 100644 --- a/src/main/java/org/olat/course/_spring/courseContext.xml +++ b/src/main/java/org/olat/course/_spring/courseContext.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> @@ -34,28 +34,7 @@ If you changing the identifier there will be a new course deployed and the old one will stay. --> <property name="courseExportFiles"> - <list> - <bean class="org.olat.course.DeployableCourseExport"> - - <property name="courseUrl" value="http://nexus.openolat.org/nexus/content/repositories/openolat-snapshots/org/openolat/course/Demo-Kurs/7.1-SNAPSHOT/Demo-Kurs-7.1-SNAPSHOT.zip" /> - <property name="identifier" value="Demo Kurs" /> - <property name="version" value="7.1" /> - </bean> - <!-- this one is the help course which will server as the online help, helpAsser flag is TRUE! --> - <bean class="org.olat.course.DeployableCourseExport"> - <property name="courseUrl" value="http://nexus.openolat.org/nexus/content/repositories/openolat/org/openolat/help/OpenOLAT-Help/8.1/OpenOLAT-Help-8.1.zip" /> - <property name="identifier" value="OLAT::help-course_de.zip" /> - <property name="access" value="4" /> - <property name="version" value="8.1" /> - <property name="redeploy" value="true" /> - <!-- - Url to the course which should be used as help course. The specified course will be used - in all languages. - To disable the help course feature, leave the helpCourseFile configuration empty. - Have also a look at the ContextHelpModule configuration. - --> - </bean> - </list> + <ref bean="deployedCourseList"/> </property> @@ -120,4 +99,33 @@ </property> </bean> + <bean id="deployedCourseList" class="java.util.ArrayList"> + <constructor-arg> + <list> + <ref bean="deployedCourse_Demo" /> + <ref bean="deployedCourse_OpenOLATHelp" /> + </list> + </constructor-arg> + </bean> + + <bean id="deployedCourse_Demo" class="org.olat.course.DeployableCourseExport"> + <property name="courseUrl" value="http://nexus.openolat.org/nexus/content/repositories/openolat-snapshots/org/openolat/course/Demo-Kurs/7.1-SNAPSHOT/Demo-Kurs-7.1-SNAPSHOT.zip" /> + <property name="identifier" value="Demo Kurs" /> + <property name="version" value="7.1" /> + </bean> + <!-- this one is the help course which will server as the online help, helpAsser flag is TRUE! --> + <bean id="deployedCourse_OpenOLATHelp" class="org.olat.course.DeployableCourseExport"> + <property name="courseUrl" value="http://nexus.openolat.org/nexus/content/repositories/openolat/org/openolat/help/OpenOLAT-Help/8.1/OpenOLAT-Help-8.1.zip" /> + <property name="identifier" value="OLAT::help-course_de.zip" /> + <property name="access" value="4" /> + <property name="version" value="8.1" /> + <property name="redeploy" value="true" /> + <!-- + Url to the course which should be used as help course. The specified course will be used + in all languages. + To disable the help course feature, leave the helpCourseFile configuration empty. + Have also a look at the ContextHelpModule configuration. + --> + </bean> + </beans> \ No newline at end of file diff --git a/src/main/java/org/olat/course/db/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/db/_i18n/LocalStrings_en.properties index cbb7a0a0f07f8ffe5c49064687014bb25e5bfc8b..ba6dcd224404bd5350e9e0c405866127383fb7ac 100644 --- a/src/main/java/org/olat/course/db/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/db/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Wed Oct 24 16:42:09 CEST 2012 +#Tue Dec 18 17:48:19 CET 2012 command.new_db=Create a new database customDb.category=Name customDb.create=Create diff --git a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties index 4697369ef5eb7931eb11d2cf3ddf3c53056b36a0..105327c2f4845cc2954c9c5c8ba45e2e7251feeb 100644 --- a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_de.properties @@ -2,10 +2,10 @@ access.form.label=Zugriff auf den gesamten Kurs haben access.legend=Zugriff auf den gesamten Kurs \u00E4ndern apply=OK -alternative=Alternative Kursbaustein erstellen -alternative.bbs=Kursbaustein -alternative.choose=Alternative Kursaustein wählen und bestätigen -alternative.choose.description=Sie können die Kursbausstein wählen. +alternative=Alternativer Kursbaustein suchen +alternative.bbs=Alternative Bausteine +alternative.choose=Alternativer Kursbaustein wählen und konvertieren +alternative.choose.description=Wählen Sie aus der Liste der möglichen alternativen Kursbausteine mit ähnlicher Funktionalität aus um diesen deaktivirten Kursbaustein zu konvertieren. Es werden der Titel und die Beschreibung sowie die Zugangsregeln und alle Kinderelemente übernommen. checkall=Alle ausw\u00E4hlen chelp.attributeEasy=<b>$org.olat.course.condition\:form.easy.attributeSwitch\: </b> @@ -494,5 +494,5 @@ undeletenode.message=Sie haben diesen Kursbaustein gel\u00F6scht, aber noch nich undeletenode.notavailable=Sie haben diesen Kursbaustein gel\u00F6scht, aber noch nicht publiziert. Um diesen Kursbaustein wiederherzustellen, m\u00FCssen Sie zuerst den \u00FCbergeordneten Kursbaustein wiederherstellen. warning.containsXXXormore.nodes=Sie haben mehr als {0} Kursbausteine. Ab {1} Kursbausteinen kann OLAT Verschiebe-, L\u00F6sch-, Kopier- und Einf\u00FCgeaktionen von Kursbausteinen nicht mehr gew\u00E4hrleisten. disabled=Deaktiviert -course.building.block.disabled=Dieser Kursbausteintyp wurde deaktiviert. Kontaktieren Sie den Administrator oder löschen Sie den Baustein aus Ihrem Kurs. +course.building.block.disabled=Dieser Kursbausteintyp wurde deaktiviert. Kontaktieren Sie den Administrator, löschen Sie den Baustein aus Ihrem Kurs oder wählen Sie die Schaltfläche "$:alternative" um einen alternativen Baustein mit ähnlicher Funktion zu suchen und den Baustein zu konvertieren. course.building.block.disabled.user=Dieser Kursbausteintyp wurde deaktiviert. Kontaktieren Sie den Administrator oder die Kursleitung. \ No newline at end of file diff --git a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties index 68664835ad1d419356659c1756dc6e59a0fa8b8e..495d11e479de4e42b0a6353117f248d656018080 100644 --- a/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/editor/_i18n/LocalStrings_en.properties @@ -1,6 +1,10 @@ -#Thu May 26 10:56:34 CEST 2011 +#Tue Dec 18 17:51:10 CET 2012 access.form.label=Access to entire course have access.legend=Modify access to entire course +alternative=Search for alternative course element +alternative.bbs=Alternative course elements +alternative.choose=Select an alternative course element and convert +alternative.choose.description=Select from the list of alternative course elements that offer similar functionality to convert this deactivated course element. The title, description, access rules and all child element will be copied to the converted element. apply=OK checkall=Select all chelp.1=You have to give this course element a short title with a maximum of 25 characters. @@ -406,11 +410,11 @@ nodeConfigForm.learningobjectives=Description nodeConfigForm.menumust=A short title must be indicated nodeConfigForm.menutitle=Short title nodeConfigForm.save=Save +nodeConfigForm.short_title_content=Short title and content +nodeConfigForm.short_title_desc_content=Short title, description and content nodeConfigForm.title=Title and description of course element nodeConfigForm.title_content=Title and content -nodeConfigForm.short_title_content=Short title and content nodeConfigForm.title_desc_content=Title, description and content -nodeConfigForm.short_title_desc_content=Short title, description and content nodeEdit.extLink=External link nodeEdit.intLink=Internal link (do not open in new window) nodeEdit.links=Set link for this course element diff --git a/src/main/java/org/olat/course/member/MembersOverviewController.java b/src/main/java/org/olat/course/member/MembersOverviewController.java index f908ab7b3577e36860fa0fb81418d5c97c95317d..49970190ae4ce37d4f77601aaa7587ce6f87b1c4 100644 --- a/src/main/java/org/olat/course/member/MembersOverviewController.java +++ b/src/main/java/org/olat/course/member/MembersOverviewController.java @@ -210,6 +210,14 @@ public class MembersOverviewController extends BasicController implements Activa } } } + } else if(source == dedupCtrl) { + if(event == Event.DONE_EVENT) { + dedupMembers(ureq, dedupCtrl.isDedupCoaches(), dedupCtrl.isDedupParticipants()); + } + cmc.deactivate(); + cleanUp(); + } else if (source == cmc) { + cleanUp(); } super.event(ureq, source, event); } diff --git a/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties index 6ae5162572affe33d323811369a66b7bfabcb09c..65e9b244cad6d6b2d58057c1f77f7c9bdd8d3937 100644 --- a/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/member/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Thu Nov 29 14:25:58 CET 2012 +#Tue Dec 18 17:51:16 CET 2012 action=Action add.member=Add member assessment=Assessment tool @@ -59,6 +59,7 @@ table.header.edit=Edit table.header.firstName=First name table.header.firstTime=Joining table.header.freePlace=Free +table.header.graduate=$org.olat.group.ui.main\:table.header.graduate table.header.groups=Groups table.header.lastName=Last name table.header.lastTime=Last visit diff --git a/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java b/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java index 3f06d0113c62959560129a9b64ac1dc8f70a8575..8b4e6d73d47fff4f8ae4b5ec68010c511bb68043 100644 --- a/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java +++ b/src/main/java/org/olat/course/member/wizard/ImportMemberMailController.java @@ -40,6 +40,8 @@ import org.olat.group.manager.BusinessGroupMailing.MailType; import org.olat.group.model.BusinessGroupMembershipChange; import org.olat.group.ui.main.MemberPermissionChangeEvent; import org.olat.group.ui.wizard.BGMailTemplateController; +import org.olat.repository.RepositoryEntry; +import org.olat.repository.RepositoryMailing; /** * @@ -50,33 +52,46 @@ public class ImportMemberMailController extends StepFormBasicController { private MailTemplate mailTemplate; private final BGMailTemplateController mailTemplateForm; - public ImportMemberMailController(UserRequest ureq, WindowControl wControl, Form rootForm, StepsRunContext runContext) { + public ImportMemberMailController(UserRequest ureq, WindowControl wControl, RepositoryEntry repoEntry, + Form rootForm, StepsRunContext runContext) { super(ureq, wControl, rootForm, runContext, LAYOUT_CUSTOM, "mail_template"); - + MemberPermissionChangeEvent e = (MemberPermissionChangeEvent)runContext.get("permissions"); boolean mandatoryEmail = CoreSpringFactory.getImpl(BusinessGroupModule.class).isMandatoryEnrolmentEmail(ureq.getUserSession().getRoles()); if(mandatoryEmail) { - boolean includeParticipantsRights = hasParticipantRightsChanges(e); - if(!includeParticipantsRights) { - mandatoryEmail = false;//only mandatory for participants + boolean includeParticipantsOrTutorsRights = hasParticipantOrTutorsRightsChanges(e); + if(!includeParticipantsOrTutorsRights) { + mandatoryEmail = false;//only mandatory for participants and tutors } } - boolean customizing = e.size() == 1; - MailType defaultType = BusinessGroupMailing.getDefaultTemplateType(e); - if(defaultType != null && e.getGroups().size() == 1) { + MailType defaultGroupType = BusinessGroupMailing.getDefaultTemplateType(e); + RepositoryMailing.Type defaultRepoType = RepositoryMailing.getDefaultTemplateType(e); + + if(defaultGroupType != null && e.getGroups().size() == 1) { BusinessGroupShort group = e.getGroups().get(0); - mailTemplate = BusinessGroupMailing.getDefaultTemplate(defaultType, group, getIdentity()); + mailTemplate = BusinessGroupMailing.getDefaultTemplate(defaultGroupType, group, getIdentity()); + } else if(defaultRepoType != null) { + mailTemplate = RepositoryMailing.getDefaultTemplate(defaultRepoType, repoEntry, getIdentity()); + } else if(hasCouresRights(e)) { + mailTemplate = RepositoryMailing.createAddParticipantMailTemplate(repoEntry, getIdentity()); } else { - mailTemplate = new TestMailTemplate(); + mailTemplate = BusinessGroupMailing.getDefaultTemplate(MailType.addParticipant, null, getIdentity()); } - mailTemplateForm = new BGMailTemplateController(ureq, wControl, mailTemplate, false, customizing, false, mandatoryEmail, rootForm); + mailTemplateForm = new BGMailTemplateController(ureq, wControl, mailTemplate, false, true, false, mandatoryEmail, rootForm); initForm (ureq); } - private boolean hasParticipantRightsChanges(MemberPermissionChangeEvent e) { - if(e.getRepoParticipant() != null && e.getRepoParticipant().booleanValue()) { + private boolean hasCouresRights(MemberPermissionChangeEvent e) { + return ((e.getRepoOwner() != null && e.getRepoOwner().booleanValue()) + || (e.getRepoParticipant() != null && e.getRepoParticipant().booleanValue()) + || (e.getRepoTutor() != null && e.getRepoTutor().booleanValue())); + } + + private boolean hasParticipantOrTutorsRightsChanges(MemberPermissionChangeEvent e) { + if((e.getRepoParticipant() != null && e.getRepoParticipant().booleanValue()) + || (e.getRepoTutor() != null && e.getRepoTutor().booleanValue())){ return true; } @@ -85,6 +100,9 @@ public class ImportMemberMailController extends StepFormBasicController { if(change.getParticipant() != null && change.getParticipant().booleanValue()) { return true; } + if(change.getTutor() != null && change.getTutor().booleanValue()) { + return true; + } } return false; } diff --git a/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java b/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java index 1fd04e22e47b5f5660faefbcbd20d3e957a2bfb5..738d372194cd155a3650f069f86bc9e11a20af10 100644 --- a/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java +++ b/src/main/java/org/olat/course/member/wizard/ImportMember_3_ChoosePermissionStep.java @@ -43,7 +43,7 @@ public class ImportMember_3_ChoosePermissionStep extends BasicStep { super(ureq); this.group = group; this.repoEntry = repoEntry; - setNextStep(new ImportMember_4_MailStep(ureq)); + setNextStep(new ImportMember_4_MailStep(ureq, repoEntry)); setI18nTitleAndDescr("import.permission.title", "import.permission.title"); } diff --git a/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java b/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java index 2462129c9de1f6fcd7f320a7fc6e91c16e59423f..51696a78c3e5af0692d69842e1a02bdb884b1b69 100644 --- a/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java +++ b/src/main/java/org/olat/course/member/wizard/ImportMember_4_MailStep.java @@ -26,15 +26,19 @@ import org.olat.core.gui.control.generic.wizard.BasicStep; import org.olat.core.gui.control.generic.wizard.PrevNextFinishConfig; import org.olat.core.gui.control.generic.wizard.StepFormController; import org.olat.core.gui.control.generic.wizard.StepsRunContext; +import org.olat.repository.RepositoryEntry; /** * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class ImportMember_4_MailStep extends BasicStep { + + private final RepositoryEntry repoEntry; - public ImportMember_4_MailStep(UserRequest ureq) { + public ImportMember_4_MailStep(UserRequest ureq, RepositoryEntry repoEntry) { super(ureq); + this.repoEntry = repoEntry; setNextStep(NOSTEP); setI18nTitleAndDescr("import.mail.title", "import.mail.title"); } @@ -46,7 +50,7 @@ public class ImportMember_4_MailStep extends BasicStep { @Override public StepFormController getStepController(UserRequest ureq, WindowControl wControl, StepsRunContext runContext, Form form) { - ImportMemberMailController controller = new ImportMemberMailController(ureq, wControl, form, runContext); + ImportMemberMailController controller = new ImportMemberMailController(ureq, wControl, repoEntry, form, runContext); return controller; } } \ No newline at end of file diff --git a/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java b/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java index 60884b5c127aa188fc605ace542c5586618b60e8..144571901cf1b35c8344b6c49f5071de0c65b14e 100644 --- a/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java +++ b/src/main/java/org/olat/course/nodes/OpenMeetingsCourseNode.java @@ -82,6 +82,12 @@ public class OpenMeetingsCourseNode extends AbstractAccessableCourseNode { public void updateModuleConfigDefaults(boolean isNewNode) { // no update to default config necessary } + + @Override + protected String getDefaultTitleOption() { + // default is to only display content because the room has its own room title + return CourseNode.DISPLAY_OPTS_CONTENT; + } @Override public TabbableController createEditController(UserRequest ureq, WindowControl wControl, StackedController stackPanel, ICourse course, diff --git a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java index 0aecbd9379bc913f787578d9c475135395bd5a7b..6e394168e92da9fb8ee8762885fd665b4e201002 100644 --- a/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java +++ b/src/main/java/org/olat/course/nodes/ProjectBrokerCourseNode.java @@ -52,6 +52,7 @@ import org.olat.core.logging.Tracing; import org.olat.core.util.ExportUtil; import org.olat.core.util.FileUtils; import org.olat.core.util.Util; +import org.olat.core.util.WebappHelper; import org.olat.core.util.ZipUtil; import org.olat.course.ICourse; import org.olat.course.assessment.AssessmentManager; @@ -707,7 +708,7 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Assess if (dropboxDir.exists() || returnboxDir.exists() ){ // Create Temp Dir for zipping - String tmpDirPath = FolderConfig.getCanonicalTmpDir() + course.getCourseEnvironment().getCourseBaseContainer().getRelPath(); + String tmpDirPath = WebappHelper.getTmpDir() + course.getCourseEnvironment().getCourseBaseContainer().getRelPath(); File tmpDir = new File( tmpDirPath ); if (!tmpDir.exists()) { tmpDir.mkdirs(); @@ -731,7 +732,7 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Assess ExportUtil.writeContentToFile(tableExportFileName, projectBrokerTableExport, tmpDir, charset); // prepare zipping the node directory and the course results overview table - Set fileList = new HashSet(); + Set<String> fileList = new HashSet<String>(); // move xls file to tmp dir // TODO:ch 28.01.2010 : ProjectBroker does not support assessment-tool in V1.0 // fileList.add(fileName); @@ -799,8 +800,8 @@ public class ProjectBrokerCourseNode extends GenericCourseNode implements Assess // zip dataFound &= ZipUtil.zip(fileList, tmpDir, archiveDir, true); // Delete all temp files - FileUtils.deleteDirsAndFiles( tmpDir, true, true); } + FileUtils.deleteDirsAndFiles( tmpDir, true, true); } return dataFound; } diff --git a/src/main/java/org/olat/course/nodes/TACourseNode.java b/src/main/java/org/olat/course/nodes/TACourseNode.java index d0564ae381bf4ba1a419a07b258fbc89377a2291..b07822134640a1626cd577a90fd9b7f8e85a6e50 100644 --- a/src/main/java/org/olat/course/nodes/TACourseNode.java +++ b/src/main/java/org/olat/course/nodes/TACourseNode.java @@ -54,6 +54,7 @@ import org.olat.core.util.ExportUtil; import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; +import org.olat.core.util.WebappHelper; import org.olat.core.util.ZipUtil; import org.olat.course.ICourse; import org.olat.course.archiver.ScoreAccountingHelper; @@ -762,8 +763,8 @@ public class TACourseNode extends GenericCourseNode implements AssessableCourseN if (dropboxDir.exists() || solutionDir.exists() || returnboxDir.exists() || hasTask.booleanValue()){ // Create Temp Dir for zipping - String tmpDirPath = FolderConfig.getCanonicalTmpDir() + course.getCourseEnvironment().getCourseBaseContainer().getRelPath(); - File tmpDir = new File( tmpDirPath ); + String tmpDirPath = WebappHelper.getTmpDir() + course.getCourseEnvironment().getCourseBaseContainer().getRelPath(); + File tmpDir = new File(tmpDirPath); if (!tmpDir.exists()) { tmpDir.mkdirs(); @@ -866,13 +867,11 @@ public class TACourseNode extends GenericCourseNode implements AssessableCourseN fDropBoxArchiveDir.mkdir(); } File archiveDir = new File(fDropBoxArchiveDir, zipName); - - // zip dataFound &= ZipUtil.zip(fileList, tmpDir, archiveDir, true); // Delete all temp files - FileUtils.deleteDirsAndFiles( tmpDir, true, true); } + FileUtils.deleteDirsAndFiles( tmpDir, true, true); } return dataFound; } diff --git a/src/main/java/org/olat/course/nodes/cp/CPEditController.java b/src/main/java/org/olat/course/nodes/cp/CPEditController.java index 64463a4fdb9593a97592f766ac52e50495acfcd0..8e1b1bb272348dd0369f55657ac35e23de315178 100644 --- a/src/main/java/org/olat/course/nodes/cp/CPEditController.java +++ b/src/main/java/org/olat/course/nodes/cp/CPEditController.java @@ -33,7 +33,6 @@ import java.util.Map; import org.olat.basesecurity.BaseSecurityManager; import org.olat.basesecurity.Constants; -import org.olat.core.commons.fullWebApp.LayoutMain3ColsPreviewController; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.form.flexible.FormItemContainer; diff --git a/src/main/java/org/olat/course/nodes/en/EnrollmentManager.java b/src/main/java/org/olat/course/nodes/en/EnrollmentManager.java index 2010d66ae206565411e0c5a4de7f3904671cf2c0..02a0c41f8f57ba622df505693542908402b470dd 100644 --- a/src/main/java/org/olat/course/nodes/en/EnrollmentManager.java +++ b/src/main/java/org/olat/course/nodes/en/EnrollmentManager.java @@ -93,7 +93,7 @@ public class EnrollmentManager extends BasicManager { // and: why can't we just have a group here and a max participants count and an identity to enrol? // the group was chosen, so why do we need the groupNames and areaNames here??? - EnrollState state =businessGroupService.enroll(identity, roles, identity, group, null);//TODO memail + EnrollState state =businessGroupService.enroll(identity, roles, identity, group, null); if(state.isFailed()) { enrollStatus.setErrorMessage(trans.translate(state.getI18nErrorMessage())); } else { @@ -116,7 +116,7 @@ public class EnrollmentManager extends BasicManager { // 1. Remove group membership, fire events, do loggin etc. // Remove participant. This will also check if a waiting-list with auto-close-ranks is configurated // and move the users accordingly - businessGroupService.removeParticipants(identity, Collections.singletonList(identity), enrolledGroup, null);//TODO memail + businessGroupService.removeParticipants(identity, Collections.singletonList(identity), enrolledGroup, null); logInfo("doCancelEnrollment in group " + enrolledGroup, identity.getName()); logInfo("doCancelEnrollment in group " + enrolledGroup, identity.getName()); diff --git a/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java index 2d7c993ef06a7837f46f1419c705b91f9ba0b9f6..84967b07050c31a4e8be99607020c449f9f3ada3 100644 --- a/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java +++ b/src/main/java/org/olat/course/nodes/openmeetings/OpenMeetingsEditFormController.java @@ -77,6 +77,9 @@ public class OpenMeetingsEditFormController extends FormBasicController { this.courseNode = courseNode; this.courseTitle = courseTitle; this.defaultSettings = defaultSettings; + if(defaultSettings != null) { + defaultSettings.setName(courseNode.getShortTitle()); + } openMeetingsManager = CoreSpringFactory.getImpl(OpenMeetingsManager.class); try { @@ -91,7 +94,10 @@ public class OpenMeetingsEditFormController extends FormBasicController { @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + setFormTitle("pane.tab.vcconfig"); setFormDescription("create.room.desc"); + setFormContextHelp(OpenMeetingsRoomEditController.class.getPackage().getName(), "room.html", "help.hover.openmeetings.room"); + if(serverDown) { setFormWarning(errorKey); } @@ -121,7 +127,7 @@ public class OpenMeetingsEditFormController extends FormBasicController { roomNameEl.setValue(hasRoom ? room.getName() : ""); roomNameEl.setVisible(hasRoom); if(hasRoom) { - String typeStr = translate(RoomType.values()[(int)room.getType()].i18nKey()); + String typeStr = translate(RoomType.getType(room.getType()).i18nKey()); roomTypeEl.setValue(typeStr); } else { roomTypeEl.setValue(""); diff --git a/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..ab8cb7af099308e1eb4bda93011f115a1b7c0454 --- /dev/null +++ b/src/main/java/org/olat/course/nodes/openmeetings/_i18n/LocalStrings_en.properties @@ -0,0 +1,12 @@ +#Tue Dec 18 17:54:01 CET 2012 +condition.accessibility.title=Access +create.room=Create room +create.room.desc=To be able to publish this OpenMeetings course element and work in virtual meetings you first have to create and configure an OpenMeetings room. Select the button below to start with this process. +edit.room=Change room parameters +error.vmsNotAvailable=$org.olat.modules.openmeetings.ui\:error.notAvailable +guestnoaccess.message=$org.olat.course.nodes\:guestnoaccess.message +guestnoaccess.title=$org.olat.course.nodes\:guestnoaccess.title +pane.tab.accessibility=Access +pane.tab.vcconfig=Room +table.empty=$org.olat.modules.openmeetings.ui\:table.empty +title_vc=OpenMeetings diff --git a/src/main/java/org/olat/course/nodes/projectbroker/ProjectBrokerCourseEditorController.java b/src/main/java/org/olat/course/nodes/projectbroker/ProjectBrokerCourseEditorController.java index 63f31ab63241f5f30bcf19fc745cb9f175e04a6a..7aca8cc362d1984154fa2b226d5e510eaeb2cf43 100644 --- a/src/main/java/org/olat/course/nodes/projectbroker/ProjectBrokerCourseEditorController.java +++ b/src/main/java/org/olat/course/nodes/projectbroker/ProjectBrokerCourseEditorController.java @@ -189,7 +189,6 @@ public class ProjectBrokerCourseEditorController extends ActivateableTabbableDef String groupDescription = translate("account.manager.groupdescription", node.getShortTitle()); accountManagerGroup = ProjectBrokerManagerFactory.getProjectGroupManager().getAccountManagerGroupFor(cpm, node, course, groupName, groupDescription, ureq.getIdentity()); if (accountManagerGroup != null) { - //TODO memail accountManagerGroupController = new GroupController(ureq, getWindowControl(), true, false, true, false, true, false, accountManagerGroup.getPartipiciantGroup()); listenTo(accountManagerGroupController); // add mail templates used when adding and removing users @@ -302,7 +301,7 @@ public class ProjectBrokerCourseEditorController extends ActivateableTabbableDef if (event instanceof IdentitiesAddEvent) { IdentitiesAddEvent identitiesAddedEvent = (IdentitiesAddEvent)event; BusinessGroupAddResponse response = businessGroupService.addParticipants(urequest.getIdentity(), urequest.getUserSession().getRoles(), - identitiesAddedEvent.getAddIdentities(), accountManagerGroup, null);//TODO memail + identitiesAddedEvent.getAddIdentities(), accountManagerGroup, null); identitiesAddedEvent.setIdentitiesAddedEvent(response.getAddedIdentities()); identitiesAddedEvent.setIdentitiesWithoutPermission(response.getIdentitiesWithoutPermission()); identitiesAddedEvent.setIdentitiesAlreadyInGroup(response.getIdentitiesAlreadyInGroup()); diff --git a/src/main/java/org/olat/course/nodes/projectbroker/ProjectGroupController.java b/src/main/java/org/olat/course/nodes/projectbroker/ProjectGroupController.java index adb0306903bf93f3ec38e3bece4ad538830f226f..60580fdeccbf41d55d8ea05328ec1229937a4c47 100644 --- a/src/main/java/org/olat/course/nodes/projectbroker/ProjectGroupController.java +++ b/src/main/java/org/olat/course/nodes/projectbroker/ProjectGroupController.java @@ -87,13 +87,11 @@ public class ProjectGroupController extends BasicController { VelocityContainer myContent = createVelocityContainer("projectgroup_management"); // Project Leader Management - //TODO memail projectLeaderController = new GroupController(ureq, getWindowControl(), true, true, true, false, true, false, project.getProjectLeaderGroup()); listenTo(projectLeaderController); myContent.put("projectLeaderController", projectLeaderController.getInitialComponent()); // Project Member Management - //TODO memail projectMemberController = new GroupController(ureq, getWindowControl(), true, false, true, false, true, false, project.getProjectParticipantGroup()); listenTo(projectMemberController); myContent.put("projectMemberController", projectMemberController.getInitialComponent()); @@ -105,7 +103,6 @@ public class ProjectGroupController extends BasicController { // Project Candidates Management if (projectBrokerModuleConfiguration.isAcceptSelectionManually()) { - //TODO memail projectCandidatesController = new WaitingGroupController(ureq, getWindowControl(), true, false, true, true, false, project.getCandidateGroup()); listenTo(projectCandidatesController); myContent.contextPut("isProjectCandidatesListEmpty", ProjectBrokerManagerFactory.getProjectGroupManager().isCandidateListEmpty(project.getCandidateGroup()) ); @@ -186,7 +183,7 @@ public class ProjectGroupController extends BasicController { if (event instanceof IdentitiesAddEvent) { IdentitiesAddEvent identitiesAddedEvent = (IdentitiesAddEvent)event; BusinessGroupAddResponse response = businessGroupService.addParticipants(urequest.getIdentity(), urequest.getUserSession().getRoles(), - identitiesAddedEvent.getAddIdentities(), project.getProjectGroup(), null);//TODO memail + identitiesAddedEvent.getAddIdentities(), project.getProjectGroup(), null); identitiesAddedEvent.setIdentitiesAddedEvent(response.getAddedIdentities()); identitiesAddedEvent.setIdentitiesWithoutPermission(response.getIdentitiesWithoutPermission()); identitiesAddedEvent.setIdentitiesAlreadyInGroup(response.getIdentitiesAlreadyInGroup()); @@ -202,7 +199,7 @@ public class ProjectGroupController extends BasicController { private void handleProjectLeaderGroupEvent(UserRequest urequest, Event event) { if (event instanceof IdentitiesAddEvent) { IdentitiesAddEvent identitiesAddedEvent = (IdentitiesAddEvent)event; - BusinessGroupAddResponse response = businessGroupService.addOwners(urequest.getIdentity(), identitiesAddedEvent.getAddIdentities(), project.getProjectGroup()); + BusinessGroupAddResponse response = businessGroupService.addOwners(urequest.getIdentity(), urequest.getUserSession().getRoles(), identitiesAddedEvent.getAddIdentities(), project.getProjectGroup(), null); identitiesAddedEvent.setIdentitiesAddedEvent(response.getAddedIdentities()); identitiesAddedEvent.setIdentitiesWithoutPermission(response.getIdentitiesWithoutPermission()); identitiesAddedEvent.setIdentitiesAlreadyInGroup(response.getIdentitiesAlreadyInGroup()); diff --git a/src/main/java/org/olat/course/nodes/projectbroker/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/projectbroker/_i18n/LocalStrings_en.properties index cc68cbcb1c2fa4910fcc09674264e15d27b9dfdb..8e550447f619ec2d08d2648cb2fdebcc33a6fcd1 100644 --- a/src/main/java/org/olat/course/nodes/projectbroker/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/projectbroker/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Thu Sep 08 17:28:43 CEST 2011 +#Tue Dec 18 17:54:04 CET 2012 ENROLLMENT_EVENT=Registration date HANDOUT_EVENT=Due date account.manager.groupdescription=Administrator of $\:chelp.projectbroker.themenboerse <i>{0}</i>, created automatically. @@ -118,10 +118,9 @@ export.header.selectedplaces=Vacancies export.header.title=$\:chelp.projectbroker.themaSg form.accountmanagement.no.account.manager.group=No topic authors available. form.accountmanagement.title=Administer topic authors +form.error.project.filenametoolong=Filename has to many characters (max 100). form.error.project.title.already.exist=A topic with this title already exists. form.error.project.title.is.empty=This title is mandatory. -form.error.project.filenametoolong=Filename has to many characters (max 100). - form.modules.dropbox=Drop box form.modules.returnbox=Return box form.modules.scoring=Assessment diff --git a/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java b/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java index 137ed01e6a54348d0e3b57723ad5bba395d4971e..7158c555b6c7668d2a06dccf698787be00cc9e69 100644 --- a/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java +++ b/src/main/java/org/olat/course/nodes/projectbroker/service/ProjectGroupManagerImpl.java @@ -247,8 +247,7 @@ public class ProjectGroupManagerImpl extends BasicManager implements ProjectGrou final Project reloadedProject = (Project) DBFactory.getInstance().loadObject(project, true); final BusinessGroupAddResponse response = new BusinessGroupAddResponse(); final BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); - //TODO memail - BusinessGroupAddResponse state = bgs.addParticipants(actionIdentity, null, identities, reloadedProject.getProjectGroup(), null);//TODO memail + BusinessGroupAddResponse state = bgs.addParticipants(actionIdentity, null, identities, reloadedProject.getProjectGroup(), null); response.getAddedIdentities().addAll(state.getAddedIdentities()); response.getIdentitiesAlreadyInGroup().addAll(state.getAddedIdentities()); diff --git a/src/main/java/org/olat/course/nodes/scorm/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/scorm/_i18n/LocalStrings_en.properties index 974f1952becab7484627fb861f1a5987b74740d3..31fa6ab9f0b12a5f47e59daeab99bd4a0690c3b7 100644 --- a/src/main/java/org/olat/course/nodes/scorm/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/scorm/_i18n/LocalStrings_en.properties @@ -1,5 +1,13 @@ -#Fri Jan 21 15:20:51 CET 2011 +#Tue Dec 18 17:55:14 CET 2012 +advance.score.label=Prevent subsequent attempts from decreasing score assessable.label=Transfer score from SCORM +assessable.type.none=Don't transfer scoring information +assessable.type.passed=Transfer passed value +assessable.type.score=Transfer score value +attempts.depends.label=Count attempts only if score is transfered +attempts.label=Max number of attempts +attempts.max.reached=Maximum number of attempts are reached. +attempts.noLimit=unlimited attempts.nomoreattempts=There are no more attempts at your disposal. attempts.yourattempts=Number of attempts chelp.auto=<i>$org.olat.course.nodes.scorm\:height.auto</i> @@ -16,6 +24,11 @@ chelp.sco2=First create your SCORM module in learning resources. Then click on t chelp.sco3=If you have already added a $\:chelp.sco its file name will appear in this field as well as the button $\:chelp.prevSco on the above right. chelp.sco4=You have now the possibility to choose another ZIP file using the button $\:chelp.chanSco chelp.set1=Determine if there should be a navigation menu on the left along with your SCORM packet. +chelp.set10=Check this box if you want OpenOLAT to be hidden while the SCORM module is active. +chelp.set11=Check this box if the SCORM module should automatically close when it's finished, returning the participant to the course. +chelp.set12=If this box is checked, a score already achieved will not be decreased by further attempts. +chelp.set13=By means of the drop-down menu the number of attempts available can be limited. +chelp.set14=Check this box if OpenOLAT has problems correctly displaying the SCORM content. If this compatibility mode is enabled, you need to manually set the window height. chelp.set2=Determine if it should be possible to navigate via the back and forward buttons within your SCORM content. chelp.set3=By means of the drop-down menu you can determine the height of your SCORM pages. chelp.set4=You have the possibility to set them via $\:chelp.auto to the respective window height or to a certain value of your choice. @@ -24,12 +37,8 @@ chelp.set6=Determine an integer to indicate your minimum score for passing that chelp.set7=OLAT tries to detect a character set automatically. If the option "Automatic" is not successful it is possible to configure the content coding by means of a predefined character set (should there be no coding the character set ISO-8899-1 will be used by default). chelp.set8=This permits the coding of Javascript by means of a predefined character set (by default the same set will be used for content and Javascript). chelp.set9=Determine if the SCORM learning content should launch automatically if the corresponding menu-node is selected within the course. If you do not select this option, a start-page is displayed instead. -chelp.set10=Check this box if you want OpenOLAT to be hidden while the SCORM module is active. -chelp.set11=Check this box if the SCORM module should automatically close when it's finished, returning the participant to the course. -chelp.set12=If this box is checked, a score already achieved will not be decreased by further attempts. -chelp.set13=By means of the drop-down menu the number of attempts available can be limited. -chelp.set14=Check this box if OpenOLAT has problems correctly displaying the SCORM content. If this compatibility mode is enabled, you need to manually set the window height. chosencp=Selected SCORM learning content +closeonfinish.label=Close module automatically on finish command.changecp=Replace SCORM learning content command.choosecp=Choose SCORM learning content command.closecp=Close view @@ -39,8 +48,6 @@ command.showscorm=Show SCORM learning content condition.accessibility.title=Access cutvalue.label=Score needed to pass cutvalue.validation=Please enter an integer -rawcontent.height.error=If "$\:rawcontent.label" is set, you need to specify the height of the window -rawcontent.label=Raw content encoding.auto=Automatically encoding.content=Content character set encoding.js=Javascript character set @@ -53,12 +60,11 @@ form.scormmode=Display of SCORM learning content form.scormmode.browse=Navigate form.scormmode.nocredit=No scoring form.scormmode.normal=Normal +fullwindow.label=Display only module, hide LMS header=Choose SCORM learning content headerform=Settings height.auto=Automatic height.label=Display height -fullwindow.label=Display only module, hide LMS -closeonfinish.label=Close module automatically on finish help.hover.scorm-filename=Help to select a SCORM learning content help.hover.scorm-settings-filename=Help to set SCORM settings no.cp.chosen=<i>No SCORM learning content selected</i> @@ -67,16 +73,11 @@ pane.tab.cpconfig=Learning content passed.no=Failed passed.yes=Passed passed.yourpassed=Status +rawcontent.height.error=If "$\:rawcontent.label" is set, you need to specify the height of the window +rawcontent.label=Raw content score.noscoreinfoyet=There is no score available for this SCORM object since you have never used it before. score.title=Score score.yourscore=Score achieved showmenu.label=Show menu -skiplaunchpage.label=Skip launch page shownavbuttons.label=Show navigation buttons -# <OLATCE-289> -advance.score.label = Prevent subsequent attempts from decreasing score -attempts.depends.label = Count attempts only if score is transfered -attempts.label = Max number of attempts -attempts.noLimit = unlimited -attempts.max.reached = Maximum number of attempts are reached. -# </OLATCE-289> \ No newline at end of file +skiplaunchpage.label=Skip launch page diff --git a/src/main/java/org/olat/course/nodes/tu/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/course/nodes/tu/_i18n/LocalStrings_en.properties index 164ae0cd7870098b1886ecc5329f487202a479f4..c9b835631105d82283b24ddf352d5a7f81c758b7 100644 --- a/src/main/java/org/olat/course/nodes/tu/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/course/nodes/tu/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Sun Jan 23 15:55:00 CET 2011 +#Tue Dec 18 17:54:50 CET 2012 TUConfigForm.invalidurl=Please enter a valid URL. TUConfigForm.pass=Password TUConfigForm.protected=Page pass-word controlled @@ -31,7 +31,6 @@ command.closetu=Close window command.preview=Show preview command.show=Show learning content command.showpopup=Show learning content in new window -preview=Preview condition.accessibility.title=Access description.label=Configure display description.preamble=Please select how your content should be presented.<br /><br />The contents' security level drops top down as the acceptability of certain design elements (frames, CSS, Javascript, etc.) increases. @@ -47,3 +46,4 @@ option.tunnel.iframe.label=Embedded (source hidden) option.tunnel.inline.label=Integrated completely (source hidden) pane.tab.accessibility=Access pane.tab.tuconfig=Page content +preview=Preview diff --git a/src/main/java/org/olat/course/repository/CreateNewCourseController.java b/src/main/java/org/olat/course/repository/CreateNewCourseController.java index 755b4486a06adda1cf5d3ffaa698f8bb30a5d212..012ce472cf88f5051dda738dc1841d384cf62e90 100644 --- a/src/main/java/org/olat/course/repository/CreateNewCourseController.java +++ b/src/main/java/org/olat/course/repository/CreateNewCourseController.java @@ -38,6 +38,7 @@ 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.olat.core.util.WebappHelper; import org.olat.course.CourseFactory; import org.olat.course.CourseModule; import org.olat.course.ICourse; @@ -163,7 +164,7 @@ public class CreateNewCourseController extends BasicController implements IAddCo CourseGroupManager sourceCgm = sourceCourse.getCourseEnvironment().getCourseGroupManager(); CourseEnvironmentMapper env = PersistingCourseGroupManager.getInstance(sourceCourse).getBusinessGroupEnvironment(); - File fExportDir = new File(System.getProperty("java.io.tmpdir"), UUID.randomUUID().toString()); + File fExportDir = new File(WebappHelper.getTmpDir(), UUID.randomUUID().toString()); fExportDir.mkdirs(); sourceCgm.exportCourseBusinessGroups(fExportDir, env, false); diff --git a/src/main/java/org/olat/course/statistic/ExportManager.java b/src/main/java/org/olat/course/statistic/ExportManager.java index 9b85ba4e5db72c881fe4eb9416cc6d07ad547e58..8ec2f7615889fdc9bad4911680da752247194769 100644 --- a/src/main/java/org/olat/course/statistic/ExportManager.java +++ b/src/main/java/org/olat/course/statistic/ExportManager.java @@ -36,18 +36,18 @@ import javax.mail.MessagingException; import javax.mail.SendFailedException; import javax.mail.internet.AddressException; -import org.olat.core.commons.modules.bc.FolderConfig; -import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; import org.olat.core.gui.translator.PackageTranslator; import org.olat.core.gui.translator.Translator; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.manager.BasicManager; import org.olat.core.util.ExportUtil; +import org.olat.core.util.WebappHelper; import org.olat.core.util.ZipUtil; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.mail.Emailer; import org.olat.core.util.vfs.LocalFileImpl; +import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; @@ -136,8 +136,8 @@ public class ExportManager extends BasicManager { String zipName = ExportUtil.createFileNameWithTimeStamp(ExportManager.COURSE_LOG_FILES, "zip"); Date date = new Date(); String tmpDirName = oresID + "-" + date.getTime(); - final VFSContainer tmpDirVFSContainer = new OlatRootFolderImpl(new File(FolderConfig.getRelativeTmpDir(), tmpDirName).getPath(), null); - final File tmpDir = new File(new File(FolderConfig.getCanonicalRoot(), FolderConfig.getRelativeTmpDir()), tmpDirName); + final VFSContainer tmpDirVFSContainer = new LocalFolderImpl(new File(WebappHelper.getTmpDir(), tmpDirName)); + final File tmpDir = new File(WebappHelper.getTmpDir(), tmpDirName); List<VFSItem> logFiles = new ArrayList<VFSItem>(); if (adminLog) { diff --git a/src/main/java/org/olat/group/BusinessGroupModule.java b/src/main/java/org/olat/group/BusinessGroupModule.java index c1680d7fa3d8c92bc7df30414246518112da487d..281c53bccfef1deca6ed9158157a6bbe276d98a6 100644 --- a/src/main/java/org/olat/group/BusinessGroupModule.java +++ b/src/main/java/org/olat/group/BusinessGroupModule.java @@ -279,8 +279,8 @@ public class BusinessGroupModule extends AbstractOLATModule { return mandatoryEnrolmentEmailForGroupmanagers; } - public void setMandatoryEnrolmentEmailForGroupmanagers(boolean mandatory) { - setStringProperty(MANDATORY_ENROLMENT_EMAIL_GROUPMANAGERS, Boolean.toString(mandatory), true); + public void setMandatoryEnrolmentEmailForGroupmanagers(String mandatory) { + setStringProperty(MANDATORY_ENROLMENT_EMAIL_GROUPMANAGERS, mandatory, true); } public String getMandatoryEnrolmentEmailForAdministrators() { @@ -347,7 +347,7 @@ public class BusinessGroupModule extends AbstractOLATModule { return acceptMembershipForAdministrators; } - public void setAcceptMembershipForAdministrators(boolean mandatory) { - setStringProperty(ACCEPT_MEMBERSHIP_ADMINISTRATORS, Boolean.toString(mandatory), true); + public void setAcceptMembershipForAdministrators(String mandatory) { + setStringProperty(ACCEPT_MEMBERSHIP_ADMINISTRATORS, mandatory, true); } } \ No newline at end of file diff --git a/src/main/java/org/olat/group/BusinessGroupService.java b/src/main/java/org/olat/group/BusinessGroupService.java index e7bcfbceb7a3924f6b474774d133d9dddffaf26d..d99a3145135880f32334c3e9c5b14dbb2348c80d 100644 --- a/src/main/java/org/olat/group/BusinessGroupService.java +++ b/src/main/java/org/olat/group/BusinessGroupService.java @@ -41,6 +41,7 @@ import org.olat.group.model.SearchBusinessGroupParams; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryEntryShort; import org.olat.resource.OLATResource; +import org.olat.resource.accesscontrol.model.ResourceReservation; /** * @@ -333,7 +334,8 @@ public interface BusinessGroupService { * @param flags * @return */ - public BusinessGroupAddResponse addOwners(Identity ureqIdentity, List<Identity> addIdentities, BusinessGroup group); + public BusinessGroupAddResponse addOwners(Identity ureqIdentity, Roles ureqRoles, List<Identity> addIdentities, + BusinessGroup group, MailPackage mailing); /** * Remove a list of users from a group as owner and does all the magic that needs to be @@ -379,10 +381,13 @@ public interface BusinessGroupService { /** * - * @param identity + * @param ureqIdentity + * @param reservationOwner * @param resource */ - public void acceptPendingParticipation(Identity ureqIdentity, Identity identity, OLATResource resource); + public void acceptPendingParticipation(Identity ureqIdentity, Identity reservationOwner, OLATResource resource); + + public void cancelPendingParticipation(Identity ureqIdentity, ResourceReservation reservation); /** * Remove a list of users from a group as participant and does all the magic that needs diff --git a/src/main/java/org/olat/group/manager/BusinessGroupMailing.java b/src/main/java/org/olat/group/manager/BusinessGroupMailing.java index 47145e8560ef05bf1e9717fabbf0b485af46d16a..d7f86a821f7dbd38cbc15702517f0cfc5f61c8c3 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupMailing.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupMailing.java @@ -46,7 +46,9 @@ public class BusinessGroupMailing { List<BusinessGroupMembershipChange> changes = event.getGroupChanges(); if(changes.size() == 1) { BusinessGroupMembershipChange change = changes.get(0); - if(change.getParticipant() != null) { + if(change.getTutor() != null) { + return MailType.addCoach; + } else if(change.getParticipant() != null) { return MailType.addParticipant; } else if (change.getWaitingList() != null) { return MailType.addToWaitingList; @@ -63,7 +65,7 @@ public class BusinessGroupMailing { if(total == 1) { if(mod.getAddOwners().size() == 1) { - return null;//no template for owner + return MailType.addCoach; } else if(mod.getAddParticipants().size() == 1) { return MailType.addParticipant; } else if(mod.getAddToWaitingList().size() == 1) { @@ -81,6 +83,10 @@ public class BusinessGroupMailing { return BGMailHelper.createAddParticipantMailTemplate(group, ureqIdentity); case removeParticipant: return BGMailHelper.createRemoveParticipantMailTemplate(group, ureqIdentity); + case addCoach: + return BGMailHelper.createAddParticipantMailTemplate(group, ureqIdentity); + case removeCoach: + return BGMailHelper.createRemoveParticipantMailTemplate(group, ureqIdentity); case addToWaitingList: return BGMailHelper.createAddWaitinglistMailTemplate(group, ureqIdentity); case removeToWaitingList: @@ -117,6 +123,8 @@ public class BusinessGroupMailing { public enum MailType { addParticipant, removeParticipant, + addCoach, + removeCoach, addToWaitingList, removeToWaitingList, graduateFromWaitingListToParticpant, diff --git a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java index 363af040fb55b94e75991aceb398dde12fd336f8..a7a2f1e6fc432a2f5c520d085fa91cda3dec17e1 100644 --- a/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java +++ b/src/main/java/org/olat/group/manager/BusinessGroupServiceImpl.java @@ -237,6 +237,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD //auto rank if possible autoRankCheck(ureqIdentity, bg, previousMaxParticipants); BusinessGroup updatedGroup = businessGroupDAO.merge(bg); + return updatedGroup; } @@ -501,7 +502,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD } for(Identity newOwner:newOwners) { - addOwner(newOwner, targetGroup); + addOwner(ureqIdentity, ureqRoles, newOwner, targetGroup, mailing); } for(Identity newParticipant:newParticipants) { addParticipant(ureqIdentity, ureqRoles, newParticipant, targetGroup, mailing); @@ -509,7 +510,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD for(Identity newWaiter:newWaiters) { addToWaitingList(ureqIdentity, newWaiter, targetGroup, mailing); } - + for(BusinessGroup group:groupsToMerge) { deleteBusinessGroup(group); } @@ -527,7 +528,6 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD private void updateMembers(Identity ureqIdentity, Roles ureqRoles, MembershipModification membersMod, BusinessGroup group, MailPackage mailing) { - group = businessGroupDAO.loadForUpdate(group.getKey()); List<Identity> currentOwners = securityManager.getIdentitiesOfSecurityGroup(group.getOwnerGroup()); @@ -536,7 +536,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD for(Identity owner:membersMod.getAddOwners()) { if(!currentOwners.contains(owner)) { - addOwner(owner, group); + addOwner(ureqIdentity, ureqRoles, owner, group, mailing); } } for(Identity participant:membersMod.getAddParticipants()) { @@ -622,7 +622,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD removeFromWaitingList(ureqIdentity, id, group, mailing); } for(Identity id:changesWrapper.addTutors) { - addOwner(id, group); + addOwner(ureqIdentity, ureqRoles, id, group, mailing); } for(Identity id:changesWrapper.removeTutors) { removeOwner(ureqIdentity, id, group); @@ -775,6 +775,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD // delete the publisher attached to this group (e.g. the forum and folder // publisher) notificationsManager.deletePublishersOf(group); + log.audit("Deleted Business Group", group.toString()); } catch(DBRuntimeException dbre) { Throwable th = dbre.getCause(); @@ -841,13 +842,14 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD } @Override - public BusinessGroupAddResponse addOwners(Identity ureqIdentity, List<Identity> addIdentities, BusinessGroup group) { + public BusinessGroupAddResponse addOwners(Identity ureqIdentity, Roles ureqRoles, List<Identity> addIdentities, + BusinessGroup group, MailPackage mailing) { BusinessGroupAddResponse response = new BusinessGroupAddResponse(); for (Identity identity : addIdentities) { group = loadBusinessGroup(group); // reload business group if (securityManager.isIdentityPermittedOnResourceable(identity, Constants.PERMISSION_HASROLE, Constants.ORESOURCE_GUESTONLY)) { response.getIdentitiesWithoutPermission().add(identity); - } else if(addOwner(identity, group)) { + } else if(addOwner(ureqIdentity, ureqRoles, identity, group, mailing)) { response.getAddedIdentities().add(identity); log.audit("added identity '" + identity.getName() + "' to securitygroup with key " + group.getOwnerGroup().getKey()); } else { @@ -857,18 +859,46 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD return response; } - private boolean addOwner(Identity identity, BusinessGroup group) { - if (!securityManager.isIdentityInSecurityGroup(identity, group.getOwnerGroup())) { - securityManager.addIdentityToSecurityGroup(identity, group.getOwnerGroup()); - // notify currently active users of this business group - BusinessGroupModifiedEvent.fireModifiedGroupEvents(BusinessGroupModifiedEvent.IDENTITY_ADDED_EVENT, group, identity); - // do logging - ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_ADDED, getClass(), LoggingResourceable.wrap(group), LoggingResourceable.wrap(identity)); + private boolean addOwner(Identity ureqIdentity, Roles ureqRoles, Identity identityToAdd, BusinessGroup group, MailPackage mailing) { + if (!securityManager.isIdentityInSecurityGroup(identityToAdd, group.getOwnerGroup())) { + boolean mustAccept = true; + if(ureqIdentity != null && ureqIdentity.equals(identityToAdd)) { + mustAccept = false;//adding itself, we hope that he knows what he makes + } else if(ureqRoles == null || ureqIdentity == null) { + mustAccept = false;//administrative task + } else { + mustAccept = groupModule.isAcceptMembership(ureqRoles); + } + + if(mustAccept) { + ResourceReservation olderReservation = reservationDao.loadReservation(identityToAdd, group.getResource()); + if(olderReservation == null) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MONTH, 6); + Date expiration = cal.getTime(); + ResourceReservation reservation = + reservationDao.createReservation(identityToAdd, "group_coach", expiration, group.getResource()); + if(reservation != null) { + BusinessGroupMailing.sendEmail(ureqIdentity, identityToAdd, group, MailType.addCoach, mailing, mailer); + } + } + } else { + internalAddCoach(identityToAdd, group); + BusinessGroupMailing.sendEmail(ureqIdentity, identityToAdd, group, MailType.addCoach, mailing, mailer); + } return true; } return false; } + private void internalAddCoach(Identity identityToAdd, BusinessGroup group) { + securityManager.addIdentityToSecurityGroup(identityToAdd, group.getOwnerGroup()); + // notify currently active users of this business group + BusinessGroupModifiedEvent.fireModifiedGroupEvents(BusinessGroupModifiedEvent.IDENTITY_ADDED_EVENT, group, identityToAdd); + // do logging + ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_ADDED, getClass(), LoggingResourceable.wrap(group), LoggingResourceable.wrap(identityToAdd)); + } + private boolean addParticipant(Identity ureqIdentity, Roles ureqRoles, Identity identityToAdd, BusinessGroup group, MailPackage mailing) { @@ -895,7 +925,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD } } } else { - internalAddParticipant(ureqIdentity, identityToAdd, group); + internalAddParticipant(identityToAdd, group); BusinessGroupMailing.sendEmail(ureqIdentity, identityToAdd, group, MailType.addParticipant, mailing, mailer); } return true; @@ -911,9 +941,9 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD * @param group * @param syncIM */ - private void internalAddParticipant(Identity ureqIdentity, Identity identityToAdd, BusinessGroup group) { + private void internalAddParticipant(Identity identityToAdd, BusinessGroup group) { securityManager.addIdentityToSecurityGroup(identityToAdd, group.getPartipiciantGroup()); - + // notify currently active users of this business group BusinessGroupModifiedEvent.fireModifiedGroupEvents(BusinessGroupModifiedEvent.IDENTITY_ADDED_EVENT, group, identityToAdd); // do logging @@ -938,18 +968,37 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD response.getIdentitiesAlreadyInGroup().add(identity); } } + return response; } + + @Override + @Transactional + public void cancelPendingParticipation(Identity ureqIdentity, ResourceReservation reservation) { + if(reservation != null && "BusinessGroup".equals(reservation.getResource().getResourceableTypeName())) { + BusinessGroup group = businessGroupDAO.loadForUpdate(reservation.getResource().getResourceableId()); + transferFirstIdentityFromWaitingToParticipant(ureqIdentity, group, null); + } + } @Override @Transactional - public void acceptPendingParticipation(Identity ureqIdentity, Identity identityToAdd, OLATResource resource) { - ResourceReservation reservation = acService.getReservation(identityToAdd, resource); + public void acceptPendingParticipation(Identity ureqIdentity, Identity reservationOwner, OLATResource resource) { + ResourceReservation reservation = acService.getReservation(reservationOwner, resource); if(reservation != null && "BusinessGroup".equals(resource.getResourceableTypeName())) { BusinessGroup group = businessGroupDAO.loadForUpdate(resource.getResourceableId()); - if(!securityManager.isIdentityInSecurityGroup(identityToAdd, group.getPartipiciantGroup())) { - internalAddParticipant(ureqIdentity, identityToAdd, group); + + String type = reservation.getType(); + if("group_coach".equals(type)) { + if(!securityManager.isIdentityInSecurityGroup(reservationOwner, group.getOwnerGroup())) { + internalAddCoach(reservationOwner, group); + } + } else if("group_participant".equals(type)) { + if(!securityManager.isIdentityInSecurityGroup(reservationOwner, group.getPartipiciantGroup())) { + internalAddParticipant(reservationOwner, group); + } } + reservationDao.deleteReservation(reservation); } } @@ -1170,6 +1219,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD response.getIdentitiesAlreadyInGroup().add(identity); } } + return response; } @@ -1221,7 +1271,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD enrollStatus.setEnrolled(BGMembership.participant); log.info("doEnroll (reservation) - setIsEnrolled ", identity.getName()); if(reservation != null) { - acService.removeReservation(reservation); + reservationDao.deleteReservation(reservation); } } else if (reloadedGroup.getMaxParticipants() != null) { int participantsCounter = securityManager.countIdentitiesOfSecurityGroup(reloadedGroup.getPartipiciantGroup()); @@ -1255,6 +1305,13 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD return enrollStatus; } + /** + * Don't forget to lock the business group before calling this method. + * @param ureqIdentity + * @param group + * @param mailing + * @param syncIM + */ private void transferFirstIdentityFromWaitingToParticipant(Identity ureqIdentity, BusinessGroup group, MailPackage mailing) { @@ -1300,14 +1357,12 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD } } } - } else { - log.warn("Called method transferFirstIdentityFromWaitingToParticipant but waiting-list or autoCloseRanks is disabled."); } } private void removeOwner(Identity ureqIdentity, Identity identityToRemove, BusinessGroup group) { securityManager.removeIdentityFromSecurityGroup(identityToRemove, group.getOwnerGroup()); - + //remove subsciptions if user gets removed removeSubscriptions(identityToRemove, group); @@ -1446,7 +1501,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD int count = 0; List<BusinessGroup> groups = null;//load only if needed - if(coaches) { + if(coaches && entry.getTutorGroup() != null) { List<Identity> repoTutorList = securityManager.getIdentitiesOfSecurityGroup(entry.getTutorGroup()); if(!repoTutorList.isEmpty()) { SearchBusinessGroupParams params = new SearchBusinessGroupParams(); @@ -1465,7 +1520,7 @@ public class BusinessGroupServiceImpl implements BusinessGroupService, UserDataD } } - if(participants) { + if(participants && entry.getParticipantGroup() != null) { List<Identity> repoParticipantList = securityManager.getIdentitiesOfSecurityGroup(entry.getParticipantGroup()); if(!repoParticipantList.isEmpty()) { diff --git a/src/main/java/org/olat/group/ui/BGMailHelper.java b/src/main/java/org/olat/group/ui/BGMailHelper.java index f4532af14c033a99891d127511774141d80e1834..9b7b4cf3bf8abc5016ec134b68fddcfa8098457d 100644 --- a/src/main/java/org/olat/group/ui/BGMailHelper.java +++ b/src/main/java/org/olat/group/ui/BGMailHelper.java @@ -58,7 +58,7 @@ import org.olat.repository.RepositoryEntryShort; public class BGMailHelper { /** - * The mail templated when adding users to a group. The method chooses + * The mail template when adding users to a group. The method chooses * automatically the right translator for the given group type to customize * the template text * @@ -73,7 +73,7 @@ public class BGMailHelper { } /** - * The mail templated when removing users from a group. The method chooses + * The mail template when removing users from a group. The method chooses * automatically the right translator for the given group type to customize * the template text * @@ -88,7 +88,7 @@ public class BGMailHelper { } /** - * The mail templated when deleting a whole group. The method chooses + * The mail template when deleting a whole group. The method chooses * automatically the right translator for the given group type to customize * the template text * @@ -103,7 +103,7 @@ public class BGMailHelper { } /** - * The mail templated when a user added himself to a group. The method chooses + * The mail template when a user added himself to a group. The method chooses * automatically the right translator for the given group type to customize * the template text * @@ -118,7 +118,7 @@ public class BGMailHelper { } /** - * The mail templated when a user removed himself from a group. The method + * The mail template when a user removed himself from a group. The method * chooses automatically the right translator for the given group type to * customize the template text * @@ -133,7 +133,7 @@ public class BGMailHelper { } /** - * The mail templated when adding users to a waitinglist. The method chooses + * The mail template when adding users to a waitinglist. The method chooses * automatically the right translator for the given group type to customize * the template text * @@ -148,7 +148,7 @@ public class BGMailHelper { } /** - * The mail templated when removing users from a waiting list. The method + * The mail template when removing users from a waiting list. The method * chooses automatically the right translator for the given group type to * customize the template text * @@ -163,7 +163,7 @@ public class BGMailHelper { } /** - * The mail templated when automatically transferring users from the + * The mail template when automatically transferring users from the * waitinglist to the participants list adding users to a waitinglist. The * method chooses automatically the right translator for the given group type * to customize the template text @@ -188,37 +188,47 @@ public class BGMailHelper { * @return */ private static MailTemplate createMailTemplate(BusinessGroupShort group, Identity actor, String subjectKey, String bodyKey) { - // build learning resources as list of url as string - StringBuilder learningResources = new StringBuilder(); - BusinessGroupService businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); - List<RepositoryEntryShort> repoEntries = businessGroupService.findShortRepositoryEntries(Collections.singletonList(group), 0, -1); - for (RepositoryEntryShort entry: repoEntries) { - String title = entry.getDisplayname(); - String url = BusinessControlFactory.getInstance().getURLFromBusinessPathString("[RepositoryEntry:" + entry.getKey() + "]"); - learningResources.append(title); - learningResources.append(" ("); - learningResources.append(url); - learningResources.append(")\n"); - } - - final String courselist = learningResources.toString(); - // get group name and description - final String groupname = group.getName(); - final String groupdescription = (group instanceof BusinessGroup ? - FilterFactory.getHtmlTagAndDescapingFilter().filter(((BusinessGroup)group).getDescription()) : ""); - // get some data about the actor and fetch the translated subject / body via i18n module String[] bodyArgs = new String[] { actor.getUser().getProperty(UserConstants.FIRSTNAME, null), actor.getUser().getProperty(UserConstants.LASTNAME, null), actor.getUser().getProperty(UserConstants.EMAIL, null), - actor.getName() }; + actor.getName() }; Locale locale = I18nManager.getInstance().getLocaleOrDefault(actor.getUser().getPreferences().getLanguage()); Translator trans = Util.createPackageTranslator(BGMailHelper.class, locale); String subject = trans.translate(subjectKey); String body = trans.translate(bodyKey, bodyArgs); - subject = subject.replaceAll("\\$groupname", groupname == null ? "" : groupname); - body = body.replaceAll("\\$groupname", groupname == null ? "" : groupname); - body = body.replaceAll("\\$groupdescription", groupdescription == null ? "" : groupdescription); - body = body.replaceAll("\\$courselist", courselist == null ? "" : courselist); + // build learning resources as list of url as string + + final String courselist; + final String groupname; + final String groupdescription; + StringBuilder learningResources = new StringBuilder(); + if(group != null) { + BusinessGroupService businessGroupService = CoreSpringFactory.getImpl(BusinessGroupService.class); + List<RepositoryEntryShort> repoEntries = businessGroupService.findShortRepositoryEntries(Collections.singletonList(group), 0, -1); + for (RepositoryEntryShort entry: repoEntries) { + String title = entry.getDisplayname(); + String url = BusinessControlFactory.getInstance().getURLFromBusinessPathString("[RepositoryEntry:" + entry.getKey() + "]"); + learningResources.append(title); + learningResources.append(" ("); + learningResources.append(url); + learningResources.append(")\n"); + } + + courselist = learningResources.toString(); + // get group name and description + groupname = group.getName(); + groupdescription = (group instanceof BusinessGroup ? + FilterFactory.getHtmlTagAndDescapingFilter().filter(((BusinessGroup)group).getDescription()) : ""); + + subject = subject.replaceAll("\\$groupname", groupname == null ? "" : groupname); + body = body.replaceAll("\\$groupname", groupname == null ? "" : groupname); + body = body.replaceAll("\\$groupdescription", groupdescription == null ? "" : groupdescription); + body = body.replaceAll("\\$courselist", courselist == null ? "" : courselist); + } else { + courselist = ""; + groupname = ""; + groupdescription = ""; + } // create a mail template which all these data MailTemplate mailTempl = new MailTemplate(subject, body, null) { diff --git a/src/main/java/org/olat/group/ui/BusinessGroupModuleAdminController.java b/src/main/java/org/olat/group/ui/BusinessGroupModuleAdminController.java index 6d7fe9d4536bfa110aede75f2988496e165b090c..699cac7cc71eaaa11b5cee03bfb101da8468ca06 100644 --- a/src/main/java/org/olat/group/ui/BusinessGroupModuleAdminController.java +++ b/src/main/java/org/olat/group/ui/BusinessGroupModuleAdminController.java @@ -19,6 +19,8 @@ */ package org.olat.group.ui; +import java.util.Set; + import org.olat.core.CoreSpringFactory; import org.olat.core.commons.taskExecutor.TaskExecutorManager; import org.olat.core.gui.UserRequest; @@ -47,8 +49,10 @@ import org.olat.group.ui.main.DedupMembersConfirmationController; */ public class BusinessGroupModuleAdminController extends FormBasicController implements ProgressDelegate { - private FormLink dedupLink; + private FormLink dedupLink, optionLink, privacyLink; private MultipleSelectionElement allowEl; + private MultipleSelectionElement enrolmentEl; + private MultipleSelectionElement membershipEl; private Panel mainPopPanel; private CloseableModalController cmc; @@ -58,6 +62,9 @@ public class BusinessGroupModuleAdminController extends FormBasicController impl private final BusinessGroupModule module; private final BusinessGroupService businessGroupService; private String[] onKeys = new String[]{"user","author"}; + private String[] enrollmentKeys = new String[]{ + "users","authors", "usermanagers", "groupmanagers", "administrators" + }; public BusinessGroupModuleAdminController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, "bg_admin"); @@ -80,9 +87,45 @@ public class BusinessGroupModuleAdminController extends FormBasicController impl FormLayoutContainer buttonsContainer = FormLayoutContainer.createButtonLayout("module.buttons", getTranslator()); buttonsContainer.setRootForm(mainForm); - formLayout.add(buttonsContainer); - uifactory.addFormSubmitButton("ok", "ok", formLayout); + optionsContainer.add(buttonsContainer); + optionLink = uifactory.addFormLink("ok", "ok", null, buttonsContainer, Link.BUTTON); + + FormLayoutContainer privacyOptionsContainer = FormLayoutContainer.createDefaultFormLayout("privacy_options", getTranslator()); + formLayout.add(privacyOptionsContainer); + String[] enrollmentValues = new String[]{ + translate("enrolment.email.users"), + translate("enrolment.email.authors"), + translate("enrolment.email.usermanagers"), + translate("enrolment.email.groupmanagers"), + translate("enrolment.email.administrators") + }; + enrolmentEl = uifactory.addCheckboxesVertical("mandatory.enrolment", privacyOptionsContainer, enrollmentKeys, enrollmentValues, null, 1); + enrolmentEl.select("users", "true".equals(module.getMandatoryEnrolmentEmailForUsers())); + enrolmentEl.select("authors", "true".equals(module.getMandatoryEnrolmentEmailForAuthors())); + enrolmentEl.select("usermanagers", "true".equals(module.getMandatoryEnrolmentEmailForUsermanagers())); + enrolmentEl.select("groupmanagers", "true".equals(module.getMandatoryEnrolmentEmailForGroupmanagers())); + enrolmentEl.select("administrators", "true".equals(module.getMandatoryEnrolmentEmailForAdministrators())); + + String[] membershipValues = new String[]{ + translate("enrolment.email.users"), + translate("enrolment.email.authors"), + translate("enrolment.email.usermanagers"), + translate("enrolment.email.groupmanagers"), + translate("enrolment.email.administrators") + }; + membershipEl = uifactory.addCheckboxesVertical("mandatory.membership", privacyOptionsContainer, enrollmentKeys, membershipValues, null, 1); + membershipEl.select("users", "true".equals(module.getAcceptMembershipForUsers())); + membershipEl.select("authors", "true".equals(module.getAcceptMembershipForAuthors())); + membershipEl.select("usermanagers", "true".equals(module.getAcceptMembershipForUsermanagers())); + membershipEl.select("groupmanagers", "true".equals(module.getAcceptMembershipForGroupmanagers())); + membershipEl.select("administrators", "true".equals(module.getAcceptMembershipForAdministrators())); + + FormLayoutContainer buttonsPrivacyContainer = FormLayoutContainer.createButtonLayout("module.buttons.privacy", getTranslator()); + buttonsPrivacyContainer.setRootForm(mainForm); + privacyOptionsContainer.add(buttonsPrivacyContainer); + privacyLink = uifactory.addFormLink("ok", "ok", "", buttonsPrivacyContainer, Link.BUTTON); + FormLayoutContainer dedupCont = FormLayoutContainer.createDefaultFormLayout("dedup", getTranslator()); formLayout.add(dedupCont); dedupLink = uifactory.addFormLink("dedup.members", dedupCont, Link.BUTTON); @@ -118,6 +161,15 @@ public class BusinessGroupModuleAdminController extends FormBasicController impl dedupCtrl = null; cmc = null; } + + + + @Override + public void setMax(float max) { + if(progressCtrl != null) { + progressCtrl.setMax(max); + } + } @Override public void setActual(float value) { @@ -126,6 +178,13 @@ public class BusinessGroupModuleAdminController extends FormBasicController impl } } + @Override + public void setInfo(String message) { + if(progressCtrl != null) { + progressCtrl.setInfo(message); + } + } + @Override public void finished() { cmc.deactivate(); @@ -136,6 +195,23 @@ public class BusinessGroupModuleAdminController extends FormBasicController impl protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { if(source == dedupLink) { doDedupMembers(ureq); + } else if(source == optionLink) { + module.setUserAllowedCreate(allowEl.isSelected(0)); + module.setAuthorAllowedCreate(allowEl.isSelected(1)); + } else if(source == privacyLink) { + Set<String> membershipSelectedKeys = membershipEl.getSelectedKeys(); + module.setAcceptMembershipForUsers(membershipSelectedKeys.contains("users") ? "true" : "false"); + module.setAcceptMembershipForAuthors(membershipSelectedKeys.contains("authors") ? "true" : "false"); + module.setAcceptMembershipForUsermanagers(membershipSelectedKeys.contains("usermanagers") ? "true" : "false"); + module.setAcceptMembershipForGroupmanagers(membershipSelectedKeys.contains("groupmanagers") ? "true" : "false"); + module.setAcceptMembershipForAdministrators(membershipSelectedKeys.contains("administrators") ? "true" : "false"); + + Set<String> enrolmentSelectedKeys = enrolmentEl.getSelectedKeys(); + module.setMandatoryEnrolmentEmailForUsers(enrolmentSelectedKeys.contains("users") ? "true" : "false"); + module.setMandatoryEnrolmentEmailForAuthors(enrolmentSelectedKeys.contains("authors") ? "true" : "false"); + module.setMandatoryEnrolmentEmailForUsermanagers(enrolmentSelectedKeys.contains("usermanagers") ? "true" : "false"); + module.setMandatoryEnrolmentEmailForGroupmanagers(enrolmentSelectedKeys.contains("groupmanagers") ? "true" : "false"); + module.setMandatoryEnrolmentEmailForAdministrators(enrolmentSelectedKeys.contains("administrators") ? "true" : "false"); } else { super.formInnerEvent(ureq, source, event); } @@ -170,7 +246,6 @@ public class BusinessGroupModuleAdminController extends FormBasicController impl @Override protected void formOK(UserRequest ureq) { - module.setUserAllowedCreate(allowEl.isSelected(0)); - module.setAuthorAllowedCreate(allowEl.isSelected(1)); + // } } \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/_content/bg_admin.html b/src/main/java/org/olat/group/ui/_content/bg_admin.html index 724e10e4459ac486e73a786c1209094f0cd7bae7..b22a3fcc0f0793463e0347805fb92fcba9054bc2 100644 --- a/src/main/java/org/olat/group/ui/_content/bg_admin.html +++ b/src/main/java/org/olat/group/ui/_content/bg_admin.html @@ -3,7 +3,11 @@ <legend>$r.translate("module.admin.title")</legend> <div class="b_form_desc">$r.translate("module.admin.desc")</div> $r.render("options") - $r.render("module.buttons") + </fieldset> + <fieldset> + <legend>$r.translate("module.privacy.title")</legend> + <div class="b_form_desc">$r.translate("module.privacy.desc")</div> + $r.render("privacy_options") </fieldset> <fieldset> <legend>$r.translate("dedup.members")</legend> diff --git a/src/main/java/org/olat/group/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/group/ui/_i18n/LocalStrings_de.properties index e19c0665285ab997e74d8453211683e868c38c07..e9f050b12856e62667cf081f4ff7663b1fc1335c 100644 --- a/src/main/java/org/olat/group/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/group/ui/_i18n/LocalStrings_de.properties @@ -39,14 +39,13 @@ dedup.members.desc=W dedup.running=Bereinigung l\u00E4uft dedup.done=Bereinigung der Kursmitglieder und Gruppenmitglieder wurde erfolgreich beendet -admin.menu.title=Gruppe -admin.menu.title.alt=Gruppe -module.admin.title=Gruppen-Modul -module.admin.desc=Bestimmen Sie hier wer Gruppen erstellen darf. -module.admin.allow.create=Darf Gruppe erstellen -user.allow.create=Benutzer -author.allow.create=Autor - +admin.menu.title=Gruppen +admin.menu.title.alt=Einstellungen für Gruppen und Kursmitgliedschaften +module.admin.title=Gruppen erstellen +module.admin.desc=Bestimmen Sie ob normale Benutzer und/oder Kursautoren Gruppen erstellen dürfen. Systemadministratoren und Gruppenverwalter dürfen in jedem Fall Gruppen erzeugen. +module.admin.allow.create=Gruppen erstellen erlauben für +user.allow.create=Lernende +author.allow.create=Kursautoren bgcopywizard.copyform.owners=Betreuer der Gruppe chkBox.show.owners=Mitglieder sehen Betreuer @@ -93,8 +92,20 @@ userlist.participants.title=Teilnehmer userlist.title=Liste aller Gruppenmitglieder userlist.waitinglist.title=Warteliste - - +module.privacy.title=Datenschutz +module.privacy.desc=Um den Datenschutzanforderungen gerecht zu werden kann festgelegt werden, ob bei einer Einladung von Benutzern in Kurse und Gruppen ein Email versendet werden muss und ob die Einladung eine direkte Mitgliedschaft zur Folge hat oder erst durch den eingeladenen Benutzer bestätigt werden muss. +mandatory.enrolment=E-Mail Benachrichtigung erzwungen bei Einladung durch +enrolment.email.users=Lernende +enrolment.email.authors=Kursautoren +enrolment.email.usermanagers=Benutzerverwalter +enrolment.email.groupmanagers=Gruppenverwalter +enrolment.email.administrators=Systemadministratoren +mandatory.membership=Bestätigung Mitgliedschaft erforderlich bei Einladung durch +membership.users=$\:enrolment.email.users +membership.authors=$\:enrolment.email.authors +membership.usermanagers=$\:enrolment.email.usermanagers +membership.groupmanagers=$\:enrolment.email.groupmanagers +membership.administrators=$\:enrolment.email.administrators archive.areas=Lernbereiche archive.coursename=Kursname diff --git a/src/main/java/org/olat/group/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/group/ui/_i18n/LocalStrings_en.properties index 2c597d52f993bcab494bbac3bbb20925e3fdb693..ab8c988226981a927d0163730aa7a2545246294b 100644 --- a/src/main/java/org/olat/group/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/group/ui/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Thu Nov 29 14:20:57 CET 2012 +#Tue Dec 18 16:55:38 CET 2012 LearningGroup=Group action.choose=Select admin.menu.title=Group @@ -48,6 +48,11 @@ dedup.members=Purge course members dedup.members.desc=Select the button "$\:dedup.members" to purge the list of course members in all courses of this system. This is a maintenance function to cleanup duplicate course and group memberships within courses. dedup.running=Purging process is running default.context=Created automatically in course +enrolment.email.administrators=System administrators +enrolment.email.authors=Course authors +enrolment.email.groupmanagers=Group administrators +enrolment.email.usermanagers=User managers +enrolment.email.users=Learner error.group.name.exists=This group name is already being used in this context, please select another one. fieldset.legend.groupowners=Coaches fieldset.legend.grouppartips=Participants @@ -63,6 +68,13 @@ groupsPortlet.no_member=You have been removed from this group as member or your groupsPortlet.nogroups=You are not a member of this group groupsPortlet.showAll=Show all groupsPortlet.title=My groups +mandatory.enrolment=Enforce e-mail notification when invited by +mandatory.membership=Require accepting of membership when invited by +membership.administrators=$\:enrolment.email.administrators +membership.authors=$\:enrolment.email.authors +membership.groupmanagers=$\:enrolment.email.groupmanagers +membership.usermanagers=$\:enrolment.email.usermanagers +membership.users=$\:enrolment.email.users menu.allgroups=All groups menu.allgroups.alt=List all groups menu.index=Group management @@ -70,6 +82,8 @@ menu.index.alt=Administer groups module.admin.allow.create=May create group module.admin.desc=Specify here who can create groups. module.admin.title=Group management +module.privacy.desc=To comply with data privacy guidelines the workflow when adding a user to a group can be configured to result in either an immediate membership of the group or only an invitation that must explicitly be accepted by the user before becoming a member of the group. +module.privacy.title=Data privacy newgroup.title=Create a new group notification.mail.added.body=*** This is an automated message. Please do not reply *** \r\n\r\nYou were invited to a group by {0} {1} ({3})\: \r\n\r\nGroup name\: $groupname\r\nDescription\: $groupdescription\r\n\r\nFor questions, please contact {0} {1} ({2}). \r\n\r\nThis group is used in the following learning resources\:\r\n\r\n$courselist notification.mail.added.self.body=*** This is an automated message. Please do not reply *** \r\n\r\nYou have just signed in to a group\: \r\n\r\nGroup name\: $groupname\r\nDescription\: $groupdescription\r\n\r\nThis group will be used in the following learning resources\:\r\n\r\n$courselist diff --git a/src/main/java/org/olat/group/ui/edit/_content/tab_bgGrpMngmnt.html b/src/main/java/org/olat/group/ui/edit/_content/tab_bgGrpMngmnt.html index 5ccfc59ae67149ff8ddc660831d0281b93b14415..8ff211edbe119dcba153304ec066012e6c34f85d 100644 --- a/src/main/java/org/olat/group/ui/edit/_content/tab_bgGrpMngmnt.html +++ b/src/main/java/org/olat/group/ui/edit/_content/tab_bgGrpMngmnt.html @@ -4,7 +4,7 @@ $r.render("displayMembers") </fieldset> <fieldset> - <legend>$r.translate("fieldset.legend.groupowners")</legend> + <legend>$r.translate("group.edit.tab.members")</legend> <div class="o_buttons_box_right"><br/><br/> #if($r.available("addMembers")) diff --git a/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_de.properties index 1c3a519e8bbcdab95bc69096e7e786a92e3471a8..52306ec5d89b06c2c9615fc3c77dd2b610314a9a 100644 --- a/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_de.properties @@ -39,7 +39,7 @@ chelp.membLearn2=Hier k\u00F6nnen Sie bestimmen, wer die Mitglieder und Wartelis chelp.membLearn5=Wenn Sie eine neue Gruppe erstellen, sind Sie automatisch Betreuer dieser Gruppe. Betreuer der Gruppe erhalten den Link "$org.olat.group.ui.run\:menutree.administration" im Menu. chelp.membLearn6=Sie k\u00F6nnen die $org.olat.group.ui\:LearningGroup also administrieren, insbesondere auch andere Benutzer zu Betreuern ernennen und die Gruppe löschen. chelp.membLearn7=$org.olat.group.ui\:fieldset.legend.groupowners k\u00F6nnen beliebige Benutzer als $\:fieldset.legend.grouppartips in die Gruppe einladen. -chelp.membLearn8=Betreuer können die Kandidaten in der Warteliste als Teilnehmer übernehmen oder aus der Warteliste entfernen. In beiden Fällen können sie bestimmen, ob die Benutzer darüber per Email notifiziert werden sollen und können gegenfalls den Emailtext anpassen. +chelp.membLearn8=Betreuer können die Kandidaten in der Warteliste als Teilnehmer zulassen oder aus der Warteliste entfernen. In beiden Fällen können sie bestimmen, ob die Benutzer darüber per Email notifiziert werden sollen und können gegenfalls den Emailtext anpassen. chelp.resource1=Hier legen Sie fest, ob und mit welchen Kursen eine Gruppe verbunden ist. Über "$:cmd.addresource" können Sie die Kurse einbinden, bei denen Sie als Besitzer eingetragen sind. Es gibt keine Beschränkung der Anzahl eingebundener Kurse. chelp.resource2=Sobald die Gruppe mit mindestens einem Kurs verbunden wurde, erscheint der Eintrag "Kurs" in der Navigation. chelp.right1=Sie haben die M\u00F6glichkeit, den Mitgliedern der Gruppe innerhalb des Kurses die Berechtigung f\u00FCr den Zugriff und die Verwendung der folgenden Werkzeuge zu vergeben\: @@ -95,10 +95,10 @@ group.edit.tab.resources=Kurse group.edit.tab.accesscontrol=Veröffentlichung und Buchungskonfiguration group.edit.title=Gruppe <i>{0}</i> editieren group.deleted=$org.olat.group.ui\:group.deleted -resource.remove=Wollen Sie die Gruppenverwaltung "{0}" wirklich nicht mehr im Kurs "{1}" verwenden? Weder der Kurs noch die Gruppenverwaltung werden bei dieser Aktion gel\u00F6scht. Die Verbindung kann jederzeit wiederhergestellt werden. +resource.remove=Wollen Sie die Gruppe "{0}" wirklich nicht mehr im Kurs "{1}" verwenden? Weder der Kurs noch die Gruppen werden bei dieser Aktion gel\u00F6scht. Die Verbindung kann jederzeit wiederhergestellt werden. resources.add=Kurs einbinden resources.add.title=Kurs ausw\u00E4hlen -resources.noresources=Diese Gruppenverwaltung wird in keinem Kurs verwendet. Bitte w\u00E4hlen Sie "Kurs hinzuf\u00FCgen" um diese Gruppenverwaltung in einem Kurs zu verwenden. +resources.noresources=Diese Gruppe wird in keinem Kurs verwendet. Bitte w\u00E4hlen Sie "Kurs hinzuf\u00FCgen" um diese Gruppe in einem Kurs zu verwenden. resources.remove=entfernen diff --git a/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_en.properties index 2049799cfcc1a07a7bec6f037e44a697360a12aa..f4a1896aaba8546661a29fe7948f0b1635117d12 100644 --- a/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/group/ui/edit/_i18n/LocalStrings_en.properties @@ -1,6 +1,8 @@ -#Wed Oct 24 16:13:13 CEST 2012 +#Tue Dec 18 16:59:56 CET 2012 +add.member=$org.olat.group.ui.main\:add.member areachoice.no.areas.admin=No learning areas found. Please create a learning area within your group management. areachoice.no.areas.owner=No learning areas found. New learning areas can only be created by users who have access to the entire group management. +assessment=$org.olat.group.ui.main\:assessment chelp.area1=Provided that groups have already been created in the course, these will appear in the tab. chelp.area2=By means of check boxes you have the possibility to decide which groups your learning area shall contain. chelp.area3=This setting is transferred to the configuration tabs <i>$\:group.edit.tab.areas</i> of the groups selected. @@ -24,9 +26,9 @@ chelp.grp-member.title=Group\: members chelp.grp-memberOwner.title=Group\: coaches chelp.grp-memberParticipants.title=Group\: participants chelp.grp-memberWaiting.title=Group\: waiting list +chelp.grp-resources.title=Group\: courses chelp.grp-select-area.title=Group\: assign learning areas chelp.grp-tools.title=Group\: configure collaborative tools -chelp.grp-resources.title=Group\: courses chelp.learn1=Provided that learning areas have already been created in the group management of this course, they will appear in a tab. chelp.learn2=By means of check boxes you have the possibility to decide to which learning areas your group shall belong. chelp.learn3=This setting is adopted into the configuration tab <i>$org.olat.group.ui.area\:tab.groups</i> of the learning areas selected. @@ -39,8 +41,8 @@ chelp.membLearn2=Here you can decide which user groups are allowed to view the m chelp.membLearn5=If you create a new group, you are automatically one of the coaches of this group. Coaches of this group will see the link "$org.olat.group.ui.run\:menutree.administration" in the menu. They can then administer this group, appoint other users as owners and delete the group. chelp.membLearn6=They can then administer that group and appoint other OLAT users as coaches. chelp.membLearn7=Coaches can invite users to be participants of their group. -chelp.membLearn8=Coaches can accept candidates from a waiting list as participants or delete them. Either way you can determine if users should be notified via e-mail; its text will be adaptable. -chelp.resource1=Here you can determine whether a group is connected to one or multiple courses. Clicking on "$:cmd.addresource" allows you to link as many courses you are owner of with the group. There is no limit to the number of embedded courses. +chelp.membLearn8=Coaches can admit candidates from a waiting list as participants or delete them. Either way you can determine if users should be notified via e-mail; its text will be adaptable. +chelp.resource1=Here you can determine whether a group is connected to one or multiple courses. Clicking on "$\:cmd.addresource" allows you to link as many courses you are owner of with the group. There is no limit to the number of embedded courses. chelp.resource2=Once the group has been associated with at least one course, the entry "Course" appears in the navigation. chelp.right1=You have the possibility to assign access rights as well as the right to use the following tools to members of a group with the same rights during this course\: chelp.tools.infoEd=You can immediately edit this information further down. @@ -66,6 +68,9 @@ chkBox.show.owners=Members can see coaches chkBox.show.partips=Members can see participants chkBox.show.waitingList=Members can see waiting list cmd.addresource=Add course +dialog.modal.bg.leave.text=$org.olat.group.ui.main\:dialog.modal.bg.leave.text +edit.member=$org.olat.group.ui.main\:edit.member +edit.member.groups=$org.olat.group.ui.main\:edit.member.groups error.message.locked=This group is being edited by user {0} ({1}) and therefore locked. Please try again later. fieldset.legend.areas=Assigned learning areas fieldset.legend.collabtools=Collaborative tools @@ -95,8 +100,27 @@ help.hover.bgGrpMngmntParticipants=Help regarding members of groups help.hover.bgGrpMngmntWaiting=Help regarding waiting lists of groups help.hover.bgGrpResources=Help regarding courses of groups help.hover.bgRights=Help regarding rights of a group -resource.remove=You really doesn't want the groups management "{0}" in course "{1}"? The group and the course are not deleted with this action. You can add the relation between them at any time. +home=$org.olat.group.ui.main\:home +import.member=$org.olat.group.ui.main\:import.member +nomembers=$org.olat.group.ui.main\:nomembers +resource.remove=Do you really want to remove the group "{0}" from course "{1}"? The group and the course are not deleted with this action. You can add the relation between them at any time. resources.add=Link course resources.add.title=Select course resources.noresources=This group is not used in any courses. Choose "Add course" to link the course to this group. resources.remove=remove +table.header.edit=$org.olat.group.ui.main\:table.header.edit +table.header.firstName=$org.olat.group.ui.main\:table.header.firstName +table.header.firstTime=$org.olat.group.ui.main\:table.header.firstTime +table.header.freePlace=$org.olat.group.ui.main\:table.header.freePlace +table.header.graduate=$org.olat.group.ui.main\:table.header.graduate +table.header.groups=$org.olat.group.ui.main\:table.header.groups +table.header.lastName=$org.olat.group.ui.main\:table.header.lastName +table.header.lastTime=$org.olat.group.ui.main\:table.header.lastTime +table.header.mail=$org.olat.group.ui.main\:table.header.mail +table.header.participants=$org.olat.group.ui.main\:table.header.participants +table.header.participantsCount=$org.olat.group.ui.main\:table.header.participantsCount +table.header.remove=$org.olat.group.ui.main\:table.header.remove +table.header.role=$org.olat.group.ui.main\:table.header.role +table.header.tutors=org.olat.group.ui.main\:table.header.tutors +table.header.tutorsCount=$org.olat.group.ui.main\:table.header.tutorsCount +table.header.waitingList=$org.olat.group.ui.main\:table.header.waitingList diff --git a/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java index 18c987ef45c66ce0bfb5e6a1f614273ab991c051..bb26d825e8b41b9e3629ace048e10f5d1e1f8f90 100644 --- a/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java +++ b/src/main/java/org/olat/group/ui/main/AbstractBusinessGroupListController.java @@ -263,6 +263,9 @@ public abstract class AbstractBusinessGroupListController extends BasicControlle if(businessGroup == null) { groupListModel.removeBusinessGroup(businessGroup); groupListCtr.modelChanged(); + } else if(TABLE_ACTION_DELETE.equals(actionid)) { + BGTableItem item = groupListModel.getObject(te.getRowId()); + confirmDelete(ureq, Collections.singletonList(item)); } else if(actionid.equals(TABLE_ACTION_LAUNCH)) { doLaunch(ureq, businessGroup); } else if(actionid.equals(TABLE_ACTION_LEAVE)) { @@ -416,7 +419,7 @@ public abstract class AbstractBusinessGroupListController extends BasicControlle // if identity was also owner it must have successfully removed to end here. // now remove the identity also as participant. // 2) remove as participant - businessGroupService.removeParticipants(getIdentity(), identityToRemove, group, null);//TODO memail + businessGroupService.removeParticipants(getIdentity(), identityToRemove, group, null); // 3) remove from waiting list businessGroupService.removeFromWaitingList(getIdentity(), identityToRemove, group, null); } @@ -662,7 +665,7 @@ public abstract class AbstractBusinessGroupListController extends BasicControlle public Step execute(UserRequest ureq, WindowControl wControl, StepsRunContext runContext) { BusinessGroup targetGroup = (BusinessGroup)runContext.get("targetGroup"); groups.remove(targetGroup); - businessGroupService.mergeBusinessGroups(getIdentity(), targetGroup, groups, null);//TODO memail + businessGroupService.mergeBusinessGroups(getIdentity(), targetGroup, groups, null); return StepsMainRunController.DONE_MODIFIED; } }; @@ -826,7 +829,7 @@ public abstract class AbstractBusinessGroupListController extends BasicControlle BusinessGroupMembership membership = memberships.get(group.getKey()); Boolean allowLeave = membership != null; - Boolean allowDelete = admin ? Boolean.TRUE : null; + Boolean allowDelete = admin ? Boolean.TRUE : (membership == null ? null : new Boolean(membership.isOwner())); boolean marked = markedResources.contains(group.getResource().getResourceableId()); BGTableItem tableItem = new BGTableItem(group, marked, membership, allowLeave, allowDelete, accessMethods); tableItem.setUnfilteredRelations(resources); diff --git a/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java b/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java index 3f56a870db619e839352ae4f4f15918b51a0b3f7..505a53b2f390993e2bbf9e17ecc495d336837805 100644 --- a/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java +++ b/src/main/java/org/olat/group/ui/main/AbstractMemberListController.java @@ -322,7 +322,7 @@ public abstract class AbstractMemberListController extends BasicController imple repositoryManager.updateRepositoryEntryMembership(getIdentity(), ureq.getUserSession().getRoles(), repoEntry, changes, null); } - businessGroupService.updateMemberships(getIdentity(), e.getGroupChanges(), null);//TODO memail + businessGroupService.updateMemberships(getIdentity(), e.getGroupChanges(), null); //make sure all is committed before loading the model again (I see issues without) DBFactory.getInstance().commitAndCloseSession(); @@ -343,7 +343,7 @@ public abstract class AbstractMemberListController extends BasicController imple //commit all changes to the group memberships List<BusinessGroupMembershipChange> allModifications = changes.generateBusinessGroupMembershipChange(members); - businessGroupService.updateMemberships(getIdentity(), allModifications, null);//TODO memail + businessGroupService.updateMemberships(getIdentity(), allModifications, null); DBFactory.getInstance().commitAndCloseSession(); if(allModifications != null && !allModifications.isEmpty()) { @@ -357,7 +357,6 @@ public abstract class AbstractMemberListController extends BasicController imple reloadModel(); } - //TODO memail protected void sendMailAfterChangePermission(BusinessGroupMembershipChange mod) { MailTemplate template = null; if(mod.getParticipant() != null) { @@ -419,11 +418,8 @@ public abstract class AbstractMemberListController extends BasicController imple List<Long> identityKeys = getMemberKeys(members); List<Identity> identitiesToGraduate = securityManager.loadIdentityByKeys(identityKeys); businessGroupService.moveIdentityFromWaitingListToParticipant(getIdentity(), identitiesToGraduate, - businessGroup, null);//TODO memail - } else { - //TODO memail do something + businessGroup, null); } - reloadModel(); } diff --git a/src/main/java/org/olat/group/ui/main/BusinessGroupDeleteDialogBoxController.java b/src/main/java/org/olat/group/ui/main/BusinessGroupDeleteDialogBoxController.java index 631cdeddfcaefef9b094aff1c189e175e8c1999a..22b247a2f62068ae27d1f73fba8cbb1e227f7b58 100644 --- a/src/main/java/org/olat/group/ui/main/BusinessGroupDeleteDialogBoxController.java +++ b/src/main/java/org/olat/group/ui/main/BusinessGroupDeleteDialogBoxController.java @@ -23,7 +23,7 @@ import java.util.List; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; -import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.elements.SingleSelection; import org.olat.core.gui.components.form.flexible.impl.FormBasicController; import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; import org.olat.core.gui.control.Controller; @@ -39,14 +39,14 @@ import org.olat.group.BusinessGroup; */ public class BusinessGroupDeleteDialogBoxController extends FormBasicController { - private MultipleSelectionElement sendMail; + private SingleSelection sendMail; - private final String[] keys = {"send"}; + private final String[] keys = {"yes","no"}; private final List<BusinessGroup> groupsToDelete; public BusinessGroupDeleteDialogBoxController(UserRequest ureq, WindowControl wControl, List<BusinessGroup> groupsToDelete) { - super(ureq, wControl); + super(ureq, wControl, "group_delete_confirmation"); this.groupsToDelete = groupsToDelete; initForm(ureq); } @@ -59,20 +59,24 @@ public class BusinessGroupDeleteDialogBoxController extends FormBasicController names.append(group.getName()); } - String text = translate("dialog.modal.bg.delete.text", new String[]{names.toString()}); - uifactory.addStaticTextElement("delete.desc", null, text, formLayout); + if(formLayout instanceof FormLayoutContainer) { + ((FormLayoutContainer)formLayout).contextPut("groups", names.toString()); + } - + FormLayoutContainer mailCont = FormLayoutContainer.createDefaultFormLayout("sendmail", getTranslator()); + formLayout.add(mailCont); String[] values = new String[]{ - translate("dialog.modal.bg.mail.text") + translate("yes"), + translate("no") }; - sendMail = uifactory.addCheckboxesHorizontal("send.mail", null, formLayout, keys, values, null); + sendMail = uifactory.addRadiosVertical("send.mail", "dialog.modal.bg.mail.text", mailCont, keys, values); + sendMail.select("no", true); FormLayoutContainer buttonsContainer = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); buttonsContainer.setRootForm(mainForm); formLayout.add(buttonsContainer); - uifactory.addFormSubmitButton("deleteButton", "ok", buttonsContainer); - uifactory.addFormCancelButton("cancel", buttonsContainer, ureq, getWindowControl()); + uifactory.addFormSubmitButton("deleteButton", "yes", buttonsContainer); + uifactory.addFormCancelButton("no", buttonsContainer, ureq, getWindowControl()); } @Override @@ -81,7 +85,7 @@ public class BusinessGroupDeleteDialogBoxController extends FormBasicController } public boolean isSendMail() { - return sendMail.isAtLeastSelected(1); + return sendMail.isOneSelected() && sendMail.isSelected(0); } public List<BusinessGroup> getGroupsToDelete() { diff --git a/src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java b/src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java index 72bf69a131368cc2e9a5393c78ddb6b760610ee4..1e0f79b4105852203cf68d35b83043bef655f24d 100644 --- a/src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java +++ b/src/main/java/org/olat/group/ui/main/OwnedBusinessGroupListController.java @@ -75,7 +75,8 @@ public class OwnedBusinessGroupListController extends AbstractBusinessGroupListC CustomCellRenderer roleRenderer = new BGRoleCellRenderer(getLocale()); groupListCtr.addColumnDescriptor(new CustomRenderColumnDescriptor(Cols.role.i18n(), Cols.role.ordinal(), null, getLocale(), ColumnDescriptor.ALIGNMENT_LEFT, roleRenderer)); groupListCtr.addColumnDescriptor(new BooleanColumnDescriptor(Cols.allowLeave.i18n(), Cols.allowLeave.ordinal(), TABLE_ACTION_LEAVE, translate("table.header.leave"), null)); - return 11; + groupListCtr.addColumnDescriptor(new BooleanColumnDescriptor(Cols.allowDelete.i18n(), Cols.allowDelete.ordinal(), TABLE_ACTION_DELETE, translate("table.header.delete"), null)); + return 12; } protected void updateOwnedGroups() { diff --git a/src/main/java/org/olat/group/ui/main/PendingEnrollmentController.java b/src/main/java/org/olat/group/ui/main/PendingEnrollmentController.java index 0f69c5abcc15c42e5fe3492b239ef855fc34d97f..056402de7376c605d403e42857230704c5b83bea 100644 --- a/src/main/java/org/olat/group/ui/main/PendingEnrollmentController.java +++ b/src/main/java/org/olat/group/ui/main/PendingEnrollmentController.java @@ -124,8 +124,10 @@ public class PendingEnrollmentController extends FormBasicController implements for(ReservationWrapper reservation:reservations) { FormLink acceptLink = uifactory.addFormLink("accept_" + reservation.getKey(), "accept", null, formLayout, Link.BUTTON); acceptLink.setUserObject(reservation); + acceptLink.setCustomEnabledLinkCSS("b_link_left_icon b_link_ok"); FormLink rejectLink = uifactory.addFormLink("reject_" + reservation.getKey(), "reject", null, formLayout, Link.BUTTON); rejectLink.setUserObject(reservation); + rejectLink.setCustomEnabledLinkCSS("b_link_left_icon b_link_nok"); formLayout.add(acceptLink.getName(), acceptLink); formLayout.add(rejectLink.getName(), rejectLink); } @@ -167,7 +169,7 @@ public class PendingEnrollmentController extends FormBasicController implements if(reservation.getAccept().booleanValue()) { acService.acceptReservationToResource(getIdentity(), reservation.getReservation()); } else { - acService.removeReservation(reservation.getReservation()); + acService.removeReservation(getIdentity(), getIdentity(), reservation.getReservation()); } } } @@ -194,6 +196,10 @@ public class PendingEnrollmentController extends FormBasicController implements public Long getKey() { return reservation.getKey(); } + + public boolean isCoach() { + return "group_coach".equals(reservation.getType()) || "repo_tutors".equals(reservation.getType()); + } public String getName() { return name == null ? "" : name; @@ -211,6 +217,16 @@ public class PendingEnrollmentController extends FormBasicController implements this.description = description; } + public boolean isGroupReservation() { + // group participants and coaches + return reservation.getType().startsWith("group_"); + } + + public boolean isRepositoryEntryReservation() { + // repo participants and coaches + return reservation.getType().startsWith("repo_"); + } + public List<String> getCourses() { if(courses == null) { courses = new ArrayList<String>(1); diff --git a/src/main/java/org/olat/group/ui/main/_content/accept_reservations.html b/src/main/java/org/olat/group/ui/main/_content/accept_reservations.html index ba53d2aadcac0aaf09ab9c75070ce8f15d00417d..a15737d004b311fa11446203bca5b9eb44d1eade 100644 --- a/src/main/java/org/olat/group/ui/main/_content/accept_reservations.html +++ b/src/main/java/org/olat/group/ui/main/_content/accept_reservations.html @@ -2,22 +2,38 @@ #set($id = $reservation.key) <div> <div class="o_reservation b_clearfix"> - <span class="o_reservation_name #if($reservation.accepted) o_reservation_accepted #elseif($reservation.refused) o_reservation_refused #end"> - ${reservation.name} - </span> - <div class="o_buttons_box_right"> - <a href="#" class="o_reservation_details_link" id="o_reservation_details_show_$id">$r.translate("show")</a> - <a href="#" class="o_reservation_details_link" id="o_reservation_details_hide_$id" style="display:none">$r.translate("hide")</a> - $r.render("accept_$id") - $r.render("reject_$id") + <div> + <span class="o_reservation_name b_with_small_icon_left #if($reservation.isGroupReservation()) b_group_icon #elseif($reservation.isRepositoryEntryReservation()) o_course_icon #end"> + ${reservation.name} + </span> + #if($reservation.coach) + <span class="o_reservation_role_coach"> + ($r.translate("reservation.coach")) + </span> + #end + #if($reservation.accepted) + <span class="o_reservation_accepted"> + $r.translate("confirm.accept") + </span> + #elseif($reservation.refused) + <span class="o_reservation_refused"> + $r.translate("confirm.reject") + </span> + #end + <div class="b_float_right"> + <a href="#" class="o_reservation_details_link" id="o_reservation_details_show_$id">$r.translate("show")</a> + <a href="#" class="o_reservation_details_link" id="o_reservation_details_hide_$id" style="display:none">$r.translate("hide")</a> + $r.render("accept_$id") + $r.render("reject_$id") + </div> </div> <div class="o_reservation_details" style="display: none" id="o_reservation_details_$id"> - <div> - <strong>$r.translate("table.header.description")</strong>: $reservation.description + <div class="o_reservation_details_desc"> + $reservation.description </div> - <div> - #if($reservation.courses) - <strong>$r.translate("table.header.resources")</strong>: + <div class="o_reservation_details_resources"> + #if(!$reservation.courses.isEmpty()) + <strong>$r.translate("group.used.in.course")</strong> <ul> #foreach($course in $reservation.courses) <li class=""><span class="b_with_small_icon_left o_CourseModule_icon">$course</span></li> diff --git a/src/main/java/org/olat/group/ui/main/_content/dedup.html b/src/main/java/org/olat/group/ui/main/_content/dedup.html index bf9c690933d37548d42a308fc9a4d6450de79cd4..7d17ef13c01c68bc86505a866b7f8404f6fc89e2 100644 --- a/src/main/java/org/olat/group/ui/main/_content/dedup.html +++ b/src/main/java/org/olat/group/ui/main/_content/dedup.html @@ -1,6 +1,10 @@ -$r.translate("dedup.members.info") -#if($numOfDuplicates) - $r.translate("dedup.members.info2", $numOfDuplicates) -#end +<p>$r.translate("dedup.members.info1")</p> +<ul> + <li><p>$r.translate("dedup.members.info2")</p></li> + #if($numOfDuplicates) + <li><p>$r.translate("dedup.members.info3", $numOfDuplicates)</p></li> + #end + <li><p>$r.translate("dedup.members.info4")</p></li> +</ul> $r.render("options") $r.render("buttons") diff --git a/src/main/java/org/olat/group/ui/main/_content/group_delete_confirmation.html b/src/main/java/org/olat/group/ui/main/_content/group_delete_confirmation.html new file mode 100644 index 0000000000000000000000000000000000000000..730a53994a83308879a07a022d649d5f48dd0cb2 --- /dev/null +++ b/src/main/java/org/olat/group/ui/main/_content/group_delete_confirmation.html @@ -0,0 +1,3 @@ +<p>$r.translate("dialog.modal.bg.delete.text", $groups)</p> +$r.render("sendmail") +$r.render("buttons") diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ar.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ar.properties index 4d582c2d1aeaea3caed1c16ee263d6098bc66d23..5a1ca11660c112582a9f38728b4e1b154f90874f 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ar.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ar.properties @@ -6,13 +6,13 @@ index.header=\u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0627\u062A index.intro=\u0641\u0649 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062A\u0627\u0644\u064A\u0629 \u062A\u0648\u062C\u062F \u0643\u0644 \u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u0648\u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0627\u0644\u062A\u0639\u0644\u064A\u0645 \u0648\u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0627\u0644\u062D\u0642\u0648\u0642 \u0627\u0644\u062A\u0649 \u062A\u0634\u0627\u0631\u0643 \u0641\u064A\u0647\u0627. index.table.nogroup=\u0623\u0646\u062A \u063A\u064A\u0631 \u0645\u0634\u062A\u0631\u0643 \u0641\u0649 \u0623\u0649 \u0645\u062C\u0645\u0648\u0639\u0629. info.group.deleted=\u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639 \u062A\u0645 \u062D\u0630\u0641\u0647\u0627. -learning.header=\u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0627\u0644\u062A\u0639\u0644\u064A\u0645 -learning.intro=\u0641\u0649 \u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062A\u0627\u0644\u064A\u0629 \u062A\u0648\u062C\u062F \u0643\u0644 \u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0627\u0644\u062A\u0639\u0644\u064A\u0645 \u0627\u0644\u062A\u0649 \u062A\u0634\u0627\u0631\u0643 \u0641\u064A\u0647\u0627. + + menu.index=\u0627\u0644\u0645\u062C\u0645\u0648\u0639\u0627\u062A menu.index.alt=\u0627\u0639\u0645\u0644 \u0645\u0639 \u0645\u062C\u0645\u0648\u0639\u0627\u062A\u0643 msg.atleastone=\u064A\u062C\u0628 \u0623\u0646 \u064A\u0643\u0648\u0646 \u0647\u0646\u0627\u0643 \u0645\u0624\u0644\u0641 \u0645\u0633\u0627\u0639\u062F \u0648\u0627\u062D\u062F\u0627\u064B \u0639\u0644\u0649 \u0627\u0644\u0623\u0642\u0644 \u0641\u0649 \u0645\u062C\u0645\u0648\u0639\u0629 \u0627\u0644\u0645\u0634\u0631\u0648\u0639. -right.header=\u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0627\u0644\u062D\u0642\u0648\u0642 -right.intro=\u0627\u0644\u0642\u0627\u0626\u0645\u0629 \u0627\u0644\u062A\u0627\u0644\u064A\u0629 \u062A\u0648\u0636\u062D \u0643\u0644 \u0645\u062C\u0645\u0648\u0639\u0627\u062A \u0627\u0644\u062D\u0642\u0648\u0642 \u0627\u0644\u062A\u0649 \u062A\u0634\u0627\u0631\u0643 \u0641\u064A\u0647\u0627. + + table.header.bgname=\u0627\u0644\u0627\u0633\u0645 table.header.delete=\u062D\u0630\u0641 table.header.description=\u0627\u0644\u0648\u0635\u0641 diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_bg.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_bg.properties index 07bf779bd9e37e6e17035551a55b642c2f52c5d9..dbc849827cd87b091b531d93975d46af132cb1dd 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_bg.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_bg.properties @@ -6,13 +6,13 @@ index.header=\u0413\u0440\u0443\u043F\u0438 index.intro=\u0422\u043E\u0437\u0438 \u0441\u043F\u0438\u0441\u044A\u043A \u043F\u043E\u043A\u0430\u0437\u0432\u0430 \u0432\u0441\u0438\u0447\u043A\u0438 \u0433\u0440\u0443\u043F\u0438 \u043F\u043E \u043F\u0440\u043E\u0435\u043A\u0442\u0438, \u0443\u0447\u0435\u0431\u043D\u0438 \u0433\u0440\u0443\u043F\u0438 \u0438 \u0433\u0440\u0443\u043F\u0438 \u0441\u044A\u0441 \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u043D\u0438 \u043F\u0440\u0430\u0432\u0430, \u0432 \u043A\u043E\u0438\u0442\u043E \u0443\u0447\u0430\u0441\u0442\u0432\u0430\u0442\u0435. index.table.nogroup=\u041D\u0435 \u0441\u0442\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0430\u043D\u0438 \u0432 \u043D\u0438\u043A\u043E\u044F \u0433\u0440\u0443\u043F\u0430. info.group.deleted=\u0422\u0430\u0437\u0438 \u0433\u0440\u0443\u043F\u0430 \u043F\u043E \u043F\u0440\u043E\u0435\u043A\u0442\u0438 \u0435 \u0438\u0437\u0442\u0440\u0438\u0442\u0430. -learning.header=\u0423\u0447\u0435\u0431\u043D\u0438 \u0433\u0440\u0443\u043F\u0438 -learning.intro=\u0422\u043E\u0437\u0438 \u0441\u043F\u0438\u0441\u044A\u043A \u043F\u043E\u043A\u0430\u0437\u0432\u0430 \u0432\u0441\u0438\u0447\u043A\u0438 \u0443\u0447\u0435\u0431\u043D\u0438 \u0433\u0440\u0443\u043F\u0438, \u0432 \u043A\u043E\u0438\u0442\u043E \u0443\u0447\u0430\u0441\u0442\u0432\u0430\u0442\u0435. + + menu.index=\u0413\u0440\u0443\u043F\u0438 menu.index.alt=\u0420\u0430\u0431\u043E\u0442\u0435\u0442\u0435 \u0441 \u0432\u0430\u0448\u0438\u0442\u0435 \u0433\u0440\u0443\u043F\u0438 msg.atleastone=\u0422\u0440\u044F\u0431\u0432\u0430 \u0434\u0430 \u0438\u043C\u0430 \u043F\u043E\u043D\u0435 \u0435\u0434\u0438\u043D \u0441\u043E\u0431\u0441\u0442\u0432\u0435\u043D\u0438\u043A \u0432 \u0442\u0430\u0437\u0438 \u0433\u0440\u0443\u043F\u0430 \u043F\u043E \u043F\u0440\u043E\u0435\u043A\u0442\u0438. -right.header=\u0413\u0440\u0443\u043F\u0438 \u0441\u044A\u0441 \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u043D\u0438 \u043F\u0440\u0430\u0432\u0430 -right.intro=\u0422\u043E\u0437\u0438 \u0441\u043F\u0438\u0441\u044A\u043A \u043F\u043E\u043A\u0430\u0437\u0432\u0430 \u0432\u0441\u0438\u0447\u043A\u0438 \u0433\u0440\u0443\u043F\u0438 \u0441\u044A\u0441 \u0441\u043F\u0435\u0446\u0438\u0430\u043B\u043D\u0438 \u043F\u0440\u0430\u0432\u0430, \u0432 \u043A\u043E\u0438\u0442\u043E \u0443\u0447\u0430\u0441\u0442\u0432\u0430\u0442\u0435. + + table.header.bgname=\u0418\u043C\u0435 table.header.delete=\u0418\u0437\u0442\u0440\u0438\u0439\u0442\u0435 table.header.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_cs.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_cs.properties index f7ec13d1b606b9fe09a1729684573b609a09d0c6..e09d2a2bdbfea61e2a118bef79c42615f641c954 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_cs.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_cs.properties @@ -5,15 +5,15 @@ dialog.modal.bg.leave.text=Pokud opust\u00EDte projektovou skupinu "{0}" ji\u017 index.header=Skupiny index.intro=Seznam v\u0161ech projektov\u00FDch, studijn\u00EDch a pr\u00E1vn\u00EDch skupin, v nich\u017E jste za\u0159azen index.table.nogroup=Nejste za\u0159azen v \u017E\u00E1dn\u00E9 skupin\u011B -learning.header=Studijn\u00ED skupiny -learning.intro=N\u00E1sleduj\u00EDc\u00ED seznam ukazuje v\u0161echny studijn\u00ED skupiny, ve kter\u00FDch jste za\u0159azen + + menu.index=Skupiny menu.index.alt=Pr\u00E1ce se skupinami menu.rightgroups=Moje skupiny pr\u00E1v menu.rightgroups.alt=Pr\u00E1ce s osobn\u00EDmi skupinami pr\u00E1v msg.atleastone=V projektov\u00E9 skupin\u011B mus\u00ED existovat alespo\u0148 jeden vlastn\u00EDk -right.header=Skupiny pr\u00E1v -right.intro=Seznam v\u0161ech skupin pr\u00E1v, ve kter\u00FDch jste za\u0159azen + + table.header.bgname=Jm\u00E9no table.header.delete=Vymazat table.header.description=Popis diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_da.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_da.properties index fe3fbc87ce28465ca60cc0890c2e0546554a9809..14fdec47747b977c9dfdf5e202c323edea428d30 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_da.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_da.properties @@ -5,13 +5,13 @@ dialog.modal.bg.leave.text=Hvis du forlader projektgruppen "{0}" vil du ikke l\u index.header=Grupper index.intro=Den f\u00F8lgende liste viser alle projekter, l\u00E6rings og rettigheds-grupper du er medlem af. index.table.nogroup=Du er ikke registreret i nogen grupper. -learning.header=L\u00E6ringsgrupper -learning.intro=Den f\u00F8lgende liste viser alle l\u00E6ringsgrupper du er medlem af. + + menu.index=Grupper menu.index.alt=Arbejd med dine grupper msg.atleastone=Der skal v\u00E6re mindst en ejer i denne projektgruppe. -right.header=Rettighedsgrupper -right.intro=Den f\u00F8lgende liste viser alle rettighedsgrupper du er medlem af. + + table.header.bgname=Navn table.header.delete=Slet table.header.description=Beskrivelse diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties index 3e2a1e64d18a253e4d56a998578ec8c577baa964..5b7486b8caab24b9b446c53a976f09de5dee43f7 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_de.properties @@ -7,20 +7,22 @@ deup.members=Mitglieder bereinigen dedup.members.typ=Rolle dedup.members.coaches=Betreuer dedup.members.particpants=Teilnehmer -dedup.members.info=<p>Wollen Sie die Mitglieder wirklich bereinigen? Bei diesem Prozess werden die jenigen Benutzer als Kursmitglieder ausgetragen welche sowohl Kursmitglieder als auch Gruppenmitglied des Kurses sind (Duplikate).<p> -dedup.members.info2={0} Mitglieder wurden gefunden welche sowohl Kursmitglieder wie auch Gruppenmitglieder dieses Kurses sind. Die Gruppenmitgliedschaften werden nicht verändert, der Zugriff zum Kurs bleibt bestehen. +dedup.members.info1=Wollen Sie die Mitglieder wirklich bereinigen? +dedup.members.info2=Bei diesem Prozess werden jene Benutzer als Kursmitglieder ausgetragen, die sowohl Kurs- als auch Gruppenmitglied des Kurses sind (Duplikate). +dedup.members.info3={0} Benutzer wurden gefunden die sowohl Kursmitglieder als auch Gruppenmitglieder des Kurses sind. +dedup.members.info4=Wählen Sie ob die Bereinigung für Betreuer und/oder die Teilnehmer durchgeführt werden soll. dialog.modal.bg.delete.title=Gruppe l\u00F6schen? dialog.modal.bg.delete.text=Wollen Sie die Gruppe "{0}" wirklich l\u00F6schen? dialog.modal.bg.mail.text=Wollen Sie die Mitglieder per Mail benachrichtigen? -dialog.modal.bg.leave.text=Wenn Sie die Arbeitsgruppe "{0}" verlassen, haben Sie keinen Zugang mehr. <br> Wollen Sie die Arbeitsgruppe wirklich verlassen?<p> +dialog.modal.bg.leave.text=Wenn Sie die Gruppe "{0}" verlassen, haben Sie keinen Zugang mehr. <br> Wollen Sie die Gruppe wirklich verlassen?<p> main.menu.title=Gruppen main.menu.title.alt=Gruppen index.header=Gruppen -index.intro=In der untenstehenden Liste finden Sie alle Arbeits-, Lern- und Rechtegruppen, an denen Sie teilnehmen. +index.intro=In der untenstehenden Liste finden Sie alle Gruppen, an denen Sie teilnehmen. index.table.nogroup=Sie sind in keiner Gruppe eingetragen. -info.group.deleted=Die Arbeitsgruppe wurde gel\u00F6scht. -learning.header=Lerngruppen -learning.intro=In der untenstehenden Liste finden Sie alle Lerngruppen, an denen Sie teilnehmen. +info.group.deleted=Die Gruppe wurde gel\u00F6scht. + + menu.group.admin=Gruppenverwaltung menu.group.admin.alt=Gruppenverwaltung menu.index=Gruppen @@ -31,8 +33,8 @@ menu.opengroups=Ver\u00F6ffentlichte Gruppen menu.opengroups.alt=Arbeitsgruppen in die \u00F6ffentlich sind und an denen ich teilnehmen kann. msg.atleastone=Es muss mindestens ein Betreuer in der Gruppe eingetragen sein. msg.alleastone.editable.group=Sie m\u00FCssen mindestens eine Gruppe wählen, die Sie besitzen. -right.header=Rechtegruppen -right.intro=In dieser Liste finden Sie alle Rechtegruppen, an denen Sie teilnehmen. + + open.header=Öffentliche Gruppen open.intro=In dieser Liste finden Sie alle ver\u00F6ffentlichten Gruppen denen Sie beitreten k\u00F6nnen. open.nogroup=Es wurden keine Gruppe gefunden die Ihren Kriterien entsprechen. @@ -79,7 +81,7 @@ table.header.leave.waiting=Verlassen table.header.group.full=Voll belegt table.header.mark=Favorit table.header.type=Typ -table.header.resources=Kurs +table.header.resources=Kurse table.header.role=Rolle table.header.firstTime=Beitritt table.header.lastTime=Zuletzt besucht @@ -119,7 +121,7 @@ notification.mail.removed.self.subject=Gruppe $groupname\: Sie haben sich ausget notification.mail.removed.subject=Gruppe $groupname\: Sie wurden ausgetragen. -pending.reservations=Pending reservations +pending.reservations=<h4>Bestätigung Teilnahme in Gruppen und Kursen</h4>Sie wurden in die folgenden Gruppen oder Kurse eingeladen. Wählen Sie für alle aufgeführten Gruppe und Kurse die Schaltfläche "$:accept" oder "$:reject" und schliessen Sie mit "$org.olat.core:ok" ab. Sie können die Bestätigung auch zu einem späteren Zeitpunkt durchführen, wählen Sie in dem Fall "$org.olat.core:cancel". course.membership.creation=Kurs Beitritt course.lastTime=Zuletzt geöffnet @@ -139,13 +141,13 @@ role.group.waiting=Warteliste role.repo.owner=Besitzer role.repo.tutor=Betreuer role.repo.participant=Teilnehmer -role.pending=Pending +role.pending=Bestätigung ausstehend edit.member.title=Mitgliederrechte Kurs "{0}" table.header.edit=Bearbeiten table.header.remove=Entfernen -table.header.graduate=Graduate +table.header.graduate=Zulassen tbl_graduate=$:table.header.graduate table.header.firstName=Vorname table.header.lastName=Name @@ -161,11 +163,17 @@ table.header.tutors=Betreuer table.header.participants=Teilnehmer table.header.waitingList=Warteliste -accept=Accept -reject=Reject +reservation.coach=als Betreuer +group.used.in.course=Diese Gruppe wird verwendet in folgenden Kursen: +accept=Bestätigen +reject=Ablehnen + +confirm.accept=Mitgliedschaft wird bestätigt +confirm.reject=Mitgliedschaft wird abgelehnt + nomembers=Es wurden keine Mitglieder gefunden die Ihren Kriterien entsprechen. -hide=Hide -show=Show +hide=Informationen ausblenden +show=Weitere Informationen diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_el.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_el.properties index da4f3f502f81acf37f4c04df2c869aa4b4e6c34a..648a80338ffda3c06e2be45d3259620b45186cb2 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_el.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_el.properties @@ -6,13 +6,13 @@ index.header=\u039F\u03BC\u03AC\u03B4\u03B5\u03C2 index.intro=\u0397 \u03C0\u03B1\u03C1\u03B1\u03BA\u03AC\u03C4\u03C9 \u03BB\u03AF\u03C3\u03C4\u03B1 \u03C0\u03B1\u03C1\u03BF\u03C5\u03C3\u03B9\u03AC\u03B6\u03B5\u03B9 \u03CC\u03BB\u03B5\u03C2 \u03C4\u03B9\u03C2 \u03BF\u03BC\u03AC\u03B4\u03B5\u03C2 \u03B5\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1\u03C2, \u03BC\u03AC\u03B8\u03B7\u03C3\u03B7\u03C2 \u03BA\u03B1\u03B9 \u03B4\u03B9\u03BA\u03B1\u03B9\u03C9\u03BC\u03AC\u03C4\u03C9\u03BD \u03C3\u03C4\u03B9\u03C2 \u03BF\u03C0\u03BF\u03AF\u03B5\u03C2 \u03C3\u03C5\u03BC\u03BC\u03B5\u03C4\u03AD\u03C7\u03B5\u03C4\u03B5. index.table.nogroup=\u0394\u03B5\u03BD \u03B5\u03AF\u03C3\u03C4\u03B5 \u03B5\u03B3\u03B3\u03B5\u03B3\u03C1\u03B1\u03BC\u03BC\u03AD\u03BD\u03BF\u03C2 \u03C3\u03B5 \u03BA\u03B1\u03BC\u03AF\u03B1 \u03BF\u03BC\u03AC\u03B4\u03B1. info.group.deleted=\u0397 \u03BF\u03BC\u03AC\u03B4\u03B1 \u03B5\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1\u03C2 \u03AD\u03C7\u03B5\u03B9 \u03B4\u03B9\u03B1\u03B3\u03C1\u03B1\u03C6\u03B5\u03AF. -learning.header=\u039F\u03BC\u03AC\u03B4\u03B5\u03C2 \u03BC\u03AC\u03B8\u03B7\u03C3\u03B7\u03C2 -learning.intro=\u0397 \u03C0\u03B1\u03C1\u03B1\u03BA\u03AC\u03C4\u03C9 \u03BB\u03AF\u03C3\u03C4\u03B1 \u03C0\u03B1\u03C1\u03BF\u03C5\u03C3\u03B9\u03AC\u03B6\u03B5\u03B9 \u03CC\u03BB\u03B5\u03C2 \u03C4\u03B9\u03C2 \u03BF\u03BC\u03AC\u03B4\u03B5\u03C2 \u03BC\u03AC\u03B8\u03B7\u03C3\u03B7\u03C2 \u03C3\u03C4\u03B9\u03C2 \u03BF\u03C0\u03BF\u03AF\u03B5\u03C2 \u03C3\u03C5\u03BC\u03BC\u03B5\u03C4\u03AD\u03C7\u03B5\u03C4\u03B5. + + menu.index=\u039F\u03BC\u03AC\u03B4\u03B5\u03C2 menu.index.alt=\u0395\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1 \u03BC\u03B5 \u03C4\u03B9\u03C2 \u03BF\u03BC\u03AC\u03B4\u03B5\u03C2 \u03C3\u03B1\u03C2 msg.atleastone=\u03A0\u03C1\u03AD\u03C0\u03B5\u03B9 \u03BD\u03B1 \u03C5\u03C0\u03AC\u03C1\u03C7\u03B5\u03B9 \u03C4\u03BF\u03C5\u03BB\u03AC\u03C7\u03B9\u03C3\u03C4\u03BF\u03BD \u03AD\u03BD\u03B1\u03C2 \u03BA\u03AC\u03C4\u03BF\u03C7\u03BF\u03C2 \u03C3\u03C4\u03B7\u03BD \u03BF\u03BC\u03AC\u03B4\u03B1 \u03B5\u03C1\u03B3\u03B1\u03C3\u03AF\u03B1\u03C2. -right.header=\u039F\u03BC\u03AC\u03B4\u03B5\u03C2 \u03B4\u03B9\u03BA\u03B1\u03B9\u03C9\u03BC\u03AC\u03C4\u03C9\u03BD -right.intro=\u0397 \u03C0\u03B1\u03C1\u03B1\u03BA\u03AC\u03C4\u03C9 \u03BB\u03AF\u03C3\u03C4\u03B1 \u03C0\u03B1\u03C1\u03BF\u03C5\u03C3\u03B9\u03AC\u03B6\u03B5\u03B9 \u03CC\u03BB\u03B5\u03C2 \u03C4\u03B9\u03C2 \u03BF\u03BC\u03AC\u03B4\u03B5\u03C2 \u03B4\u03B9\u03BA\u03B1\u03B9\u03C9\u03BC\u03AC\u03C4\u03C9\u03BD \u03C3\u03C4\u03B9\u03C2 \u03BF\u03C0\u03BF\u03AF\u03B5\u03C2 \u03C3\u03C5\u03BC\u03BC\u03B5\u03C4\u03AD\u03C7\u03B5\u03C4\u03B5. + + table.header.bgname=\u038C\u03BD\u03BF\u03BC\u03B1 table.header.delete=\u0394\u03B9\u03B1\u03B3\u03C1\u03B1\u03C6\u03AE table.header.description=\u03A0\u03B5\u03C1\u03B9\u03B3\u03C1\u03B1\u03C6\u03AE diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties index 24e05843df28d7a70af6bb06c114e70c1c8615d0..c67f5b24cee002adea996b56748882eaa3743d8f 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_en.properties @@ -1,5 +1,8 @@ -#Thu Nov 29 14:24:42 CET 2012 +#Tue Dec 18 17:12:34 CET 2012 +accept=Confirm action=Action +add.member=Add member +assessment=Assessment tool cif.coursetitle=Course title cif.description=Description cif.displayname=Name @@ -7,14 +10,22 @@ cif.error.allempty=Please fill at least one form field. cif.id=ID cif.owner=Coach config.group=Configure +confirm.accept=accept membership +confirm.reject=reject membership copy.group=Duplicate course.groups=From courses +course.lastTime=Last usage +course.membership.creation=Added date +course.numOfVisits=Visits create.form.title=Create a new group create.group=Create group create.group.description=Create a new group with the button below. As coach of this group you may then unlock the group tools, add users or publish the group. dedup.members.coaches=Coach dedup.members.info=<p>Do you really want to purge course members? This process will remove course memberships of users that are course and group members at the same time (duplikats). <p> +dedup.members.info1=Do you really want to purge all members? dedup.members.info2={0} members have been found that have both a course and a group memberships of this course. The group memberships will not be modified, access to the course remains unchanged. +dedup.members.info3={0} users have been identified that are both course members and group members of the same course. +dedup.members.info4=Choose if the purging of members shall be done for coaches and/or participants. dedup.members.particpants=Participants dedup.members.typ=Role deup.members=Purge members @@ -22,14 +33,19 @@ dialog.modal.bg.delete.text=Do you really want to delete the group "{0}" ?<p> dialog.modal.bg.delete.title=Delete group? dialog.modal.bg.leave.text=If you leave the group "{0}" you will no longer have access. <br>Do you really want to leave this group?<p> dialog.modal.bg.mail.text=Do you want to inform the members of this group by email? +edit.member=Edit membership +edit.member.groups=Group memberships +edit.member.title=Member rights course {0} email.group=Send E-mail group.access.success=Access to group is successful +group.used.in.course=This group is used in the following courses\: +hide=Hide information +home=Visiting card +import.member=Add members index.header=Groups index.intro=The following list shows all groups, learning groups, and right groups you participate in. index.table.nogroup=You are not registered in any group. info.group.deleted=This group has been deleted. -learning.header=Learning groups -learning.intro=The following list shows all learning groups you participate in. main.menu.title=Groups main.menu.title.alt=Groups marked.groups=Bookmark @@ -44,6 +60,7 @@ menu.opengroups.alt=Groups that are published and bookable. merge.group=Merge msg.alleastone.editable.group=You must select at least one group you own. msg.atleastone=There must be at least one coach in this group. +nomembers=No members found that matches the given criteria. notification.mail.added.body=*** This is an automated message. Please do not reply *** \r\n\r\nYou were invited to a group by {0} {1} ({3})\: \r\n\r\nGroup name\: $groupname\r\nDescription\: $groupdescription\r\n\r\nIf you do not agree, you can sign out from this group. notification.mail.added.self.body=*** This is an automated message. Please do not reply *** \r\n\r\nYou have created a group in OLAT\: \r\n\r\nGroup name\: $groupname\r\nDescription\: $groupdescription\r\n\r\nYou can delete this group anytime. notification.mail.added.self.subject=Group $groupname @@ -61,8 +78,16 @@ opengroups.all=All groups opengroups.search=Search owned.groups=Coach owned.groups.2=Coached -right.header=Right groups -right.intro=The following list shows all right groups you participate in. +pending.reservations=<h4>Accept group and course memberships</h4>You have been invited to the following groups and courses. For each listed groups and courses select the button "$\:accept" or "$\:reject" and finally save your choice with the button "$org.olat.core\:ok". You can safely skip this question now using the button "$org.olat.core\:cancel" and answer them on your next login. +reject=Reject +reservation.coach=as coach +role.group.participant=Group member +role.group.tutor=Group coach +role.group.waiting=Waiting list +role.pending=Acceptance pending +role.repo.owner=Owner +role.repo.participant=Participant +role.repo.tutor=Coach search.all=all search.attendee=Participant search.generic=Search mask @@ -80,6 +105,7 @@ search.resources=Linked with courses search.roles=Role search.waiting=Waiting list search.yes=yes +show=More information table.access=Book table.access.waitingList=Add to waiting list table.config=Configure @@ -93,24 +119,35 @@ table.header.businesscard=Contact table.header.delete=Delete table.header.description=Description table.header.edit=Edit +table.header.firstName=First name table.header.firstTime=Registration +table.header.freePlace=Available table.header.freePlaces=Slots +table.header.graduate=Admit table.header.group.full=Full +table.header.groups=Group table.header.key=ID +table.header.lastName=Lastname table.header.lastTime=Last visit table.header.lastUsage=Last access (admin) table.header.leave=Leave table.header.leave.waiting=Leave +table.header.mail=E-mail table.header.mark=Bookmark +table.header.participants=Participant table.header.participantsCount=Assigned +table.header.remove=Remove table.header.resources=Course table.header.role=Role +table.header.tutors=Coach table.header.tutorsCount=Coach table.header.type=Type +table.header.waitingList=Waiting list table.header.waitingListCount=Waiting list table.leave=Leave table.merge=Merge table.users.management=Manage members +tbl_graduate=$\:table.header.graduate tools.add.buddygroup=Group tools.add.header=Create tools.delete.header=Delete diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_es.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_es.properties index 3b41b5ab2ea41b0f7d5623eab512793aed97da62..71b76b2e5229fc85e8ece96fea1bb5972a4f7af0 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_es.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_es.properties @@ -6,13 +6,13 @@ index.header=Grupos index.intro=La lista siguiente muestra todos los grupos de colaboraci\u00F3n, de estudios y de permisos en los que t\u00FA participas. index.table.nogroup=No est\u00E1s registrado en ning\u00FAn grupo. info.group.deleted=Este grupo de colaboraci\u00F3n se ha eliminado -learning.header=Grupos de estudios -learning.intro=La lista siguiente muestra todos los grupos de estudios en los que participas. + + menu.index=Grupos menu.index.alt=Trabaja con tus grupos msg.atleastone=Al menos debe haber un propietario en el grupo de colaboraci\u00F3n. -right.header=Grupos de permisos -right.intro=La lista siguiente muestra todos los grupos de permisos en los que participas. + + table.header.bgname=Nombre table.header.delete=Eliminar table.header.description=Descripci\u00F3n diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fa.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fa.properties index 7a39871ceb7b7093ebc8da43bc2c6ff20b4ca6e2..4f825590701a46068b73581e38c03ee76f335257 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fa.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fa.properties @@ -5,13 +5,13 @@ dialog.modal.bg.leave.text=\u0627\u06AF\u0631 \u0634\u0645\u0627 \u0645\u06CC \u index.header=\u06AF\u0631\u0648\u0647\u0647\u0627 index.intro=\u0644\u064A\u0633\u062A \u067E\u0627\u064A\u064A\u0646 \u062A\u0645\u0627\u0645 \u06AF\u0631\u0648\u0647 \u0647\u0627\u06CC \u0622\u0645\u0648\u0632\u0634\u06CC \u0648 \u0631\u0627\u064A\u062A \u06AF\u0631\u0648\u0647 \u0647\u0627\u064A\u064A \u0631\u0627 \u06A9\u0647 \u062F\u0631 \u0622\u0646 \u0645\u0634\u0627\u0631\u06A9\u062A \u062F\u0627\u0634\u062A\u0647 \u0627\u064A\u062F \u0646\u0645\u0627\u064A\u0634 \u0645\u064A \u062F\u0647\u062F index.table.nogroup=\u0634\u0645\u0627 \u062F\u0631 \u0627\u06CC\u0646 \u06AF\u0631\u0648\u0647 \u062B\u0628\u062A \u0646\u0627\u0645 \u0646\u06A9\u0631\u062F\u0646 \u0627\u06CC\u062F -learning.header=\u06AF\u0631\u0648\u0647 \u0622\u0645\u0648\u0632\u0634\u06CC -learning.intro=\u062F\u0646\u0628\u0627\u0644 \u06A9\u0631\u062F\u0646 \u0644\u06CC\u0633\u062A \u0646\u0645\u0627\u06CC\u0634 \u062A\u0645\u0627\u0645 \u06AF\u0631\u0648\u0647 \u0647\u0627\u06CC \u0622\u0645\u0648\u0632\u0634\u06CC \u0648 \u0634\u0631\u06CC\u06A9 \u0634\u062F\u0646 \u062F\u0631 \u0627\u0646\u0647\u0627 + + menu.index=\u06AF\u0631\u0648\u0647 \u0647\u0627 menu.index.alt=\u0641\u0639\u0627\u0644\u06CC\u062A \u062F\u0631 \u0627\u06CC\u0646 \u06AF\u0631\u0648\u0647 msg.atleastone=\u0634\u0645\u0627 \u062D\u062F\u0627\u0642\u0644 \u0628\u0627\u06CC\u062F \u062F\u0631 \u0627\u06CC\u0646 \u06AF\u0631\u0648\u0647 \u06A9\u0627\u0631\u06CC \u0645\u0634\u0627\u0631\u06A9\u062A \u062F\u0627\u0634\u062A\u0647 \u0628\u0627\u0634\u06CC\u062F -right.header=\u06AF\u0631\u0648\u0647\u0647\u0627\u06CC \u062F\u0631\u0633\u062A -right.intro=\u0644\u064A\u0633\u062A \u067E\u0627\u064A\u064A\u0646 \u062A\u0645\u0627\u0645\u064A \u0631\u0627\u064A\u062A \u06AF\u0631\u0648\u0647 \u0647\u0627\u064A\u064A \u0631\u0627 \u06A9\u0647 \u062F\u0631 \u0622\u0646 \u0645\u0634\u0627\u0631\u06A9\u062A \u062F\u0627\u0634\u062A\u0647 \u0627\u064A\u062F \u0646\u0645\u0627\u064A\u0634 \u0645\u064A \u062F\u0647\u062F + + table.header.bgname=\u0646\u0627\u0645 table.header.delete=\u062D\u0630\u0641 table.header.description=\u0634\u0631\u062D diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties index 8ff73a1b606720eb4f1524c12d7bda4a86c718f9..3b9885614fe775c3c6beb35c8276b875671aaf1c 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_fr.properties @@ -22,8 +22,8 @@ index.header=Groupes index.intro=Dans la liste ci-dessus, vous trouvez tous les groupes de travail, d'\u00E9tude et de droits dont vous faites partie. index.table.nogroup=Vous ne faites partie d'aucun groupe. info.group.deleted=Le groupe de travail a \u00E9t\u00E9 effac\u00E9 -learning.header=Groupes d'\u00E9tudes -learning.intro=Dans la liste ci-dessus, vous trouvez tous les groupes d'\u00E9tude dont vous faites partie. + + main.menu.title=Groupes main.menu.title.alt=Groupes marked.groups=Favoris @@ -55,8 +55,8 @@ opengroups.all=Tous les groupes opengroups.search=Recherche owned.groups=Coach owned.groups.2=Supervis\u00E9 -right.header=Groupes de droits -right.intro=Dans la liste ci-dessus, vous trouvez tous les groupes de droits dont vous faites partie. + + search.all=tous search.attendee=Participant search.generic=Recherche @@ -90,6 +90,7 @@ table.header.edit=Modifier table.header.firstTime=Souscription table.header.freePlaces=Places table.header.group.full=Plein +table.header.graduate=Promouvoir table.header.key=ID table.header.lastTime=Derni\u00E8re visite table.header.lastUsage=Derni\u00E8re utilisation diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_it.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_it.properties index e95a9c9b2c992d5da776894273c936db487b0174..dae038e89cabcb9af2f6dcae0a68207cea58581f 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_it.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_it.properties @@ -18,8 +18,8 @@ index.header=Gruppi index.intro=Nella lista sottostante trova tutti i gruppi di lavoro, di studio e con diritti a cui partecipa. index.table.nogroup=Lei non \u00E8 registrata/o in alcun gruppo. info.group.deleted=Il gruppo di lavoro \u00E8 stato eliminato -learning.header=Gruppi di studio -learning.intro=Nella lista sottostante trova tutti i gruppi di studio a cui partecipa. + + menu.index=Gruppi menu.index.alt=Lavori con i Suoi gruppi. msg.atleastone=Nel gruppo di lavoro deve essere registrato almeno una/un proprietaria/o. @@ -35,8 +35,8 @@ notification.mail.removed.self.subject=Gruppo di lavoro OLAT $groupname\: Lei si notification.mail.removed.subject=Gruppo di lavoro OLAT $groupname\: \u00E8 stata/o disiscritta/o. owned.groups=Proprietario owned.groups.2=Di propriet\u00E0 -right.header=Gruppi con diritti -right.intro=In questa lista trova tutti i gruppi con diritti a cui partecipa. + + search.owner=Proprietario table.header.bgname=Nome table.header.delete=Eliminare diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_jp.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_jp.properties index 131780bbc5266155bef9a7a67d7c01db80515bb9..470a7da7802a8e56576764d526940606198a2b78 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_jp.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_jp.properties @@ -5,11 +5,11 @@ index.header=\u30B0\u30EB\u30FC\u30D7 index.intro=\u4EE5\u4E0B\u306E\u30EA\u30B9\u30C8\u3067\u306F\u3001\u3042\u306A\u305F\u304C\u53C2\u52A0\u3057\u3066\u3044\u308B\u3001\u3059\u3079\u3066\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3001\u5B66\u7FD2\u304A\u3088\u3073\u6A29\u5229\u30B0\u30EB\u30FC\u30D7\u304C\u8868\u793A\u3055\u308C\u3066\u3044\u307E\u3059\u3002 index.table.nogroup=\u3042\u306A\u305F\u306F\u3001\u3069\u306E\u30B0\u30EB\u30FC\u30D7\u306B\u3082\u767B\u9332\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002 info.group.deleted=\u3053\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u30B0\u30EB\u30FC\u30D7\u306F\u3001\u524A\u9664\u3055\u308C\u307E\u3057\u305F\u3002 -learning.header=\u5B66\u7FD2\u30B0\u30EB\u30FC\u30D7 -learning.intro=\u4EE5\u4E0B\u306E\u30EA\u30B9\u30C8\u3067\u306F\u3001\u3042\u306A\u305F\u304C\u53C2\u52A0\u3057\u3066\u3044\u308B\u3001\u3059\u3079\u3066\u306E\u5B66\u7FD2\u30B0\u30EB\u30FC\u30D7\u304C\u8868\u793A\u3055\u308C\u3066\u3044\u307E\u3059\u3002 + + menu.index=\u30B0\u30EB\u30FC\u30D7 -right.header=\u6A29\u5229\u30B0\u30EB\u30FC\u30D7 -right.intro=\u4EE5\u4E0B\u306E\u30EA\u30B9\u30C8\u3067\u306F\u3001\u3042\u306A\u305F\u304C\u53C2\u52A0\u3057\u3066\u3044\u308B\u3001\u3059\u3079\u3066\u306E\u6A29\u5229\u30B0\u30EB\u30FC\u30D7\u304C\u8868\u793A\u3055\u308C\u3066\u3044\u307E\u3059\u3002 + + table.header.bgname=\u540D\u79F0 table.header.delete=\u524A\u9664 table.header.description=\u8AAC\u660E diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_lt.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_lt.properties index ca0821ad0648bde4889f3945891c81b1ce0763cb..ffa52d7bca9f35c6d9df19c71f87dd7e214678df 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_lt.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_lt.properties @@ -5,13 +5,13 @@ dialog.modal.bg.leave.text=Jeigu j\u016Bs paliekate projekto grup\u0119 "{0}", j index.header=Grup\u0117s index.intro=\u0160is s\u0105ra\u0161as parodo visus projektus, mokymosi ir teisi\u0173 grupes, kuriose j\u016Bs dalyvaujate. index.table.nogroup=J\u016Bs nesate priregistruotas jokioje grup\u0117je. -learning.header=Mokymosi grup\u0117s -learning.intro=\u0160is s\u0105ra\u0161as parodo visas mokymo grupes, kuriose j\u016Bs dalyvaujate. + + menu.index=Grup\u0117s menu.index.alt=Dirbti su savo grup\u0117mis msg.atleastone=Turi b\u016Bti ma\u017Eiausiai vienas savininkas \u0161ioje projekto grup\u0117je. -right.header=Teisi\u0173 grup\u0117s -right.intro=\u0160is s\u0105ra\u0161as parodo visas teisi\u0173 grupes, kuriose j\u016Bs dalyvaujate. + + table.header.bgname=Pavadinimas table.header.delete=Pa\u0161alinti table.header.description=Apib\u016Bdinimas diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_nl_NL.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_nl_NL.properties index 40aaf0203e8db805eb842afe0bd2f08559ecaecb..7cec03588334a6740b9e1e4e3a10ab9d2c7fadea 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_nl_NL.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_nl_NL.properties @@ -6,13 +6,13 @@ index.header=Groepen index.intro=Volgende lijst toont alle werk-, leer- en rechtgroepen waaraan je deelneemt. index.table.nogroup=Je bent in geen enkele groep ingeschreven. info.group.deleted=Deze werkgroep werd verwijderd. -learning.header=Leergroepen -learning.intro=Volgende lijst toont alle leergroepen waaraan je deelneemt. + + menu.index=Groepen menu.index.alt=Werk met jouw groepen msg.atleastone=Er moet minstens een eigenaar zijn in deze werkgroep. -right.header=Rechtgroepen -right.intro=Volgende link toont alle rechtgroepen waaraan je deelneemt. + + table.header.bgname=Naam table.header.delete=Wissen table.header.description=Beschrijving diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pl.properties index 1625ffed6639ade4b9e6770427bed80be09121ba..0ec700c975725fa7453cb5aa2bee7a9ea17590e3 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pl.properties @@ -6,15 +6,15 @@ index.header=Grupy index.intro=Poni\u017Csza lista pokazuje wszystkie grupy projektu, grupy edukacyjne i grupy uprawnie\u0144, w kt\u00F3rych uczestniczysz. index.table.nogroup=Nie jeste\u015B w \u017Cadnej grupie. info.group.deleted=Grupa projektu zosta\u0142a usuni\u0119ta. -learning.header=Grupy edukacyjne -learning.intro=Poni\u017Csza lista pokazuje wszystkie grupy edukacyjne, w kt\u00F3rych uczestniczysz. + + menu.index=Grupy menu.index.alt=Pracuj ze swoimi grupami menu.opengroups=Grupy "opublikowane" menu.opengroups.alt="Opublikowane" grupy projektu z otwart\u0105 rejestracj\u0105 msg.atleastone=W grupie projektu musi by\u0107 co najmniej jeden w\u0142a\u015Bciciel. -right.header=Grupy uprawnie\u0144 -right.intro=Poni\u017Csza lista pokazuje wszystkie grupy uprawnie\u0144, w kt\u00F3rych uczestniczysz. + + table.header.bgname=Nazwa table.header.delete=Usu\u0144 table.header.description=Opis diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_BR.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_BR.properties index 4aa3a69bbdde0c1cdeb89592a62a235f9d4328a9..5522becbb569c6d615f3792257e7c50e61f67523 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_BR.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_BR.properties @@ -22,8 +22,8 @@ index.header=Grupos index.intro=A seguinte lista mostra todos os grupos de projeto, estudo e direitos que voc\u00EA participa. index.table.nogroup=Voc\u00EA n\u00E3o est\u00E1 registrado em nenhum grupo. info.group.deleted=Esse grupo de projeto foi removido. -learning.header=Grupos de estudo -learning.intro=A seguinte lista mostra todos os grupos de estudo que voc\u00EA participa. + + main.menu.title=Grupos main.menu.title.alt=Grupos marked.groups=Favorito @@ -55,8 +55,8 @@ opengroups.all=Todos grupos opengroups.search=Buscar owned.groups=Treinador owned.groups.2=Treinados -right.header=Grupos de direitos -right.intro=A seguinte lista mostra todos os grupos de direitos que voc\u00EA participa. + + search.all=Todos search.attendee=Participante search.generic=M\u00E1scara de busca diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_PT.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_PT.properties index 4d1f8922dbaab7228eaa74d97ed422eccf3b2bc5..949c45e3e9ba86c99e326289b33f7d4735400805 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_PT.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_pt_PT.properties @@ -5,13 +5,13 @@ dialog.modal.bg.leave.text=Se voc\u00EA deixar o grupo de projeto "{0}" voc\u00E index.header=Grupos index.intro=A seguinte lista mostra todos os grupos de projeto, estudo e direitos que voc\u00EA participa. index.table.nogroup=Voc\u00EA n\u00E3o est\u00E1 registrado em nenhum grupo. -learning.header=Grupos de estudo -learning.intro=A seguinte lista mostra todos os grupos de estudo que voc\u00EA participa. + + menu.index=Grupos menu.index.alt=Trabalhar com seus grupos msg.atleastone=Deve haver no m\u00EDnimo um propriet\u00E1rio neste grupo de projeto. -right.header=Grupos de direitos -right.intro=A seguinte lista mostra todos os grupos de direitos que voc\u00EA participa. + + table.header.bgname=Nome table.header.delete=Apagar table.header.description=Descri\u00E7\u00E3o diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ru.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ru.properties index a0aa18f9cc065d4e8198d274adfc4148f0e81e7b..a11764a402602b354db7c43ad268542f3fbccee0 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ru.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_ru.properties @@ -6,13 +6,13 @@ index.header=\u0413\u0440\u0443\u043F\u043F\u044B index.intro=\u0412 \u043D\u0438\u0436\u0435\u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C \u0441\u043F\u0438\u0441\u043A\u0435 \u043D\u0430\u0445\u043E\u0434\u044F\u0442\u0441\u044F \u0432\u0441\u0435 \u0440\u0430\u0431\u043E\u0447\u0438\u0435 \u0433\u0440\u0443\u043F\u043F\u044B, \u0433\u0440\u0443\u043F\u043F\u044B \u043E\u0431\u0443\u0447\u0435\u043D\u0438\u044F \u0438 \u043F\u0440\u0430\u0432 \u0434\u043E\u0441\u0442\u0443\u043F\u0430, \u0432 \u043A\u043E\u0442\u043E\u0440\u044B\u0445 \u0432\u044B \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442\u0435. index.table.nogroup=\u0412\u044B \u043D\u0435 \u0437\u0430\u043D\u0435\u0441\u0435\u043D\u044B \u043D\u0438 \u0432 \u043E\u0434\u043D\u0443 \u0433\u0440\u0443\u043F\u043F\u0443. info.group.deleted=\u0420\u0430\u0431\u043E\u0447\u0430\u044F \u0433\u0440\u0443\u043F\u043F\u0430 \u0431\u044B\u043B\u0430 \u0443\u0434\u0430\u043B\u0435\u043D\u0430 -learning.header=\u0413\u0440\u0443\u043F\u043F\u044B \u043E\u0431\u0443\u0447\u0435\u043D\u0438\u044F -learning.intro=\u0412 \u043D\u0438\u0436\u0435\u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C \u0441\u043F\u0438\u0441\u043A\u0435 \u043D\u0430\u0445\u043E\u0434\u044F\u0442\u0441\u044F \u0432\u0441\u0435 \u0433\u0440\u0443\u043F\u043F\u044B \u043E\u0431\u0443\u0447\u0435\u043D\u0438\u044F, \u0432 \u043A\u043E\u0442\u043E\u0440\u044B\u0445 \u0432\u044B \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442\u0435. + + menu.index=\u0413\u0440\u0443\u043F\u043F\u044B menu.index.alt=\u0420\u0430\u0431\u043E\u0442\u0430 \u0441 \u0412\u0430\u0448\u0438\u043C\u0438 \u0433\u0440\u0443\u043F\u043F\u0430\u043C\u0438 msg.atleastone=\u041F\u043E \u043A\u0440\u0430\u0439\u043D\u0435\u0439 \u043C\u0435\u0440\u0435 \u043E\u0434\u0438\u043D \u0432\u043B\u0430\u0434\u0435\u043B\u0435\u0446 \u0434\u043E\u043B\u0436\u0435\u043D \u0431\u044B\u0442\u044C \u0437\u0430\u043D\u0435\u0441\u0451\u043D \u0432 \u0440\u0430\u0431\u043E\u0447\u0443\u044E \u0433\u0440\u0443\u043F\u043F\u0443. -right.header=\u0413\u0440\u0443\u043F\u043F\u044B \u043F\u0440\u0430\u0432 \u0434\u043E\u0441\u0442\u0443\u043F\u0430 -right.intro=\u0412 \u043D\u0438\u0436\u0435\u0443\u043A\u0430\u0437\u0430\u043D\u043D\u043E\u043C \u0441\u043F\u0438\u0441\u043A\u0435 \u043D\u0430\u0445\u043E\u0434\u044F\u0442\u0441\u044F \u0432\u0441\u0435 \u0433\u0440\u0443\u043F\u043F\u044B \u043F\u0440\u0430\u0432 \u0434\u043E\u0441\u0442\u0443\u043F\u0430, \u0432 \u043A\u043E\u0442\u043E\u0440\u044B\u0445 \u0432\u044B \u0443\u0447\u0430\u0441\u0442\u0432\u0443\u0435\u0442\u0435. + + table.header.bgname=\u0418\u043C\u044F table.header.delete=\u0423\u0434\u0430\u043B\u0438\u0442\u044C table.header.description=\u041E\u043F\u0438\u0441\u0430\u043D\u0438\u0435 diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_sq.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_sq.properties index 4e5b7237a7e4a30853f6a10fa2b77068be7bab00..3f079c4fc4035479d8d8092dc78dcc4a33df9979 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_sq.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_sq.properties @@ -5,13 +5,13 @@ dialog.modal.bg.leave.text=N\u00EBse ju e braktisni grupin e projektit "{0}" ju index.header=Grupet index.intro=Lista n\u00EB vijim shfaq t\u00EB gjitha grupet e projekteve, t\u00EB m\u00EBsimit dhe t\u00EB t\u00EB drejtave q\u00EB ju i p\u00EBrkisni. index.table.nogroup=Ju nuk jeni t\u00EB regjistruar n\u00EB ndonj\u00EB grup. -learning.header=Grupe m\u00EBsimit -learning.intro=Lista n\u00EB vijim shfaq t\u00EB gjitha grupet e m\u00EBsimi n\u00EB t\u00EB cilat ju merrni pjes\u00EB. + + menu.index=Grupet menu.index.alt=Puna me grupet tuaja msg.atleastone=Duhet t\u00EB ket\u00EB t\u00EB pakt\u00EBn nj\u00EB pronar n\u00EB grup projekti. -right.header=Grupet e t\u00EB t\u00EB drejtave -right.intro=Lisa n\u00EB vijim shfaq t\u00EB gjitha grupet e t\u00EB drejtave n\u00EB t\u00EB cilat ju i p\u00EBrkisni. + + table.header.bgname=Emri table.header.delete=Fshij table.header.description=P\u00EBrshkrimi diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_CN.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_CN.properties index 9ce01a7b2bc246ac1a9d1aa88cb3740dbae06de4..5cddc022f9c8eb64bb9107cbc437181859e4bce9 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_CN.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_CN.properties @@ -6,13 +6,13 @@ index.header=\u7FA4\u7EC4 index.intro=\u4E0B\u8868\u662F\u6240\u6709\u4F60\u53C2\u52A0\u7684\u9879\u76EE\u7EC4\u3001\u5B66\u4E60\u7EC4\u548C\u6743\u9650\u7EC4 index.table.nogroup=\u4F60\u6CA1\u6709\u6CE8\u518C\u4EFB\u4F55\u7FA4\u7EC4 info.group.deleted=\u6B64\u9879\u76EE\u5DF2\u88AB\u5220\u9664\u3002 -learning.header=\u5B66\u4E60\u7EC4 -learning.intro=\u4E0B\u8868\u662F\u6240\u6709\u4F60\u53C2\u52A0\u7684\u5B66\u4E60\u7EC4 + + menu.index=\u7FA4\u7EC4 menu.index.alt=\u5C0F\u7EC4\u534F\u4F5C msg.atleastone=\u8BE5\u9879\u76EE\u7EC4\u4E2D\u81F3\u5C11\u8981\u6709\u4E00\u4E2A\u6240\u6709\u8005\u3002 -right.header=\u6743\u9650\u7EC4 -right.intro=\u4E0B\u8868\u662F\u6240\u6709\u4F60\u53C2\u52A0\u7684\u6743\u9650\u7EC4 + + table.header.bgname=\u540D\u79F0 table.header.delete=\u5220\u9664 table.header.description=\u8BF4\u660E diff --git a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_TW.properties b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_TW.properties index cbc59527a4476a1c337e8124f97b03e242bf1c45..47cf85f57b1566bafbb66dd211e73588b86492ee 100644 --- a/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_TW.properties +++ b/src/main/java/org/olat/group/ui/main/_i18n/LocalStrings_zh_TW.properties @@ -6,13 +6,13 @@ index.header=\u7FA4\u7D44 index.intro=\u4E0B\u5217\u7684\u6E05\u55AE\u986F\u793A\u6240\u6709\u60A8\u53C3\u8207\u7684\u5C08\u6848\u3001\u5B78\u7FD2\u53CA\u6B0A\u9650\u7FA4\u7D44\u3002 index.table.nogroup=\u60A8\u5C1A\u672A\u8A3B\u518A\u5230\u4EFB\u4F55\u7FA4\u7D44\u3002 info.group.deleted=\u9019\u500B\u5C08\u6848\u7FA4\u7D44\u5DF2\u88AB\u522A\u9664\u4E86\u3002 -learning.header=\u5B78\u7FD2\u7FA4\u7D44 -learning.intro=\u4E0B\u5217\u7684\u6E05\u55AE\u986F\u793A\u6240\u6709\u60A8\u53C3\u8207\u7684\u5B78\u7FD2\u7FA4\u7D44\u3002 + + menu.index=\u7FA4\u7D44 menu.index.alt=\u8207\u60A8\u7684\u7FA4\u7D44\u5DE5\u4F5C msg.atleastone=\u9019\u500B\u5C08\u6848\u7FA4\u7D44\u81F3\u5C11\u8981\u6709\u4E00\u540D\u64C1\u6709\u8005\u3002 -right.header=\u6B0A\u9650\u7FA4\u7D44 -right.intro=\u4E0B\u5217\u7684\u6E05\u55AE\u986F\u793A\u6240\u6709\u60A8\u53C3\u8207\u7684\u6B0A\u9650\u7FA4\u7D44\u3002 + + table.header.bgname=\u540D\u7A31 table.header.delete=\u522A\u9664 table.header.description=\u8AAA\u660E diff --git a/src/main/java/org/olat/group/ui/run/DisposedBusinessGroup.java b/src/main/java/org/olat/group/ui/run/DisposedBusinessGroup.java index f40e35e825fb19566aada0f9d9d21dec386a7fcc..d7cd743784d484e9aa53b257104d87aeab606379 100644 --- a/src/main/java/org/olat/group/ui/run/DisposedBusinessGroup.java +++ b/src/main/java/org/olat/group/ui/run/DisposedBusinessGroup.java @@ -33,7 +33,7 @@ import org.olat.core.gui.control.controller.BasicController; /** * Description:<br> - * TODO: patrickb Class Description for DisposedBusinessGroup + * Empty controller for deleted groups * * <P> * Initial Date: 28.04.2008 <br> @@ -52,8 +52,7 @@ class DisposedBusinessGroup extends BasicController { */ @Override protected void doDispose() { - // TODO Auto-generated method stub - + // } /** @@ -61,8 +60,6 @@ class DisposedBusinessGroup extends BasicController { */ @Override protected void event(UserRequest ureq, Component source, Event event) { - // TODO Auto-generated method stub - + // } - } diff --git a/src/main/java/org/olat/group/ui/run/_content/waiting.html b/src/main/java/org/olat/group/ui/run/_content/waiting.html index f3857c669df0bb48b3c1fb831f386a47a5fbbb28..f0f36a712de5b878fbac37ad97fce087a8856b77 100644 --- a/src/main/java/org/olat/group/ui/run/_content/waiting.html +++ b/src/main/java/org/olat/group/ui/run/_content/waiting.html @@ -1,4 +1,6 @@ <h4 class="b_with_small_icon_left b_group_icon"> $name </h4> -$r.translate("group.on.waitinglist") \ No newline at end of file +<p class="b_warning"> + $r.translate("group.on.waitinglist") +</p> \ No newline at end of file diff --git a/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_en.properties index 2a811c0cf724d3d3233e2a35ab016f084e8d1078..3aaf9bf80d517e430e2ffab20a2bd9fb2d66984a 100644 --- a/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/group/ui/run/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Thu May 26 09:55:51 CEST 2011 +#Tue Dec 18 17:12:45 CET 2012 businessgroup.contact.bodytext=\n\n---\nDirect link to the group {0} \: "{1}" businessgroup.contact.subject={0} \: group.deleted=$org.olat.group.ui\:group.deleted @@ -28,6 +28,8 @@ menutree.members=Members menutree.members.alt=Show members menutree.news=Information menutree.news.alt=Information for all members +menutree.openmeetings=OpenMeetings +menutree.openmeetings.alt=Apache OpenMeetings menutree.portfolio=Portfolio menutree.portfolio.alt=Collaborative portfolio folder menutree.resources=Course diff --git a/src/main/java/org/olat/group/ui/wizard/BGMailTemplateController.java b/src/main/java/org/olat/group/ui/wizard/BGMailTemplateController.java index 28e8b2210fef8cee9ef2b881a07c62d4e78620b5..4fa0e33bf850b95ead94f283f9f1de8e9211790c 100644 --- a/src/main/java/org/olat/group/ui/wizard/BGMailTemplateController.java +++ b/src/main/java/org/olat/group/ui/wizard/BGMailTemplateController.java @@ -105,7 +105,9 @@ public class BGMailTemplateController extends FormBasicController { if(bodyElem != null) { template.setBodyTemplate(bodyElem.getValue()); } - template.setCpfrom(ccSender.isSelected(0)); + if(ccSender != null) { + template.setCpfrom(ccSender.isSelected(0)); + } } @Override @@ -157,7 +159,7 @@ public class BGMailTemplateController extends FormBasicController { } defaultTemplate = uifactory.addCheckboxesVertical("deftemplate", "", formLayout, new String[]{"xx"}, new String[]{translate("mailtemplateform.defaultTemplate")}, null, 1); - if(!customizingAvailable || !StringHelper.containsNonWhitespace(template.getSubjectTemplate())) { + if(!customizingAvailable && StringHelper.containsNonWhitespace(template.getSubjectTemplate())) { defaultTemplate.select("xx", true); } diff --git a/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_de.properties index 16f9e1e35f335342f0c373d8a8b140218c4aa5d9..43bfe20dc2d1ddd3ed00f0f5e292c9c50c633018 100644 --- a/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_de.properties @@ -81,7 +81,7 @@ table.subject.action=Aktion table.status=Status table.role=Rolle -mailtemplateform.defaultTemplate=Default template +mailtemplateform.defaultTemplate=Standard Email Vorlage mailnotification.title=$org.olat.core.util.mail\:mailnotification.title mailtemplateform.sendMailSwitchElem=$org.olat.core.util.mail\:mailtemplateform.sendMailSwitchElem mailtemplateform.subject=$org.olat.core.util.mail\:mailtemplateform.subject diff --git a/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_en.properties index db5869b10b53cbf0b97c6801876c30c7d86da35b..9b376510af3a4eae5d362d8f607c63f9355534ba 100644 --- a/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/group/ui/wizard/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Thu Sep 27 13:51:45 CEST 2012 +#Tue Dec 18 17:15:03 CET 2012 action.general=Action backLink=Back bgcopywizard.copyform.areas=Configuration of learning areas @@ -28,6 +28,7 @@ config.tools.desc=Collaborative tools config.tools.off=off config.tools.on=on config.tools.title=Tools +contact.cp.from=$org.olat.core.util.mail\:contact.cp.from continue=Next copy.wizard.bgstep=Copy "{0}" create.form.error.emptylist=Please indicate at least one group name @@ -46,6 +47,13 @@ error.selectatleastonecolumn=Please select at least one column. error.selectatleastonegroup=Please select at least one group. error.selectonevalue=Please select one value. error.selectonlyonevalue=Please select only one value. +mailnotification.title=$org.olat.core.util.mail\:mailnotification.title +mailtemplateform.body=$org.olat.core.util.mail\:mailtemplateform.body +mailtemplateform.continue=$org.olat.core.util.mail\:mailtemplateform.continue +mailtemplateform.defaultTemplate=Default mail template +mailtemplateform.error.emptyfield=$org.olat.core.util.mail\:mailtemplateform.error.emptyfield +mailtemplateform.sendMailSwitchElem=$org.olat.core.util.mail\:mailtemplateform.sendMailSwitchElem +mailtemplateform.subject=$org.olat.core.util.mail\:mailtemplateform.subject memberlistwizard.archive.type.allInOne=All in one single Excel file memberlistwizard.archive.type.filePerGroupOrArea=ZIP file with one single Excel file per group/learning area memberlistwizard.archive.type.filePerGroupOrAreaInclGroupMembership=One Excel file per group/learning area incl. overview of group affiliations (ZIP) diff --git a/src/main/java/org/olat/gui/demo/guidemo/GuiDemoFlexiForm.java b/src/main/java/org/olat/gui/demo/guidemo/GuiDemoFlexiForm.java index 7ce6242b2b5f55ad5e3eeec902604d3810114bb8..d535cdc918bc53e9941087fa4c960fe7a9dac86e 100644 --- a/src/main/java/org/olat/gui/demo/guidemo/GuiDemoFlexiForm.java +++ b/src/main/java/org/olat/gui/demo/guidemo/GuiDemoFlexiForm.java @@ -112,7 +112,7 @@ public class GuiDemoFlexiForm extends FormBasicController { personData.setReadOnly(true); // get file and store it in temporary location - tmpFile = new File(WebappHelper.getUserDataRoot() + "/tmp/" + fileElement.getUploadFileName()); + tmpFile = new File(WebappHelper.getTmpDir() + "/" + fileElement.getUploadFileName()); fileElement.moveUploadFileTo(tmpFile); personData.setFile(tmpFile); diff --git a/src/main/java/org/olat/ims/cp/CPManagerImpl.java b/src/main/java/org/olat/ims/cp/CPManagerImpl.java index 53cc24a62f491cd156db856abb54b2d82e747925..308df39b27cfa1d72bc87d4efdf0709fb37e44b7 100644 --- a/src/main/java/org/olat/ims/cp/CPManagerImpl.java +++ b/src/main/java/org/olat/ims/cp/CPManagerImpl.java @@ -303,7 +303,7 @@ public class CPManagerImpl extends CPManager { // delete old archive and create new one VFSItem oldArchive = oresRoot.resolve(zipFileName); if (oldArchive != null) { - oldArchive.delete(); + oldArchive.deleteSilently();//don't versioned the zip } ZipUtil.zip(cpRoot.getItems(), oresRoot.createChildLeaf(zipFileName), true); VFSLeaf zip = (VFSLeaf) oresRoot.resolve(zipFileName); diff --git a/src/main/java/org/olat/ims/cp/ui/CPContentController.java b/src/main/java/org/olat/ims/cp/ui/CPContentController.java index 105abdde2028a4feaa299ba3021929332ae5e35d..20a3c25f77c03d2d686e76bdb05555b91c0511c7 100644 --- a/src/main/java/org/olat/ims/cp/ui/CPContentController.java +++ b/src/main/java/org/olat/ims/cp/ui/CPContentController.java @@ -134,7 +134,7 @@ public class CPContentController extends BasicController { String virtualRootFolderName = translate("cpfileuploadcontroller.virtual.root"); VFSContainer pseudoContainer = new VFSRootCPContainer(virtualRootFolderName, cp, rootDir, getTranslator()); - mceCtr = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), pseudoContainer, filePath, false); + mceCtr = WysiwygFactory.createWysiwygController(ureq, getWindowControl(), pseudoContainer, filePath, false, false); if(mceCtr.isEditable()) { mceCtr.setCancelButtonEnabled(false); mceCtr.setSaveCloseButtonEnabled(false); diff --git a/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java b/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java index 843b526c5b1c79fc0ec2e54ec6178712aaf1b8bb..884e1fcc3e8a9458f53fee93374d064737685d11 100644 --- a/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java +++ b/src/main/java/org/olat/ims/cp/ui/VFSCPContainer.java @@ -71,7 +71,12 @@ public class VFSCPContainer extends AbstractVirtualContainer implements VFSConta cpMgm = (CPManagerImpl) CPManager.getInstance(); treeModel = cpMgm.getTreeDataModel(cp); } - + + @Override + public boolean exists() { + return true; + } + @Override public boolean isSame(VFSItem vfsItem) { if(this == vfsItem) { diff --git a/src/main/java/org/olat/ims/cp/ui/VFSMediaFilesContainer.java b/src/main/java/org/olat/ims/cp/ui/VFSMediaFilesContainer.java index 7d7a2b17a0c985504853e178058256b1544e9e7d..79c05775bf7df49e607f81ddeefa575067690200 100644 --- a/src/main/java/org/olat/ims/cp/ui/VFSMediaFilesContainer.java +++ b/src/main/java/org/olat/ims/cp/ui/VFSMediaFilesContainer.java @@ -51,6 +51,11 @@ public class VFSMediaFilesContainer extends AbstractVirtualContainer implements this.rootContainer.setParentContainer(null); } + @Override + public boolean exists() { + return rootContainer != null && rootContainer.exists(); + } + @Override public boolean isSame(VFSItem vfsItem) { return this == vfsItem || rootContainer.isSame(vfsItem); diff --git a/src/main/java/org/olat/ims/cp/ui/VFSRootCPContainer.java b/src/main/java/org/olat/ims/cp/ui/VFSRootCPContainer.java index 49f832326520263509466434e349d40fc6f0aa82..07f21d718f4a343147481ce1b2a4cab07c7bc1f3 100644 --- a/src/main/java/org/olat/ims/cp/ui/VFSRootCPContainer.java +++ b/src/main/java/org/olat/ims/cp/ui/VFSRootCPContainer.java @@ -87,7 +87,12 @@ public class VFSRootCPContainer extends AbstractVirtualContainer implements VFSC } return null; } - + + @Override + public boolean exists() { + return rootContainer != null && rootContainer.exists(); + } + @Override public boolean isSame(VFSItem vfsItem) { if(this == vfsItem) { diff --git a/src/main/java/org/olat/ims/qti/editor/AddNewQTIDocumentController.java b/src/main/java/org/olat/ims/qti/editor/AddNewQTIDocumentController.java index dfc1d37ba289ae19234ff0eb04f5f8e2b9a0cac6..8beb970fca1c6cd2bfbf2d61c946d49e9e993dd0 100644 --- a/src/main/java/org/olat/ims/qti/editor/AddNewQTIDocumentController.java +++ b/src/main/java/org/olat/ims/qti/editor/AddNewQTIDocumentController.java @@ -28,7 +28,6 @@ package org.olat.ims.qti.editor; import java.io.File; import java.util.Locale; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.control.ControllerEventListener; @@ -40,6 +39,7 @@ import org.olat.core.gui.translator.Translator; import org.olat.core.logging.Tracing; import org.olat.core.util.CodeHelper; import org.olat.core.util.Util; +import org.olat.core.util.WebappHelper; import org.olat.fileresource.FileResourceManager; import org.olat.fileresource.types.AddingResourceException; import org.olat.fileresource.types.FileResource; @@ -101,7 +101,7 @@ public class AddNewQTIDocumentController extends DefaultController implements IA * @see org.olat.repository.controllers.IAddController#transactionFinishBeforeCreate() */ public boolean transactionFinishBeforeCreate() { - File fTempQTI = new File(FolderConfig.getCanonicalTmpDir() + "/" + CodeHelper.getGlobalForeverUniqueID() + ".zip"); + File fTempQTI = new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID() + ".zip"); tmpPackage = new QTIEditorPackage(DUMMY_TITLE, type, locale); // we need to save the package in order to be able to create a file resource entry. // package will be created again after changing title. diff --git a/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java b/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java index 51d4c65a7cf6c73ad84ec8bdf8f041560de53d80..c3bdcba493cabe36fa5181538a7cfcd141d84c77 100644 --- a/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java +++ b/src/main/java/org/olat/ims/qti/editor/QTIEditorMainController.java @@ -85,7 +85,6 @@ import org.olat.fileresource.types.FileResource; import org.olat.ims.qti.QTIChangeLogMessage; import org.olat.ims.qti.QTIResult; import org.olat.ims.qti.QTIResultManager; -import org.olat.ims.qti.editor.QTIEditHelper; import org.olat.ims.qti.editor.beecom.objects.ChoiceQuestion; import org.olat.ims.qti.editor.beecom.objects.Item; import org.olat.ims.qti.editor.beecom.objects.QTIDocument; diff --git a/src/main/java/org/olat/ims/qti/editor/QTIEditorPackage.java b/src/main/java/org/olat/ims/qti/editor/QTIEditorPackage.java index 498c6fff9756c9b6ba7dbf6f8c0998947edd0991..66ae0fd19959ef70d23433a9ba387f744116ebd8 100644 --- a/src/main/java/org/olat/ims/qti/editor/QTIEditorPackage.java +++ b/src/main/java/org/olat/ims/qti/editor/QTIEditorPackage.java @@ -133,7 +133,7 @@ public class QTIEditorPackage { section.setItems(itemList); // initialize package packageSubDir = CodeHelper.getGlobalForeverUniqueID(); - packageDir = new File(getTmpBaseDir(), packageSubDir); + packageDir = new File(getQTIEditorBaseDir(), packageSubDir); packageDir.mkdirs(); getMediaBaseDir().mkdirs(); getChangelogBaseDir().mkdirs(); @@ -153,7 +153,7 @@ public class QTIEditorPackage { private void init() { packageSubDir = getPackageSubDir(identity, fileResource); - packageDir = new File(getTmpBaseDir(), packageSubDir); + packageDir = new File(getQTIEditorBaseDir(), packageSubDir); packageDir.mkdirs(); getMediaBaseDir().mkdirs(); getChangelogBaseDir().mkdirs(); @@ -172,8 +172,8 @@ public class QTIEditorPackage { * Get the temporary root dir where all packages are located. * @return The editor's package temp base directory. */ - public static File getTmpBaseDir() { - return new File(WebappHelper.getUserDataRoot() + "/tmp/qtieditor/"); + public static File getQTIEditorBaseDir() { + return new File(WebappHelper.getUserDataRoot() + "/qtieditor/"); } /** @@ -249,7 +249,7 @@ public class QTIEditorPackage { */ public boolean savePackageToRepository() { FileResourceManager frm = FileResourceManager.getInstance(); - File tmpZipFile = new File(FolderConfig.getCanonicalTmpDir() + "/" + CodeHelper.getRAMUniqueID() + ".zip"); + File tmpZipFile = new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID() + ".zip"); // first save complete ZIP package to repository if (!savePackageTo(tmpZipFile)) return false; // move file from temp to repository root and rename diff --git a/src/main/java/org/olat/ims/qti/editor/QTIEditorStaticsHandler.java b/src/main/java/org/olat/ims/qti/editor/QTIEditorStaticsHandler.java index 42a4b95e91be5f117c18a32c1f959e3c77fe428e..d869c5a4e9e0804b1174dabec731a178ddcb3e60 100644 --- a/src/main/java/org/olat/ims/qti/editor/QTIEditorStaticsHandler.java +++ b/src/main/java/org/olat/ims/qti/editor/QTIEditorStaticsHandler.java @@ -61,7 +61,7 @@ public class QTIEditorStaticsHandler implements PathHandler { */ public InputStream getInputStream(HttpServletRequest request, ResourceDescriptor rd) { try { - File f = new File(QTIEditorPackage.getTmpBaseDir() + rd.getRelPath()); + File f = new File(QTIEditorPackage.getQTIEditorBaseDir() + rd.getRelPath()); return new BufferedInputStream(new FileInputStream(f)); } catch (Exception e) { return null; @@ -74,7 +74,7 @@ public class QTIEditorStaticsHandler implements PathHandler { public ResourceDescriptor getResourceDescriptor(HttpServletRequest request, String relPath) { try { ResourceDescriptor rd = new ResourceDescriptor(relPath); - File f = new File(QTIEditorPackage.getTmpBaseDir() + relPath); + File f = new File(QTIEditorPackage.getQTIEditorBaseDir() + relPath); rd.setLastModified(f.lastModified()); rd.setSize(f.length()); String mimeType = WebappHelper.getMimeType(relPath); diff --git a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java index 34cdb95948613bcf3736504581279875d91eef0b..27c8d3a930c8c97b04f9c2896f0f5d5c7de07ea9 100644 --- a/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java +++ b/src/main/java/org/olat/ldap/ui/LDAPAuthenticationController.java @@ -48,8 +48,11 @@ import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLATSecurityException; import org.olat.core.util.Encoder; +import org.olat.core.util.StringHelper; +import org.olat.core.util.UserSession; import org.olat.core.util.Util; import org.olat.core.util.WebappHelper; +import org.olat.core.util.i18n.I18nManager; import org.olat.ldap.LDAPError; import org.olat.ldap.LDAPLoginManager; import org.olat.ldap.LDAPLoginModule; @@ -168,6 +171,16 @@ protected void event(UserRequest ureq, Component source, Event event) { showError("login.error", ldapError.get()); return; } + } else { + try { + String language = authenticatedIdentity.getUser().getPreferences().getLanguage(); + UserSession usess = ureq.getUserSession(); + if(StringHelper.containsNonWhitespace(language)) { + usess.setLocale(I18nManager.getInstance().getLocaleOrDefault(language)); + } + } catch (Exception e) { + logError("Cannot set the user language", e); + } } LoginModule.clearFailedLoginAttempts(login); diff --git a/src/main/java/org/olat/login/OLATAuthenticationController.java b/src/main/java/org/olat/login/OLATAuthenticationController.java index 11b70a32c44dcde93dd3d4aefbcbd49959935f7a..a24c5b0da89e8b34f15e668cfc4e4ad4ec1e996a 100644 --- a/src/main/java/org/olat/login/OLATAuthenticationController.java +++ b/src/main/java/org/olat/login/OLATAuthenticationController.java @@ -50,8 +50,11 @@ import org.olat.core.id.context.StateEntry; import org.olat.core.logging.OLATSecurityException; import org.olat.core.logging.Tracing; import org.olat.core.util.Encoder; +import org.olat.core.util.StringHelper; +import org.olat.core.util.UserSession; import org.olat.core.util.Util; import org.olat.core.util.WebappHelper; +import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.mail.MailHelper; import org.olat.login.auth.AuthenticationController; import org.olat.login.auth.OLATAuthentcationForm; @@ -204,6 +207,16 @@ public class OLATAuthenticationController extends AuthenticationController imple showError("login.error", WebappHelper.getMailConfig("mailReplyTo")); return; } + } else { + try { + String language = authenticatedIdentity.getUser().getPreferences().getLanguage(); + UserSession usess = ureq.getUserSession(); + if(StringHelper.containsNonWhitespace(language)) { + usess.setLocale(I18nManager.getInstance().getLocaleOrDefault(language)); + } + } catch (Exception e) { + logError("Cannot set the user language", e); + } } LoginModule.clearFailedLoginAttempts(login); @@ -286,8 +299,10 @@ public class OLATAuthenticationController extends AuthenticationController imple ident = findIdentInChangingEmailWorkflow(login); } } - - if (ident == null) return null; + + if (ident == null) { + return null; + } // find OLAT authentication provider Authentication auth = BaseSecurityManager.getInstance().findAuthentication( diff --git a/src/main/java/org/olat/login/_content/about.html b/src/main/java/org/olat/login/_content/about.html index 7c6960c1b3f2afdc99a57875843e879978f2ddcd..27ead21a65185d8cb62e9540412021aba20f0710 100644 --- a/src/main/java/org/olat/login/_content/about.html +++ b/src/main/java/org/olat/login/_content/about.html @@ -32,7 +32,7 @@ Contributors and copy right holders of openolat.org codebase since 2011: Michael Enz, Christian Franck, Florian Gnägi, Roman Haag, Joël Krähemann, Matthai Kurian, Stéphane Rossé, Kirsten Scherer, Sergio Trentini - BPS Bildungsportal Sachsen GmbH, Germany [http://www.bildungsportal.sachsen.de]: - Armin Blawitzki, Stefan Köber, Sven Morgener + Armin Blawitzki, Stefan Köber, Sven Morgner - VCRP Virtueller Campus Rheinland-Pfalz [http://www.vcrp.de] Stephan Clemenz diff --git a/src/main/java/org/olat/login/auth/AuthenticationController.java b/src/main/java/org/olat/login/auth/AuthenticationController.java index 5eeab51bfb7cc862edf361b89dac760db2b78410..a1a8603ad0de1ea24fb9bc3bd7f0291fbfe4d94f 100644 --- a/src/main/java/org/olat/login/auth/AuthenticationController.java +++ b/src/main/java/org/olat/login/auth/AuthenticationController.java @@ -56,7 +56,7 @@ public abstract class AuthenticationController extends BasicController { * @param identity */ public void authenticated(UserRequest ureq, Identity identity) { - UserDeletionManager.getInstance().setIdentityAsActiv(identity); + identity = UserDeletionManager.getInstance().setIdentityAsActiv(identity); fireEvent(ureq, new AuthenticationEvent(identity)); } diff --git a/src/main/java/org/olat/modules/fo/FilterForUserController.java b/src/main/java/org/olat/modules/fo/FilterForUserController.java index ec765ee7e229b198363e3bffa3bf306216e15d1f..597ca831485a8fcc18bedffa7dc712e61372ae01 100644 --- a/src/main/java/org/olat/modules/fo/FilterForUserController.java +++ b/src/main/java/org/olat/modules/fo/FilterForUserController.java @@ -406,11 +406,13 @@ public class FilterForUserController extends BasicController { MarkResourceStat stat = stats.get(subPath); MarkingService markingService = (MarkingService)CoreSpringFactory.getBean(MarkingService.class); - String businessPath = currentMark == null ? - getWindowControl().getBusinessControl().getAsString() + "[Message:" + m.getKey() + "]" - : currentMark.getBusinessPath(); - Controller markCtrl = markingService.getMarkController(ureq, getWindowControl(), currentMark, stat, forumOres, subPath, businessPath); - vcThreadView.put("mark_"+msgCount, markCtrl.getInitialComponent()); + if(!ureq.getUserSession().getRoles().isGuestOnly()) { + String businessPath = currentMark == null ? + getWindowControl().getBusinessControl().getAsString() + "[Message:" + m.getKey() + "]" + : currentMark.getBusinessPath(); + Controller markCtrl = markingService.getMarkController(ureq, getWindowControl(), currentMark, stat, forumOres, subPath, businessPath); + vcThreadView.put("mark_"+msgCount, markCtrl.getInitialComponent()); + } map.put("modified", dateFormat.format(m.getLastModified())); // message attachments diff --git a/src/main/java/org/olat/modules/fo/ForumController.java b/src/main/java/org/olat/modules/fo/ForumController.java index d81cb747e7632353cd956c8234ae9a3ca2bdd25c..83eb9a660220fd786e1ed12cc83b59341811a8c0 100644 --- a/src/main/java/org/olat/modules/fo/ForumController.java +++ b/src/main/java/org/olat/modules/fo/ForumController.java @@ -1181,15 +1181,17 @@ public class ForumController extends BasicController implements GenericEventList MarkResourceStat stat = stats.get(subPath); MarkingService markingService = (MarkingService)CoreSpringFactory.getBean(MarkingService.class); - String businessPath = currentMark == null ? - getWindowControl().getBusinessControl().getAsString() + "[Message:" + m.getKey() + "]" - : currentMark.getBusinessPath(); - Controller markCtrl = markingService.getMarkController(ureq, getWindowControl(), currentMark, stat, forumOres, subPath, businessPath); - vcThreadView.put("mark_"+msgCount, markCtrl.getInitialComponent()); + if(!ureq.getUserSession().getRoles().isGuestOnly()) { + String businessPath = currentMark == null ? + getWindowControl().getBusinessControl().getAsString() + "[Message:" + m.getKey() + "]" + : currentMark.getBusinessPath(); + Controller markCtrl = markingService.getMarkController(ureq, getWindowControl(), currentMark, stat, forumOres, subPath, businessPath); + vcThreadView.put("mark_"+msgCount, markCtrl.getInitialComponent()); + } - businessPath = BusinessControlFactory.getInstance().getAsString(getWindowControl().getBusinessControl()) + "[Message:" + m.getKey() + "]"; if (uIsMsgC) { OLATResourceable messageOres = OresHelper.createOLATResourceableInstance("Forum", m.getKey()); + String businessPath = BusinessControlFactory.getInstance().getAsString(getWindowControl().getBusinessControl()) + "[Message:" + m.getKey() + "]"; Controller ePFCollCtrl = EPUIFactory.createArtefactCollectWizzardController(ureq, getWindowControl(), messageOres, businessPath); if (ePFCollCtrl != null) { diff --git a/src/main/java/org/olat/modules/fo/MessageEditController.java b/src/main/java/org/olat/modules/fo/MessageEditController.java index 63ac0f755f347264371d7b933f23f10ff5e6b459..7ce405c593133cfd462f0d1fea5ccb11af7fffb2 100644 --- a/src/main/java/org/olat/modules/fo/MessageEditController.java +++ b/src/main/java/org/olat/modules/fo/MessageEditController.java @@ -54,6 +54,9 @@ import org.olat.core.util.CodeHelper; import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; +import org.olat.core.util.WebappHelper; +import org.olat.core.util.vfs.LocalFolderImpl; +import org.olat.core.util.vfs.VFSContainer; import org.olat.core.util.vfs.VFSItem; import org.olat.core.util.vfs.VFSLeaf; import org.olat.core.util.vfs.filters.VFSItemExcludePrefixFilter; @@ -96,7 +99,7 @@ public class MessageEditController extends FormBasicController { private DisplayPortraitController portraitCtr; private ForumManager fm; private DialogBoxController delAttCtr; - private OlatRootFolderImpl tempUploadFolder; + private VFSContainer tempUploadFolder; private boolean userIsMsgCreator; private boolean msgHasChildren; private VFSItemExcludePrefixFilter exclFilter; @@ -117,7 +120,7 @@ public class MessageEditController extends FormBasicController { this.message = message; this.fm = ForumManager.getInstance(); - tempUploadFolder = new OlatRootFolderImpl(File.separator + "tmp/" + CodeHelper.getGlobalForeverUniqueID() + "/", null); + tempUploadFolder = new LocalFolderImpl(new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID())); // nfs creates .nfs12345 - files during deletion, those shouldn't be displayed / copied after save // See OLAT-4182 and OLAT-4219 exclFilter = new VFSItemExcludePrefixFilter(ATTACHMENT_EXCLUDE_PREFIXES); @@ -344,7 +347,7 @@ public class MessageEditController extends FormBasicController { } else { // files got stored in an extra tempFolder, to use the same // fileUploader multiple times - fileUpload.moveUploadFileTo(tempUploadFolder.getBasefile()); + fileUpload.moveUploadFileTo(tempUploadFolder); fileUpload.showError(false); fileUpload.reset(); diff --git a/src/main/java/org/olat/modules/fo/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/fo/_i18n/LocalStrings_fr.properties index 493c5775b839081863e12959b60d1a62a7972181..a8034a10cd7abbb5a62da0405ed9f6ce5517d596 100644 --- a/src/main/java/org/olat/modules/fo/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/fo/_i18n/LocalStrings_fr.properties @@ -70,7 +70,7 @@ no=Non notifications.entry=Message "{0}" \u00E9tabli par {1} notifications.entry.modified=Message "{0}" de {1} a \u00E9t\u00E9 modifi\u00E9 notifications.header=Il y a des nouveaux messages dans un des forums que vous avez abonn\u00E9s\: -notifications.header.course=Formu dans le cours "{0}" +notifications.header.course=Forum dans le cours "{0}" notifications.header.group=Forum dans groupe "{0}" open.thread=Ouvrir discussion reallydeleteAtt=Voulez-vous vraiment supprimer ce(s) fichier(s)? diff --git a/src/main/java/org/olat/modules/glossary/GlossaryManagerImpl.java b/src/main/java/org/olat/modules/glossary/GlossaryManagerImpl.java index dd8590122ea66e1d9b4bf27a8758fe517af8ab0b..b650664f43c6db6948cafbba2fd00f42fb82f948 100644 --- a/src/main/java/org/olat/modules/glossary/GlossaryManagerImpl.java +++ b/src/main/java/org/olat/modules/glossary/GlossaryManagerImpl.java @@ -20,6 +20,7 @@ package org.olat.modules.glossary; import java.io.File; +import java.io.IOException; import java.util.Date; import java.util.Iterator; import java.util.List; @@ -34,6 +35,7 @@ import org.olat.core.gui.media.CleanupAfterDeliveryFileMediaResource; import org.olat.core.gui.media.MediaResource; import org.olat.core.id.OLATResourceable; import org.olat.core.util.StringHelper; +import org.olat.core.util.WebappHelper; import org.olat.core.util.ZipUtil; import org.olat.core.util.filter.Filter; import org.olat.core.util.filter.FilterFactory; @@ -66,7 +68,8 @@ import org.olat.search.service.SearchResourceContext; * Initial Date: 15.01.2009 <br> * @author Roman Haag, frentix GmbH, roman.haag@frentix.com */ -public class GlossaryManagerImpl extends GlossaryManager { +public class GlossaryManagerImpl extends GlossaryManager { + private static final String EXPORT_FOLDER_NAME = "glossary"; private ReferenceManager referenceManager; @@ -171,13 +174,20 @@ public class GlossaryManagerImpl extends GlossaryManager { */ public MediaResource getAsMediaResource(OLATResourceable res) { RepositoryEntry repoEntry = RepositoryManager.getInstance().lookupRepositoryEntry(res, false); - String exportFileName = repoEntry.getDisplayname() + ".zip"; + String exportFileName = repoEntry.getDisplayname(); // OO-135 check for special / illegal chars in filename exportFileName = StringHelper.transformDisplayNameToFileSystemName(exportFileName); - File fExportZIP = new File(FolderConfig.getCanonicalTmpDir() + "/" + exportFileName); - VFSContainer glossaryRoot = getGlossaryRootFolder(res); - ZipUtil.zip(glossaryRoot.getItems(), new LocalFileImpl(fExportZIP), false); - return new CleanupAfterDeliveryFileMediaResource(fExportZIP); + + try { + File tmpDir = new File(WebappHelper.getTmpDir()); + File fExportZIP = File.createTempFile(exportFileName, ".zip", tmpDir); + VFSContainer glossaryRoot = getGlossaryRootFolder(res); + ZipUtil.zip(glossaryRoot.getItems(), new LocalFileImpl(fExportZIP), false); + return new CleanupAfterDeliveryFileMediaResource(fExportZIP); + } catch (IOException e) { + logError("Cannot export glossar: " + res, e); + return null; + } } diff --git a/src/main/java/org/olat/modules/iq/IQDisplayController.java b/src/main/java/org/olat/modules/iq/IQDisplayController.java index 998e3fbd89d4bd9503a399cb14873c13e657cb8c..249e02636bd89d4874eea11d00b3f87a8eb0ad7b 100644 --- a/src/main/java/org/olat/modules/iq/IQDisplayController.java +++ b/src/main/java/org/olat/modules/iq/IQDisplayController.java @@ -558,6 +558,9 @@ public class IQDisplayController extends DefaultController implements GenericEve if (qtistatus.isSurvey()) { // Send also finished event in case of survey fireEvent(ureq, new IQSubmittedEvent()); + } else { + // for test and self-assessment, generate detailed results + generateDetailsResults(ureq, ai); } } diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsDAO.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsDAO.java index 23192a4384cabf74862e4a4b0b76987a1d2c1a18..ef9acb75b5a0fa0e1a927665ead1379472e9ba03 100644 --- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsDAO.java +++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsDAO.java @@ -67,8 +67,10 @@ public class OpenMeetingsDAO { ref.setRoomId(room.getRoomId()); ref.setConfig(serialized); ref.setGroup(group); - ref.setResourceTypeName(courseResource.getResourceableTypeName()); - ref.setResourceTypeId(courseResource.getResourceableId()); + if(courseResource != null) { + ref.setResourceTypeName(courseResource.getResourceableTypeName()); + ref.setResourceTypeId(courseResource.getResourceableId()); + } ref.setSubIdentifier(subIdentifier); dbInstance.getCurrentEntityManager().persist(ref); return ref; @@ -87,7 +89,7 @@ public class OpenMeetingsDAO { boolean where = false; if(group != null) { where = and(sb, where); - sb.append(" ref.group=:groupKey"); + sb.append(" ref.group.key=:groupKey"); } if(courseResource != null) { where = and(sb, where); diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java index e1119f1deeeb4a1f7178c37df3a3401b5927ccb8..63e795b12cd62827a61953fad29a3365ac27cbb6 100644 --- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java +++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManager.java @@ -120,6 +120,13 @@ public interface OpenMeetingsManager { public String getRecordingURL(OpenMeetingsRecording recording) throws OpenMeetingsException; + /** + * Delete a recording + * @param recording + * @return + */ + boolean deleteRecording(OpenMeetingsRecording recording); + /** * A UUID mapped to the identity is saved in a cache * @param token diff --git a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java index 38d3f9ce2650d9e8db03eebd87aad192f87ff690..9441a127a2d2c454c7956e06214fd665e6cf5da9 100644 --- a/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java +++ b/src/main/java/org/olat/modules/openmeetings/manager/OpenMeetingsManagerImpl.java @@ -62,6 +62,8 @@ import org.openmeetings.axis.services.AddRoomWithModerationAndRecordingFlags; import org.openmeetings.axis.services.AddRoomWithModerationAndRecordingFlagsResponse; import org.openmeetings.axis.services.CloseRoom; import org.openmeetings.axis.services.CloseRoomResponse; +import org.openmeetings.axis.services.DeleteFlvRecording; +import org.openmeetings.axis.services.DeleteFlvRecordingResponse; import org.openmeetings.axis.services.DeleteRoom; import org.openmeetings.axis.services.DeleteRoomResponse; import org.openmeetings.axis.services.GetFlvRecordingByRoomId; @@ -552,7 +554,7 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel omRoom.setNumberOfPartizipants(room.getSize()); omRoom.setRoomtypes_id(room.getType()); omRoom.setSID(sessionId); - omRoom.setWaitForRecording(true); + omRoom.setWaitForRecording(false); AddRoomWithModerationAndRecordingFlagsResponse addRoomResponse = roomWs.addRoomWithModerationAndRecordingFlags(omRoom); long returned = addRoomResponse.get_return(); @@ -638,6 +640,22 @@ public class OpenMeetingsManagerImpl implements OpenMeetingsManager, UserDataDel } } + @Override + public boolean deleteRecording (OpenMeetingsRecording recording) { + try { + String adminSID = adminLogin(); + RoomServiceStub roomWs = getRoomWebService(); + DeleteFlvRecording deleteRecordingCl = new DeleteFlvRecording(); + deleteRecordingCl.setFlvRecordingId(recording.getRecordingId()); + deleteRecordingCl.setSID(adminSID); + DeleteFlvRecordingResponse resp = roomWs.deleteFlvRecording(deleteRecordingCl); + return resp.get_return(); + } catch (Exception e) { + log.error("", e); + return false; + } + } + @Override public List<OpenMeetingsUser> getUsersOf(OpenMeetingsRoom room) throws OpenMeetingsException { diff --git a/src/main/java/org/olat/modules/openmeetings/model/RoomType.java b/src/main/java/org/olat/modules/openmeetings/model/RoomType.java index ce53f5f91b42a78cd1dbccfc6e427ce07425a827..7fb50c7b2b553f9e6c1d75fbc849e21bc2c25281 100644 --- a/src/main/java/org/olat/modules/openmeetings/model/RoomType.java +++ b/src/main/java/org/olat/modules/openmeetings/model/RoomType.java @@ -44,6 +44,15 @@ public enum RoomType { return type; } + public static RoomType getType(long type) { + for(RoomType roomType:RoomType.values()) { + if(roomType.type == type) { + return roomType; + } + } + return null; + } + public String typeStr() { return Long.toString(type); } diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingController.java index 43f22918b32a4a56c6cc01c9c06cca3630bbb49d..4f8a7bf6fc9ec6bd672f563e32bd41cd764ada0c 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingController.java +++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingController.java @@ -55,7 +55,7 @@ public class OpenMeetingsRecordingController extends BasicController { mainVC = createVelocityContainer("recording"); downloadLink = LinkFactory.createLink("download", mainVC, this); - downloadLink.setTarget("_blanck"); + downloadLink.setTarget("_blank"); downloadLink.setCustomEnabledLinkCSS("b_content_download"); try { diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingsController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingsController.java index 7728e4e45aa4f98e7b28c4c0e084d9bff7b4a82e..5f4563ca7a0df4914942cff519099a8acfe361b7 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingsController.java +++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRecordingsController.java @@ -19,6 +19,7 @@ */ package org.olat.modules.openmeetings.ui; +import java.util.ArrayList; import java.util.List; import org.olat.core.CoreSpringFactory; @@ -34,7 +35,10 @@ 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.gui.control.generic.closablewrapper.CloseableModalController; +import org.olat.core.gui.control.generic.modal.DialogBoxController; +import org.olat.core.gui.control.generic.modal.DialogBoxUIFactory; import org.olat.core.gui.translator.Translator; +import org.olat.core.util.StringHelper; import org.olat.modules.openmeetings.manager.OpenMeetingsException; import org.olat.modules.openmeetings.manager.OpenMeetingsManager; import org.olat.modules.openmeetings.model.OpenMeetingsRecording; @@ -51,11 +55,19 @@ public class OpenMeetingsRecordingsController extends BasicController { private TableController tableCtr; private CloseableModalController cmc; private OpenMeetingsRecordingController recordingController; + private DialogBoxController confirmRemoveRecording; private final long roomId; private final OpenMeetingsManager openMeetingsManager; - public OpenMeetingsRecordingsController(UserRequest ureq, WindowControl wControl, long roomId) { + /** + * + * @param ureq + * @param wControl + * @param roomId The room id + * @param admin True the user can delete recordings + */ + public OpenMeetingsRecordingsController(UserRequest ureq, WindowControl wControl, long roomId, boolean admin) { super(ureq, wControl); this.roomId = roomId; @@ -70,6 +82,9 @@ public class OpenMeetingsRecordingsController extends BasicController { tableCtr.addColumnDescriptor(new DefaultColumnDescriptor("room.name", OpenMeetingsRecordingsDataModel.Col.name.ordinal(), null, getLocale())); tableCtr.addColumnDescriptor(new StaticColumnDescriptor("view", "view", translate("view"))); + if(admin) { + tableCtr.addColumnDescriptor(new StaticColumnDescriptor("delete", "delete", translate("delete"))); + } tableCtr.setTableDataModel(new OpenMeetingsRecordingsDataModel()); loadModel(); @@ -79,7 +94,13 @@ public class OpenMeetingsRecordingsController extends BasicController { private void loadModel() { try { List<OpenMeetingsRecording> recordings = openMeetingsManager.getRecordings(roomId); - ((OpenMeetingsRecordingsDataModel)tableCtr.getTableDataModel()).setObjects(recordings); + List<OpenMeetingsRecording> readyRecordings = new ArrayList<OpenMeetingsRecording>(recordings.size()); + for (OpenMeetingsRecording recording : recordings) { + if (StringHelper.containsNonWhitespace(recording.getDownloadName())) { + readyRecordings.add(recording); + } + } + ((OpenMeetingsRecordingsDataModel)tableCtr.getTableDataModel()).setObjects(readyRecordings); tableCtr.modelChanged(); } catch (OpenMeetingsException e) { showError(e.i18nKey()); @@ -105,8 +126,17 @@ public class OpenMeetingsRecordingsController extends BasicController { OpenMeetingsRecording recording = (OpenMeetingsRecording)tableCtr.getTableDataModel().getObject(row); if("view".equals(e.getActionId())) { doView(ureq, recording); + } else if("delete".equals(e.getActionId())) { + String text = getTranslator().translate("recording.remove", new String[]{ recording.getFilename() }); + confirmRemoveRecording = activateYesNoDialog(ureq, null, text, confirmRemoveRecording); + confirmRemoveRecording.setUserObject(recording); } } + } else if (source == confirmRemoveRecording) { + if (DialogBoxUIFactory.isYesEvent(event)) { // yes case + OpenMeetingsRecording recording = (OpenMeetingsRecording)confirmRemoveRecording.getUserObject(); + doDelete(ureq, recording); + } } } @@ -122,4 +152,9 @@ public class OpenMeetingsRecordingsController extends BasicController { listenTo(cmc); cmc.activate(); } + + private void doDelete(UserRequest ureq, OpenMeetingsRecording recording) { + openMeetingsManager.deleteRecording(recording); + loadModel(); + } } diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java index 215fd6bb0ae5c23009684770b6ed71975e2a67cc..ded9badeff472f31bf589dfb890022f5412a885c 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java +++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRoomEditController.java @@ -19,6 +19,9 @@ */ package org.olat.modules.openmeetings.ui; +import java.util.ArrayList; +import java.util.List; + import org.olat.core.CoreSpringFactory; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -38,6 +41,8 @@ import org.olat.modules.openmeetings.manager.OpenMeetingsManager; import org.olat.modules.openmeetings.model.OpenMeetingsRoom; import org.olat.modules.openmeetings.model.RoomType; +import edu.emory.mathcs.backport.java.util.Collections; + /** * * Initial date: 06.11.2012<br> @@ -58,7 +63,6 @@ public class OpenMeetingsRoomEditController extends FormBasicController { private final String[] moderationModeKeys; private final String[] recordingKeys = {"xx"}; - private final BusinessGroup group; private final OLATResourceable ores; private final String subIdentifier; @@ -66,6 +70,8 @@ public class OpenMeetingsRoomEditController extends FormBasicController { private OpenMeetingsRoom room; private OpenMeetingsRoom defaultSettings; private final OpenMeetingsManager openMeetingsManager; + + private long[] sizes = {2, 4, 6, 8, 10, 12, 14, 16, 25, 50, 100, 150, 200, 1000}; public OpenMeetingsRoomEditController(UserRequest ureq, WindowControl wControl, BusinessGroup group, OLATResourceable ores, String subIdentifier, String resourceName, OpenMeetingsRoom defaultSettings, boolean admin) { @@ -88,20 +94,49 @@ public class OpenMeetingsRoomEditController extends FormBasicController { showError(e.i18nKey()); } - if(room != null && room.getSize() != 16 && room.getSize() != 100) { - roomSizes = new String[]{"16", Long.toString(room.getSize()), "100"}; + if(room != null && !isLegalSize(room.getSize())) { + roomSizes = toStringSizes(room.getSize()); } else { - roomSizes = new String[]{"16", "100"}; + roomSizes = toStringSizes(); } initForm(ureq); } + private String[] toStringSizes(long... addSizes) { + List<Long> endSizes = new ArrayList<Long>(sizes.length + 2); + for(long size:sizes) { + endSizes.add(new Long(size)); + } + if(addSizes != null && addSizes.length > 0) { + for(long size:addSizes) { + endSizes.add(new Long(size)); + } + } + Collections.sort(endSizes); + String[] stringuifiedSizes = new String[endSizes.size()]; + int count = 0; + for(Long endSize:endSizes) { + stringuifiedSizes[count++] = endSize.toString(); + } + return stringuifiedSizes; + } + + private boolean isLegalSize(long roomSize) { + for(long size:sizes) { + if(size == roomSize) { + return true; + } + } + return false; + } + public OpenMeetingsRoom getRoom() { return room; } @Override protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + setFormContextHelp(this.getClass().getPackage().getName(), "room.html", "help.hover.openmeetings.room"); String name = room == null ? (defaultSettings == null ? null : defaultSettings.getName()) : room.getName(); roomNameEl = uifactory.addTextElement("roomname", "room.name", 255, name == null ? "" : name, formLayout); diff --git a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java index 78b738d1435a1004ed85c3e8cfd940bc8a43f7d6..2770adabaff1f5a3eed768d665dbebf78d7828f0 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java +++ b/src/main/java/org/olat/modules/openmeetings/ui/OpenMeetingsRunController.java @@ -33,6 +33,7 @@ import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; import org.olat.core.gui.media.RedirectMediaResource; import org.olat.core.id.OLATResourceable; +import org.olat.core.util.StringHelper; import org.olat.group.BusinessGroup; import org.olat.modules.openmeetings.OpenMeetingsModule; import org.olat.modules.openmeetings.manager.OpenMeetingsException; @@ -111,7 +112,7 @@ public class OpenMeetingsRunController extends BasicController { mainVC.put("room.members", membersLink); } if(admin) { - editLink = LinkFactory.createButton("edit", mainVC, this); + editLink = LinkFactory.createButton("edit.room", mainVC, this); mainVC.put("edit", editLink); } @@ -147,7 +148,11 @@ public class OpenMeetingsRunController extends BasicController { } mainVC.contextPut("roomName", room.getName()); - mainVC.contextPut("roomComment", room.getComment()); + if (StringHelper.containsNonWhitespace(room.getComment())) { + mainVC.contextPut("roomComment", room.getComment()); + } else { + mainVC.contextRemove("roomComment"); + } mainVC.contextPut("roomClosed", new Boolean(closed)); } } @@ -239,7 +244,7 @@ public class OpenMeetingsRunController extends BasicController { private void doOpenRecordings(UserRequest ureq) { cleanupPopups(); - recordingsController = new OpenMeetingsRecordingsController(ureq, getWindowControl(), room.getRoomId()); + recordingsController = new OpenMeetingsRecordingsController(ureq, getWindowControl(), room.getRoomId(), admin || moderator); listenTo(recordingsController); cmc = new CloseableModalController(getWindowControl(), translate("close"), recordingsController.getInitialComponent(), true, translate("recordings")); diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_chelp/module.html b/src/main/java/org/olat/modules/openmeetings/ui/_chelp/module.html index 80f92dfea2bb05737ef59128a48ce47ac27ab078..b42c50e0137843af21e568da6af7dde417030e1d 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/_chelp/module.html +++ b/src/main/java/org/olat/modules/openmeetings/ui/_chelp/module.html @@ -1,6 +1,18 @@ <p> - $r.translate("chelp.openmeetings1") - <br /> - <a href="http://incubator.apache.org/openmeetings" target="_blank" class="b_extern">http://incubator.apache.org/openmeetings</a> + $r.translate("chelp.openmeetings.intro") +</p> +<p> + $r.translate("chelp.openmeetings.url") <a href="http://incubator.apache.org/openmeetings" target="_blank" class="b_extern">http://incubator.apache.org/openmeetings</a> +</p> +<p> + $r.translate("chelp.openmeetings.module") +</p> +<p> + <ul> + <li>$r.translate("chelp.openmeetings.course")</li> + <li>$r.translate("chelp.openmeetings.group")</li> + </ul> +</p> +<p> + $r.translate("chelp.openmeetings.config") </p> - diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_chelp/room.html b/src/main/java/org/olat/modules/openmeetings/ui/_chelp/room.html new file mode 100644 index 0000000000000000000000000000000000000000..4fc0a17fd60cc1247a4d6da23f62fa65bc5002b9 --- /dev/null +++ b/src/main/java/org/olat/modules/openmeetings/ui/_chelp/room.html @@ -0,0 +1,43 @@ +<p> + $r.translate("chelp.openmeetings.intro") +</p> +<p> + $r.translate("chelp.openmeetings.url") <a href="http://incubator.apache.org/openmeetings" target="_blank" class="b_extern">http://incubator.apache.org/openmeetings</a> +</p> + +<hr /> + +<p> + $r.translate("chelp.openmeetings.room") +</p> +<p> + <ul> + <li>$r.translate("chelp.openmeetings.course")</li> + <li>$r.translate("chelp.openmeetings.group")</li> + </ul> +</p> +<p> + $r.translate("chelp.openmeetings.room.config") +</p> +<table class="b_grid"> + <thead> + <tr><th>$r.translate("chelp.openmeetings.room.options")</th><th>$r.translate("chelp.openmeetings.room.values")</th><th>$r.translate("chelp.openmeetings.room.desc")</th></tr> + </thead> + <tbody> + <tr><th>$r.translate("room.name")</th><td>$r.translate("chelp.openmeetings.room.text")</td><td>$r.translate("room.name.desc")</td></tr> + + <tr><th>$r.translate("room.type")</th><td>$r.translate("room.type.conference")</br>$r.translate("room.type.restricted")</br>$r.translate("room.type.interview")</td><td>$r.translate("room.type.desc")</td></tr> + + <tr><th>$r.translate("room.size")</th><td>2-1000</td><td>$r.translate("room.size.desc")</td></tr> + + <tr><th>$r.translate("room.moderation.mode")</td><td>$r.translate("room.moderation.yes")</br>$r.translate("room.moderation.no")</td><td>$r.translate("room.moderation.mode.desc")</td></tr> + + <tr><th>$r.translate("room.recording")</th><td>$r.translate("room.recording.enabled")</td><td>$r.translate("room.recording.desc")</td></tr> + + <tr><th>$r.translate("room.comment")</th><td>$r.translate("chelp.openmeetings.room.text")</td><td>$r.translate("room.comment.desc")</td></tr> + + </tbody> +</table> +<p> + $r.translate("chelp.openmeetings.room.create") +</p> diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_chelp/room_admin.html b/src/main/java/org/olat/modules/openmeetings/ui/_chelp/room_admin.html new file mode 100644 index 0000000000000000000000000000000000000000..b086985388c237a69e9e9cf6507fec6092332601 --- /dev/null +++ b/src/main/java/org/olat/modules/openmeetings/ui/_chelp/room_admin.html @@ -0,0 +1,16 @@ +<p> + $r.translate("chelp.openmeetings.admin") +</p> +<table class="b_grid"> + <thead> + <tr><th>$r.translate("room.actions")</th><th>$r.translate("room.actions.desc")</th></tr> + </thead> + <tbody> + <tr><th>$r.translate("open.room")</th><td>$r.translate("open.room.desc")</td></tr> + + <tr><th>$r.translate("room.members")</th><td>$r.translate("room.members.desc")</td></tr> + + <tr><th>$r.translate("edit.room")</th><td>$r.translate("edit.room.desc")</td></tr> + + </tbody> +</table> diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html b/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html index fdc534debbe647740f03ae2bdc5f8101622489c8..fb0c65507b294b2d6138f8dc3ec2c1529284d776 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html +++ b/src/main/java/org/olat/modules/openmeetings/ui/_content/room.html @@ -3,39 +3,52 @@ #elseif($noroom) <div class="b_warning">$r.translate("room.notfound.error")</div> #else - <h4>$roomName</h4> + <h3 class="b_with_small_icon_left o_openmeetings_icon">$roomName</h3> #if($roomComment) - <p>$roomComment</p> + <div class="b_note">$roomComment</div> #end + + <p> + $r.translate("start.hint") + </p> #if($roomClosed) - <p>$r.translate("room.closed.explanation")</p> + <p class="b_important">$r.translate("room.closed.explanation")</p> #end - #if($r.available("open.room")) - $r.render("open.room") - $r.render("close.room") + #if($r.available("start.room.guest")) + $r.render("start.room.guest") + ## Component to render dialog with guest nickname + #if($r.available("openCmd")) + $r.render("openCmd") + #end + #else + $r.render("start.room") #end #if($r.available("open.recordings")) $r.render("open.recordings") #end - #if($r.available("room.members")) - $r.render("room.members") - #end + #if($r.available("open.room") || $r.available("room.members") || $r.available("edit")) + <p /> + <hr /> + $r.contextHelpWithWrapper("org.olat.modules.openmeetings.ui","room_admin.html","help.hover.openmeetings.room_admin") + <h4>$r.translate("administration.title")</h4> + #if($r.available("open.room")) + $r.render("open.room") + $r.render("close.room") + #end - #if($r.available("edit")) - $r.render("edit") + + #if($r.available("room.members")) + $r.render("room.members") + #end + + #if($r.available("edit")) + $r.render("edit") + #end #end - #if($r.available("start.room.guest")) - $r.render("start.room.guest") - #else - $r.render("start.room") - #end #end -#if($r.available("openCmd")) - $r.render("openCmd") -#end \ No newline at end of file diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties index c136b71e5751159b2f2ffb647f53db9b2beadc4a..9db611cf397cb15394ba1a136a32fd5522f7736f 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_de.properties @@ -14,6 +14,7 @@ delete.ok=Der Raum w\u00FCrde erfolgreich gel\u00F6scht. delete.nok=Der Raum konnte nicht gel\u00F6scht werden. download=Herunterladen edit.room=Raumeinstellungen +edit.room.desc=Ändern Sie die Konfigurationsparameter des Raumes wie z.B. Raumtyp oder verfügbare Anzahl Plätze. kickout=Sitzung beenden kickout.ok=Der Benutzer wurde erfolgreich entfernt. kickout.nok=Der Benutzer konnte nicht entfernt werden. @@ -24,14 +25,19 @@ openmeetings.module.enabled=Modul "OpenMeetings" view=Ansehen table.empty=Kein Raum wurde nicht gefunden. recording.name=Name +recording.remove=M\u00F6chten Sie wirklich die Aufzeichnung "{0}" l\u00F6schen? recordings=Aufzeichnungen recordings.empty=Dieser Raum hat noch keine Aufzeichnung -rooms.title=Ra\u00FCme -room.closed.explanation=Der Raum ist geschlossen. +rooms.title=R\u00E4ume +room.closed.explanation=Der Raum wurde vom Betreuer dieser Sitzung temporär geschlossen. Bitte versuchen Sie es später noch einmal oder wenden Sie sich an Ihren Betreuer. room.comment=Beschreibung -room.members=Teilnehmer +room.comment.desc=In der Beschreibung können Sie die Inhalte der Sitzung und das Zielpublikum beschreiben. +room.members=Teilnehmerverwaltung +room.members.desc=Anzeige aller Benutzer die sich aktuell im Raum befinden. Wählen sie den Link "$\:kickout" um die Sitzung für einen bestimmten Benutzer sofort zu beenden. room.name=Raumname +room.name.desc=Der Name des Sitzungszimmer wie es in dem Raum angezeigt werden soll room.type=Typ +room.type.desc=Art der Sitzung. Dies beeinflusst die zur Verfügung stehenden Werkzeuge und Moderationsrechte in dem Sitzungszimmer. Konferenzen sind für eher kleinere Benutzerzahlen gedacht bei denen alle Teilnehmer gleichberechtigt mit Videosignal auftreten und alle Werkzeuge bedienen können. Ein Webinar auf der anderen Seite entspricht einer Frontalvorlesung mit einem Vortragenden mit Videosignal und vielen Zuhörern. Ein Interview ist eine Sitzung bei der eine Person interviewt und das Gespräch aufgezeichnet wird. room.type.conference=Conference (1 - 25 Benutzer) room.type.audience=Audience room.type.restricted=Webinar (1 - 150 Benutzer) @@ -39,30 +45,60 @@ room.type.interview=Interview (1:1 meeting with recording) room.moderation.mode=Moderation room.moderation.yes=Moderator notwendig room.moderation.no=Ohne Moderation +room.moderation.mode.desc=Falls in der Administration freigeschaltet kann mit dieser Option die Anwesenheit eines Moderators erzwungen werden. Nicht-Moderatoren können in dem Raum keine Aktionen durchführen bis ein Moderator den Raum betritt. Als Moderatoren gelten in Kursen die Kursautoren sowie die Betreuer des Kurses, bei Gruppen sind dies die Gruppenbetreuer. room.size=Sitzplätze +room.size.desc=Die Anzahl der Sitzplätze limitiert die verfügbaren Plätze des Sitzungsraumes. Sind alle Plätze belegt können keine neuen Benutzer zu der Sitzung hinzustossen. room.recording=Aufzeichnung room.recording.enabled=erlauben +room.recording.desc=Mit dieser Option können Sie die Aufzeichnung der Sitzung als Film erlauben. Nach der Sitzung wird der Film automatisch konvertiert und bereitgestellt. room.resource=Ressourcen room.numOfUsers=# Teilnehmer room.infos=Detailinformationen room.recording=Aufzeichnung -start.room=Betreten -start.room.guest=Betreten -open.room=Offnen -close.room=Schliessen +room.actions=Schaltfläche +room.actions.desc=Beschreibung +start.room=Sitzungsraum betreten +start.room.guest=Sitzungsraum als Gast betreten +start.hint=Wählen Sie die Schaltfläche "$\:start.room" um an der Sitzung teilzunehmen. Falls vorhanden können Sie die Aufzeichnungen von früheren Sitzungen ansehen. Wählen sie hierzu die Schaltfläche "$\:recordings" +open.room=Raum öffnen +open.room.desc=Der Raum kann temporär geschlossen und wieder geöffnet werden. Diese Aktion löscht keine Daten im Raum und kann beliebig oft wiederholt werden. Dies ist z.B. sinnvoll um den Raum vorzubereiten und dann zu schliessen um ihn kurz vor Verwendung wieder zu öffnen. +close.room=Raum temporär schliessen room.raw.title=Detailinformationen guest.room=Teilnehmer Informationen first.name=Vorname last.name=Nachname users=Teilnehmer -users.description=Die Teilnehmerliste zeigt die sich aktuell im Raum befindenden Benutzer. Sie können die OpenMeetings Sitzung eines einzelnen Benutzer jederzeit beenden. -users.empty=Der Raum ist leer -openolat.externaltype=External type +users.description=Die Teilnehmerliste zeigt die sich aktuell im Raum befindenden Benutzer. Sie k\u00F6nnen die OpenMeetings Sitzung eines einzelnen Benutzer jederzeit beenden. +users.empty=Zur Zeit wird dieser Raum von niemandem verwendet. +openolat.externaltype=OpenOLAT Identifikator room.notfound.error=Der Raum wurde nicht gefunden openmeetings.disabled.error=Der Modul "OpenMeetings" ist nicht eingeschaltet. option.baseurl=URL OpenMeetings Server option.adminlogin=Web Service Benutzername option.adminpassword=Web Service Passwort -chelp.openmeetings1=Apache OpenMeetings Hilfe -chelp.module.title=Apache OpenMeetings: Konfiguration -help.hover.openmeetings=Hilfe zur Einbung eines Apache OpenMeetings Server +administration.title=Administration + +help.hover.openmeetings=Hilfe zur Verwendung und Konfiguration eines Apache OpenMeetings Servers +chelp.module.title=Apache OpenMeetings: Konfiguration des OpenMeetings Servers +chelp.openmeetings.intro=OpenMeetings ist virtuelles Klassenzimmer und eine Kommunikationslösung zur unterstützung synchroner Konferenzen und Sitzungen. OpenMeetings ist eine Open Source Software und wird kostenlos unter der Apache 2.0 Open Source Lizenz vertrieben. Die Hauptfunktionen sind die Audio- und Videoübertragung, Meetingaufzeichnung, Chat, Desktop-Sharing, File-Sharing, Whiteboard sowie Umfragen. +chelp.openmeetings.url=Weitere Informationen zu Apache OpenMeetings finden Sie unter der URL +chelp.openmeetings.module=In der OpenOLAT Systemadministraton können Sie das OpenMeetings module konfigurieren und die Funktionalität freischalten. Wenn das Modul eingeschaltet und die Verbindungsparameter zum OpenMeetingssserver korrekt sind können in OpenOLAT an den folgenden Stellen OpenMeetings Räume erzeugt und genutzt werden: +chelp.openmeetings.course=In Kursen mit dem Kursbaustein OpenMeetings. Jeder Kursbaustein erzeugt einen entsprechenden Raum auf dem OpenMeetings Server. +chelp.openmeetings.group=In Gruppen mit dem Gruppenwerkzeut OpenMeetings. Jede Gruppe hat ihren eigenen OpenMeetings Raum zur Verfügung. +chelp.openmeetings.config=Um das OpenMeetings Modul zu konfigurieren geben Sie in dem Administrationsmodul die Adresse des OpenMeetings Server ein und fügen einen gültigen Benutzername und Passwort hinzu den Sie zuvor auf dem OpenMeetings Server erstellt haben. Der Benutzer muss Adminstrationsrechte besitzen. Speichern Sie die Daten anschliessen und drücken Sie die Schaltfläche "$:check" um die Verbindungsdaten zu überprüfen. +chelp.openmeetings.ext=Das Feld "$:openolat.externaltype" wird automatisch erzeugt und kann nicht verändert werden. Es wird für die Zuordnung von Räumen zum OpenOLAT System von OpenMeetings verwendet. + +help.hover.openmeetings.room=Hilfe zur Konfiguration eines OpenMeeting Raumes +chelp.room.title=Apache OpenMeetings: Konfiguration eines Sitzungsraumes +chelp.openmeetings.room=Ist das OpenMeetings Module in der Systemadministration konfiguriert und eingeschaltet, so können in OpenOLAT an den folgenden Stellen OpenMeetings Räume erzeugt und genutzt werden: +chelp.openmeetings.room.config=Um OpenMeetings Sitzungsräume zu konfigurieren stehen Ihnen folgende Parameter zur Verfügung: +chelp.openmeetings.room.options=Parameter +chelp.openmeetings.room.values=Werte +chelp.openmeetings.room.desc=Beschreibung +chelp.openmeetings.room.text=Text +chelp.openmeetings.room.create=Haben Sie die Konfigurationen des Raumes angepasst können Sie den Raum speichern. Die Konfiguration kann zu einem späteren Zeitpunkt angepasst werden. + +help.hover.openmeetings.room_admin=Hilfe zur Administration eines OpenMeeting Raumes +chelp.room_admin.title=Apache OpenMeetings: Administration eines Sitzungsraumes +chelp.openmeetings.admin=Wählen sie die folgenden Aktionen um einen bestehenden OpenMeetings Raum zu administrieren: + diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_en.properties index 4f0e9564e50a7f7170536b9ac01b14e740dcb50c..d53f7896f96c9ecfa939f4131996a3ff444fbfd4 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_en.properties @@ -1,21 +1,38 @@ +#Tue Dec 18 17:48:17 CET 2012 admin.menu.title=OpenMeetings admin.menu.title.alt=Configuration of the integration to an Apache OpenMeetings Server +administration.title=Administration check=Check the connection check.nok=The server connection and configuration test was not successful. Please check the server URL, the system user name and password you configured. check.ok=The server connection and configuration test was successful. You can now use OpenMeetings in OpenOLAT. +chelp.module.title=Apache OpenMeetings\: configuration +chelp.openmeetings.admin=Select from the following actions to administrate an OpenMeetings room\: +chelp.openmeetings.config=Add the address of the OpenMeetings server and a valid username and password to configure the OpenMeetings module for OpenOLAT. The user must already exist on the OpenMeetings server and have administrative rights. Save the form and press the button "$\:check" to verify the configuration and server availablilty. +chelp.openmeetings.course=In courses using the course element OpenMeetings. Each instance of the course element creates a dedicated room on the OpenMeetings server. +chelp.openmeetings.ext=The property "$\:openolat.externaltype" is created automatically and can not be modified. It is used by OpenMeetings to relate rooms with OpenOLAT. +chelp.openmeetings.group=In groups using the OpenMeetings tool. Each group has its own independent OpenMeetings room. +chelp.openmeetings.intro=OpenMeetings is a virtual classroom and communication solution to support synchronous conferences and meetings. OpenMeetings is an open source software that is distributed at no cost under the Apache 2.0 open source license. The key features are audio- and videoconferencing, meeting recording, chat, desktop sharing, file sharing, whiteboard and surveys. +chelp.openmeetings.module=In the OpenOLAT system administration section the OpenMeetings module must be configured to enable the OpenMeetings functionality. When the connection parameters of the module are configured and the module has been enabled, OpenOLAT offers the use of OpenMeetings rooms at the following places\: +chelp.openmeetings.room=When the OpenMeetings module is configured and enabled in the system administration you can user OpenMeetings rooms at the following places in OpenOLAT\: +chelp.openmeetings.room.config=Configure the following parameters of an OpenMeetings room\: +chelp.openmeetings.room.create=When making changes to the room configuration press save to activate and persist the changes. The configuration can be modified multiple times. +chelp.openmeetings.room.desc=Description +chelp.openmeetings.room.options=Parameter +chelp.openmeetings.room.text=Text +chelp.openmeetings.room.values=Values +chelp.openmeetings.url=More information regarding Apache OpenMeetings can be found at the URL +chelp.openmeetings1=Help Apache OpenMeetings +chelp.room.title=Apache OpenMeetings\: Configuration of a meeting room +chelp.room_admin.title=Apache OpenMeetings\: Administration of a meeting room +close.room=Close +delete=Delete +delete.confirm=Do you really want to delete this room "{0}"? +delete.nok=The room could not be deleted for unknown reasons. Please try again later or contact the administrator. +delete.ok=The room has successfuly been deleted. +download=Download +edit.room=Room configuration +edit.room.desc=Change the configuration parameter of the room such as the room type, available seats etc. enabled=enabled -error.notAvailable=The server is not available. -error.unkown=Unexpected error -error.noroom.short=The room is not configured in "{0}". -error.noroom.long=The room is not configured in "{0}". -error.-2=Please enter either an email address or a user name -error.-3=There is no user connected to this username -error.-4=The email containing a special link has been sent to your email address -error.-5=No user found -error.-6=The passwords you entered weren't identical -error.-7=Password and or username too short, required minimum length for user name / password are: -error.-8=Password set. You can now login. -error.-9=No such email address was found. Make sure you entered the same email address you used to create your account. error.-10=Username not found error.-11=Invalid password error.-12=Successfully logged out @@ -26,6 +43,7 @@ error.-16=System error please contact the administrator error.-17=The mail address is already registered error.-18=Your account has been created. You can now login. error.-19=Invalid email address +error.-2=Please enter either an email address or a user name error.-20=Duplicate file name, please enter another error.-21=File name too short error.-22=Could not save the address @@ -36,6 +54,7 @@ error.-26=Admin authorization required error.-27=Invalid label ID error.-28=You have deleted the label error.-29=Invalid label ID +error.-3=There is no user connected to this username error.-30=This room is full error.-31=No invitation available for this invitation code error.-32=This invitation was already used @@ -46,6 +65,7 @@ error.-36=This method needs an adminstration account to be invoked error.-37=There was no session associated with this ID error.-38=You cannot delete your own user error.-39=This is an administrator or moderator account. You can only edit this account through the administration panel. +error.-4=The email containing a special link has been sent to your email address error.-40=You have successfully signed up. An email with a verification code will be sent to your mailbox. error.-41=Your account is not activated. Please use the link in the email you received during registration. error.-42=This session hash has already been used @@ -56,64 +76,81 @@ error.-46=The user is already denied. error.-47=The user is already approved. error.-48=This user contact hash is invalid. error.-49=There is no such contact. -error.-50=You invitation code is not valid, the code is only valid during this specific date and time: +error.-5=No user found +error.-50=You invitation code is not valid, the code is only valid during this specific date and time\: error.-51=Please enter a password error.-52=You need an account with user level user, moderator or admin error.-53=Please enter email error.-54=You don't have the right to give yourself or others exclusive audio. You need to apply for the right from the moderator or ask the moderator to give you exclusive audio. error.-55=Ping failed, could not find server by this name. error.-56=Ping failed, multiple servers found with this name. -delete=Delete -delete.confirm=Do you really want to delete this room "{0}"? -delete.ok=The room has successfuly been deleted. -delete.nok=The room could not be deleted for unknown reasons. Please try again later or contact the administrator. +error.-6=The passwords you entered weren't identical +error.-7=Password and or username too short, required minimum length for user name / password are\: +error.-8=Password set. You can now login. +error.-9=No such email address was found. Make sure you entered the same email address you used to create your account. +error.noroom.long=The room is not configured in "{0}". +error.noroom.short=The room is not configured in "{0}". +error.notAvailable=The server is not available. +error.unkown=Unexpected error +first.name=First name +guest.room=User information +help.hover.openmeetings=Help to integrate an Apache OpenMeetings Server +help.hover.openmeetings.room=Help regarding the configuration of an OpenMeetings room +help.hover.openmeetings.room_admin=Help regarding the administration of an OpenMeetings room kickout=Kick out -kickout.ok=The user has successfuly been kicked out. kickout.nok=The user could not be kicked out for unknown reasons. Please try again later or contact the administrator. +kickout.ok=The user has successfuly been kicked out. +last.name=Last name +open.room=Open +open.room.desc=The room can be closed temporarily and reopened again. This action does nor delete the room or the data in the room, it just blocks access to the room. The action can be performed multiple times. This is useful to prepare a room for a session and then close to open it just sharply before the session begins. openmeetings.account=Configuration -openmeetings.title=OpenMeetings +openmeetings.disabled.error=The OpenMeetings module is not enabled. openmeetings.intro=Configuration Apache OpenMeetings v2.0 openmeetings.module.enabled=Module "OpenMeetings" -view=View -table.empty=No raum has been found. +openmeetings.title=OpenMeetings +openolat.externaltype=External type +option.adminlogin=Web Service username +option.adminpassword=Web Service password +option.baseurl=URL OpenMeetings Server recording.name=Name +recording.remove=Do you really want to delete recording "{0}"? recordings=Recordings recordings.empty=This room hasn't any recordings -rooms.title=Room +room.actions=Button +room.actions.desc=Description room.closed.explanation=The room is closed. room.comment=Comment +room.comment.desc=Use the description to describe the meeting agenda or the target audience. +room.infos=Detail information room.members=Members +room.members.desc=Display all users currently in the room. Select the link "$\:kickout" to immediately terminate the meeting participation for a certain user. +room.moderation.mode=Moderation +room.moderation.mode.desc=If enabled in the system administration, this option will require a moderator in the room. Non-moderators can enter the room, however no actions can be performed until a moderator participates the meeting. Moderator rights are automatically assigned to course authors and coaches of the course in courses and the group coaches in groups. +room.moderation.no=No moderation +room.moderation.yes=Moderated room.name=Room's name +room.name.desc=The name of the meeting room as displayed in the room. +room.notfound.error=Room not found +room.numOfUsers=\# Users +room.raw.title=Detail information +room.recording=Recording allowed +room.recording.desc=With this option the recording of meeting sessions can be enabled or disabled. After the meeting the recording will be converted automatically and listed for viewing. +room.recording.enabled=allow +room.resource=Resources +room.size=Number of participants +room.size.desc=The number of available seats limits the number of users that can participate in the meeting at the same time. When all seats are taken it is not possible to enter the room anymore until someone is leaving the room. room.type=Room's type -room.type.conference=Conference (1 - 25 users) room.type.audience=Audience +room.type.conference=Conference (1 - 25 users) +room.type.desc=Type of the meeting. Depending on the type the available tools and rights configuration varies. Conferences are optimized for meetings with little participants and where all participants have video feeds to share and can use al tools. A webinar on the other hand should be used to implement a lecture with one speaker with video feed and many participants. The interview is a meeting where one person interviews another person and the interview can be recorded. +room.type.interview=Interview (1\:1 meeting with recording) room.type.restricted=Webinar (1 - 150 users) -room.type.interview=Interview (1:1 meeting with recording) -room.moderation.mode=Moderation -room.moderation.yes=Moderated -room.moderation.no=No moderation -room.size=Number of participants -room.recording=Recording -room.resource=Resources -room.numOfUsers=# Users -room.infos=Detail information -room.recording=Recording allowed +rooms.title=Room +start.hint=Select the button "$\:start.room" to participate in this meeting room. If available you can also watch recordings of previous meetings. Select the button "$\:recordings" to see the list of available recordings. start.room=Enter start.room.guest=Enter -open.room=Open -close.room=Close -room.raw.title=Detail information -guest.room=User information -first.name=First name -last.name=Last name +table.empty=No raum has been found. users=Users +users.description=The participant list displays a list of users that are currently in the meeting room. You can terminate the meeting session for each user at any time. users.empty=The room is still empty -openolat.externaltype=External type -room.notfound.error=Room not found -openmeetings.disabled.error=The OpenMeetings module is not enabled. -option.baseurl=URL OpenMeetings Server -option.adminlogin=Web Service username -option.adminpassword=Web Service password -chelp.openmeetings1=Help Apache OpenMeetings -chelp.module.title=Apache OpenMeetings: configuration -help.hover.openmeetings=Help to integrate an Apache OpenMeetings Server +view=View diff --git a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_fr.properties b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_fr.properties index a7db9ea51592789a58d3809f3c4ddba61118c6df..d41bdecade90a9af4c14a79df13ced0d93c0a9d8 100644 --- a/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_fr.properties +++ b/src/main/java/org/olat/modules/openmeetings/ui/_i18n/LocalStrings_fr.properties @@ -22,6 +22,7 @@ openmeetings.module.enabled=Module "OpenMeetings" view=Regarder table.empty=Aucune salle n'a \u00E9t\u00E9 trouv\u00E9e. recording.name=Nom +recording.remove=Voulez-vous vraiment effacer l'enregistrement "{0}"? recordings=Enregistrements recordings.empty=La salle n'a aucun enregistrements disponibles. rooms.title=Salle diff --git a/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java b/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java index 44d9d5804503d5c526b1902b55c32be823efcd3e..1a871e7d8f9b14fb8af19aca755283f0f09bf273 100644 --- a/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java +++ b/src/main/java/org/olat/modules/scorm/ScormAPIandDisplayController.java @@ -60,6 +60,7 @@ import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.activity.LearningResourceLoggingAction; import org.olat.core.logging.activity.ThreadLocalUserActivityLogger; import org.olat.core.util.FileUtils; +import org.olat.core.util.WebappHelper; import org.olat.core.util.resource.OresHelper; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.course.CourseModule; @@ -372,7 +373,7 @@ public class ScormAPIandDisplayController extends MainLayoutBasicController impl private void cleanUpCollectedScoData() { if(scorm_lesson_mode.equals(ScormConstants.SCORM_MODE_BROWSE) || scorm_lesson_mode.equals(ScormConstants.SCORM_MODE_REVIEW)){ - String path = FolderConfig.getCanonicalRoot()+"/tmp/"+this.hashCode(); + String path = WebappHelper.getTmpDir() + "/tmpscorm/" + hashCode(); FileUtils.deleteDirsAndFiles( new File(path),true, true); } } diff --git a/src/main/java/org/olat/modules/scorm/SettingsHandlerImpl.java b/src/main/java/org/olat/modules/scorm/SettingsHandlerImpl.java index f404bb165c775a3ed759f71be70bb45dda12b82d..7c9788791b37f31af9f553cd52661e3a4259bffe 100644 --- a/src/main/java/org/olat/modules/scorm/SettingsHandlerImpl.java +++ b/src/main/java/org/olat/modules/scorm/SettingsHandlerImpl.java @@ -29,9 +29,9 @@ import java.io.File; import java.io.IOException; import org.jdom.JDOMException; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; +import org.olat.core.util.WebappHelper; import org.olat.modules.scorm.contentpackaging.NoItemFoundException; import org.olat.modules.scorm.contentpackaging.ScormPackageHandler; @@ -165,8 +165,8 @@ public class SettingsHandlerImpl implements ISettingsHandler { if(courseId == null) courseId = ""; if(repoId == null) repoId = ""; StringBuilder tempPath = new StringBuilder(); - tempPath.append(FolderConfig.getCanonicalRoot()); - tempPath.append("/tmp/"); + tempPath.append(WebappHelper.getTmpDir()); + tempPath.append("/tmpscorm/"); tempPath.append(controllerHashCode); tempPath.append("/"); tempPath.append(userid); diff --git a/src/main/java/org/olat/modules/sharedfolder/SharedFolderManager.java b/src/main/java/org/olat/modules/sharedfolder/SharedFolderManager.java index 5fd3725d66f63e78ab8c048e82728412fed482d7..2805b0944e933b773bc9ccd31c4d778bef72e9e5 100644 --- a/src/main/java/org/olat/modules/sharedfolder/SharedFolderManager.java +++ b/src/main/java/org/olat/modules/sharedfolder/SharedFolderManager.java @@ -27,7 +27,6 @@ package org.olat.modules.sharedfolder; import java.io.File; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.modules.bc.vfs.OlatNamedContainerImpl; import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; import org.olat.core.commons.persistence.DBFactory; @@ -36,6 +35,7 @@ import org.olat.core.gui.media.MediaResource; import org.olat.core.id.OLATResourceable; import org.olat.core.manager.BasicManager; import org.olat.core.util.Formatter; +import org.olat.core.util.WebappHelper; import org.olat.core.util.ZipUtil; import org.olat.core.util.vfs.LocalFileImpl; import org.olat.core.util.vfs.VFSContainer; @@ -91,7 +91,7 @@ public class SharedFolderManager extends BasicManager { public MediaResource getAsMediaResource(OLATResourceable res) { String exportFileName = res.getResourceableId() + ".zip"; - File fExportZIP = new File(FolderConfig.getCanonicalTmpDir() + "/" + exportFileName); + File fExportZIP = new File(WebappHelper.getTmpDir() + "/" + exportFileName); VFSContainer sharedFolder = SharedFolderManager.getInstance().getSharedFolder(res); //OLAT-5368: do intermediate commit to avoid transaction timeout diff --git a/src/main/java/org/olat/notifications/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/notifications/_i18n/LocalStrings_pl.properties index 67bb275c19ef31ab779ed3690a0a08ffe5836da6..b0807ab84ed82a991d61bcab118d74e7c5436dc2 100644 --- a/src/main/java/org/olat/notifications/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/notifications/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Wed Jul 28 13:33:32 CEST 2010 +#Wed Dec 05 14:42:44 CET 2012 action.choose=Wybierz confirm.delete=Czy na pewno chcesz usun\u0105\u0107 powiadomienie, kt\u00F3re zasubskrybowa\u0142e\u015B? email.nok=Nowo\u015Bci nie mog\u0142y zosta\u0107 wys\u0142ane za pomoc\u0105 poczty elektronicznej. Spr\u00F3buj ponownie p\u00F3\u017Aniej lub skontaktuj si\u0119 z administratorem. @@ -13,6 +13,7 @@ news.no.news=Brak informacji news.since=Zmiany od\: news.since.link=Poka\u017C zmiany news.title=Nowo\u015Bci w subskrybcjach +news.type.all=Wszystkie notifcations.rss.desc=O wszystkich nowo\u015Bciach mo\u017Cesz by\u0107 powiadamiany r\u00F3wnie\u017C za po\u015Brednictwem kana\u0142u RSS. Wybierz link RSS poni\u017Cej, zanim dodasz go do swojego czytnika RSS. notifcations.rss.title=Osobisty kana\u0142 RSS notificationsPortlet.description=Szybki dost\u0119p do subskrybowanych nowo\u015Bci diff --git a/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java b/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java index b616b7c7907bce4f2bc16bfbb7dd229488bf6f0a..fdcfd69107c0011a8efc33f123711b78869906f0 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java +++ b/src/main/java/org/olat/portfolio/ui/structel/EPShareListController.java @@ -153,6 +153,10 @@ public class EPShareListController extends FormBasicController { for (PolicyWrapper policyWrapper : policyWrappers) { Type type = policyWrapper.getType(); + if(type == null) { + continue;//tutor implicit rule + } + TextElement mailEl = policyWrapper.getMailEl(); if (mailEl != null) { String mail = mailEl.getValue(); @@ -185,7 +189,8 @@ public class EPShareListController extends FormBasicController { allOk &= false; } } - if (policyWrapper.getFromChooser().hasError() || policyWrapper.getToChooser().hasError()){ + if ((policyWrapper.getFromChooser() != null && policyWrapper.getFromChooser().hasError()) + || (policyWrapper.getToChooser() != null && policyWrapper.getToChooser().hasError())){ genericError = translate("map.share.date.invalid"); allOk &= false; } @@ -200,7 +205,9 @@ public class EPShareListController extends FormBasicController { FormLayoutContainer cmp = (FormLayoutContainer) flc.getFormComponent(policyWrapper.getComponentName()); String errorCompName = policyWrapper.calc("errorpanel"); StaticTextElement errTextEl = (StaticTextElement) cmp.getFormComponent(errorCompName); - if (genericError != null) errTextEl.setValue(genericError); + if (genericError != null && errTextEl != null) { + errTextEl.setValue(genericError); + } } return allOk && super.validateFormLogic(ureq); @@ -213,6 +220,8 @@ public class EPShareListController extends FormBasicController { List<EPMapPolicy> mapPolicies = new ArrayList<EPMapPolicy>(); for(PolicyWrapper wrapper:policyWrappers) { + if(wrapper.getType() == null) continue; + mapPolicies.add(wrapper.getMapPolicy()); if (wrapper.getType().equals(EPMapPolicy.Type.invitation)){ // always send an invitation mail for invited-non-olat users @@ -387,8 +396,12 @@ public class EPShareListController extends FormBasicController { if(mailEl != null) { policyWrapper.getInvitation().setMail(mailEl.getValue()); } - policyWrapper.setFrom(policyWrapper.getFromChooser().getDate()); - policyWrapper.setTo(policyWrapper.getToChooser().getDate()); + if(policyWrapper.getFromChooser() != null) { + policyWrapper.setFrom(policyWrapper.getFromChooser().getDate()); + } + if(policyWrapper.getToChooser() != null) { + policyWrapper.setTo(policyWrapper.getToChooser().getDate()); + } } } @@ -413,10 +426,10 @@ public class EPShareListController extends FormBasicController { container.contextPut("wrapper", policyWrapper); container.setRootForm(mainForm); - SingleSelection type = uifactory.addDropdownSingleselect("map.share.target." + cmpName, "map.share.target", container, targetKeys, targetValues, null); - type.addActionListener(this, FormEvent.ONCHANGE); - type.setUserObject(policyWrapper); if(policyWrapper.getType() != null) { + SingleSelection type = uifactory.addDropdownSingleselect("map.share.target." + cmpName, "map.share.target", container, targetKeys, targetValues, null); + type.addActionListener(this, FormEvent.ONCHANGE); + type.setUserObject(policyWrapper); type.select(policyWrapper.getType().name(), true); switch(policyWrapper.getType()) { case user: @@ -628,7 +641,7 @@ public class EPShareListController extends FormBasicController { if (StringHelper.containsNonWhitespace(searchValue)) { String searchValueLower = searchValue.toLowerCase(); for(BusinessGroup group:groupList) { - if(group.getName().toLowerCase().indexOf(searchValueLower) >= 0) { + if(group.getName() != null && group.getName().toLowerCase().indexOf(searchValueLower) >= 0) { resMap.put(group.getName(), group.getKey().toString()); } } @@ -638,6 +651,11 @@ public class EPShareListController extends FormBasicController { public class TutorPolicyWrapper extends PolicyWrapper { + @Override + public Type getType() { + return null; + } + @Override public Date getTo() { return null; diff --git a/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_de.properties index a5902ad35a501cb4b3764194ac167f806b4297e5..8e86ad74992f1b699a1b4a2ff1d8d516d8b7dc4b 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_de.properties @@ -85,7 +85,7 @@ map.share.with.mail.error=Bitte geben Sie eine g map.share.with.mail.error.olatUser=Diese E-Mailadresse wird bereits von einem OLAT-Benutzer verwendet. map.share.with.link=URL map.share.with.allOlatUsers=Für alle OLAT-Benutzer freigegeben -map.share.with.tutor=Für Ihren Betreuer freigegeben +map.share.with.tutor=Automatisch für die Betreuer des Kurses freigegeben map.share.empty.warn=Dieses Feld muss ausgefüllt werden. map.share.invitation.mail.subject=Einladung zu einer freigegebenen Sammelmappe map.share.invitation.mail.list=Eingeladene Personen diff --git a/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_en.properties index 3993b8b2f3b66f36070d140eb6e684f637fc00c3..17377640e0031207137568c7f48c0b059b9de1c7 100644 --- a/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/portfolio/ui/structel/_i18n/LocalStrings_en.properties @@ -84,7 +84,7 @@ map.share.to.invitation=Release invitation map.share.to.user=User map.share.to.user.hint=Click here to select user map.share.with.allOlatUsers=Release for all OLAT users -map.share.with.tutor=Release for your coach +map.share.with.tutor=Automatically released for the coaches of the course map.share.with.firstName=First name map.share.with.lastName=Last name map.share.with.link=URL diff --git a/src/main/java/org/olat/registration/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/registration/_i18n/LocalStrings_pl.properties index 80e9e02ec53b26aa8688938664678192a2130f79..087f890332451c456563170b50ffdd343d60c426 100644 --- a/src/main/java/org/olat/registration/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/registration/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Fri Sep 03 15:02:22 CEST 2010 +#Wed Dec 05 14:39:33 CET 2012 disclaimer.acknowledged=<b>Przeczyta\u0142em regulamin, rozumiem i akceptuj\u0119.</b> disclaimer.additionalcheckbox=<b>Akceptuj\u0119 zasady przechowywania danych</b> disclaimer.additionallinktext=Warunki korzystania (dokument PDF) @@ -7,7 +7,7 @@ disclaimer.form.cancelled=Nie zaakceptowa\u0142e\u015B warunk\u00F3w disclaimer.header=Warunki disclaimer.nok=Odrzu\u0107 disclaimer.ok=Akceptuj -disclaimer.paragraph1=U\u017Cytkownik OpenOLAT musi by\u0107 \u015Bwiadom, \u017Ce OpenOLAT mo\u017Ce by\u0107 u\u017Cywany wy\u0142\u0105cznie do uczenia si\u0119 lub nauczania. On/ona nie mo\u017Ce narusza\u0107 jakiegokolwiek prawa Szwajcarii. W szczeg\u00F3lno\u015Bci u\u017Cytkownicy OpenOLAT nie mog\u0105 rozpowszechnia\u0107 materia\u0142\u00F3w pornograficznych, rasistowskich, lub natutury drastycznej, lub przechowywa\u0107 takie materia\u0142y na serwerze OpenOLAT. Ponadto u\u017Cytkownicy nie mog\u0105 udost\u0119pnia\u0107 materia\u0142\u00F3w pod\u017Cegaj\u0105cych do nielegalnych dzia\u0142a\u0144. +disclaimer.paragraph1=U\u017Cytkownik OpenOLAT musi by\u0107 \u015Bwiadom, \u017Ce OpenOLAT mo\u017Ce by\u0107 u\u017Cywany wy\u0142\u0105cznie do uczenia si\u0119 lub nauczania. U\u017Cytkownikom OpenOLAT nie wolno narusza\u0107 jakiegokolwiek prawa Szwajcarii. W szczeg\u00F3lno\u015Bci u\u017Cytkownicy OpenOLAT nie mog\u0105 rozpowszechnia\u0107 materia\u0142\u00F3w pornograficznych, rasistowskich, natutury drastycznej lub przechowywa\u0107 takich materia\u0142\u00F3w na platformie OpenOLAT. Ponadto u\u017Cytkownicy nie mog\u0105 udost\u0119pnia\u0107 materia\u0142\u00F3w pod\u017Cegaj\u0105cych do nielegalnych dzia\u0142a\u0144. disclaimer.paragraph2=Administrator platformy rezerwuje sobie prawo do blokowania dost\u0119pu do serwera OpenOLAT u\u017Cytkwonikom naruszaj\u0105cym powy\u017Csze zasady i usuni\u0119cia danych u\u017Cytkownika. Uniwersystet w Zurychu mo\u017Ce r\u00F3wnie\u017C podj\u0105\u0107 w powy\u017Cszych przypadkach kroki prawne. disclaimer.terms.of.usage=<b>Regulamin</b> email.address=Adres e-mail diff --git a/src/main/java/org/olat/repository/RepositoryMailing.java b/src/main/java/org/olat/repository/RepositoryMailing.java index 39a0bc48eb37bea48c6382143b45d149590b4f45..a69ab7b6d9ab4f3229cabc30f1d1d10852141bfe 100644 --- a/src/main/java/org/olat/repository/RepositoryMailing.java +++ b/src/main/java/org/olat/repository/RepositoryMailing.java @@ -27,7 +27,9 @@ import org.olat.core.gui.translator.Translator; import org.olat.core.id.Identity; import org.olat.core.id.User; import org.olat.core.id.UserConstants; +import org.olat.core.util.StringHelper; import org.olat.core.util.Util; +import org.olat.core.util.filter.FilterFactory; import org.olat.core.util.i18n.I18nManager; import org.olat.core.util.mail.MailContext; import org.olat.core.util.mail.MailContextImpl; @@ -35,6 +37,7 @@ import org.olat.core.util.mail.MailPackage; import org.olat.core.util.mail.MailTemplate; import org.olat.core.util.mail.MailerResult; import org.olat.core.util.mail.MailerWithTemplate; +import org.olat.group.ui.main.MemberPermissionChangeEvent; /** * @@ -42,10 +45,19 @@ import org.olat.core.util.mail.MailerWithTemplate; */ public class RepositoryMailing { + public static Type getDefaultTemplateType(MemberPermissionChangeEvent event) { + if(event.size() == 1) { + if(event.getRepoTutor() != null && event.getRepoTutor().booleanValue()) { + return Type.addTutor; + } else if(event.getRepoParticipant() != null && event.getRepoParticipant().booleanValue()) { + return Type.addParticipant; + } + } + return null; + } + /** - * The mail template when adding users to a group. The method chooses - * automatically the right translator for the given group type to customize - * the template text + * The mail template when adding users to a group. * * @param re * @param actor @@ -58,9 +70,20 @@ public class RepositoryMailing { } /** - * The mail template when removing users from a repository entry. The method chooses - * automatically the right translator for the given group type to customize - * the template text + * The mail template when adding tutors to a group. + * + * @param re + * @param actor + * @return the generated MailTemplate + */ + public static MailTemplate createAddTutorMailTemplate(RepositoryEntry re, Identity actor) { + String subjectKey = "notification.mail.added.subject"; + String bodyKey = "notification.mail.added.body"; + return createMailTemplate(re, actor, subjectKey, bodyKey); + } + + /** + * The mail template when removing users from a repository entry. * * @param re * @param actor @@ -80,6 +103,8 @@ public class RepositoryMailing { return createAddParticipantMailTemplate(re, ureqIdentity); case removeParticipant: return createRemoveParticipantMailTemplate(re, ureqIdentity); + case addTutor: + return createAddTutorMailTemplate(re, ureqIdentity); } return null; } @@ -100,8 +125,6 @@ public class RepositoryMailing { if(context == null) { context = new MailContextImpl(null, null, "[RepositoryEntry:" + re.getKey() + "]"); } - - System.out.println("***************************** Send mail"); MailerResult result = mailer.sendMailAsSeparateMails(context, Collections.singletonList(identity), null, template, null); if(mailing != null) { @@ -112,12 +135,13 @@ public class RepositoryMailing { public enum Type { addParticipant, removeParticipant, + addTutor, } private static MailTemplate createMailTemplate(RepositoryEntry re, Identity actor, String subjectKey, String bodyKey) { // build learning resources as list of url as string final String reName = re.getDisplayname(); - final String redescription = re.getDescription(); + final String redescription = (StringHelper.containsNonWhitespace(re.getDescription()) ? FilterFactory.getHtmlTagAndDescapingFilter().filter(re.getDescription()) : ""); // get some data about the actor and fetch the translated subject / body via i18n module String[] bodyArgs = new String[] { @@ -151,5 +175,4 @@ public class RepositoryMailing { }; return mailTempl; } - -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/repository/RepositoryManager.java b/src/main/java/org/olat/repository/RepositoryManager.java index 9e1fbf361447586ea03ce024e4e386fdd5bb213f..22300a30cad836440a025e1536e4747c9bb6d299 100644 --- a/src/main/java/org/olat/repository/RepositoryManager.java +++ b/src/main/java/org/olat/repository/RepositoryManager.java @@ -1633,6 +1633,22 @@ public class RepositoryManager extends BasicManager { } } + public void acceptPendingParticipation(Identity ureqIdentity, Identity identityToAdd, OLATResource resource, ResourceReservation reservation) { + RepositoryEntry re = lookupRepositoryEntry(resource, false); + if(re != null) { + if("repo_participant".equals(reservation.getType())) { + IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd); + //roles is not needed as I add myself as participant + addParticipants(ureqIdentity, null, iae, re, null); + } else if("repo_tutors".equals(reservation.getType())) { + IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd); + //roles is not needed as I add myself as tutor + addTutors(ureqIdentity, null, iae, re, null); + } + reservationDao.deleteReservation(reservation); + } + } + /** * add provided list of identities as tutor to the repo entry. silently ignore * if some identities were already tutor before. @@ -1641,28 +1657,65 @@ public class RepositoryManager extends BasicManager { * @param re * @param userActivityLogger */ - public void addTutors(Identity ureqIdentity, IdentitiesAddEvent iae, RepositoryEntry re) { + public void addTutors(Identity ureqIdentity, Roles ureqRoles, IdentitiesAddEvent iae, RepositoryEntry re, MailPackage mailing) { List<Identity> addIdentities = iae.getAddIdentities(); List<Identity> reallyAddedId = new ArrayList<Identity>(); - for (Identity identity : addIdentities) { - if (!securityManager.isIdentityInSecurityGroup(identity, re.getTutorGroup())) { - securityManager.addIdentityToSecurityGroup(identity, re.getTutorGroup()); - reallyAddedId.add(identity); - ActionType actionType = ThreadLocalUserActivityLogger.getStickyActionType(); - ThreadLocalUserActivityLogger.setStickyActionType(ActionType.admin); - try{ - ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_ADDED, getClass(), - LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry), LoggingResourceable.wrap(identity)); - } finally { - ThreadLocalUserActivityLogger.setStickyActionType(actionType); + for (Identity identityToAdd : addIdentities) { + if (!securityManager.isIdentityInSecurityGroup(identityToAdd, re.getTutorGroup())) { + + boolean mustAccept = true; + if(ureqIdentity != null && ureqIdentity.equals(identityToAdd)) { + mustAccept = false;//adding itself, we hope that he knows what he makes + } else if(ureqRoles == null || ureqIdentity == null) { + mustAccept = false;//administrative task + } else { + mustAccept = repositoryModule.isAcceptMembership(ureqRoles); } - logAudit("Idenitity(.key):" + ureqIdentity.getKey() + " added identity '" + identity.getName() - + "' to securitygroup with key " + re.getTutorGroup().getKey()); + + if(mustAccept) { + ResourceReservation olderReservation = reservationDao.loadReservation(identityToAdd, re.getOlatResource()); + if(olderReservation == null) { + Calendar cal = Calendar.getInstance(); + cal.add(Calendar.MONTH, 6); + Date expiration = cal.getTime(); + ResourceReservation reservation = + reservationDao.createReservation(identityToAdd, "repo_tutors", expiration, re.getOlatResource()); + if(reservation != null) { + RepositoryMailing.sendEmail(ureqIdentity, identityToAdd, re, RepositoryMailing.Type.addTutor, mailing, mailer); + } + } + } else { + addInternalTutors(ureqIdentity, identityToAdd, re, reallyAddedId); + RepositoryMailing.sendEmail(ureqIdentity, identityToAdd, re, RepositoryMailing.Type.addTutor, mailing, mailer); + } + }//else silently ignore already owner identities } iae.setIdentitiesAddedEvent(reallyAddedId); } + /** + * Internal method to add tutors, it makes no check. + * @param ureqIdentity + * @param identity + * @param re + * @param reallyAddedId + */ + private void addInternalTutors(Identity ureqIdentity, Identity identity, RepositoryEntry re, List<Identity> reallyAddedId) { + securityManager.addIdentityToSecurityGroup(identity, re.getTutorGroup()); + reallyAddedId.add(identity); + ActionType actionType = ThreadLocalUserActivityLogger.getStickyActionType(); + ThreadLocalUserActivityLogger.setStickyActionType(ActionType.admin); + try{ + ThreadLocalUserActivityLogger.log(GroupLoggingAction.GROUP_OWNER_ADDED, getClass(), + LoggingResourceable.wrap(re, OlatResourceableType.genRepoEntry), LoggingResourceable.wrap(identity)); + } finally { + ThreadLocalUserActivityLogger.setStickyActionType(actionType); + } + logAudit("Idenitity(.key):" + ureqIdentity.getKey() + " added identity '" + identity.getName() + + "' to securitygroup with key " + re.getTutorGroup().getKey()); + } + /** * remove list of identities as tutor of given repository entry. * @param ureqIdentity @@ -1811,6 +1864,13 @@ public class RepositoryManager extends BasicManager { } } + List<ResourceReservation> reservations = reservationDao.loadReservations(Collections.singletonList(re.getOlatResource())); + for(ResourceReservation reservation:reservations) { + if(members.contains(reservation.getIdentity())) { + reservationDao.deleteReservation(reservation); + } + } + return securityManager.removeIdentityFromSecurityGroups(members, secGroups); } @@ -1979,7 +2039,7 @@ public class RepositoryManager extends BasicManager { if(e.getRepoTutor() != null) { if(e.getRepoTutor().booleanValue()) { - addTutors(ureqIdentity, new IdentitiesAddEvent(e.getMember()), re); + addTutors(ureqIdentity, ureqRoles, new IdentitiesAddEvent(e.getMember()), re, mailing); } else { removeTutors(ureqIdentity, Collections.singletonList(e.getMember()), re); } diff --git a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties index 5d849e4bf04a1f4f858ae1597bb5750ae6784d5e..438604b7a8e18ce06dddee129d3b103fc7de7ef0 100644 --- a/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/repository/_i18n/LocalStrings_en.properties @@ -1,4 +1,4 @@ -#Wed Oct 24 16:41:12 CEST 2012 +#Tue Dec 18 17:57:53 CET 2012 CourseModule=Course EPStructuredMapTemplate=Portfolio template Failed=The transmission of this file failed. @@ -305,6 +305,10 @@ new.test=Create test new.test.intro=Create new test new.wiki=Create wiki new.wiki.intro=Create new wiki +notification.mail.added.body=*** This is an automatically generated message. Please do not answer to this message *** \r\n\r\nYou have been added by {0} {1} ({3}) to a course\:\r\n\r\nCourse name\: $coursename\r\nDescription\: $coursedescription\r\n\r\nIf you have questions regarding this action, please contact {0} {1} ({2}). +notification.mail.added.subject=Course $coursename +notification.mail.removed.body=*** This is an automatically generated message. Please do not answer to this message *** \r\n\r\nYou have been removed by {0} {1} ({3}) from a course\:\r\n\r\nCourse name\: $coursename\r\nDescription\: $coursedescription\r\n\r\nIf you have questions regarding this action, please contact {0} {1} ({2}). +notification.mail.removed.subject=Course $coursename\: you have been removed. properties.for=Settings - {0} referencableSearch.cmd.allEntries=All entries referencableSearch.cmd.myEntries=My entries diff --git a/src/main/java/org/olat/repository/controllers/RepositoryEntryImageController.java b/src/main/java/org/olat/repository/controllers/RepositoryEntryImageController.java index a03697aa93cfc294a1e04d03248e304a2cf758b1..5dc3630a7da408e20a9faa0a7111a05c8a3485ee 100644 --- a/src/main/java/org/olat/repository/controllers/RepositoryEntryImageController.java +++ b/src/main/java/org/olat/repository/controllers/RepositoryEntryImageController.java @@ -44,6 +44,7 @@ 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.gui.translator.Translator; +import org.olat.core.util.WebappHelper; import org.olat.core.util.vfs.LocalFolderImpl; import org.olat.core.util.vfs.Quota; import org.olat.core.util.vfs.VFSContainer; @@ -101,7 +102,7 @@ public class RepositoryEntryImageController extends BasicController { mimeTypes.add("image/jpg"); mimeTypes.add("image/jpeg"); mimeTypes.add("image/png"); - File uploadDir = new File(FolderConfig.getCanonicalTmpDir()); + File uploadDir = new File(WebappHelper.getTmpDir()); VFSContainer uploadContainer = new LocalFolderImpl(uploadDir); uploadCtr = new FileUploadController(getWindowControl(), uploadContainer, ureq, limitKB, Quota.UNLIMITED, mimeTypes, false, false, false, true); uploadCtr.hideTitleAndFieldset(); @@ -135,7 +136,8 @@ public class RepositoryEntryImageController extends BasicController { if (event instanceof FolderEvent && event.getCommand().equals(FolderEvent.UPLOAD_EVENT)) { FolderEvent folderEvent = (FolderEvent) event; // Get file from temp folder location - VFSContainer tmpHome = new LocalFolderImpl(new File(FolderConfig.getCanonicalTmpDir())); + + VFSContainer tmpHome = new LocalFolderImpl(new File(WebappHelper.getTmpDir())); VFSItem newFile = tmpHome.resolve(folderEvent.getFilename()); if (newFile instanceof VFSLeaf) { boolean ok = repositoryManager.setImage((VFSLeaf)newFile, repositoryEntry); diff --git a/src/main/java/org/olat/repository/controllers/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/repository/controllers/_i18n/LocalStrings_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..b0af7dcb35c40959f6662fce85678b1382d41052 --- /dev/null +++ b/src/main/java/org/olat/repository/controllers/_i18n/LocalStrings_en.properties @@ -0,0 +1,24 @@ +#Tue Dec 18 17:59:47 CET 2012 +add.member=$org.olat.group.ui.main\:add.member +assessment=$org.olat.group.ui.main\:assessment +dialog.modal.bg.leave.text=$org.olat.group.ui.main\:dialog.modal.bg.leave.text +edit.member=$org.olat.group.ui.main\:edit.member +edit.member.groups=$org.olat.group.ui.main\:edit.member.groups +home=$org.olat.group.ui.main\:home +import.member=$org.olat.group.ui.main\:import.member +table.header.edit=$org.olat.group.ui.main\:table.header.edit +table.header.firstName=$org.olat.group.ui.main\:table.header.firstName +table.header.firstTime=$org.olat.group.ui.main\:table.header.firstTime +table.header.freePlace=$org.olat.group.ui.main\:table.header.freePlace +table.header.graduate=$org.olat.group.ui.main\:table.header.graduate +table.header.groups=$org.olat.group.ui.main\:table.header.groups +table.header.lastName=$org.olat.group.ui.main\:table.header.lastName +table.header.lastTime=$org.olat.group.ui.main\:table.header.lastTime +table.header.mail=$org.olat.group.ui.main\:table.header.mail +table.header.participants=$org.olat.group.ui.main\:table.header.participants +table.header.participantsCount=$org.olat.group.ui.main\:table.header.participantsCount +table.header.remove=$org.olat.group.ui.main\:table.header.remove +table.header.role=$org.olat.group.ui.main\:table.header.role +table.header.tutors=$org.olat.group.ui.main\:table.header.tutors +table.header.tutorsCount=$org.olat.group.ui.main\:table.header.tutorsCount +table.header.waitingList=$org.olat.group.ui.main\:table.header.waitingList diff --git a/src/main/java/org/olat/repository/handlers/CourseHandler.java b/src/main/java/org/olat/repository/handlers/CourseHandler.java index 8a325f47ea4919a0e584574ed8183a29c3d10158..4e0bc250755eb9523cc57863fa279167abfce755 100644 --- a/src/main/java/org/olat/repository/handlers/CourseHandler.java +++ b/src/main/java/org/olat/repository/handlers/CourseHandler.java @@ -29,7 +29,6 @@ import java.io.File; import java.util.ArrayList; import java.util.List; -import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.gui.UserRequest; import org.olat.core.gui.control.Controller; import org.olat.core.gui.control.WindowControl; @@ -157,7 +156,7 @@ public class CourseHandler implements RepositoryHandler { RepositoryEntry re = RepositoryManager.getInstance().lookupRepositoryEntry(res, true); String exportFileName = re.getDisplayname() + ".zip"; exportFileName = StringHelper.transformDisplayNameToFileSystemName(exportFileName); - File fExportZIP = new File(System.getProperty("java.io.tmpdir")+File.separator+exportFileName); + File fExportZIP = new File(WebappHelper.getTmpDir() + File.separator + exportFileName); CourseFactory.exportCourseToZIP(res, fExportZIP, backwardsCompatible); return new CleanupAfterDeliveryFileMediaResource(fExportZIP); } @@ -267,7 +266,7 @@ public class CourseHandler implements RepositoryHandler { public String archive(Identity archiveOnBehalfOf, String archivFilePath, RepositoryEntry entry) { ICourse course = CourseFactory.loadCourse(entry.getOlatResource() ); // Archive course runtime data (like delete course, archive e.g. logfiles, node-data) - File tmpExportDir = new File(FolderConfig.getCanonicalTmpDir() + "/" + CodeHelper.getRAMUniqueID()); + File tmpExportDir = new File(WebappHelper.getTmpDir(), CodeHelper.getUniqueID()); tmpExportDir.mkdirs(); CourseFactory.archiveCourse(archiveOnBehalfOf, course, WebappHelper.getDefaultCharset(), I18nModule.getDefaultLocale(), tmpExportDir , true); // Archive course run structure (like course export) diff --git a/src/main/java/org/olat/resource/accesscontrol/ACService.java b/src/main/java/org/olat/resource/accesscontrol/ACService.java index ebc0099f698cb072e1f27ac007f24d1d99bd5f11..444cb59d30a417fecb24c91e16dffde21032c553 100644 --- a/src/main/java/org/olat/resource/accesscontrol/ACService.java +++ b/src/main/java/org/olat/resource/accesscontrol/ACService.java @@ -111,8 +111,6 @@ public interface ACService { public boolean denyAccesToResource(Identity identity, Offer offer); - public void removeReservation(ResourceReservation reservation); - /** * Get the reservation form an identity on a resource * @param identity @@ -150,6 +148,13 @@ public interface ACService { */ public void acceptReservationToResource(Identity identity, ResourceReservation reservation); + /** + * Cancel a reservation + * @param identity + * @param reservation + */ + public void removeReservation(Identity ureqIdentity, Identity identity, ResourceReservation reservation); + public int countReservations(OLATResource resource); public void cleanupReservations(); 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 282de3b8d18f1cb4b691e9f368327a1bd9ca3a3a..1d5ad4766ce43d04d5df4adfdcfc2625c5551f9a 100644 --- a/src/main/java/org/olat/resource/accesscontrol/_spring/acContext.xml +++ b/src/main/java/org/olat/resource/accesscontrol/_spring/acContext.xml @@ -65,16 +65,16 @@ </bean> <bean id="acReservationCleanupJob" class="org.springframework.scheduling.quartz.SimpleTriggerBean"> - <property name="jobDetail"> - <bean class="org.springframework.scheduling.quartz.JobDetailBean"> - <property name="jobClass" value="org.olat.resource.accesscontrol.manager.ReservationsJob" /> - </bean> - </property> + <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"> + <property name="jobClass" value="org.olat.resource.accesscontrol.manager.ReservationsJob" /> + </bean> + <bean id="acOfferManager" class="org.olat.resource.accesscontrol.manager.ACOfferManagerImpl"> <property name="dbInstance" ref="database"/> </bean> diff --git a/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java b/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java index 4a5037777b17a1012ac89512ca49dde24f3bfa63..6beccb866d328a7eb8a8723df663ca6bdf2dcbca 100644 --- a/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java +++ b/src/main/java/org/olat/resource/accesscontrol/manager/ACFrontendManager.java @@ -30,8 +30,8 @@ import java.util.List; import java.util.Map; import java.util.Set; -import org.olat.admin.securitygroup.gui.IdentitiesAddEvent; import org.olat.basesecurity.BaseSecurity; +import org.olat.core.commons.persistence.DB; import org.olat.core.id.Identity; import org.olat.core.id.Roles; import org.olat.core.manager.BasicManager; @@ -76,6 +76,8 @@ import org.springframework.stereotype.Service; @Service("acService") public class ACFrontendManager extends BasicManager implements ACService { + @Autowired + private DB dbInstance; @Autowired private BaseSecurity securityManager; @Autowired @@ -304,8 +306,6 @@ public class ACFrontendManager extends BasicManager implements ACService { return new AccessResult(false); } - - @Override public void acceptReservationToResource(Identity identity, ResourceReservation reservation) { OLATResource resource = reservation.getResource(); @@ -313,19 +313,18 @@ public class ACFrontendManager extends BasicManager implements ACService { //it's a reservation for a group businessGroupService.acceptPendingParticipation(identity, identity, resource); } else { - RepositoryEntry re = repositoryManager.lookupRepositoryEntry(resource, false); - if(re != null) { - IdentitiesAddEvent iae = new IdentitiesAddEvent(identity); - //roles is not needed as I add myself as participant - repositoryManager.addParticipants(identity, null, iae, re, null); - removeReservation(reservation); - } + repositoryManager.acceptPendingParticipation(identity, identity, resource, reservation); } } @Override - public void removeReservation(ResourceReservation reservation) { + public void removeReservation(Identity ureqIdentity, Identity identity, ResourceReservation reservation) { + OLATResource resource = reservation.getResource(); reservationDao.deleteReservation(reservation); + if("BusinessGroup".equals(resource.getResourceableTypeName())) { + dbInstance.commit();//needed to have the right number of participants to calculate upgrade from waiting list + businessGroupService.cancelPendingParticipation(ureqIdentity, reservation); + } } @Override @@ -414,7 +413,7 @@ public class ACFrontendManager extends BasicManager implements ACService { } else if("BusinessGroup".equals(resourceType)) { BusinessGroup group = businessGroupService.loadBusinessGroup(resource); if(group != null) { - EnrollState result = businessGroupService.enroll(identity, null, identity, group, null);//TODO memail + EnrollState result = businessGroupService.enroll(identity, null, identity, group, null); return result.isFailed() ? Boolean.FALSE : Boolean.TRUE; } } diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypal/PaypalIPNFilter.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypal/PaypalIPNFilter.java index d6ab240b0ad5fc3bb951d017daded3e712d0c802..29996af16e059aeacce962611807176a8c8a5766 100644 --- a/src/main/java/org/olat/resource/accesscontrol/provider/paypal/PaypalIPNFilter.java +++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypal/PaypalIPNFilter.java @@ -82,23 +82,17 @@ public class PaypalIPNFilter implements Filter { @SuppressWarnings("deprecation") private void verify(ServletRequest request, PaypalManager paypalManager) { try { - System.out.println("Verifify **************************************************"); - //code from the Paypal example // read post from PayPal system and add 'cmd' StringBuilder sb = new StringBuilder(); sb.append("cmd=_notify-validate"); Map<String,String> values = new HashMap<String,String>(); - for(@SuppressWarnings("unchecked") - Enumeration<String> en = request.getParameterNames(); en.hasMoreElements(); ){ + for(Enumeration<String> en = request.getParameterNames(); en.hasMoreElements(); ){ String paramName = en.nextElement(); String paramValue = request.getParameter(paramName); sb.append("&").append(paramName).append("=").append(URLEncoder.encode(paramValue)); values.put(paramName, paramValue); } - - - System.out.println("Verifify " + values); // post back to PayPal system to validate // NOTE: change http: to https: in the following URL to verify using SSL (for increased security). diff --git a/src/main/java/org/olat/resource/accesscontrol/provider/paypal/manager/PaypalManagerImpl.java b/src/main/java/org/olat/resource/accesscontrol/provider/paypal/manager/PaypalManagerImpl.java index 5ec0964174df78da4318b7921d16a581b6f2660a..061165f8c9ac483a3ceaf717aadae92fc202994a 100644 --- a/src/main/java/org/olat/resource/accesscontrol/provider/paypal/manager/PaypalManagerImpl.java +++ b/src/main/java/org/olat/resource/accesscontrol/provider/paypal/manager/PaypalManagerImpl.java @@ -387,7 +387,7 @@ public class PaypalManagerImpl extends BasicManager implements PaypalManager { OLATResource resource = line.getOffer().getResource(); ResourceReservation reservation = acService.getReservation(identity, resource); if(reservation != null) { - acService.removeReservation(reservation); + acService.removeReservation(identity, identity, reservation); logAudit("Remove reservation after cancellation for: " + reservation + " to " + identity, null); } } @@ -455,7 +455,7 @@ public class PaypalManagerImpl extends BasicManager implements PaypalManager { ResourceReservation reservation = reservationDao.loadReservation(identity, line.getOffer().getResource()); if(reservation != null) { - acService.removeReservation(reservation); + acService.removeReservation(identity, identity, reservation); logAudit("Remove reservation after cancellation for: " + reservation + " to " + identity, null); } } diff --git a/src/main/java/org/olat/restapi/group/LearningGroupWebService.java b/src/main/java/org/olat/restapi/group/LearningGroupWebService.java index a94fda02c05bdbab3e3213d5d9bd06b29a665239..77a06c5aba3fd06468927364ea5ac0a354da9eac 100644 --- a/src/main/java/org/olat/restapi/group/LearningGroupWebService.java +++ b/src/main/java/org/olat/restapi/group/LearningGroupWebService.java @@ -574,7 +574,7 @@ public class LearningGroupWebService { return Response.serverError().status(Status.NOT_FOUND).build(); } - bgs.addOwners(ureq.getIdentity(), Collections.singletonList(identity), group); + bgs.addOwners(ureq.getIdentity(), ureq.getUserSession().getRoles(), Collections.singletonList(identity), group, null); return Response.ok().build(); } catch (Exception e) { log.error("Trying to add an owner to a group", e); @@ -642,7 +642,7 @@ public class LearningGroupWebService { return Response.serverError().status(Status.NOT_FOUND).build(); } - BusinessGroupAddResponse state = bgs.addParticipants(ureq.getIdentity(), ureq.getUserSession().getRoles(), Collections.singletonList(identity), group, null);//TODO memail + BusinessGroupAddResponse state = bgs.addParticipants(ureq.getIdentity(), ureq.getUserSession().getRoles(), Collections.singletonList(identity), group, null); if(state.getAddedIdentities().contains(identity)) { return Response.ok().build(); } else if(state.getIdentitiesAlreadyInGroup().contains(identity)) { diff --git a/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java b/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java index 0ed97d28e134c9d0bc638b72e4bcc5db3111b376..8d559dd26a2f98b87af4818316d100bf091fd7b7 100644 --- a/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java +++ b/src/main/java/org/olat/restapi/repository/RepositoryEntryResource.java @@ -298,7 +298,7 @@ public class RepositoryEntryResource { UserRequest ureq = RestSecurityHelper.getUserRequest(request); IdentitiesAddEvent iae = new IdentitiesAddEvent(identityToAdd); - repositoryManager.addTutors(ureq.getIdentity(), iae, repoEntry); + repositoryManager.addTutors(ureq.getIdentity(), ureq.getUserSession().getRoles(), iae, repoEntry, null); return Response.ok().build(); } catch (Exception e) { log.error("Trying to add a coach to a repository entry", e); diff --git a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java index c01378fa731a9adebc8416d7891e132167e49c78..23e86f9de9241948ac3a1c3d32c48b6a6500532a 100644 --- a/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java +++ b/src/main/java/org/olat/restapi/security/RestApiLoginFilter.java @@ -72,6 +72,7 @@ public class RestApiLoginFilter implements Filter { private static final String BASIC_AUTH_REALM = "OLAT Rest API"; private static List<String> openUrls; + private static List<String> alwaysEnabledUrls; private static String LOGIN_URL; /** @@ -99,8 +100,9 @@ public class RestApiLoginFilter implements Filter { HttpServletRequest httpRequest = (HttpServletRequest)request; HttpServletResponse httpResponse = (HttpServletResponse)response; + String requestURI = httpRequest.getRequestURI(); RestModule restModule = (RestModule)CoreSpringFactory.getBean("restModule"); - if(!restModule.isEnabled()) { + if(!restModule.isEnabled() && !isRequestURIAlwaysEnabled(requestURI)) { httpResponse.sendError(403); return; } @@ -115,7 +117,6 @@ public class RestApiLoginFilter implements Filter { //use the available session followSession(httpRequest, httpResponse, chain); } else { - String requestURI = httpRequest.getRequestURI(); if(requestURI.startsWith(getLoginUrl())) { followForAuthentication(requestURI, uress, httpRequest, httpResponse, chain); } else if(isRequestURIInOpenSpace(requestURI)) { @@ -210,6 +211,15 @@ public class RestApiLoginFilter implements Filter { return false; } + private boolean isRequestURIAlwaysEnabled(String requestURI) { + for(String openURI : getAlwaysEnabledURIs()) { + if(requestURI.startsWith(openURI)) { + return true; + } + } + return false; + } + private void followForAuthentication(String requestURI, UserSession uress, HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException { //create a session for login without security check @@ -320,6 +330,19 @@ public class RestApiLoginFilter implements Filter { return LOGIN_URL; } + private List<String> getAlwaysEnabledURIs() { + if(alwaysEnabledUrls == null) { + String context = (Settings.isJUnitTest() ? "/olat" : WebappHelper.getServletContextPath() + RestSecurityHelper.SUB_CONTEXT); + alwaysEnabledUrls = new ArrayList<String>(); + alwaysEnabledUrls.add(context + "/i18n"); + alwaysEnabledUrls.add(context + "/api"); + alwaysEnabledUrls.add(context + "/ping"); + alwaysEnabledUrls.add(context + "/openmeetings"); + alwaysEnabledUrls.add(context + "/system"); + } + return alwaysEnabledUrls; + } + private List<String> getOpenURIs() { if(openUrls == null) { String context = (Settings.isJUnitTest() ? "/olat" : WebappHelper.getServletContextPath() + RestSecurityHelper.SUB_CONTEXT); diff --git a/src/main/java/org/olat/restapi/support/MultipartReader.java b/src/main/java/org/olat/restapi/support/MultipartReader.java index 33600fb1ae973839aebef1e5ac7bb3df0c6d4ec9..c5ff14874b6aae39a7827b46969d70fa631c25cc 100644 --- a/src/main/java/org/olat/restapi/support/MultipartReader.java +++ b/src/main/java/org/olat/restapi/support/MultipartReader.java @@ -38,6 +38,7 @@ import org.apache.commons.fileupload.util.Streams; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.StringHelper; +import org.olat.core.util.WebappHelper; /** * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com @@ -79,7 +80,7 @@ public class MultipartReader { } else { filename = "upload-" + UUID.randomUUID().toString().replace("-", ""); } - file = new File(System.getProperty("java.io.tmpdir"), filename); + file = new File(WebappHelper.getTmpDir(), filename); try { save(itemStream, file); } catch (Exception e) { diff --git a/src/main/java/org/olat/restapi/system/IndexerWebService.java b/src/main/java/org/olat/restapi/system/IndexerWebService.java new file mode 100644 index 0000000000000000000000000000000000000000..01de03c8078a3eed5763331731d0c0aa7824126a --- /dev/null +++ b/src/main/java/org/olat/restapi/system/IndexerWebService.java @@ -0,0 +1,110 @@ +/** + * <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.restapi.system; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +import org.olat.core.commons.services.search.SearchServiceStatus; +import org.olat.restapi.system.vo.IndexerStatisticsVO; +import org.olat.restapi.system.vo.IndexerStatus; +import org.olat.search.service.SearchServiceFactory; +import org.olat.search.service.SearchServiceStatusImpl; +import org.olat.search.service.indexer.FullIndexerStatus; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class IndexerWebService { + + /** + * Return the statistics about the indexer + * @response.representation.200.qname {http://www.example.com}releaseVO + * @response.representation.200.mediaType application/xml, application/json + * @response.representation.200.doc The verison of the instance + * @response.representation.200.example {@link org.olat.restapi.system.vo.Examples#SAMPLE_OO_INDEXERSTATSVO} + * @response.representation.401.doc The roles of the authenticated user are not sufficient + + * @return The statistics about the indexer + */ + @GET + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response getStatistics() { + IndexerStatisticsVO stats = getIndexerStatistics(); + return Response.ok(stats).build(); + } + + @GET + @Path("status") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response getStatus(@Context HttpServletRequest request) { + SearchServiceStatus serviceStatus = SearchServiceFactory.getService().getStatus(); + String status = serviceStatus.getStatus(); + return Response.ok(new IndexerStatus(status)).build(); + } + + @GET + @Path("status") + @Produces({MediaType.TEXT_PLAIN}) + public Response getPlainTextStatus(@Context HttpServletRequest request) { + SearchServiceStatus serviceStatus = SearchServiceFactory.getService().getStatus(); + return Response.ok(serviceStatus.getStatus()).build(); + } + + @POST + @Path("status") + public Response setStatus(@FormParam("status") String status, @Context HttpServletRequest request) { + if(FullIndexerStatus.STATUS_RUNNING.equals(status)) { + SearchServiceFactory.getService().startIndexing(); + } else if(FullIndexerStatus.STATUS_STOPPED.equals(status)) { + SearchServiceFactory.getService().stopIndexing(); + } + return Response.ok().build(); + } + + protected IndexerStatisticsVO getIndexerStatistics() { + IndexerStatisticsVO stats = new IndexerStatisticsVO(); + + SearchServiceStatus status = SearchServiceFactory.getService().getStatus(); + if(status instanceof SearchServiceStatusImpl) { + SearchServiceStatusImpl statusImpl = (SearchServiceStatusImpl)status; + FullIndexerStatus fStatus = statusImpl.getFullIndexerStatus(); + stats.setIndexedDocumentCount(fStatus.getDocumentCount()); + stats.setExcludedDocumentCount(fStatus.getExcludedDocumentCount()); + stats.setIndexSize(fStatus.getIndexSize()); + stats.setIndexingTime(fStatus.getIndexingTime()); + stats.setFullIndexStartedAt(fStatus.getFullIndexStartedAt()); + stats.setDocumentQueueSize(fStatus.getDocumentQueueSize()); + stats.setRunningFolderIndexerCount(fStatus.getNumberRunningFolderIndexer()); + stats.setAvailableFolderIndexerCount(fStatus.getNumberAvailableFolderIndexer()); + stats.setLastFullIndexTime(fStatus.getLastFullIndexTime()); + } + stats.setStatus(status.getStatus()); + return stats; + } +} diff --git a/src/main/java/org/olat/restapi/system/NotificationsAdminWebService.java b/src/main/java/org/olat/restapi/system/NotificationsAdminWebService.java new file mode 100644 index 0000000000000000000000000000000000000000..7db133f80cbbbb7886cc926d38faf0ac982fe78d --- /dev/null +++ b/src/main/java/org/olat/restapi/system/NotificationsAdminWebService.java @@ -0,0 +1,96 @@ +/** + * <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.restapi.system; + +import java.util.List; + +import javax.servlet.http.HttpServletRequest; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +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.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.Scheduler; +import org.quartz.SchedulerException; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class NotificationsAdminWebService { + + private static final OLog log = Tracing.createLoggerFor(NotificationsAdminWebService.class); + + @GET + @Path("status") + @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + public Response getStatus(@Context HttpServletRequest request) { + return Response.ok(new NotificationsStatus(getJobStatus())).build(); + } + + @GET + @Path("status") + @Produces({MediaType.TEXT_PLAIN}) + public Response getPlainTextStatus(@Context HttpServletRequest request) { + return Response.ok(getJobStatus()).build(); + } + + 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())) { + return "running"; + } + } + return "stopped"; + } catch (SchedulerException e) { + log.error("", e); + return "error"; + } + } + + @POST + @Path("status") + public Response setStatus(@FormParam("status") String status, @Context HttpServletRequest request) { + 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()); + } catch (SchedulerException e) { + log.error("", e); + } + } + return Response.ok().build(); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/restapi/system/OpenOLATStatisticsWebService.java b/src/main/java/org/olat/restapi/system/OpenOLATStatisticsWebService.java index 75dc1dd1423c6decceaa5c661308d78e825ec5ba..bcd90bd58b070c637d4d53bc7bda348e3f22876d 100644 --- a/src/main/java/org/olat/restapi/system/OpenOLATStatisticsWebService.java +++ b/src/main/java/org/olat/restapi/system/OpenOLATStatisticsWebService.java @@ -31,7 +31,6 @@ import javax.ws.rs.core.Response; import org.olat.basesecurity.BaseSecurity; import org.olat.core.CoreSpringFactory; -import org.olat.core.commons.services.search.SearchServiceStatus; import org.olat.core.util.SessionInfo; import org.olat.core.util.UserSession; import org.olat.core.util.session.UserSessionManager; @@ -40,14 +39,10 @@ import org.olat.group.BusinessGroupService; import org.olat.instantMessaging.InstantMessagingService; import org.olat.repository.RepositoryEntry; import org.olat.repository.RepositoryManager; -import org.olat.restapi.system.vo.IndexerStatisticsVO; import org.olat.restapi.system.vo.OpenOLATStatisticsVO; import org.olat.restapi.system.vo.RepositoryStatisticsVO; import org.olat.restapi.system.vo.SessionsVO; import org.olat.restapi.system.vo.UserStatisticsVO; -import org.olat.search.service.SearchServiceFactory; -import org.olat.search.service.SearchServiceStatusImpl; -import org.olat.search.service.indexer.FullIndexerStatus; /** * @@ -55,6 +50,8 @@ import org.olat.search.service.indexer.FullIndexerStatus; */ public class OpenOLATStatisticsWebService { + private final IndexerWebService indexerWebService = new IndexerWebService(); + /** * Return the statistics about OpenOLAT, users count, courses count... * @response.representation.200.qname {http://www.example.com}releaseVO @@ -72,7 +69,7 @@ public class OpenOLATStatisticsWebService { stats.setSessions(getSessionsVO()); stats.setUserStatistics(getUserStatistics()); stats.setRepositoryStatistics(getRepositoryStatistics()); - stats.setIndexerStatistics(getIndexerStatistics()); + stats.setIndexerStatistics(indexerWebService.getIndexerStatistics()); return Response.ok(stats).build(); } @@ -122,12 +119,9 @@ public class OpenOLATStatisticsWebService { * @param request The HTTP request * @return The statistics about the indexer */ - @GET @Path("indexer") - @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) - public Response getIndexerStatistics(@Context HttpServletRequest request) { - IndexerStatisticsVO stats = getIndexerStatistics(); - return Response.ok(stats).build(); + public IndexerWebService getIndexerStatistics(@Context HttpServletRequest request) { + return indexerWebService; } /** @@ -171,28 +165,6 @@ public class OpenOLATStatisticsWebService { return stats; } - private IndexerStatisticsVO getIndexerStatistics() { - IndexerStatisticsVO stats = new IndexerStatisticsVO(); - - SearchServiceStatus status = SearchServiceFactory.getService().getStatus(); - if(status instanceof SearchServiceStatusImpl) { - SearchServiceStatusImpl statusImpl = (SearchServiceStatusImpl)status; - FullIndexerStatus fStatus = statusImpl.getFullIndexerStatus(); - stats.setIndexedDocumentCount(fStatus.getDocumentCount()); - stats.setExcludedDocumentCount(fStatus.getExcludedDocumentCount()); - stats.setIndexSize(fStatus.getIndexSize()); - stats.setIndexingTime(fStatus.getIndexingTime()); - stats.setFullIndexStartedAt(fStatus.getFullIndexStartedAt()); - stats.setDocumentQueueSize(fStatus.getDocumentQueueSize()); - stats.setRunningFolderIndexerCount(fStatus.getNumberRunningFolderIndexer()); - stats.setAvailableFolderIndexerCount(fStatus.getNumberAvailableFolderIndexer()); - stats.setLastFullIndexTime(fStatus.getLastFullIndexTime()); - } - stats.setStatus(status.getStatus()); - - return stats; - } - private SessionsVO getSessionsVO() { SessionsVO vo = new SessionsVO(); diff --git a/src/main/java/org/olat/restapi/system/SystemWebService.java b/src/main/java/org/olat/restapi/system/SystemWebService.java index fb3749d45f618cb0953e490a764a69f97bab4ac4..f3b27963c1485d77060a07d6d75dc7b360870d35 100644 --- a/src/main/java/org/olat/restapi/system/SystemWebService.java +++ b/src/main/java/org/olat/restapi/system/SystemWebService.java @@ -118,6 +118,22 @@ public class SystemWebService { return new MonitoringWebService(); } + @Path("indexer") + public IndexerWebService getIndexer(@Context HttpServletRequest request) { + if(!isAdmin(request)) { + return null; + } + return new IndexerWebService(); + } + + @Path("notifications") + public NotificationsAdminWebService getNotifications(@Context HttpServletRequest request) { + if(!isAdmin(request)) { + return null; + } + return new NotificationsAdminWebService(); + } + private boolean isMonitoringEnabled() { MonitoringModule module = CoreSpringFactory.getImpl(MonitoringModule.class); return module.isEnabled(); diff --git a/src/main/java/org/olat/restapi/system/vo/IndexerStatus.java b/src/main/java/org/olat/restapi/system/vo/IndexerStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..0f131a8948cc9562f23ab6f12fe3c5fd9b467aca --- /dev/null +++ b/src/main/java/org/olat/restapi/system/vo/IndexerStatus.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.restapi.system.vo; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +import org.olat.core.commons.services.search.SearchServiceStatus; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "indexerStatusVO") +public class IndexerStatus implements SearchServiceStatus { + + @XmlAttribute(name="status") + private String status; + + public IndexerStatus() { + // + } + + public IndexerStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/src/main/java/org/olat/restapi/system/vo/NotificationsStatus.java b/src/main/java/org/olat/restapi/system/vo/NotificationsStatus.java new file mode 100644 index 0000000000000000000000000000000000000000..25531aa7c8c03a6980a6eb0f486f531997af85a8 --- /dev/null +++ b/src/main/java/org/olat/restapi/system/vo/NotificationsStatus.java @@ -0,0 +1,54 @@ +/** + * <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.restapi.system.vo; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + * + */ +@XmlAccessorType(XmlAccessType.FIELD) +@XmlRootElement(name = "notificationsStatusVO") +public class NotificationsStatus { + + @XmlAttribute(name="status") + private String status; + + public NotificationsStatus() { + // + } + + public NotificationsStatus(String status) { + this.status = status; + } + + public String getStatus() { + return status; + } + + public void setStatus(String status) { + this.status = status; + } +} diff --git a/src/main/java/org/olat/search/_spring/searchContext.xml b/src/main/java/org/olat/search/_spring/searchContext.xml index b3925523df03e5671d64f6a4591b55bf401d4c24..f8684d98d21de27750eec26f6ba6868872f4c376 100644 --- a/src/main/java/org/olat/search/_spring/searchContext.xml +++ b/src/main/java/org/olat/search/_spring/searchContext.xml @@ -15,6 +15,7 @@ <constructor-arg index="0" ref="searchModule" /> <constructor-arg index="1" ref="mainIndexer" /> <constructor-arg index="2" ref="searchProvider" /> + <constructor-arg index="3" ref="schedulerFactoryBean"/> <!-- When index is older than maxIndexTime in millis, an error will be logged 432000000 = 5d, 86400 = 1d --> <property name="maxIndexTime" value="432000000"/> <property name="metadataFields" ref="SearchMetadataFieldsProvider" /> @@ -69,13 +70,10 @@ <property name="arguments"> <value> generateIndexAtStartup=${generate.index.at.startup} - <!-- restartInterval in ms (0=no restart) - fxdiff FXOLAT-221: start indexer at different times for each instance --> - restartInterval=${search.indexing.restart.interval} - tempIndexPath=temp_search_index - tempSpellCheckPath=temp_spellcheck_index - pdfTextBufferPath=temp_pdf_text_buf - indexPath=search_index + tempIndexPath=${search.index.tempIndex} + tempSpellCheckPath=${search.index.tempSpellcheck} + pdfTextBufferPath=${search.index.pdfBuffer} + indexPath=${search.index.path} <!-- indexInterval in ms (0=no delay) --> indexInterval=0 documentsPerInterval=4 diff --git a/src/main/java/org/olat/search/service/SearchServiceImpl.java b/src/main/java/org/olat/search/service/SearchServiceImpl.java index 5067b9fc353adb3d546c56f74476144ca5e22900..b2e788c2769c4d2ac6683186965c798990aa42a2 100644 --- a/src/main/java/org/olat/search/service/SearchServiceImpl.java +++ b/src/main/java/org/olat/search/service/SearchServiceImpl.java @@ -34,7 +34,6 @@ import java.util.Set; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexReader; import org.apache.lucene.queryParser.MultiFieldQueryParser; import org.apache.lucene.queryParser.ParseException; @@ -48,6 +47,7 @@ import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.util.Version; +import org.olat.core.CoreSpringFactory; import org.olat.core.commons.services.search.AbstractOlatDocument; import org.olat.core.commons.services.search.SearchModule; import org.olat.core.commons.services.search.SearchResults; @@ -67,7 +67,9 @@ import org.olat.search.service.indexer.MainIndexer; import org.olat.search.service.searcher.JmsSearchProvider; import org.olat.search.service.searcher.SearchResultsImpl; import org.olat.search.service.spell.SearchSpellChecker; -import org.olat.search.service.update.IndexUpdater; +import org.quartz.JobDetail; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; /** * @@ -78,8 +80,8 @@ public class SearchServiceImpl implements SearchService { private Index indexer; private SearchModule searchModuleConfig; - private IndexUpdater indexUpdater; private MainIndexer mainIndexer; + private Scheduler scheduler; private long maxIndexTime; private Analyzer analyzer; @@ -101,37 +103,49 @@ public class SearchServiceImpl implements SearchService { /** * [used by spring] */ - private SearchServiceImpl(SearchModule searchModule, MainIndexer mainIndexer, JmsSearchProvider searchProvider) { + private SearchServiceImpl(SearchModule searchModule, MainIndexer mainIndexer, JmsSearchProvider searchProvider, Scheduler scheduler) { log.info("Start SearchServiceImpl constructor..."); + this.scheduler = scheduler; this.searchModuleConfig = searchModule; this.mainIndexer = mainIndexer; - analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT); + analyzer = new StandardAnalyzer(Version.LUCENE_30); searchProvider.setSearchService(this); - - } - - public void addToIndex(Document document) { - if (indexUpdater==null) throw new AssertException ("Try to call addToIndex() but indexUpdater is null!"); - log.info("addToIndex document=" + document); - indexUpdater.addToIndex(document); } + /** + * Start the job indexer + */ public void startIndexing() { if (indexer==null) throw new AssertException ("Try to call startIndexing() but indexer is null"); - indexer.startFullIndex(); - log.info("startIndexing..."); + + try { + Scheduler scheduler = CoreSpringFactory.getImpl(Scheduler.class); + JobDetail detail = scheduler.getJobDetail("org.olat.search.job.enabled", Scheduler.DEFAULT_GROUP); + scheduler.triggerJob(detail.getName(), detail.getGroup()); + log.info("startIndexing..."); + } catch (SchedulerException e) { + log.error("Error trigerring the indexer job: ", e); + } } + /** + * Interrupt the job indexer + */ public void stopIndexing() { if (indexer==null) throw new AssertException ("Try to call stopIndexing() but indexer is null"); - indexer.stopFullIndex(); - log.info("stopIndexing."); - } - public void deleteFromIndex(Document document) { - if (indexUpdater==null) throw new AssertException ("Try to call deleteFromIndex() but indexUpdater is null"); - log.info("deleteFromIndex document=" + document); - indexUpdater.deleteFromIndex(document); + try { + Scheduler scheduler = CoreSpringFactory.getImpl(Scheduler.class); + JobDetail detail = scheduler.getJobDetail("org.olat.search.job.enabled", Scheduler.DEFAULT_GROUP); + scheduler.interrupt(detail.getName(), detail.getGroup()); + log.info("stopIndexing."); + } catch (SchedulerException e) { + log.error("Error interrupting the indexer job: ", e); + } + } + + public Index getInternalIndexer() { + return indexer; } public void init() { @@ -140,7 +154,6 @@ public class SearchServiceImpl implements SearchService { log.info("Running with indexPath=" + searchModuleConfig.getFullIndexPath()); log.info(" tempIndexPath=" + searchModuleConfig.getFullTempIndexPath()); log.info(" generateAtStartup=" + searchModuleConfig.getGenerateAtStartup()); - log.info(" restartInterval=" + searchModuleConfig.getRestartInterval()); log.info(" indexInterval=" + searchModuleConfig.getIndexInterval()); searchSpellChecker = new SearchSpellChecker(); @@ -149,7 +162,6 @@ public class SearchServiceImpl implements SearchService { searchSpellChecker.setSpellCheckEnabled(searchModuleConfig.getSpellCheckEnabled()); indexer = new Index(searchModuleConfig, searchSpellChecker, mainIndexer); - indexUpdater = new IndexUpdater(searchModuleConfig.getFullIndexPath(), searchModuleConfig.getUpdateInterval()); indexPath = searchModuleConfig.getFullIndexPath(); @@ -160,7 +172,12 @@ public class SearchServiceImpl implements SearchService { } if (startingFullIndexingAllowed()) { - indexer.startFullIndex(); + try { + JobDetail detail = scheduler.getJobDetail("org.olat.search.job.enabled", Scheduler.DEFAULT_GROUP); + scheduler.triggerJob(detail.getName(), detail.getGroup()); + } catch (SchedulerException e) { + log.error("", e); + } } log.info("init DONE"); } diff --git a/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java b/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java index dadd70dfef08b2470e876e3ad530278505fe024e..ef56dd4ed600e017955d469d2771cf161dd4ff05 100644 --- a/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java +++ b/src/main/java/org/olat/search/service/indexer/OlatFullIndexer.java @@ -32,13 +32,13 @@ import java.util.List; import java.util.Map; import java.util.Vector; +import org.apache.lucene.LucenePackage; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.analysis.standard.StandardAnalyzer; import org.apache.lucene.document.Document; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; -import org.apache.lucene.LucenePackage; import org.apache.lucene.util.Version; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.services.search.OlatDocument; @@ -51,14 +51,14 @@ import org.olat.search.service.SearchResourceContext; * Controls the hole generation of a full-index. Runs in own thread. * @author Christian Guretzki */ -public class OlatFullIndexer implements Runnable { +public class OlatFullIndexer { private OLog log = Tracing.createLoggerFor(OlatFullIndexer.class); /* TODO:chg: define merge-factor in olat-config.*/ private static final int INDEX_MERGE_FACTOR = 1000; - private static final int MAX_SIZE_QUEUE = 10000; + private static final int MAX_SIZE_QUEUE = 500; private int numberIndexWriter = 5; private String tempIndexPath; @@ -67,17 +67,10 @@ public class OlatFullIndexer implements Runnable { * Reference to indexer for done callback. */ private Index index; - - private Thread indexingThread = null; - private IndexWriter indexWriter = null; /** Flag to stop indexing. */ private boolean stopIndexing; - - - /** When restartIndexingWhenFinished is true, the restart interval in ms can be set. */ - private long restartInterval; /** When restartIndexingWhenFinished is true, the restart interval in ms can be set. */ private long indexInterval = 500; @@ -116,7 +109,6 @@ public class OlatFullIndexer implements Runnable { this.index = index; this.mainIndexer = mainIndexer; tempIndexPath = searchModuleConfig.getFullTempIndexPath(); - restartInterval = searchModuleConfig.getRestartInterval(); indexInterval = searchModuleConfig.getIndexInterval(); numberIndexWriter = searchModuleConfig.getNumberIndexWriter(); documentsPerInterval = searchModuleConfig.getDocumentsPerInterval(); @@ -133,19 +125,11 @@ public class OlatFullIndexer implements Runnable { */ public void startIndexing() { // Start updateThread - if ( (indexingThread == null) || !indexingThread.isAlive()) { - if (stopIndexing) { - log.info("start full indexing thread..."); - indexingThread = new Thread(this, "FullIndexer"); - stopIndexing = false; - resetDocumentCounters(); - // Set to lowest priority - indexingThread.setPriority(Thread.MIN_PRIORITY); - indexingThread.setDaemon(true); - indexingThread.start(); - } - } else { - log.debug("indexing allready running"); + if (stopIndexing) { + log.info("start full indexing thread..."); + stopIndexing = false; + resetDocumentCounters(); + run(); } } @@ -153,11 +137,8 @@ public class OlatFullIndexer implements Runnable { * Stop full indexer thread asynchron. */ public void stopIndexing() { - if ( (indexingThread != null) && indexingThread.isAlive()) { - stopIndexing = true; - indexingThread.interrupt(); - if (log.isDebug()) log.debug("stop current indexing when"); - } + stopIndexing = true; + if (log.isDebug()) log.debug("stop current indexing when"); } /** @@ -262,41 +243,30 @@ public class OlatFullIndexer implements Runnable { * @see java.lang.Runnable#run() */ public void run() { - boolean runAgain = true; try { //TODO: Workround : does not start immediately Thread.sleep(10000); - while (runAgain && !this.stopIndexing) { - log.info("full indexing starts... Lucene-version:" + LucenePackage.get().getImplementationVersion()); - fullIndexerStatus.indexingStarted(); - doIndex(); - index.indexingIsDone(); - fullIndexerStatus.indexingFinished(); - log.info("full indexing done in " + fullIndexerStatus.getIndexingTime() + "ms"); - - //OLAT-5630 - dump more infos about the indexer run - for analysis later - FullIndexerStatus status = getStatus(); - log.info("full indexing summary: started: "+status.getFullIndexStartedAt()); - log.info("full indexing summary: counter: "+status.getDocumentCount()); - log.info("full indexing summary: index.per.minute: "+status.getIndexPerMinute()); - log.info("full indexing summary: finished: "+status.getLastFullIndexTime()); - log.info("full indexing summary: time: "+status.getIndexingTime()+" ms"); - log.info("full indexing summary: size: "+status.getIndexSize()); - - log.info("full indexing summary: document counters: "+status.getDocumentCounters()); - log.info("full indexing summary: file type counters:"+status.getFileTypeCounters()); - log.info("full indexing summary: excluded counter: "+status.getExcludedDocumentCount()); - if (restartInterval == 0) { - log.debug("do not run again"); - runAgain = false; - } else { - if (log.isDebug()) log.debug("Indexing sleep=" + restartInterval + "ms"); - fullIndexerStatus.setStatus(FullIndexerStatus.STATUS_SLEEPING); - Thread.sleep(restartInterval); - if (log.isDebug()) log.debug("Restart indexing"); - } - } + log.info("full indexing starts... Lucene-version:" + LucenePackage.get().getImplementationVersion()); + fullIndexerStatus.indexingStarted(); + doIndex(); + index.indexingIsDone(); + fullIndexerStatus.indexingFinished(); + log.info("full indexing done in " + fullIndexerStatus.getIndexingTime() + "ms"); + + //OLAT-5630 - dump more infos about the indexer run - for analysis later + FullIndexerStatus status = getStatus(); + log.info("full indexing summary: started: "+status.getFullIndexStartedAt()); + log.info("full indexing summary: counter: "+status.getDocumentCount()); + log.info("full indexing summary: index.per.minute: "+status.getIndexPerMinute()); + log.info("full indexing summary: finished: "+status.getLastFullIndexTime()); + log.info("full indexing summary: time: "+status.getIndexingTime()+" ms"); + log.info("full indexing summary: size: "+status.getIndexSize()); + + log.info("full indexing summary: document counters: "+status.getDocumentCounters()); + log.info("full indexing summary: file type counters:"+status.getFileTypeCounters()); + log.info("full indexing summary: excluded counter: "+status.getExcludedDocumentCount()); + } catch(InterruptedException iex) { log.info("FullIndexer was interrupted ;" + iex.getMessage()); } catch(Throwable ex) { @@ -308,13 +278,11 @@ public class OlatFullIndexer implements Runnable { } fullIndexerStatus.setStatus(FullIndexerStatus.STATUS_STOPPED); stopIndexing = true; - indexingThread = null; try { log.info("quit indexing run."); } catch (NullPointerException nex) { // no logging available (shut down)=> do nothing } - } /** @@ -331,7 +299,7 @@ public class OlatFullIndexer implements Runnable { Thread.sleep(indexInterval); } else { // do not sleep, check for stopping indexing - if (this.stopIndexing) { + if (stopIndexing) { throw new InterruptedException("Do stop indexing at element=" + indexWriter.maxDoc()); } } @@ -349,7 +317,7 @@ public class OlatFullIndexer implements Runnable { countIndexPerMinute(); if (log.isDebug()) log.debug("documentQueue.add size=" + documentQueue.size()); // check for stopping indexing - if (this.stopIndexing) { + if (stopIndexing) { throw new InterruptedException("Do stop indexing at element=" + indexWriter.maxDoc()); } } diff --git a/src/main/java/org/olat/search/service/indexer/SearchIndexingJob.java b/src/main/java/org/olat/search/service/indexer/SearchIndexingJob.java index cc3c51da890f438e6906df899460311fd4b1f8b5..4b2488fc7579a88e1d94f3fc3e613b85ca65d9f9 100644 --- a/src/main/java/org/olat/search/service/indexer/SearchIndexingJob.java +++ b/src/main/java/org/olat/search/service/indexer/SearchIndexingJob.java @@ -25,11 +25,15 @@ package org.olat.search.service.indexer; import org.olat.core.commons.scheduler.JobWithDB; +import org.olat.core.commons.services.search.SearchService; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.search.service.SearchServiceFactory; +import org.olat.search.service.SearchServiceImpl; +import org.quartz.InterruptableJob; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; +import org.quartz.UnableToInterruptJobException; /** * Description:<br> @@ -39,7 +43,7 @@ import org.quartz.JobExecutionException; * Initial Date: 09.09.2008 <br> * @author Christian Guretzki */ -public class SearchIndexingJob extends JobWithDB { +public class SearchIndexingJob extends JobWithDB implements InterruptableJob { private OLog log = Tracing.createLoggerFor(SearchIndexingJob.class); /** @@ -49,7 +53,18 @@ public class SearchIndexingJob extends JobWithDB { @Override public void executeWithDB(JobExecutionContext arg0) throws JobExecutionException { log.info("Search indexer started via cronjob."); - SearchServiceFactory.getService().startIndexing(); + SearchService searchService = SearchServiceFactory.getService(); + if(searchService instanceof SearchServiceImpl) { + ((SearchServiceImpl)searchService).getInternalIndexer().startFullIndex(); + } } + @Override + public void interrupt() throws UnableToInterruptJobException { + log.info("Interrupt indexer via quartz."); + SearchService searchService = SearchServiceFactory.getService(); + if(searchService instanceof SearchServiceImpl) { + ((SearchServiceImpl)searchService).getInternalIndexer().stopFullIndex(); + } + } } diff --git a/src/main/java/org/olat/search/service/update/IndexUpdater.java b/src/main/java/org/olat/search/service/update/IndexUpdater.java deleted file mode 100644 index cfa6f357fb1fea5d8eb77935567f0ec31cd0266e..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/search/service/update/IndexUpdater.java +++ /dev/null @@ -1,229 +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. -*/ - -package org.olat.search.service.update; - -import java.io.File; -import java.util.List; -import java.util.Vector; - -import org.apache.lucene.analysis.standard.StandardAnalyzer; -import org.apache.lucene.document.Document; -import org.apache.lucene.index.IndexReader; -import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.index.Term; -import org.apache.lucene.store.Directory; -import org.apache.lucene.store.FSDirectory; -import org.apache.lucene.util.Version; -import org.olat.core.commons.services.search.OlatDocument; -import org.olat.core.logging.OLog; -import org.olat.core.logging.Tracing; - -/** - * The IndexUpdater thread controls the update of existing search index. - * The update thread could be disabled with config parameter 'updateInterval=0'. - * @author Christian Guretzki - */ -public class IndexUpdater implements Runnable { - private static final int INDEX_MERGE_FACTOR = 1000; - private static OLog log = Tracing.createLoggerFor(IndexUpdater.class); - - private String indexPath; - - private Thread updaterThread = null; - private long updateInterval; - - private boolean stopUpdater; - - private List<Document> updateQueue; - private List<Document> deleteQueue; - - /** - * - * @param indexPath Absolute file-path of existing index-directory which will be updated - * @param updateInterval Updater sleeps this time [ms] between running again. - */ - public IndexUpdater(String indexPath, long updateInterval) { - this.indexPath = indexPath; - updateQueue = new Vector<Document>(); - deleteQueue = new Vector<Document>(); - this.updateInterval = updateInterval; - stopUpdater = true; - if (updateInterval != 0) { - startUpdater(); - } else { - log.info("IndexUpdater is disabled"); - } - } - - /** - * Add new or changed index document to update-queue. - * @param document New or changed index document. - */ - // o_clusterNOK: IndexUpdater is only prove of concept (with groups) and NOT designed for cluster !!! - public void addToIndex(Document document) { - // The IndexUpdate is disabled with updateInterval == 0 => do not add documents - if (updateInterval != 0) { - updateQueue.add(document); - } - } - - /** - * Add index document to delete-queue. - * @param document Delete this index document. - */ - // o_clusterNOK: IndexUpdater is only prove of concept (with groups) and NOT designed for cluster !!! - public void deleteFromIndex(Document document) { - // The IndexUpdate is disabled with updateInterval == 0 => do not add documents - if (updateInterval != 0) { - deleteQueue.add(document); - } - } - - public void run() { - boolean runAgain = true; - try { - while (runAgain && !this.stopUpdater) { - log.info("Updater starts..."); - doUpdate(); - log.info("Updater done "); - if (updateInterval == 0) { - log.debug("do not run again"); - runAgain = false; - } else { - if (log.isDebug()) log.debug("Updater sleep=" + updateInterval + "ms"); - Thread.sleep(updateInterval); - if (log.isDebug()) log.debug("Restart updater"); - } - } - } catch(InterruptedException iex) { - log.info("FullIndexer was interrupted ;" + iex.getMessage()); - } - stopUpdater = true; - log.info("quit indexing run."); - } - - /** - * Check update and delete-queue. Update existing index and writes new index file. - * - */ - private void doUpdate() { - if (!updateQueue.isEmpty() || !deleteQueue.isEmpty()) { - try { - log.info("updateQueue.size=" + updateQueue.size() + " deleteQueue.size" + deleteQueue.size()); - // 0. make copy of queue's and delete it - List<Document> updateCopy; - synchronized (updateQueue) { - updateCopy = new Vector<Document>(updateQueue); - updateQueue.clear(); - } - List<Document> deleteCopy; - synchronized (deleteQueue) { - deleteCopy = new Vector<Document>(deleteQueue); - deleteQueue.clear(); - } - // 1. Open Index Reader - File indexFile = new File(indexPath); - Directory directory = FSDirectory.open(indexFile); - IndexReader indexReader = IndexReader.open(directory); - - log.info("befor delete: indexReader.numDocs()=" + indexReader.numDocs()); - // 2. Delete old Document - // loop over all documents in updateQueue - for (int i = 0; i < updateCopy.size(); i++) { - String resourceUrl = updateCopy.get(i).get(OlatDocument.RESOURCEURL_FIELD_NAME); - Term term = new Term(OlatDocument.RESOURCEURL_FIELD_NAME, resourceUrl ); - log.info("updateQueue:delete documents with resourceUrl=" + resourceUrl ); - indexReader.deleteDocuments(term); - } - // loop over all documents in deleteQueue - for (int i = 0; i < deleteCopy.size(); i++) { - String resourceUrl = deleteCopy.get(i).get(OlatDocument.RESOURCEURL_FIELD_NAME); - Term term = new Term(OlatDocument.RESOURCEURL_FIELD_NAME, resourceUrl ); - log.info("deleteQueue:delete documents with resourceUrl='" + resourceUrl + "'"); - indexReader.deleteDocuments(term); - - } - log.info("after delete: indexReader.numDocs()=" + indexReader.numDocs()); - // 3. Close reader - indexReader.close(); - directory.close(); - - // 4. open writer - IndexWriter indexWriter = new IndexWriter(directory, new StandardAnalyzer(Version.LUCENE_CURRENT), false, IndexWriter.MaxFieldLength.UNLIMITED); - indexWriter.setMergeFactor(INDEX_MERGE_FACTOR); //for better performance - // 5. Add new Document - for (int i = 0; i < updateCopy.size(); i++) { - Document document = updateCopy.get(i); - log.info("addDocument:" + document); - indexWriter.addDocument(document); - } - // 6. Close writer - long startOptimizeTime = 0; - if (log.isDebug()) startOptimizeTime = System.currentTimeMillis(); - indexWriter.optimize();// TODO:chg: dauert ev. zulange oder nocht noetig - if (log.isDebug()) log.debug("Optimized in " + (System.currentTimeMillis() - startOptimizeTime) + "ms"); - indexWriter.close(); - } catch (Exception ex) { - log.warn("Exception during doUpdate. ", ex); - } - } else { - log.debug("Queues are ampty."); - } - } - - /** - * Start updater thread. - */ - public void startUpdater() { - // Start updateThread - if ( (updaterThread == null) || !updaterThread.isAlive()) { - log.info("start Updater thread..."); - if (stopUpdater) { - updaterThread = new Thread(this, "Updater"); - stopUpdater = false; - // Set to lowest priority - updaterThread.setPriority(Thread.MIN_PRIORITY); - updaterThread.setDaemon(true); - updaterThread.start(); - } - } else { - if (log.isDebug()) log.debug("Updater allready running"); - } - } - - /** - * Stop update thread asynchron. - */ - public void stopUpdater() { - if (updaterThread.isAlive()) { - stopUpdater = true; - updaterThread.interrupt(); - if (log.isDebug()) log.debug("stop Updater"); - } - } - - -} diff --git a/src/main/java/org/olat/search/service/update/package.html b/src/main/java/org/olat/search/service/update/package.html deleted file mode 100644 index f76e0bbda8dec4db1b20adda65ea63d8a69c6c40..0000000000000000000000000000000000000000 --- a/src/main/java/org/olat/search/service/update/package.html +++ /dev/null @@ -1,9 +0,0 @@ -<html> -<head> -</head> - -<body> -This package includes all classes to update an existing index. -Update includes adding new elements, delete existing elements or modify existing index-elements. -</body> -</html> \ No newline at end of file diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_8_3_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_8_3_0.java new file mode 100644 index 0000000000000000000000000000000000000000..b421af5a82819bd09bfa62537b7b41c118ecbdf5 --- /dev/null +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_8_3_0.java @@ -0,0 +1,137 @@ +/** + * <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.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.io.FileUtils; +import org.olat.core.util.WebappHelper; + +/** + * Description:<br> + * upgrade code for OLAT 7.1.0 -> OLAT 7.1.1 + * - fixing invalid structures being built by synchronisation, see OLAT-6316 and OLAT-6306 + * - merges all yet found data to last valid node + * + * <P> + * Initial Date: 24.03.2011 <br> + * + * @author Roman Haag, roman.haag@frentix.com, www.frentix.com + */ +public class OLATUpgrade_8_3_0 extends OLATUpgrade { + + private static final String TASK_MOVE_QTI_EDITOR_TMP = "Move qtieditor tmp"; + private static final String VERSION = "OLAT_8.3.0"; + + + public OLATUpgrade_8_3_0() { + 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 = moveQTIEditorTmp(upgradeManager, uhd); + uhd.setInstallationComplete(allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + if(allOk) { + log.audit("Finished OLATUpgrade_8_3_0 successfully!"); + } else { + log.audit("OLATUpgrade_8_3_0 not finished, try to restart OpenOLAT!"); + } + return allOk; + } + + private boolean moveQTIEditorTmp(UpgradeManager upgradeManager, UpgradeHistoryData uhd) { + boolean allOk = true; + + if (!uhd.getBooleanDataValue(TASK_MOVE_QTI_EDITOR_TMP)) { + try { + File current = new File(WebappHelper.getUserDataRoot() + "/tmp/qtieditor/"); + if(current.exists()) { + File destDir = new File(WebappHelper.getUserDataRoot() + "/qtieditor/"); + destDir.mkdirs(); + FileUtils.copyDirectory(current, destDir); + allOk = compareRecursive(current, destDir); + if(allOk) { + FileUtils.deleteDirectory(current); + } + } + uhd.setBooleanDataValue(TASK_MOVE_QTI_EDITOR_TMP, allOk); + upgradeManager.setUpgradesHistory(uhd, VERSION); + } catch (IOException e) { + log.error("", e); + return false; + } + } + return allOk; + } + + private boolean compareRecursive(File tmp, File qtieditor) { + File[] tmpFiles = tmp.listFiles(new SystemFilenameFilter()); + String[] editorFiles = tmp.list(new SystemFilenameFilter()); + + Set<String> editorFileSet = new HashSet<String>(); + for(String editorFile:editorFiles) { + editorFileSet.add(editorFile); + } + + for(File tmpFile:tmpFiles) { + String tmpName = tmpFile.getName(); + if(!editorFileSet.contains(tmpName)) { + return false; + } + if(tmpFile.isDirectory()) { + compareRecursive(tmpFile, new File(qtieditor, tmpName)); + } + } + return true; + } + + private static class SystemFilenameFilter implements FilenameFilter { + @Override + public boolean accept(File dir, String name) { + return name != null && !name.startsWith("."); + } + } +} diff --git a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml index e329df9dfdd0a99785941b8cbe4a9cf6afb57a6f..04070bd436ca6e8b3421503120a6183e5ac63da2 100644 --- a/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml +++ b/src/main/java/org/olat/upgrade/_spring/upgradeContext.xml @@ -38,6 +38,7 @@ </bean> <bean id="upgrade_8_1_0" class="org.olat.upgrade.OLATUpgrade_8_1_0"/> <bean id="upgrade_8_2_0" class="org.olat.upgrade.OLATUpgrade_8_2_0"/> + <bean id="upgrade_8_3_0" class="org.olat.upgrade.OLATUpgrade_8_3_0"/> </list> </property> </bean> diff --git a/src/main/java/org/olat/user/DisplayPortraitManager.java b/src/main/java/org/olat/user/DisplayPortraitManager.java index 5447df4f847e8933cf22ff5062bfbbd0ad0bea46..a80abc37e9e3667e96d1d6ae3795b72199007c3f 100644 --- a/src/main/java/org/olat/user/DisplayPortraitManager.java +++ b/src/main/java/org/olat/user/DisplayPortraitManager.java @@ -174,7 +174,7 @@ public class DisplayPortraitManager extends BasicManager implements UserDataDele */ public File getPortraitDir(Identity identity){ String portraitPath = FolderConfig.getCanonicalRoot() + - FolderConfig.getUserHomePage(identity.getName()) + "/portrait"; + FolderConfig.getUserHomePage(identity.getName()) + "/portrait"; File portraitDir = new File(portraitPath); portraitDir.mkdirs(); return portraitDir; diff --git a/src/main/java/org/olat/user/UserManager.java b/src/main/java/org/olat/user/UserManager.java index a4559252b0e3ba6ad20c0c3dd418ede962a6fa29..8d6876f4e5e6deadc55d7e5b420b5f19b776e0a7 100644 --- a/src/main/java/org/olat/user/UserManager.java +++ b/src/main/java/org/olat/user/UserManager.java @@ -139,11 +139,6 @@ public abstract class UserManager extends BasicManager { */ public abstract void updateUser(User usr); - /** - * @param user The user to be saved - */ - public abstract void saveUser(User user); - /** * Updates the user object for a given identity * diff --git a/src/main/java/org/olat/user/UserManagerImpl.java b/src/main/java/org/olat/user/UserManagerImpl.java index 9f369ff6ddcd066c94f781c1e5ab6199302d2380..c0351b4d22eca001b319b2ebe25fde084a5a1aa4 100644 --- a/src/main/java/org/olat/user/UserManagerImpl.java +++ b/src/main/java/org/olat/user/UserManagerImpl.java @@ -42,6 +42,7 @@ import org.olat.core.util.mail.MailHelper; import org.olat.properties.Property; import org.olat.properties.PropertyManager; import org.olat.user.propertyhandlers.UserPropertyHandler; +import org.springframework.beans.factory.annotation.Autowired; /** * <h3>Description:</h3> @@ -57,6 +58,9 @@ public class UserManagerImpl extends UserManager { private static final String CHARSET = "charset"; private UserDisplayNameCreator userDisplayNameCreator; + @Autowired + private DB dbInstance; + /** * Use UserManager.getInstance(), this is a spring factory method to load the * correct user manager @@ -92,7 +96,7 @@ public class UserManagerImpl extends UserManager { */ public User createAndPersistUser(String firstName, String lastName, String email) { User user = new UserImpl(firstName, lastName, email); - DBFactory.getInstance().saveObject(user); + dbInstance.getCurrentEntityManager().persist(user); return user; } @@ -266,20 +270,13 @@ public class UserManagerImpl extends UserManager { public void updateUser(User usr) { if (usr == null) throw new AssertException("User object is null!"); DBFactory.getInstance().updateObject(usr); - } - - /** - * @see org.olat.user.UserManager#saveUser(org.olat.core.id.User) - */ - public void saveUser(User user) { - DBFactory.getInstance().saveObject(user); } /** * @see org.olat.user.UserManager#updateUserFromIdentity(org.olat.core.id.Identity) */ public boolean updateUserFromIdentity(Identity identity) { - this.updateUser(identity.getUser()); + updateUser(identity.getUser()); return true; } diff --git a/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties b/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties index c79626d9d74b3478ca310e8ecbdf1c0c20ee480f..e366bf2aaaf1815ab633b9335b0c537786c1647c 100644 --- a/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties +++ b/src/main/java/org/olat/user/_i18n/LocalStrings_pl.properties @@ -1,4 +1,4 @@ -#Thu Nov 22 14:38:06 CET 2012 +#Wed Dec 05 14:34:59 CET 2012 Failed=Nie uda\u0142o si\u0119 przekaza\u0107 pliku. NoImage=Ten format pliku nie mo\u017Ce zosta\u0107 przekazany jako obrazek. ULLimitExceeded=Rozmiar obrazka nie mo\u017Ce przekracza\u0107 {0} KB. @@ -6,6 +6,9 @@ accessibility.web2aMode.label=Tryb Web 2.a dla os\u00F3b czytaj\u0105cych braill action.choose=Wybierz ajaxon.global.label=Tryb AJAX jest aktywny dla ca\u0142ego systemu ajaxon.label=Tryb AJAX jest aktywny na poziomie u\u017Cytkownika +back.label=Obs\u0142uga przycisku "Wstecz" w przegl\u0105darce internetowej +back.off=Wy\u0142\u0105czone +back.on=W\u0142\u0105czone (testowo) change=Zmie\u0144 chelp.card1=Masz mo\u017Cliwo\u015B\u0107 stworzenia wizyt\u00F3wki, kt\u00F3ra b\u0119dzie widoczna dla wszystkich zarejestrowanych u\u017Cytkownik\u00F3w. chelp.card2=$\:chelp.choice umo\u017Clwia okre\u015Blenie przy pomocy p\u00F3l wyboru, kt\u00F3re wpisy z zak\u0142adki $\:chelp.tabProf maj\u0105 by\u0107 wy\u015Bwietlana na wizyt\u00F3wce. @@ -20,11 +23,15 @@ chelp.fName=<i>$org.olat.user.propertyhandlers\:form.name.firstName</i> chelp.fNameF=<b>$org.olat.user.propertyhandlers\:form.name.firstName\:</b> chelp.folder=<b>$org.olat.user\:menu.folder</b> chelp.home=<i>$org.olat.home\:main.menu.title</i> +chelp.home-imsettings-roster.title=Komunikator\: wy\u015Bwietlanie statusu na li\u015Bcie kontakt\u00F3w chelp.home-imsettings.title=Konfiguracja Komunikatora +chelp.home-picture.hover=Pomoc dotycz\u0105ca wstawienia obrazka do Twojego profilu u\u017Cytkownika +chelp.home-picture.title=Profil u\u017Cytkownika\: Wstaw obrazek chelp.home-prefs-ajax.title=Pomoc dotycz\u0105ca ustawie\u0144 trybu AJAX chelp.home-prefs.title=Pomoc dla ustawie\u0144 osobistych chelp.home-profile.title=Uzupe\u0142nianie profilu u\u017Cytkownika chelp.home-vcard.title=Konfiguracja wizyt\u00F3wki +chelp.home-webdav.title=Ustal has\u0142o WebDAV chelp.id=<i>$org.olat.user.propertyhandlers\:form.name.institutionalUserIdentifier</i> chelp.im1=W celu u\u0142atwienia kontaktu za pomoc\u0105 Komunikatora, niekt\u00F3re dane u\u017Cytkownika musz\u0105 by\u0107 dost\u0119pne dla potencjalnych partner\u00F3w czata. chelp.im2=Dost\u0119pno\u015B\u0107 danych jest wa\u017Cn\u0105 cz\u0119\u015Bci\u0105 tzw. \u015Bwiadomo\u015Bci. @@ -118,9 +125,12 @@ form.please.enter.new=Podaj nowe has\u0142o. form.please.enter.old=Podaj swoje stare has\u0142o form.text=Tw\u00F3j tekst form.username=Nazwa u\u017Cytkownika +help.hover.home.prefs.special=Pomoc odno\u015Bnie specyficznych ustawie\u0144 systemowych help.hover.imsettings=Pomoc odno\u015Bnie ustawie\u0144 komunikatora help.hover.prefs=Pomoc odno\u015Bnie ustawie\u0144 systemu help.hover.vcard=Pomoc odno\u015Bnie konfiguracji wizyt\u00F3wki +help.hover.webdav=Pomoc odno\u015Bnie u\u017Cycia WebDAV +identity.not.existing=Wybrany u\u017Cytkownik nie mo\u017Ce by\u0107 znaleziony info.password.aai=Mo\u017Cesz zmieni\u0107 swoje has\u0142o w odpowiednim wydziale swojej uczelni. info.password.olat=Je\u015Bli posiadasz osobiste has\u0142o OLAT/WebDAVIn, mo\u017Cesz je tutaj zmieni\u0107. informSessionTimeout.false=Nie @@ -132,6 +142,9 @@ interval.monthly=Co miesi\u0105c interval.never=Nigdy interval.two-hourly=Co dwie godziny interval.weekly=Co tydzie\u0144 +mail.intern.only=Wysy\u0142aj wiadomo\u015Bci na wewn\u0119trzn\u0105 skrzynk\u0119 +mail.send.copy=Wysy\u0142aj wiadomo\u015Bci na wewn\u0119trzn\u0105 skrzynk\u0119 i na adres e-mail +mail.system=Dostarczanie e-maili menu.calendar=Kalendarz menu.calendar.alt=Kalendarz wybranego u\u017Cytkownika menu.contact=Kontakt @@ -140,12 +153,15 @@ menu.folder=Folder menu.folder.alt=Folder wybranego u\u017Cytkownika menu.homepage=Wizyt\u00F3wka menu.homepage.alt=Wizyt\u00F3wka wybranego u\u017Cytkownika +menu.portfolio=Portfolio notallowedtochangepwd=Nie mo\u017Cesz zmieni\u0107 swojego has\u0142a. Skontaktuj si\u0119 z {0} password.failed=Twoje nowe has\u0142o nie mo\u017Ce zosta\u0107 zapisane. Wyst\u0105pi\u0142 nieoczekiwany b\u0142\u0105d serwera. password.successful=Nowe has\u0142o zosta\u0142o pomy\u015Blnie zapisane. Obowi\u0105zuje od teraz. preferences.successful=Ustawienia systemu zosta\u0142y zapisane. Zmiany ustawie\u0144 j\u0119zyka zostan\u0105 aktywowane po nast\u0119pnym zalogowaniu. preferences.unsuccessful=Ustawienia systemu nie mog\u0142y zosta\u0107 zapisane. Spr\u00F3buj ponownie. profile.unsuccessful=Nie mo\u017Cna by\u0142o zapisa\u0107 profilu. Spr\u00F3buj ponownie. +propdelete.yesno.text=Rzeczywi\u015Bcie chcesz usun\u0105\u0107parametr '{0}' u\u017Cytkownika '{1}'? +propdelete.yesno.title=Jeste\u015B pewny/pewna? pwdav.access_data=<h4>Dane dost\u0119pu</h4> pwdav.description=WebDAV umo\u017Cliwia \u0142atwy transfer danych z twojego komputera do folderu w OLAT. Dodatkowo, opr\u00F3cz pojedynczych plik\u00F3w, mo\u017Cesz kopiowa\u0107 r\u00F3wnie\u017C ca\u0142e katalogi do folder\u00F3w OLAT, u\u017Cywaj\u0105c techniki przeci\u0105gnij i upu\u015B\u0107. \u017Beby skorzysta\u0107 z WebDAV, utworzy\u0107 w swoim komputerze dysk sieciowy o nast\u0119puj\u0105cym adresie\: pwdav.password=Has\u0142o WebDAV @@ -160,7 +176,17 @@ pwdav.password.successful=Twoje has\u0142o WebDAV zosta\u0142o zapisane i jest o pwdav.title=Dost\u0119p WebDAV pwdav.username=Nazwa u\u017Cytkownika WebDAV replayurl.active=Load performance URL active +reset.desc=U\u017Cywaj\u0105c tego formularza mo\u017Cesz przywr\u00F3ci\u0107 Twoj\u0105 osobist\u0105 konfiguracje systemu do warto\u015Bci domy\u015Blnych. \u017Beby wprowadzi\u0107 zmiany, system automatycznie dokona Twojego wylogowania. +reset.elements=Zakres przywracanych ustawie\u0144 +reset.elements.guiprefs=Indywidualne elementy interfejsu (menu, narz\u0119dzia, tabele, portal, kalendarz, itp.) +reset.elements.resume=Wznawianie sesji +reset.elements.sysprefs=Konfiguracja systemu (rozmiar czcionki, powiadomienia, e-mail, zestaw znak\u00F3w, etc.) +reset.submit=Przywr\u00F3\u0107 +reset.title=Przywracanie ustawie\u0144 +resume.auto=Tak, automatycznie +resume.label=Przywr\u00F3\u0107 ostatni\u0105 sesj\u0119 resume.none=Nie +resume.ondemand=Tak, na \u017Cyczenie runonce.changepw.intro=Zmie\u0144 has\u0142o runonce.profile.intro=Zanim klikniesz w przycisk "Zapisz", sprawd\u017A, czy dane w Twoim profilu s\u0105 aktualne. success.change.email=Adres {0} zosta\u0142 zmieniony poprawnie na {1}. @@ -189,7 +215,7 @@ title.prefs.ajax=WEB 2.0 / AJAX title.prefs.replay=Tryb powtarzania title.prefs.special=Specyficzne ustawienia systemu title.profile=Profil u\u017Cytkownika -ul.header=Tw\u00F3j obrazek (.jpg .jpeg .png .gif) +ul.header=Tw\u00F3j obrazek (.jpg, .jpeg, .png, .gif, max. 500 kB) ul.select=Prze\u015Blij plik z dysku Twojego komputera ul.upload=Wy\u015Blij user.deleted=Ten u\u017Cytkownik zosta\u0142 usuni\u0119ty z OLAT diff --git a/src/main/java/org/olat/user/_spring/userContext.xml b/src/main/java/org/olat/user/_spring/userContext.xml index 973ba1f24717dc127c6b2f978acbb2affb450a28..dc09867826ff5a68bab78a15101488685dbe8ab1 100644 --- a/src/main/java/org/olat/user/_spring/userContext.xml +++ b/src/main/java/org/olat/user/_spring/userContext.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <bean id="userModule" class="org.olat.user.UserModule" @@ -169,16 +169,16 @@ <value>[\.\-_].*</value> <value>[\.\-_]*</value> </list> -</property> -<!-- -<property name="afterLoginConfig"> ---> - <!-- enable Controllers or add others if you want them presented right after the Login of a user in an overlay. --> +</property> + <property name="afterLoginConfig"> + <ref bean="org.olat.user.AfterLoginConfig"/> + </property> + +</bean> - <!-- <bean id="org.olat.user.AfterLoginConfig" class="org.olat.login.AfterLoginConfig" scope="prototype"> + <bean id="org.olat.user.AfterLoginConfig" class="org.olat.login.AfterLoginConfig" scope="prototype"> <property name="afterLoginControllerList"> <list> - --> <!-- Configuration to force users to regularly check and update the user profile, redoTimeout sets the interval (seconds) <map> <entry key="controller"> @@ -233,13 +233,9 @@ <entry key="i18nIntro"><value>org.olat.user:runonce.intro</value></entry> </map> --> - <!-- </list> + </list> </property> - </bean> --> -<!-- -</property> ---> -</bean> + </bean> <bean id="triggerUserModuleInit" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="targetObject" ref="userModule" /> @@ -260,17 +256,7 @@ <ref bean="org.olat.user.UserPropertiesConfig" /> </property> <property name="userNameAndPasswordSyntaxChecker"> - <!-- a) enable to use standard username and password checker --> - <bean name="org.olat.user.UserNameAndPasswordSyntaxChecker" class="org.olat.user.UserNameAndPasswordSyntaxChecker" /> - <!-- b) enable to use email-adresses as usernames (allowing @ in username) --> - <!--<bean name="org.olat.user.UserNameAndPasswordSyntaxChecker" class="org.olat.user.UserNameAndPasswordSyntaxCheckerWithEmail" />--> - <!-- c) enable to use a generic regexp based email and password checker. Make sure you adjusted also the corresponding i18n keys --> - <!-- - <bean name="org.olat.user.UserNameAndPasswordSyntaxChecker" class="org.olat.user.UserNameAndPasswordSyntaxCheckerWithRegexp"> - <property name="usernameRegExp" value="[0-9a-z\\.\\-_@]{3,32}" /> - <property name="passwordRegExp"><value><![CDATA[^[\\p{Graph}[^'\\"]]{4,128}$]]></value></property> - </bean> - --> + <ref bean="org.olat.user.UserNameAndPasswordSyntaxChecker"/> </property> <property name="userDisplayNameCreator"> <!-- Implementation to display "firstname lastname" @@ -281,6 +267,9 @@ </property> </bean> + <!-- enable to use a generic regexp based email and password checker. Make sure you adjusted also the corresponding i18n keys --> + <bean id="org.olat.user.UserNameAndPasswordSyntaxChecker" class="org.olat.user.UserNameAndPasswordSyntaxCheckerWithEmail" /> + <bean id="personalFolderManager" class="org.olat.user.PersonalFolderManager"> <constructor-arg ref="userDeletionManager"></constructor-arg> </bean> diff --git a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertriesHandlersContext.xml b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertriesHandlersContext.xml index bc716941d465c20ea33226fd95a4716825d63bb6..794979f42d9856041247e7378581b10ec0636e30 100644 --- a/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertriesHandlersContext.xml +++ b/src/main/java/org/olat/user/propertyhandlers/_spring/userPropertriesHandlersContext.xml @@ -1,174 +1,171 @@ <?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" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd - http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- Define all available user properties and its handlers --> - <bean name="userPropertyFirstName" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyFirstName" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="firstName" /> <property name="group" value="account" /> <property name="deletable" value="false" /> </bean> - <bean name="userPropertyLastName" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyLastName" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="lastName" /> <property name="group" value="account" /> <property name="deletable" value="false" /> </bean> - <bean name="userPropertyEmail" class="org.olat.user.propertyhandlers.EmailProperty"> + <bean id="userPropertyEmail" class="org.olat.user.propertyhandlers.EmailProperty"> <property name="name" value="email" /> <property name="group" value="account" /> <property name="deletable" value="false" /> </bean> - <bean name="userPropertyBirthDay" class="org.olat.user.propertyhandlers.PastDatePropertyHandler"> + <bean id="userPropertyBirthDay" class="org.olat.user.propertyhandlers.PastDatePropertyHandler"> <property name="name" value="birthDay" /> <property name="group" value="person" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyGender" class="org.olat.user.propertyhandlers.GenderPropertyHandler"> + <bean id="userPropertyGender" class="org.olat.user.propertyhandlers.GenderPropertyHandler"> <property name="name" value="gender" /> <property name="group" value="person" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyTelPrivate" class="org.olat.user.propertyhandlers.PhonePropertyHandler"> + <bean id="userPropertyTelPrivate" class="org.olat.user.propertyhandlers.PhonePropertyHandler"> <property name="name" value="telPrivate" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyTelMobile" class="org.olat.user.propertyhandlers.PhonePropertyHandler"> + <bean id="userPropertyTelMobile" class="org.olat.user.propertyhandlers.PhonePropertyHandler"> <property name="name" value="telMobile" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyTelOffice" class="org.olat.user.propertyhandlers.PhonePropertyHandler"> + <bean id="userPropertyTelOffice" class="org.olat.user.propertyhandlers.PhonePropertyHandler"> <property name="name" value="telOffice" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertySkype" class="org.olat.user.propertyhandlers.SkypePropertyHandler"> + <bean id="userPropertySkype" class="org.olat.user.propertyhandlers.SkypePropertyHandler"> <property name="name" value="skype" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyMSN" class="org.olat.user.propertyhandlers.MSNPropertyHandler"> + <bean id="userPropertyMSN" class="org.olat.user.propertyhandlers.MSNPropertyHandler"> <property name="name" value="msn" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyXing" class="org.olat.user.propertyhandlers.XingPropertyHandler"> + <bean id="userPropertyXing" class="org.olat.user.propertyhandlers.XingPropertyHandler"> <property name="name" value="xing" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyICQ" class="org.olat.user.propertyhandlers.ICQPropertyHandler"> + <bean id="userPropertyICQ" class="org.olat.user.propertyhandlers.ICQPropertyHandler"> <property name="name" value="icq" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyHomepage" class="org.olat.user.propertyhandlers.URLPropertyHandler"> + <bean id="userPropertyHomepage" class="org.olat.user.propertyhandlers.URLPropertyHandler"> <property name="name" value="homepage" /> <property name="group" value="contact" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyStreet" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyStreet" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="street" /> <property name="group" value="address" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyExtendedAddress" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyExtendedAddress" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="extendedAddress" /> <property name="group" value="address" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyPoBox" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyPoBox" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="poBox" /> <property name="group" value="address" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyZipCode" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyZipCode" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="zipCode" /> <property name="group" value="address" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyRegion" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyRegion" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="region" /> <property name="group" value="address" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyCity" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyCity" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="city" /> <property name="group" value="address" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyCountry" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyCountry" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="country" /> <property name="group" value="address" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyInstitutionalName" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyInstitutionalName" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="institutionalName" /> <property name="group" value="institute" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyInstitutionalUserIdentifier" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyInstitutionalUserIdentifier" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="institutionalUserIdentifier" /> <property name="group" value="institute" /> <property name="deletable" value="false" /> </bean> - <bean name="userPropertyInstitutionalEmail" class="org.olat.user.propertyhandlers.EmailProperty"> + <bean id="userPropertyInstitutionalEmail" class="org.olat.user.propertyhandlers.EmailProperty"> <property name="name" value="institutionalEmail" /> <property name="group" value="institute" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyOrgUnit" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyOrgUnit" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="orgUnit" /> <property name="group" value="institute" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyStudySubject" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyStudySubject" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="studySubject" /> <property name="group" value="institute" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyEmailChangedKey" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="userPropertyEmailChangedKey" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="emchangeKey" /> <property name="group" value="account" /> <property name="deletable" value="true" /> </bean> - <bean name="userPropertyEmailDisabled" class="de.bps.olat.user.propertyhandlers.GenericCheckboxPropertyHandler"> + <bean id="userPropertyEmailDisabled" class="de.bps.olat.user.propertyhandlers.GenericCheckboxPropertyHandler"> <property name="name" value="emailDisabled" /> <property name="group" value="account" /> <property name="deletable" value="true" /> @@ -197,63 +194,63 @@ before you go live with your system, and if you change the order or remove/replace something, that your statistics get confused. --> - <bean name="usertrackingAttrEduPersonAffiliation" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrEduPersonAffiliation" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="eduPersonAffiliation" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrSwissEduHomeOrganisation" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrSwissEduHomeOrganisation" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="swissEduPersonHomeOrganization" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrSwissEduPersonStudyLevel" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrSwissEduPersonStudyLevel" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="swissEduPersonStudyLevel" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrSwissEduPersonHomeOrganisationType" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrSwissEduPersonHomeOrganisationType" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="swissEduPersonHomeOrganizationType" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrEmployeeNumber" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrEmployeeNumber" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="employeeNumber" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrSwissEduPersonStaffCategory" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrSwissEduPersonStaffCategory" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="swissEduPersonStaffCategory" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrOrganizationalUnit" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrOrganizationalUnit" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="organizationalUnit" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrSwissEduPersonStudyBranch1" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrSwissEduPersonStudyBranch1" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="swissEduPersonStudyBranch1" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrSwissEduPersonStudyBranch2" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrSwissEduPersonStudyBranch2" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="swissEduPersonStudyBranch2" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingAttrSwissEduPersonStudyBranch3" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingAttrSwissEduPersonStudyBranch3" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="swissEduPersonStudyBranch3" /> <property name="group" value="shibbattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingLanguage" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingLanguage" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="language" /> <property name="group" value="olatattr" /> <property name="deletable" value="false" /> </bean> - <bean name="usertrackingWebDAV" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> + <bean id="usertrackingWebDAV" class="org.olat.user.propertyhandlers.Generic127CharTextPropertyHandler"> <property name="name" value="iswebdav" /> <property name="group" value="olatattr" /> <property name="deletable" value="false" /> diff --git a/src/main/java/org/olat/user/restapi/ContactsWebService.java b/src/main/java/org/olat/user/restapi/ContactsWebService.java index 7f82dea4e05edcdb6291ede36ba87d7f5ada7d12..51b471f1bf6bbcd77c52724ff55e3cbf13f340df 100644 --- a/src/main/java/org/olat/user/restapi/ContactsWebService.java +++ b/src/main/java/org/olat/user/restapi/ContactsWebService.java @@ -35,6 +35,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; +import javax.ws.rs.core.Response.Status; import org.olat.core.CoreSpringFactory; import org.olat.core.id.Identity; @@ -68,6 +69,9 @@ public class ContactsWebService { @Context HttpServletRequest httpRequest, @Context UriInfo uriInfo) { Identity identity = getIdentity(httpRequest); + if(identity == null) { + return Response.serverError().status(Status.NOT_FOUND).build(); + } BusinessGroupService bgs = CoreSpringFactory.getImpl(BusinessGroupService.class); List<Identity> contacts = bgs.findContacts(identity, start, limit); diff --git a/src/main/java/org/olat/user/restapi/UserWebService.java b/src/main/java/org/olat/user/restapi/UserWebService.java index 8b8ffac5a68a85a7d906b72addf9e39bb7968b14..77da3d79843a5367df4cd391fd1d74663cba684d 100644 --- a/src/main/java/org/olat/user/restapi/UserWebService.java +++ b/src/main/java/org/olat/user/restapi/UserWebService.java @@ -135,16 +135,12 @@ public class UserWebService { public Response getUserListQuery(@QueryParam("login") String login, @QueryParam("authProvider") String authProvider, @QueryParam("authUsername") String authUsername, @Context UriInfo uriInfo, @Context HttpServletRequest httpRequest) { - MultivaluedMap<String,String> params = uriInfo.getQueryParameters(); - return getUserList(login, authProvider, authUsername, params, uriInfo, httpRequest); - } - - private Response getUserList(String login, String authProvider, String authUsername, Map<String,List<String>> params, - UriInfo uriInfo, HttpServletRequest httpRequest) { + if(!isUserManager(httpRequest)) { return Response.serverError().status(Status.UNAUTHORIZED).build(); } + MultivaluedMap<String,String> params = uriInfo.getQueryParameters(); List<Identity> identities; //make only a search by authUsername if(StringHelper.containsNonWhitespace(authProvider) && StringHelper.containsNonWhitespace(authUsername)) { diff --git a/src/main/resources/serviceconfig/brasatoconfig.xml b/src/main/resources/serviceconfig/brasatoconfig.xml index 573ab2755486a0fb106b985c8bab9dc5507e0302..9164f566e3ad939026fc0a6e7ea6372f87f4912c 100644 --- a/src/main/resources/serviceconfig/brasatoconfig.xml +++ b/src/main/resources/serviceconfig/brasatoconfig.xml @@ -16,7 +16,7 @@ <property name="mailConfig"> <map> <entry key="mailhost" value="${smtp.host}"/> - <entry key="mailTimeout" value="5000"/> <!-- timeout in milliseconds --> + <entry key="mailTimeout" value="8000"/> <!-- timeout in milliseconds --> <entry key="smtpUser" value="${smtp.user}"/> <entry key="smtpPwd" value="${smtp.pwd}"/> <entry key="sslEnabled" value="${smtp.sslEnabled}"/> diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties index 0b6556d62fff58ab459657f54024783ae5cc22f5..d92b6f8320159e9abad27b99b358155c5969747d 100644 --- a/src/main/resources/serviceconfig/olat.properties +++ b/src/main/resources/serviceconfig/olat.properties @@ -95,9 +95,15 @@ history.resume.enabled.default.values=none,auto,ondemand # the owner of repository-entries of deleted users deletionModule.adminUserName=administrator -#session timeout in seconds -session.timeout=7200 - +# Session timeout configuration. +# Note that this are default values only. If you want to change the configuration, open the administration panel +# in OpenOLAT and change the values there. They are stored in olatdata/system/configuration/ and will override +# the values from the olat.local.properties file. +# a) Session timeout in seconds for not-authenticated sessions (login screen etc). +# Keep small to prevent denial of service attacks. Default is 5 minutes. +session.timeout=300 +# b) Session timeout in seconds for authenticated users and guest users. Default is two hours. +session.timeout.authenticated=7200 ######################################################################## # SMTP (mail) settings @@ -194,31 +200,40 @@ notification.interval.daily=true notification.interval.half-daily=true notification.interval.four-hourly=true notification.interval.two-hourly=true +#notification cron job +notification.cronjob.expression=0 10 */2 * * ? #################################################### # Groups #################################################### -# standard users can create groups +# Standard users can create groups group.user.create=true group.user.create.values=true,false -# authors can create groups +# Authors can create groups. (Group managers and system administrators can create groups in any case) group.author.create=true group.author.create.values=true,false -# show the contact form in the business group card. +# Show the contact form in the business group card to send mails to group members or the coaches group.card.contact=groupconfig group.card.contact.values=never,always,groupconfig -# user can download member list of groups +# Users can download member list of groups (default, can be overridden for each group) group.userlist.download.default.allowed=false group.userlist.download.default.allowed.values=true,false -group.mandatory.enrolment.email.users=false +# Behavior when manually adding a user to a group. There are two workflow elements regarding data privacy +# that can be configured: +# a) Email notification: is the notification email about the new group membership mandatory or optional? +# Default is true for normal users and optional for users with role author, usermanager, groupmanager or administrator +group.mandatory.enrolment.email.users=true group.mandatory.enrolment.email.authors=false group.mandatory.enrolment.email.usermanagers=false group.mandatory.enrolment.email.groupmanagers=false group.mandatory.enrolment.email.administrators=false - -group.accept.membership.users=false +# b) Invitation only or direct membership: is the new group membership immediate or is it only an invitation +# that must be accepted by the invited user? +# Default is invitation-only for normal users and immediate group membership without the need to accept +# for users with the role author, usermanager, groupmanager or administrator +group.accept.membership.users=true group.accept.membership.authors=false group.accept.membership.usermanagers=false group.accept.membership.groupmanagers=false @@ -355,6 +370,10 @@ minimalhome.ext.calendar=true minimalhome.ext.mysettings=true minimalhome.ext.portal=true +site.home.order=1 +site.repository.enable=true +site.groups.enable=true + course.db.enabled=false ######################################################################## @@ -521,6 +540,12 @@ generate.index.at.startup=false # but only if startup is during the restart window... restart.window.start=0 restart.window.end=24 + +search.index.path=search_index +search.index.tempIndex=temp_search_index +search.index.tempSpellcheck=temp_spellcheck_index +search.index.pdfBuffer=temp_pdf_text_buf + # Interval in millisecond after which the indexer should run again. O means: do not run again search.indexing.restart.interval=0 # 2) Enable triggering indexer via cron-job instead at startup [ enabled | disabled ] @@ -530,6 +555,8 @@ search.indexing.cronjob=enabled # expression but have set search.indexing.cronjob=enabled, the system will generate a # cron expression that triggers the indexer every four hour depending on your tomcat.id variable search.indexing.cronjob.expression=0 0 3 * * ? +#examples: +# never fire: 0 0 0 1 1 ? 3000 ######################################################################## # REST API diff --git a/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml b/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml index ca6bfa504e1a966a7470a471a489d35f62a08ce0..c3c13e1b96b20eba342b531f911d1d34af19a0a3 100644 --- a/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml +++ b/src/main/resources/serviceconfig/org/olat/_spring/extensionContext.xml @@ -3,7 +3,7 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- generic OLAT extensions --> <bean id="extmanager" class="org.olat.core.extensions.ExtManager" /> @@ -462,8 +462,6 @@ <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeCustomizing" /> </bean> - - <!-- SYSADMIN maintenance parent node <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> <property name="order" value="7300" /> diff --git a/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml b/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml index a1fdc89e263ab0a3b8beafc8146727edc29d9d6c..044327372905a5116cea88911c29df4d954c8afa 100644 --- a/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml +++ b/src/main/resources/serviceconfig/org/olat/_spring/sitedefContext.xml @@ -1,12 +1,9 @@ <?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-3.0.xsd - http://www.springframework.org/schema/context - http://www.springframework.org/schema/context/spring-context-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- OLAT sites --> @@ -16,23 +13,25 @@ <!-- Disable site by adding '<property name="enabled" value="false"/>' --> <bean id="olatsites_home" class="org.olat.home.HomeSiteDef" scope="prototype" > - <property name="order" value="1" /> + <property name="order" value="${site.home.order}" /> <property name="enabled" value="${site.minimalhome.enabled}"/> </bean> <bean id="olatsites_groups" class="org.olat.group.site.GroupsSiteDef" scope="prototype" > - <property name="order" value="2" /> + <property name="order" value="4" /> + <property name="enabled" value="${site.groups.enable}"/> </bean> <bean id="olatsites_repository" class="org.olat.repository.site.RepositorySiteDef" scope="prototype" > - <property name="order" value="3" /> + <property name="order" value="5" /> + <property name="enabled" value="${site.repository.enable}"/> </bean> <bean id="olatsites_useradmin" class="org.olat.admin.site.UserAdminSiteDef" scope="prototype" > - <property name="order" value="5" /> + <property name="order" value="9" /> </bean> <bean id="olatsites_admin" class="org.olat.admin.site.AdminSiteDef" scope="prototype"> - <property name="order" value="6" /> + <property name="order" value="10" /> </bean> <bean id="olatsites_guidemo" class="org.olat.gui.demo.site.GUIDemoSiteDef" scope="prototype" > - <property name="order" value="7" /> + <property name="order" value="11" /> <property name="enabled" value="${guidemo.enabled}"/> </bean> diff --git a/src/main/resources/serviceconfig/org/olat/_spring/webdavContext.xml b/src/main/resources/serviceconfig/org/olat/_spring/webdavContext.xml index 68babd990c78438e75c2e718146796351961bb53..1f8fe1e6830bd6fa92739d973389a32d73c0d99e 100644 --- a/src/main/resources/serviceconfig/org/olat/_spring/webdavContext.xml +++ b/src/main/resources/serviceconfig/org/olat/_spring/webdavContext.xml @@ -3,17 +3,24 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans - http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> + http://www.springframework.org/schema/beans/spring-beans-3.1.xsd"> <!-- WebDAV provider factory --> <bean id="webdavfactory" class="org.olat.core.util.servlets.WebDAVProviderFactory" > <property name="webdavProviderList"> <list> - <!-- WebDAV providers --> - <bean id="webdav_briefcase" class="org.olat.core.commons.modules.bc.BriefcaseWebDAVProvider" scope="prototype" /> - <bean id="webdav_coursefolders" class="org.olat.course.CoursefolderWebDAVProvider" scope="prototype" /> - <bean id="webdav_sharedfolders" class="org.olat.modules.sharedfolder.SharedFolderWebDAVProvider" scope="prototype" > + <ref bean="webdav_briefcase"/> + <ref bean="webdav_coursefolders"/> + <ref bean="webdav_sharedfolders"/> + <ref bean="webdav_groupfolders"/> + </list> + </property> + </bean> + + <bean id="webdav_briefcase" class="org.olat.core.commons.modules.bc.BriefcaseWebDAVProvider" scope="prototype" /> + <bean id="webdav_coursefolders" class="org.olat.course.CoursefolderWebDAVProvider" scope="prototype" /> + <bean id="webdav_sharedfolders" class="org.olat.modules.sharedfolder.SharedFolderWebDAVProvider" scope="prototype" > <!-- Optional configuration: specify shared folder that should be visible to normal users. By default, shared folders are only mounted for shared folder owners (read/write). By @@ -38,15 +45,9 @@ </list> </property> --> - </bean> - <bean id="webdav_groupfolders" class="org.olat.group.GroupfoldersWebDAVProvider" scope="prototype"> - <property name="collaborationManager" ref="collaborationManager" /> - </bean> - <!-- bean id="webdav_calendars" class="org.olat.calendar.CalendarWebDAVProvider" scope="prototype" / --> - <!-- comment out following line to enable webdav-provider for static/themes folder, only accessible by administrators --> - <!-- bean id="webdav_themes" class="org.olat.util.themes.ThemesWebDAVProvider" scope="prototype" /--> - </list> - </property> + </bean> + <bean id="webdav_groupfolders" class="org.olat.group.GroupfoldersWebDAVProvider" scope="prototype"> + <property name="collaborationManager" ref="collaborationManager" /> </bean> </beans> \ No newline at end of file diff --git a/src/main/resources/serviceconfig/org/olat/notifications/_spring/olatdefaultconfig.xml b/src/main/resources/serviceconfig/org/olat/notifications/_spring/olatdefaultconfig.xml index e62f85aa925eb22eb04a6c80a057a5b624b1412f..c767c84375e578b19e6dfb1e534279d1324911aa 100644 --- a/src/main/resources/serviceconfig/org/olat/notifications/_spring/olatdefaultconfig.xml +++ b/src/main/resources/serviceconfig/org/olat/notifications/_spring/olatdefaultconfig.xml @@ -30,7 +30,7 @@ As of OLAT 6.3 it's best to let the cronjob run every two hours since users can now choose how often they will get notified. The shortest interval is set to two hours. --> - <property name="cronExpression" value="0 10 */2 * * ?" /> + <property name="cronExpression" value="${notification.cronjob.expression}" /> <!-- OLAT-5093 start delay ensures there's no conflict with server startup and db not being ready yet --> <property name="startDelay" value="300000" /> diff --git a/src/main/webapp/static/msg/en/service_not_available.html b/src/main/webapp/static/msg/en/service_not_available.html deleted file mode 100644 index 14fbfd9ab587ec4cef43d0f17010fa9d74ae361b..0000000000000000000000000000000000000000 --- a/src/main/webapp/static/msg/en/service_not_available.html +++ /dev/null @@ -1,26 +0,0 @@ -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> -<HTML> -<HEAD> - <META HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=windows-1252"> - <TITLE>Web 2.0 information</TITLE> - <META NAME="GENERATOR" CONTENT="OpenOffice.org 2.3 (Win32)"> - <META NAME="CREATED" CONTENT="0;0"> - <META NAME="CHANGED" CONTENT="20080515;17060542"> - <STYLE TYPE="text/css"> - <!-- - @page { size: 21cm 29.7cm } - --> - </STYLE> -</HEAD> -<BODY LANG="en" DIR="LTR"> -<P STYLE="margin-left: 0.26cm; margin-right: 0.26cm; margin-top: 0.26cm; margin-bottom: 0.26cm"> -We are sorry!<BR><BR>The OLAT server is overloaded.<BR>Please try -again later.</P> -<P STYLE="margin-left: 0.26cm; margin-right: 0.26cm; margin-top: 0.26cm; margin-bottom: 0.26cm"> -<BR><BR> -</P> -<P STYLE="margin-left: 0.26cm; margin-right: 0.26cm; margin-top: 0.26cm; margin-bottom: 0.26cm"> -<BR><BR> -</P> -</BODY> -</HTML> \ No newline at end of file diff --git a/src/main/webapp/static/themes/openolat/all/_definitions.scss b/src/main/webapp/static/themes/openolat/all/_definitions.scss index 046b3a174c82755ef319594b23ef7bd59ef54602..6437e8a58018f9d10eb8cb0bf3f40cc88ea7195b 100644 --- a/src/main/webapp/static/themes/openolat/all/_definitions.scss +++ b/src/main/webapp/static/themes/openolat/all/_definitions.scss @@ -30,6 +30,10 @@ $glossColor2 : #444 !default; $glossColor3 : #222 !default; $glossColor4 : #3C3C3C !default; +/* colors for ok (green) and not ok (red) in assessment, accept workflows etc */ +$okcolor : #009900 !default; +$nokcolor : #990000 !default; + /* full screen margins. Set to 0% to have have no surrounding border at all */ $fullScreenModalMarginPercents: 2% !default; diff --git a/src/main/webapp/static/themes/openolat/all/_icons.scss b/src/main/webapp/static/themes/openolat/all/_icons.scss index 07ed1e038a82f0a30c3206ca4e831d75d7a6d300..c33748c19f9ad9f02c4a6941372c0f16239c47bb 100644 --- a/src/main/webapp/static/themes/openolat/all/_icons.scss +++ b/src/main/webapp/static/themes/openolat/all/_icons.scss @@ -255,8 +255,8 @@ li a.b_toolbox_copy, .b_copy_icon { background-image: url('../openolat/images/do .o_midpub{ top: -2px; left: 9px; background-image: url('../openolat/images/decorator/deco_ok.png'); } /* --- assessment and efficiency statement eff -- */ -span.o_passed { background: url(../openolat/images/tick.png) no-repeat right 50%; padding: 0 25px 0 0; color: #009900; } -span.o_notpassed { background: url(../openolat/images/cross.png) no-repeat right 50%; padding: 0 25px 0 0; color: #990000; } +span.o_passed { background: url(../openolat/images/tick.png) no-repeat right 50%; padding: 0 25px 0 0; color: $okcolor; } +span.o_notpassed { background: url(../openolat/images/cross.png) no-repeat right 50%; padding: 0 25px 0 0; color: $nokcolor; } .o_efficiencystatement_icon { background-image: url(../openolat/images/seal.png);} span.o_green_led { background: url(../openolat/images/green_led.png) no-repeat left 50%; padding: 0 0 0 25px; } @@ -298,7 +298,7 @@ span.o_grey_led { background: url(../openolat/images/grey_led.png) no-repeat lef .o_vc_icon { background-image: url('../openolat/images/projection-screen.png')!important } /* </OLATCE-103> */ .o_vitero_icon { background-image: url('../openolat/images/vitero.png') !important; } -.o_openmeetings_icon { background-image: url('../openolat/images/apache.png') !important; } +.o_openmeetings_icon { background-image: url('../openolat/images/projection-screen-presentation.png') !important; } .o_ep_icon, { background-image: url('../openolat/images/le_resources/portfolio.png') !important; } .o_EPStructuredMapTemplate_icon { background-image: url('../openolat/images/portfolio/briefcase.png')!important; } diff --git a/src/main/webapp/static/themes/openolat/all/_mixins.scss b/src/main/webapp/static/themes/openolat/all/_mixins.scss index e0d3b40d3a11c0136af5df820b185e5e7d4e4f61..d1684a8e936ae9b01546e78aba3df05c9ea7f877 100644 --- a/src/main/webapp/static/themes/openolat/all/_mixins.scss +++ b/src/main/webapp/static/themes/openolat/all/_mixins.scss @@ -177,7 +177,7 @@ @include o-border-radius(2px); white-space: nowrap; cursor:pointer; - margin: 0 0.5em 0.5em 0; + margin: 0 0.5em 0 0; padding: 0; color: #444; background: transparent; diff --git a/src/main/webapp/static/themes/openolat/all/content.scss b/src/main/webapp/static/themes/openolat/all/content.scss index d8813aecb29c85ace6250dc9b7c206004d214e0b..1208cad06b32cab4ab4aecb4b84f50c9d5f6915f 100644 --- a/src/main/webapp/static/themes/openolat/all/content.scss +++ b/src/main/webapp/static/themes/openolat/all/content.scss @@ -41,7 +41,7 @@ body { /** ----------------- HEADERS ----------------- **/ -h1,h2,h3,h4,h5,h6 {font-family: $headerfont; font-weight:bold; margin: 0 0 0.25em 0; } +h1,h2,h3,h4,h5,h6 {font-family: $headerfont; font-weight:bold; margin: 0 0 0.5em 0; } h1 { font-size: 200% } /* 24px */ h2 { font-size: 166.67% } /* 20px */ h3 { font-size: 150% } /* 18px */ @@ -132,6 +132,19 @@ blockquote.b_quote { margin: 0; border: 1px solid rgb(229, 229, 229);color: blac .b_dimmed { @include o-opacity(40); } .o_ochre { color: #c8a959; } +/* nice table formatting */ +table.b_grid { + td, th { + padding: 2px 5px; + border: 1px solid #888; + } + thead th { + background: #ccc; + } + tbody th { + background: #eee; + } +} @@ -229,7 +242,7 @@ div.b_form_auto_completer_item { background-color:#FFF; text-align: left; paddin div.b_form_auto_completer_item.x-combo-selected { background-color: $basecolor_ultra_light; border-left:0 ! important; border-right:0 ! important;} div.b_form_auto_completer_item span.b_key { color: #999; margin-right: 2px; } div.b_form_auto_completer_item span.b_value { } -div.b_form_auto_completer_item.b_error_icon { color: #990000; font-style: italic;} +div.b_form_auto_completer_item.b_error_icon { color: $nokcolor; font-style: italic;} /* ---------- smilies / emoticons in tinyMCE ------------------------ */ diff --git a/src/main/webapp/static/themes/openolat/all/modules/_formsandbuttons.scss b/src/main/webapp/static/themes/openolat/all/modules/_formsandbuttons.scss index bfb4a857c5cd2c1cfc2216ee690adf3c3cbf18aa..a4a31f4d289e6d61d680b6697f9ab5c4f2e7841e 100644 --- a/src/main/webapp/static/themes/openolat/all/modules/_formsandbuttons.scss +++ b/src/main/webapp/static/themes/openolat/all/modules/_formsandbuttons.scss @@ -166,6 +166,15 @@ span.b_toggle_slide_legend {font-size: 90%; } > span {background-image: url('../openolat/images/le_resources/thumb-up.png');} } +.b_link_ok { + > span {background-image: url('../openolat/images/tick.png');} +} + +.b_link_nok { + > span {background-image: url('../openolat/images/cross.png');} +} + + /** ----------------- FORMS + LOGIN ----------------- **/ div.o_login { div.o_login_form { @@ -220,7 +229,7 @@ fieldset { div.b_form { div.b_form_desc { padding-bottom: 1em; font-style: italic;} - div.b_form_general_error { padding: 10px 10px 10px 50px; margin-bottom: 20px; text-align: left; background: url(../openolat/images/icon_error_32.png) no-repeat 10px 10px; min-height: 32px; border: 1px solid #990000; color: #990000; font-style: italic;} + div.b_form_general_error { padding: 10px 10px 10px 50px; margin-bottom: 20px; text-align: left; background: url(../openolat/images/icon_error_32.png) no-repeat 10px 10px; min-height: 32px; border: 1px solid $nokcolor; color: $nokcolor; font-style: italic;} div.b_form_spacer { margin: 10px 0; } hr { @@ -257,9 +266,9 @@ div.b_form { /** errors **/ &.b_form_error { - input,select {border: 1px solid #990000; background: #ebcccc;} + input,select {border: 1px solid $nokcolor; background: #ebcccc;} } - div.b_form_error_msg { clear: both; color: #990000; font-style: italic; display: block;} + div.b_form_error_msg { clear: both; color: $nokcolor; font-style: italic; display: block;} div.b_form_element_wrapper { margin: 0; @@ -389,5 +398,14 @@ div.b_mark { } +/* Fix for firefox strange spacing in button and other input elements (http://stackoverflow.com/questions/5517744/remove-extra-button-spacing-padding-in-firefox) */ +button::-moz-focus-inner, +input[type="reset"]::-moz-focus-inner, +input[type="button"]::-moz-focus-inner, +input[type="submit"]::-moz-focus-inner, +input[type="file"] > input[type="button"]::-moz-focus-inner { + padding: 0; + border: 0 +} \ No newline at end of file diff --git a/src/main/webapp/static/themes/openolat/all/modules/_misc.scss b/src/main/webapp/static/themes/openolat/all/modules/_misc.scss index 30769e7c2135fe4a048fa473606415fffefa9249..8ab87e223ab4d8cedf4295f5ffa6319bf48e1bc6 100644 --- a/src/main/webapp/static/themes/openolat/all/modules/_misc.scss +++ b/src/main/webapp/static/themes/openolat/all/modules/_misc.scss @@ -33,26 +33,52 @@ div.o_bcard_footer {text-align: right; clear: both; font-size: 95%; color:rgb(31 /* Resume reservations */ div.o_reservation { position:relative; - padding-bottom: 15px; + margin-top: 2em; + padding: 1em; + background: #F7F7F7; + border:1px solid #eee; + @include o-border-radius(4px); span.o_reservation_name { - padding-left: 20px; + font-weight: bold; + line-height: 2em; + } + span.o_reservation_role_coach { + margin-left: 1em; } span.o_reservation_accepted { - background: transparent url(../openolat/images/tick.png) top left no-repeat; + margin-left: 2em; + background: transparent url(../openolat/images/tick.png) 0 50% no-repeat; + color: $okcolor; + padding-left: 20px; + font-style: italic; + line-height: 2em; } span.o_reservation_refused { - background: transparent url(../openolat/images/cross.png) top left no-repeat; + margin-left: 2em; + background: transparent url(../openolat/images/cross.png) 0 50% no-repeat; + color: $nokcolor; + padding-left: 20px; + font-style: italic; + line-height: 2em; + } + + a.o_reservation_details_link { + padding: 0 1em; } div.o_reservation_details { - padding: 5px 0 0 20px; + padding: 1em 0 0 0; } ul { list-style:none; + padding:0; + margin:0; li { background-repeat: no-repeat; + padding:0; + margin:0; } } } @@ -216,11 +242,11 @@ div.o_notifications_news_url { } span.o_search_highlight { padding-left: 2em;} } #o_search_results_header.o_search_did_you_mean, -#o_search_results_header.o_search_no_results { background-image: url(../openolat/images/exclamation.png); color: #990000; } +#o_search_results_header.o_search_no_results { background-image: url(../openolat/images/exclamation.png); color: $nokcolor; } #o_search_results_header.o_search_did_you_mean span.o_search_did_you_mean_words{ color: #000; font-weight: bold;} #o_search_results_header #o_search_pageing { padding-left: 2em; display: inline; } #o_search_pageing_bottom { text-align: center; background: #F8F8F8; border-bottom: 1px solid #eee; padding: 3px;} -#o_search_results_toomany { background: url(../openolat/images/exclamation.png) no-repeat center left #F8F8F8; color: #990000; padding: 5px 0 3px 20px; position: relative; top: -5px; margin-bottom: 5px;} +#o_search_results_toomany { background: url(../openolat/images/exclamation.png) no-repeat center left #F8F8F8; color: $nokcolor; padding: 5px 0 3px 20px; position: relative; top: -5px; margin-bottom: 5px;} div.o_search_result {margin: 0 0 1em 0; padding: 1em 0 0 0; } div.o_search_result_title a {font-weight: bold; } div.o_search_result_title a.o_search_result_details_link { margin-left: 1em; font-weight: normal; font-size: 90%; vertical-align: bottom;} diff --git a/src/main/webapp/static/themes/openolat/images/apache.png b/src/main/webapp/static/themes/openolat/images/apache.png deleted file mode 100644 index 674fec6fb784158c7256ebeb3adfae119c32122d..0000000000000000000000000000000000000000 Binary files a/src/main/webapp/static/themes/openolat/images/apache.png and /dev/null differ diff --git a/src/main/webapp/static/themes/openolat/images/projection-screen-presentation.png b/src/main/webapp/static/themes/openolat/images/projection-screen-presentation.png new file mode 100644 index 0000000000000000000000000000000000000000..e1e6e091ed62b54c9c1e76480dc7025a19c4e50c Binary files /dev/null and b/src/main/webapp/static/themes/openolat/images/projection-screen-presentation.png differ diff --git a/src/main/webapp/static/themes/openolatexample/all/content.css b/src/main/webapp/static/themes/openolatexample/all/content.css index 5c25a240716c6c0222fdd380abe4f1de3562b421..c4719769199b6a16d65360d23efc9a6dc0a8e927 100644 --- a/src/main/webapp/static/themes/openolatexample/all/content.css +++ b/src/main/webapp/static/themes/openolatexample/all/content.css @@ -1 +1 @@ -@import url("../../openolat/all/content.css");body{font-family:Courier;font-size:90%;color:#444}h1,h2,h3,h4,h5,fieldset legend{text-shadow:0 3px 3px rgba(0, 0, 0, 0.4);-moz-text-shadow:0 3px 3px rgba(0, 0, 0, 0.4);font-family:Comic Sans, Comic Sans MS, cursive}a,a:visited{text-decoration:none;color:red}a:hover{text-decoration:underline;color:red} +@import url("../../openolat/all/content.css");body{font-family:Courier;font-size:90%;color:#444}h1,h2,h3,h4,h5,fieldset legend{text-shadow:0 3px 3px rgba(0,0,0,0.4);-moz-text-shadow:0 3px 3px rgba(0,0,0,0.4);font-family:Comic Sans,Comic Sans MS,cursive}a,a:visited{text-decoration:none;color:red}a:hover{text-decoration:underline;color:red} diff --git a/src/test/java/org/olat/basesecurity/BaseSecurityTest.java b/src/test/java/org/olat/basesecurity/BaseSecurityTest.java index 1509406a3ac4e3d644f4f3585e325db0a354c8c9..a40b8aee7b765e0138d7199eb4f5321703fba50e 100644 --- a/src/test/java/org/olat/basesecurity/BaseSecurityTest.java +++ b/src/test/java/org/olat/basesecurity/BaseSecurityTest.java @@ -73,7 +73,7 @@ public class BaseSecurityTest extends OlatTestCase { Identity ident = getOrCreateIdentity("anIdentity"); Identity ident2 = getOrCreateTestIdentity("extremegroovy"); Identity deletedIdent = getOrCreateTestIdentity("delete"); - baseSecurityManager.saveIdentityStatus(deletedIdent, Identity.STATUS_DELETED); + deletedIdent = baseSecurityManager.saveIdentityStatus(deletedIdent, Identity.STATUS_DELETED); SecurityGroup admins = baseSecurityManager.findSecurityGroupByName(Constants.GROUP_ADMIN); baseSecurityManager.addIdentityToSecurityGroup(deletedIdent, admins); @@ -179,8 +179,8 @@ public class BaseSecurityTest extends OlatTestCase { Identity ident2 = getOrCreateTestIdentity("extremegroovy"); // add some stats - baseSecurityManager.saveIdentityStatus(ident, Identity.STATUS_ACTIV); - baseSecurityManager.saveIdentityStatus(ident2, Identity.STATUS_ACTIV); + ident = baseSecurityManager.saveIdentityStatus(ident, Identity.STATUS_ACTIV); + ident2 = baseSecurityManager.saveIdentityStatus(ident2, Identity.STATUS_ACTIV); // check on those four default groups SecurityGroup admins, authors, anonymous; diff --git a/src/test/java/org/olat/core/id/IdentityEnvironmentTest.java b/src/test/java/org/olat/core/id/IdentityEnvironmentTest.java new file mode 100644 index 0000000000000000000000000000000000000000..9f8ec4f94068a9d94cc3f1e93e399980ef9c629e --- /dev/null +++ b/src/test/java/org/olat/core/id/IdentityEnvironmentTest.java @@ -0,0 +1,51 @@ +/** + * <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.id; + +import org.junit.Test; +import org.olat.core.logging.AssertException; + +/** + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class IdentityEnvironmentTest { + + /** + * Can set several times the roles if they are the same + */ + @Test + public void testSetRoles() { + IdentityEnvironment env = new IdentityEnvironment(); + env.setRoles(new Roles(true, true, true, true, true, true, true)); + env.setRoles(new Roles(true, true, true, true, true, true, true)); + } + + /** + * Cannot set roles with different permissions + */ + @Test(expected=AssertException.class) + public void testSetDifferentRoles() { + IdentityEnvironment env = new IdentityEnvironment(); + env.setRoles(new Roles(true, true, true, true, true, true, true)); + env.setRoles(new Roles(true, false, false, false, false, false, false)); + } + +} diff --git a/src/test/java/org/olat/core/util/vfs/VersionManagerTest.java b/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java similarity index 74% rename from src/test/java/org/olat/core/util/vfs/VersionManagerTest.java rename to src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java index dc9d029aabf9324b091f20fd90176c196dec9037..af8b716334b1afd23aa8b617b03e88886f05c849 100644 --- a/src/test/java/org/olat/core/util/vfs/VersionManagerTest.java +++ b/src/test/java/org/olat/core/util/vfs/version/VersionManagerTest.java @@ -17,7 +17,7 @@ * frentix GmbH, http://www.frentix.com * <p> */ -package org.olat.core.util.vfs; +package org.olat.core.util.vfs.version; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; @@ -32,6 +32,8 @@ import java.io.OutputStream; import java.util.List; import java.util.UUID; +import junit.framework.Assert; + import org.apache.commons.io.IOUtils; import org.junit.Before; import org.junit.Test; @@ -40,14 +42,13 @@ import org.olat.core.commons.modules.bc.meta.MetaInfo; import org.olat.core.commons.modules.bc.meta.tagged.MetaTagged; import org.olat.core.commons.modules.bc.vfs.OlatRootFolderImpl; import org.olat.core.id.Identity; -import org.olat.core.util.vfs.version.SimpleVersionConfig; -import org.olat.core.util.vfs.version.VFSRevision; -import org.olat.core.util.vfs.version.Versionable; -import org.olat.core.util.vfs.version.Versions; -import org.olat.core.util.vfs.version.VersionsFileManager; -import org.olat.core.util.vfs.version.VersionsManager; +import org.olat.core.util.vfs.VFSContainer; +import org.olat.core.util.vfs.VFSItem; +import org.olat.core.util.vfs.VFSLeaf; +import org.olat.core.util.vfs.restapi.SystemItemFilter; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -64,6 +65,9 @@ public class VersionManagerTest extends OlatTestCase { private static Identity id1, id2; + @Autowired + private VersionsFileManager versionManager; + @Before public void setUp() throws Exception { if(setuped) return; @@ -132,6 +136,99 @@ public class VersionManagerTest extends OlatTestCase { assertEquals("Version 3", versions.getComment()); } + @Test + public void testVersionChecksum() throws IOException { + OlatRootFolderImpl rootTest = new OlatRootFolderImpl("/ver-" + UUID.randomUUID(), null); + String filename = getRandomName(); + VFSLeaf file = rootTest.createChildLeaf(filename); + OutputStream out = file.getOutputStream(false); + InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); + int byteCopied = IOUtils.copy(in, out); + IOUtils.closeQuietly(in); + assertFalse(byteCopied == 0); + assertTrue(file instanceof Versionable); + + + //save a first version + Versionable versionedFile = (Versionable)file; + InputStream in1 = VersionManagerTest.class.getResourceAsStream("test.txt"); + versionedFile.getVersions().addVersion(id2, "Version 1", in1); + IOUtils.closeQuietly(in1); + + //save a second version + InputStream in2 = VersionManagerTest.class.getResourceAsStream("test.txt"); + versionedFile.getVersions().addVersion(id2, "Version 2", in2); + IOUtils.closeQuietly(in2); + + //save a third version + InputStream in3 = VersionManagerTest.class.getResourceAsStream("test.txt"); + versionedFile.getVersions().addVersion(id2, "Version 3", in2); + IOUtils.closeQuietly(in3); + + //check if there is only one backup file + VFSContainer versionContainer = versionManager.getCanonicalVersionFolder(file.getParentContainer(), false); + Assert.assertNotNull(versionContainer); + List<VFSItem> items = versionContainer.getItems(new SystemItemFilter()); + Assert.assertNotNull(items); + Assert.assertEquals(2, items.size()); + + //check number of versions + VFSItem reloadFile = rootTest.resolve(filename); + assertTrue(reloadFile instanceof Versionable); + Versionable reloadedVersionedFile = (Versionable)reloadFile; + List<VFSRevision> revisions = reloadedVersionedFile.getVersions().getRevisions(); + Assert.assertNotNull(revisions); + Assert.assertEquals(3, revisions.size()); + } + + @Test + public void testDeleteRevisions_withSameFile() throws IOException { + OlatRootFolderImpl rootTest = new OlatRootFolderImpl("/ver-" + UUID.randomUUID(), null); + String filename = getRandomName(); + VFSLeaf file = rootTest.createChildLeaf(filename); + OutputStream out = file.getOutputStream(false); + InputStream in = VersionManagerTest.class.getResourceAsStream("test.txt"); + int byteCopied = IOUtils.copy(in, out); + IOUtils.closeQuietly(in); + assertFalse(byteCopied == 0); + assertTrue(file instanceof Versionable); + + + //save a first version + Versionable versionedFile = (Versionable)file; + InputStream in1 = VersionManagerTest.class.getResourceAsStream("test.txt"); + versionedFile.getVersions().addVersion(id2, "Version 1", in1); + IOUtils.closeQuietly(in1); + + //save a second version + InputStream in2 = VersionManagerTest.class.getResourceAsStream("test.txt"); + versionedFile.getVersions().addVersion(id2, "Version 2", in2); + IOUtils.closeQuietly(in2); + + //save a third version + InputStream in3 = VersionManagerTest.class.getResourceAsStream("test.txt"); + versionedFile.getVersions().addVersion(id2, "Version 3", in2); + IOUtils.closeQuietly(in3); + + //delete revisions + versionManager.deleteRevisions(versionedFile, versionedFile.getVersions().getRevisions().subList(0, 2)); + + //check number of versions + VFSItem reloadFile = rootTest.resolve(filename); + assertTrue(reloadFile instanceof Versionable); + Versionable reloadedVersionedFile = (Versionable)reloadFile; + List<VFSRevision> revisions = reloadedVersionedFile.getVersions().getRevisions(); + Assert.assertNotNull(revisions); + Assert.assertEquals(1, revisions.size()); + + //check if there is only one backup file + VFSContainer versionContainer = versionManager.getCanonicalVersionFolder(file.getParentContainer(), false); + Assert.assertNotNull(versionContainer); + List<VFSItem> items = versionContainer.getItems(new SystemItemFilter()); + Assert.assertNotNull(items); + Assert.assertEquals(2, items.size()); + } + @Test public void testAuthorsAndCreators() throws IOException { //create a file @@ -175,7 +272,7 @@ public class VersionManagerTest extends OlatTestCase { //make the checks VFSItem retrievedFile = rootTest.resolve(filename); assertTrue(retrievedFile instanceof Versionable); - Versions versions = VersionsFileManager.getInstance().createVersionsFor((VFSLeaf)retrievedFile); + Versions versions = versionManager.createVersionsFor((VFSLeaf)retrievedFile); List<VFSRevision> revisions = versions.getRevisions(); assertNotNull(revisions); assertEquals(3, revisions.size()); diff --git a/src/test/java/org/olat/core/util/vfs/version/test.txt b/src/test/java/org/olat/core/util/vfs/version/test.txt new file mode 100644 index 0000000000000000000000000000000000000000..5ab2f8a4323abafb10abb68657d9d39f1a775057 --- /dev/null +++ b/src/test/java/org/olat/core/util/vfs/version/test.txt @@ -0,0 +1 @@ +Hello \ No newline at end of file diff --git a/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java b/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java index f5937613d036fb81214c067e18661cfd76054e01..3151bebecd7276aaa4a8d505bb37786215d9b325 100644 --- a/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java +++ b/src/test/java/org/olat/resource/accesscontrol/ACReservationDAOTest.java @@ -26,10 +26,9 @@ import java.util.UUID; import junit.framework.Assert; -import org.junit.After; +import org.junit.Before; import org.junit.Test; import org.olat.core.commons.persistence.DB; -import org.olat.core.commons.persistence.DBFactory; import org.olat.core.id.Identity; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; @@ -38,6 +37,8 @@ import org.olat.resource.accesscontrol.manager.ACReservationDAO; import org.olat.resource.accesscontrol.model.ResourceReservation; import org.olat.test.JunitTestHelper; import org.olat.test.OlatTestCase; +import org.quartz.Scheduler; +import org.quartz.SchedulerException; import org.springframework.beans.factory.annotation.Autowired; /** @@ -48,18 +49,19 @@ public class ACReservationDAOTest extends OlatTestCase { private final OLog log = Tracing.createLoggerFor(ACReservationDAOTest.class); + @Autowired + private Scheduler scheduler; @Autowired private DB dbInstance; @Autowired private ACReservationDAO acReservationDao; - @After - public void tearDown() throws Exception { + @Before + public void interruptReservationJob() { try { - DBFactory.getInstance().commitAndCloseSession(); - } catch (Exception e) { - log.error("Exception in tearDown(): " + e); - throw e; + scheduler.pauseJob("acReservationCleanupJobDetail", Scheduler.DEFAULT_GROUP); + } catch (SchedulerException e) { + log.error("Cannot intterupt the reservation job.", e); } } @@ -156,7 +158,7 @@ public class ACReservationDAOTest extends OlatTestCase { cal.add(Calendar.SECOND, -2); Date date = cal.getTime(); List<ResourceReservation> oldReservations = acReservationDao.loadExpiredReservation(date); - Assert.assertNotNull(oldReservations); + Assert.assertNotNull("Old reservations cannot be null", oldReservations); Assert.assertFalse(oldReservations.isEmpty()); Assert.assertTrue(oldReservations.contains(reservation1)); Assert.assertTrue(oldReservations.contains(reservation2)); diff --git a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java index 3dbc768cf3fc3d94e9fce8cf2692926629237c4e..31d6ed4650f0442d81c41b236cd537df9d446321 100644 --- a/src/test/java/org/olat/restapi/RepositoryEntriesTest.java +++ b/src/test/java/org/olat/restapi/RepositoryEntriesTest.java @@ -404,13 +404,15 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase { Assert.assertFalse(owners.contains(owner)); } + private static final Roles ADMIN_ROLES = new Roles(true, false, false, false, false, false, false); + @Test public void testGetCoaches() throws IOException, URISyntaxException { Identity coach1 = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-1-" + UUID.randomUUID().toString()); Identity coach2 = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-2-" + UUID.randomUUID().toString()); RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry(); - repositoryManager.addTutors(coach1, new IdentitiesAddEvent(coach1), re); - repositoryManager.addTutors(coach1, new IdentitiesAddEvent(coach2), re); + repositoryManager.addTutors(coach1, ADMIN_ROLES, new IdentitiesAddEvent(coach1), re, null); + repositoryManager.addTutors(coach1, ADMIN_ROLES, new IdentitiesAddEvent(coach2), re, null); dbInstance.commitAndCloseSession(); //get the coaches @@ -470,7 +472,7 @@ public class RepositoryEntriesTest extends OlatJerseyTestCase { public void testRemoveCoach() throws IOException, URISyntaxException { Identity coach = JunitTestHelper.createAndPersistIdentityAsAuthor("coach-4-" + UUID.randomUUID().toString()); RepositoryEntry re = JunitTestHelper.createAndPersistRepositoryEntry(); - repositoryManager.addTutors(coach, new IdentitiesAddEvent(coach), re); + repositoryManager.addTutors(coach, ADMIN_ROLES, new IdentitiesAddEvent(coach), re, null); dbInstance.commitAndCloseSession(); //remove the owner diff --git a/src/test/java/org/olat/restapi/UserMgmtTest.java b/src/test/java/org/olat/restapi/UserMgmtTest.java index 1d1b3813297f8d5d4bd622466236fa2fb9580f6d..ebc2664bbacddebfa8e59c3578168b8aed8bcc30 100644 --- a/src/test/java/org/olat/restapi/UserMgmtTest.java +++ b/src/test/java/org/olat/restapi/UserMgmtTest.java @@ -131,7 +131,6 @@ public class UserMgmtTest extends OlatJerseyTestCase { private static boolean setuped = false; - private RestConnection conn; @Autowired DB dbInstance; @@ -144,7 +143,6 @@ public class UserMgmtTest extends OlatJerseyTestCase { @Override public void setUp() throws Exception { super.setUp(); - conn = new RestConnection(); if(setuped) return; //create identities @@ -277,9 +275,6 @@ public class UserMgmtTest extends OlatJerseyTestCase { @After public void tearDown() throws Exception { try { - if(conn != null) { - conn.shutdown(); - } dbInstance.closeSession(); } catch (Exception e) { e.printStackTrace(); @@ -289,6 +284,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { @Test public void testGetUsers() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); URI request = UriBuilder.fromUri(getContextURI()).path("users").build(); @@ -303,10 +299,13 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(vos); assertFalse(vos.isEmpty()); assertEquals(vos.size(), identities.size()); + + conn.shutdown(); } @Test public void testFindUsersByLogin() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); URI request = UriBuilder.fromUri(getContextURI()).path("users") @@ -331,10 +330,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { } } assertTrue(onlyLikeAdmin); + conn.shutdown(); } @Test public void testFindUsersByProperty() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); URI request = UriBuilder.fromUri(getContextURI()).path("users") @@ -350,10 +351,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(vos); assertFalse(vos.isEmpty()); + conn.shutdown(); } @Test public void testFindAdminByAuth() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); URI request = UriBuilder.fromUri(getContextURI()).path("users") @@ -370,10 +373,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertFalse(vos.isEmpty()); assertEquals(1, vos.size()); assertEquals("administrator",vos.get(0).getLogin()); + conn.shutdown(); } @Test public void testGetUser() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); URI request = UriBuilder.fromUri(getContextURI()).path("/users/" + id1.getKey()).build(); @@ -387,10 +392,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertEquals(vo.getLogin(), id1.getName()); //are the properties there? assertFalse(vo.getProperties().isEmpty()); + conn.shutdown(); } @Test public void testGetUserNotAdmin() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI request = UriBuilder.fromUri(getContextURI()).path("/users/" + id2.getKey()).build(); @@ -404,6 +411,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertEquals(vo.getLogin(), id2.getName()); //no properties for security reason assertTrue(vo.getProperties().isEmpty()); + conn.shutdown(); } /** @@ -412,6 +420,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { */ @Test public void testGetRawJsonUser() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); URI request = UriBuilder.fromUri(getContextURI()).path("/users/" + id1.getKey()).build(); @@ -422,6 +431,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { System.out.println("User"); System.out.println(bodyJson); System.out.println("User"); + conn.shutdown(); } /** @@ -430,6 +440,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { */ @Test public void testGetRawXmlUser() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); URI request = UriBuilder.fromUri(getContextURI()).path("/users/" + id1.getKey()).build(); @@ -440,10 +451,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { System.out.println("User"); System.out.println(bodyXml); System.out.println("User"); + conn.shutdown(); } @Test public void testCreateUser() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); UserVO vo = new UserVO(); @@ -475,6 +488,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertEquals("Female", savedIdent.getUser().getProperty("gender", Locale.ENGLISH)); assertEquals("39847592", savedIdent.getUser().getProperty("telPrivate", Locale.ENGLISH)); assertEquals("12/12/09", savedIdent.getUser().getProperty("birthDay", Locale.ENGLISH)); + conn.shutdown(); } /** @@ -482,6 +496,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { */ @Test public void testCreateUser2() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); UserVO vo = new UserVO(); @@ -513,10 +528,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertEquals("Female", savedIdent.getUser().getProperty("gender", Locale.ENGLISH)); assertEquals("39847592", savedIdent.getUser().getProperty("telPrivate", Locale.ENGLISH)); assertEquals("12/12/09", savedIdent.getUser().getProperty("birthDay", Locale.ENGLISH)); + conn.shutdown(); } @Test public void testCreateUserWithValidationError() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); UserVO vo = new UserVO(); @@ -545,22 +562,27 @@ public class UserMgmtTest extends OlatJerseyTestCase { Identity savedIdent = BaseSecurityManager.getInstance().findIdentityByName("rest-809"); assertNull(savedIdent); + conn.shutdown(); } @Test public void testDeleteUser() throws IOException, URISyntaxException { + Identity idToDelete = JunitTestHelper.createAndPersistIdentityAsUser("user-to-delete-" + UUID.randomUUID().toString()); + dbInstance.commitAndCloseSession(); + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); - + //delete an authentication token - URI request = UriBuilder.fromUri(getContextURI()).path("/users/" + id2.getKey()).build(); + URI request = UriBuilder.fromUri(getContextURI()).path("/users/" + idToDelete.getKey()).build(); HttpDelete method = conn.createDelete(request, MediaType.APPLICATION_XML, true); HttpResponse response = conn.execute(method); assertEquals(200, response.getStatusLine().getStatusCode()); + EntityUtils.consume(response.getEntity()); - - Identity deletedIdent = BaseSecurityManager.getInstance().loadIdentityByKey(id2.getKey()); + Identity deletedIdent = BaseSecurityManager.getInstance().loadIdentityByKey(idToDelete.getKey()); assertNotNull(deletedIdent);//Identity aren't deleted anymore assertEquals(Identity.STATUS_DELETED, deletedIdent.getStatus()); + conn.shutdown(); } @Test @@ -568,7 +590,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { //create an author Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("author-" + UUID.randomUUID().toString()); dbInstance.commitAndCloseSession(); - + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); //get roles of author @@ -585,6 +607,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { Assert.assertFalse(roles.isInvitee()); Assert.assertFalse(roles.isOlatAdmin()); Assert.assertFalse(roles.isUserManager()); + conn.shutdown(); } @Test @@ -592,7 +615,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { //create an author Identity author = JunitTestHelper.createAndPersistIdentityAsAuthor("author-" + UUID.randomUUID().toString()); dbInstance.commitAndCloseSession(); - + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); RolesVO roles = new RolesVO(); @@ -617,10 +640,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { Assert.assertFalse(reloadRoles.isInvitee()); Assert.assertFalse(reloadRoles.isOLATAdmin()); Assert.assertTrue(reloadRoles.isUserManager()); + conn.shutdown(); } @Test public void testUserForums() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id1.getKey().toString()).path("forums") @@ -651,10 +676,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(forum.getCourseKey()); } } + conn.shutdown(); } @Test public void testUserGroupForum() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id1.getKey().toString()).path("forums") @@ -669,10 +696,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(threads); assertNotNull(threads.getMessages()); assertTrue(threads.getMessages().length > 0); + conn.shutdown(); } @Test public void testUserCourseForum() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id1.getKey().toString()).path("forums") @@ -687,10 +716,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(threads); assertNotNull(threads.getMessages()); assertTrue(threads.getMessages().length > 0); + conn.shutdown(); } @Test public void testUserFolders() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id1.getKey().toString()).path("folders").build(); @@ -727,10 +758,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { //id1 is participant of g2. Make sure it found the folder assertTrue(matchG2); + conn.shutdown(); } @Test public void testUserGroupFolder() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id1.getKey().toString()).path("folders") @@ -748,10 +781,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { FileVO portrait = folders.get(0); assertEquals("portrait.jpg", portrait.getTitle()); + conn.shutdown(); } @Test public void testUserBCCourseNodeFolder() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id1.getKey().toString()).path("folders") @@ -769,10 +804,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { FileVO singlePage = folders.get(0); assertEquals("singlepage.html", singlePage.getTitle()); + conn.shutdown(); } @Test public void testUserPersonalFolder() throws Exception { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id1.getKey().toString()).path("folders").path("personal").build(); @@ -786,10 +823,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(files); assertFalse(files.isEmpty()); assertEquals(2, files.size()); //private and public + conn.shutdown(); } @Test public void testOtherUserPersonalFolder() throws Exception { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id2.getKey().toString()).path("folders").path("personal").build(); @@ -803,10 +842,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(files); assertTrue(files.isEmpty()); assertEquals(0, files.size()); //private and public + conn.shutdown(); } @Test public void testOtherUserPersonalFolderOfId3() throws Exception { + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); URI uri = UriBuilder.fromUri(getContextURI()).path("users").path(id3.getKey().toString()).path("folders").path("personal").build(); @@ -823,10 +864,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { FileVO portrait = files.get(0); assertEquals("portrait.jpg", portrait.getTitle()); + conn.shutdown(); } @Test public void testUserGroup() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); //retrieve all groups @@ -839,10 +882,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { List<GroupVO> groups = parseGroupArray(body); assertNotNull(groups); assertEquals(3, groups.size());//g1, g2 and g3 + conn.shutdown(); } @Test public void testUserGroupWithPaging() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); //retrieve all groups @@ -858,10 +903,12 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(groups.getGroups()); assertEquals(1, groups.getGroups().length); assertEquals(3, groups.getTotalCount());//g1, g2 and g3 + conn.shutdown(); } @Test public void testUserGroupInfosWithPaging() throws IOException, URISyntaxException { + RestConnection conn = new RestConnection(); assertTrue(conn.login("administrator", "openolat")); //retrieve all groups @@ -877,6 +924,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { assertNotNull(groups.getGroups()); assertEquals(1, groups.getGroups().length); assertEquals(3, groups.getTotalCount());//g1, g2 and g3 + conn.shutdown(); } @Test @@ -884,7 +932,7 @@ public class UserMgmtTest extends OlatJerseyTestCase { URL portraitUrl = CoursesElementsTest.class.getResource("portrait.jpg"); assertNotNull(portraitUrl); File portrait = new File(portraitUrl.toURI()); - + RestConnection conn = new RestConnection(); assertTrue(conn.login(id1.getName(), "A6B7C8")); //upload portrait @@ -942,6 +990,8 @@ public class UserMgmtTest extends OlatJerseyTestCase { } catch (Exception e) { assertFalse("Cannot read the portrait after Base64 encoding/decoding", false); } + + conn.shutdown(); } protected List<UserVO> parseUserArray(InputStream body) { diff --git a/src/test/java/org/olat/test/AllTestsJunit4.java b/src/test/java/org/olat/test/AllTestsJunit4.java index ff0e088f7cee91a8042c1857f1681643c0324346..3d094b823e93fe328c46bf4144fa04528b18dab9 100644 --- a/src/test/java/org/olat/test/AllTestsJunit4.java +++ b/src/test/java/org/olat/test/AllTestsJunit4.java @@ -62,6 +62,7 @@ import org.junit.runners.Suite; org.olat.core.util.FormatterTest.class, org.olat.core.util.mail.manager.MailManagerTest.class, org.olat.core.id.context.BusinessControlFactoryTest.class, + org.olat.core.id.IdentityEnvironmentTest.class, org.olat.core.gui.render.VelocityTemplateTest.class, org.olat.note.NoteTest.class,//ok org.olat.user.UserPropertiesPerformanceTest.class,//ok @@ -173,7 +174,7 @@ import org.junit.runners.Suite; org.olat.resource.accesscontrol.ACOrderManagerTest.class, org.olat.resource.accesscontrol.ACTransactionManagerTest.class, org.olat.resource.accesscontrol.ACReservationDAOTest.class, - org.olat.core.util.vfs.VersionManagerTest.class, + org.olat.core.util.vfs.version.VersionManagerTest.class, /** * Pure JUnit test without need of framework */ diff --git a/src/test/java/org/olat/test/OlatJerseyTestCase.java b/src/test/java/org/olat/test/OlatJerseyTestCase.java index 5586d39103b194ddfee223254d171178c4cc15a4..d50021b5a54bd6689ceb72c3c1801ba83d353252 100644 --- a/src/test/java/org/olat/test/OlatJerseyTestCase.java +++ b/src/test/java/org/olat/test/OlatJerseyTestCase.java @@ -94,6 +94,7 @@ public abstract class OlatJerseyTestCase extends OlatTestCase { private void instantiateGrizzlyWebServer() { if(webServer == null) { webServer = new GrizzlyWebServer(PORT); + webServer.useAsynchronousWrite(false); ServletAdapter sa = new ServletAdapter(); Servlet servletInstance = null; try { @@ -105,7 +106,7 @@ public abstract class OlatJerseyTestCase extends OlatTestCase { sa.addFilter(new RestApiLoginFilter(), "jerseyfilter", null); sa.addInitParameter("javax.ws.rs.Application", OlatRestApplication.class.getName()); sa.setContextPath("/" + CONTEXT_PATH); - webServer.addGrizzlyAdapter(sa, null); + webServer.addGrizzlyAdapter(sa, new String[]{""}); } } diff --git a/src/test/java/org/olat/test/VFSJavaIOFile.java b/src/test/java/org/olat/test/VFSJavaIOFile.java index 6cff7c7097cf6afa26b8aff3a99390cef87d5a67..b4a1313f7ef558ea475e4c41505064228f5f1a32 100644 --- a/src/test/java/org/olat/test/VFSJavaIOFile.java +++ b/src/test/java/org/olat/test/VFSJavaIOFile.java @@ -53,6 +53,11 @@ public class VFSJavaIOFile implements VFSLeaf { this.file = file; } + @Override + public boolean exists() { + return file != null && file.exists(); + } + @Override public VFSItem resolve(String path) { return null; @@ -78,6 +83,11 @@ public class VFSJavaIOFile implements VFSLeaf { return VFSConstants.NO; } + @Override + public VFSStatus deleteSilently() { + return VFSConstants.NO; + } + @Override public VFSStatus canRename() { return VFSConstants.NO;