diff --git a/src/main/java/org/olat/admin/restapi/RestapiAdminController.java b/src/main/java/org/olat/admin/restapi/RestapiAdminController.java index 58ce2e853a534648b703d097b2303b62e64af437..7f15212e89d375a84ff557df52266456caa4fe77 100644 --- a/src/main/java/org/olat/admin/restapi/RestapiAdminController.java +++ b/src/main/java/org/olat/admin/restapi/RestapiAdminController.java @@ -19,7 +19,7 @@ */ package org.olat.admin.restapi; -import org.olat.core.CoreSpringFactory; +import org.olat.commons.calendar.CalendarModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; @@ -34,36 +34,37 @@ import org.olat.group.BusinessGroupModule; import org.olat.repository.RepositoryModule; import org.olat.restapi.RestModule; import org.olat.restapi.security.RestSecurityHelper; +import org.springframework.beans.factory.annotation.Autowired; /** * * Description:<br> - * This is a controller to configure the SimpleVersionConfig, the configuration - * of the versioning system for briefcase. + * This is a controller to configure the REST API and the + * managed courses, groups and calendars. * * <P> * Initial Date: 21 sept. 2009 <br> * - * @author srosse + * @author srosse, stephane.rosse@frentix.com, https://ww.frentix.com */ public class RestapiAdminController extends FormBasicController { - private MultipleSelectionElement enabled, managedGroupsEl, managedRepoEl; + private MultipleSelectionElement enabled, managedGroupsEl, managedRepoEl, managedCalendarEl; private FormLayoutContainer docLinkFlc; private static final String[] keys = {"on"}; - private final RestModule restModule; - private final BusinessGroupModule groupModule; - private final RepositoryModule repositoryModule; + @Autowired + private RestModule restModule; + @Autowired + private CalendarModule calendarModule; + @Autowired + private BusinessGroupModule groupModule; + @Autowired + private RepositoryModule repositoryModule; public RestapiAdminController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl, "rest"); - - restModule = CoreSpringFactory.getImpl(RestModule.class); - groupModule = CoreSpringFactory.getImpl(BusinessGroupModule.class); - repositoryModule = CoreSpringFactory.getImpl(RepositoryModule.class); - initForm(ureq); } @@ -106,6 +107,11 @@ public class RestapiAdminController extends FormBasicController { managedRepoEl = uifactory.addCheckboxesHorizontal("managed.repo", managedFlc, keys, valueRes); managedRepoEl.addActionListener(FormEvent.ONCHANGE); managedRepoEl.select(keys[0], repositoryModule.isManagedRepositoryEntries()); + + String[] valueCal = new String[] { getTranslator().translate("rest.on") }; + managedCalendarEl = uifactory.addCheckboxesHorizontal("managed.cal", managedFlc, keys, valueCal); + managedCalendarEl.addActionListener(FormEvent.ONCHANGE); + managedCalendarEl.select(keys[0], calendarModule.isManagedCalendars()); } } @@ -127,11 +133,14 @@ public class RestapiAdminController extends FormBasicController { docLinkFlc.setVisible(on); getWindowControl().setInfo("saved"); } else if(source == managedGroupsEl) { - boolean enabled = managedGroupsEl.isAtLeastSelected(1); - groupModule.setManagedBusinessGroups(enabled); + boolean enable = managedGroupsEl.isAtLeastSelected(1); + groupModule.setManagedBusinessGroups(enable); } else if (source == managedRepoEl) { boolean enable = managedRepoEl.isAtLeastSelected(1); repositoryModule.setManagedRepositoryEntries(enable); + } else if (source == managedCalendarEl) { + boolean enable = managedCalendarEl.isAtLeastSelected(1); + calendarModule.setManagedCalendars(enable); } super.formInnerEvent(ureq, source, event); } diff --git a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties index e112e2352b12893d19ad20e3f4ea84706895ddb4..38648b766b63d7ea1198e4da1731aaa9f204734e 100644 --- a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_de.properties @@ -13,6 +13,7 @@ chelp.managed.title=Extern verwaltete Kurse und Gruppen chelp.managed.ID=Über das REST API können für Kurse und Gruppen die ID des externen Systems hinterlegt werden. Bei Kursen ist kann zudem eine externe Referenz verwendet werden, die aus Benutzersicht eine Identifikation des Kurses ermöglicht. chelp.managed.flags=Verwendet man die externen ID's für Kurse oder Gruppen, so ist zusätzlich zu definieren welche Elemente einer sochen extern erstellten Ressource in OpenOLAT nicht verwaltet werden dürfen. Dies wird mit sogenannten "managed Flags" definiert. Es können entweder alle Elemente von extern verwaltet sein oder feingranular z.B. nur die Metadaten und die Benutzerverwaltung. Die Konfiguration der "managed Flags" entnehmen Sie der technischen dokumentation des REST API. chelp.managed.enabled=Ist die externe Verwaltung eingeschaltet, so werden in der OpenOLAT Benutzerschnittstelle für entsprechende Ressourcen die mit den "managed Flags" konfigurierten Elemente als nicht editierbar dargestellt. Zudem werden die externen Id's in Suchfeldern, Anzeigen und Tabellen verwendet. Andere, nicht extern erstellte Ressourcen können parallell dazu normal verwendet und verwaltet werden. +managed.cal=Managed Kalender managed.objects=Extern verwaltete Kurse und Gruppen managed.intro=Kurse und Gruppen können über das REST API erstellt werden. Solch extern erstellt Kurse und Gruppen werden als "managed" bezeichnet da ein externes System das datenführende System ist. Die Verwendung dieser Funktion können Sie hier ein- und ausschalten. managed.group=Managed Gruppen diff --git a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties index 16fb9c48b2fef5d38386785ab6e5ff3f16899758..f5a0a57c8e3c81a1874faa637f424f1296d025a0 100644 --- a/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/restapi/_i18n/LocalStrings_en.properties @@ -7,6 +7,7 @@ chelp.rest.intro=With this form you can activate or deactivate the REST API. $\: chelp.rest.title=REST API help.hover.managed=Help about externally managed courses and groups help.hover.rest=Configure REST API +managed.cal=Managed calendars managed.flags.course.access=Access configuration managed.flags.course.all=Fully externally managed managed.flags.course.bookings=Booking rules diff --git a/src/main/java/org/olat/commons/calendar/CalendarManager.java b/src/main/java/org/olat/commons/calendar/CalendarManager.java index 9b48c3b5b91d1dbc4dac4acf2b9c78890275e035..641d1bbe5d9fda8ac9f3a09ba259cefd8bef591f 100644 --- a/src/main/java/org/olat/commons/calendar/CalendarManager.java +++ b/src/main/java/org/olat/commons/calendar/CalendarManager.java @@ -53,6 +53,8 @@ public interface CalendarManager { public static final String ICAL_X_OLAT_NUMPARTICIPANTS = "X-OLAT-NUMPARTICIPANTS"; public static final String ICAL_X_OLAT_PARTICIPANTS = "X-OLAT-PARTICIPANTS"; public static final String ICAL_X_OLAT_SOURCENODEID = "X-OLAT-SOURCENODEID"; + public static final String ICAL_X_OLAT_MANAGED = "X-OLAT-MANAGED"; + public static final String ICAL_X_OLAT_EXTERNAL_ID = "X-OLAT-EXTERNAL-ID"; public static final int MAX_SUBJECT_DISPLAY_LENGTH = 30; diff --git a/src/main/java/org/olat/commons/calendar/CalendarModule.java b/src/main/java/org/olat/commons/calendar/CalendarModule.java index 4da0476193c01406ccaf3d50ed51a99d927fd732..d8626c47d2d9226afd286ea3b734b83a036d21c7 100644 --- a/src/main/java/org/olat/commons/calendar/CalendarModule.java +++ b/src/main/java/org/olat/commons/calendar/CalendarModule.java @@ -52,6 +52,7 @@ public class CalendarModule extends AbstractSpringModule { private static final String CALENDAR_GROUP_ENABLED = "calendar.group.enabled"; private static final String CALENDAR_COURSE_TOOL_ENABLED = "calendar.course.tool.enabled"; private static final String CALENDAR_COURSE_ELEMENT_ENABLED = "calendar.course.element.enabled"; + private static final String MANAGED_CAL_ENABLED = "managedCalendars"; private TimeZone defaultTimeZone; private TimeZoneRegistry timeZoneRegistry; @@ -66,6 +67,9 @@ public class CalendarModule extends AbstractSpringModule { private boolean enableCourseToolCalendar; @Value("${calendar.course.element.enabled:true}") private boolean enableCourseElementCalendar; + + @Value("${calendar.managed:false}") + private boolean managedCalendars; @Autowired public CalendarModule(CoordinatorManager coordinatorManager) { @@ -118,6 +122,11 @@ public class CalendarModule extends AbstractSpringModule { if(StringHelper.containsNonWhitespace(courseElementEnabledObj)) { enableCourseElementCalendar = "true".equals(courseElementEnabledObj); } + + String managedCalEnabledObj = getStringPropertyValue(MANAGED_CAL_ENABLED, true); + if(StringHelper.containsNonWhitespace(managedCalEnabledObj)) { + managedCalendars = "true".equals(managedCalEnabledObj); + } } public TimeZone getDefaultTimeZone() { @@ -168,4 +177,13 @@ public class CalendarModule extends AbstractSpringModule { this.enableCourseElementCalendar = enableCourseElementCalendar; setStringProperty(CALENDAR_COURSE_ELEMENT_ENABLED, Boolean.toString(enableCourseElementCalendar), true); } + + public boolean isManagedCalendars() { + return managedCalendars; + } + + public void setManagedCalendars(boolean enabled) { + this.managedCalendars = enabled; + setStringProperty(MANAGED_CAL_ENABLED, Boolean.toString(enabled), true); + } } \ No newline at end of file diff --git a/src/main/java/org/olat/commons/calendar/CalendarUtils.java b/src/main/java/org/olat/commons/calendar/CalendarUtils.java index 4ba4ceb9d4241bb5b8fe5086a59159e2ef6db3b1..29cd1b4ae8c72f729f51395db90c3269b017cfc9 100644 --- a/src/main/java/org/olat/commons/calendar/CalendarUtils.java +++ b/src/main/java/org/olat/commons/calendar/CalendarUtils.java @@ -54,7 +54,7 @@ import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; public class CalendarUtils { - static OLog log = Tracing.createLoggerFor(CalendarUtils.class); + private static final OLog log = Tracing.createLoggerFor(CalendarUtils.class); private static final SimpleDateFormat ical4jFormatter = new SimpleDateFormat("yyyyMMdd"); public static String getTimeAsString(Date date, Locale locale) { @@ -291,7 +291,7 @@ public class CalendarUtils { return frequency; } } catch (ParseException e) { - Tracing.createLoggerFor(CalendarUtils.class).error("cannot restore recurrence rule", e); + log.error("cannot restore recurrence rule", e); } } @@ -317,7 +317,7 @@ public class CalendarUtils { return dtUntil; } } catch (ParseException e) { - Tracing.createLoggerFor(CalendarUtils.class).error("cannot restore recurrence rule", e); + log.error("cannot restore recurrence rule", e); } } @@ -366,7 +366,7 @@ public class CalendarUtils { RRule rrule = new RRule(recur); return rrule.getValue(); } catch (ParseException e) { - Tracing.createLoggerFor(CalendarUtils.class).error("cannot create recurrence rule: " + recurrence.toString(), e); + log.error("cannot create recurrence rule: " + recurrence.toString(), e); } } @@ -390,7 +390,7 @@ public class CalendarUtils { recurExcDates.add(excDate); } } catch (ParseException e) { - Tracing.createLoggerFor(CalendarUtils.class).error("cannot restore recurrence exceptions", e); + log.error("cannot restore recurrence exceptions", e); } } diff --git a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java index 29a4c4519ad16acf833451fe6fb1b633dcfcef34..89ee961fcfcc4efa8d6663d5be78406242f100c0 100644 --- a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java +++ b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java @@ -452,6 +452,14 @@ public class ICalFileCalendarManager implements CalendarManager { vEventProperties.add(new XProperty(ICAL_X_OLAT_SOURCENODEID, kEvent.getSourceNodeId())); } + if(kEvent.isManaged()) { + vEventProperties.add(new XProperty(ICAL_X_OLAT_MANAGED, "true")); + } + + if(StringHelper.containsNonWhitespace(kEvent.getExternalId())) { + vEventProperties.add(new XProperty(ICAL_X_OLAT_EXTERNAL_ID, kEvent.getExternalId())); + } + // recurrence String recurrence = kEvent.getRecurrenceRule(); if(recurrence != null && !recurrence.equals("")) { @@ -460,9 +468,10 @@ public class ICalFileCalendarManager implements CalendarManager { RRule rrule = new RRule(recur); vEventProperties.add(rrule); } catch (ParseException e) { - Tracing.createLoggerFor(getClass()).error("cannot create recurrence rule: " + recurrence.toString(), e); + log.error("cannot create recurrence rule: " + recurrence.toString(), e); } } + // recurrence exclusions String recurrenceExc = kEvent.getRecurrenceExc(); if(recurrenceExc != null && !recurrenceExc.equals("")) { @@ -471,7 +480,7 @@ public class ICalFileCalendarManager implements CalendarManager { exdate.setValue(recurrenceExc); vEventProperties.add(exdate); } catch (ParseException e) { - e.printStackTrace(); + log.error("", e); } } @@ -603,8 +612,19 @@ public class ICalFileCalendarManager implements CalendarManager { } Property sourceNodId = event.getProperty(ICAL_X_OLAT_SOURCENODEID); - if (sourceNodId != null) + if (sourceNodId != null) { calEvent.setSourceNodeId(sourceNodId.getValue()); + } + + Property managed = event.getProperty(ICAL_X_OLAT_MANAGED); + if(managed != null) { + calEvent.setManaged("true".equals(managed.getValue())); + } + + Property externalId = event.getProperty(ICAL_X_OLAT_EXTERNAL_ID); + if(externalId != null) { + calEvent.setExternalId(externalId.getValue()); + } // recurrence if (event.getProperty(ICAL_RRULE) != null) { diff --git a/src/main/java/org/olat/commons/calendar/model/KalendarEvent.java b/src/main/java/org/olat/commons/calendar/model/KalendarEvent.java index 1eec100ad2d147652a168d234e34412bc24d13a3..d3a24d52250427ea7a2cf2add5c1fcf546822638 100644 --- a/src/main/java/org/olat/commons/calendar/model/KalendarEvent.java +++ b/src/main/java/org/olat/commons/calendar/model/KalendarEvent.java @@ -69,6 +69,9 @@ public class KalendarEvent implements Cloneable, Comparable<KalendarEvent> { private String recurrenceRule; private String recurrenceExc; + + private boolean managed; + private String externalId; public KalendarEvent() { // save no-args constructor for XStream @@ -165,6 +168,22 @@ public class KalendarEvent implements Cloneable, Comparable<KalendarEvent> { this.subject = subject; } + public boolean isManaged() { + return managed; + } + + public void setManaged(boolean managed) { + this.managed = managed; + } + + public String getExternalId() { + return externalId; + } + + public void setExternalId(String externalId) { + this.externalId = externalId; + } + public int getClassification() { return classification; } diff --git a/src/main/java/org/olat/commons/calendar/restapi/EventVO.java b/src/main/java/org/olat/commons/calendar/restapi/EventVO.java index 888417458f583a440d019c5e9df338f756a730c0..ec9b5433ae9df08877159b1d01c8584d1bee2434 100644 --- a/src/main/java/org/olat/commons/calendar/restapi/EventVO.java +++ b/src/main/java/org/olat/commons/calendar/restapi/EventVO.java @@ -41,6 +41,9 @@ public class EventVO { private Date end; private boolean allDayEvent; + private boolean managed; + private String externalId; + public EventVO() { // } @@ -54,6 +57,8 @@ public class EventVO { end = event.getEnd(); allDayEvent = event.isAllDayEvent(); calendarId = event.getCalendar().getType() + "_" + event.getCalendar().getCalendarID(); + managed = event.isManaged(); + externalId = event.getExternalId(); } public String getId() { @@ -119,4 +124,20 @@ public class EventVO { public void setCalendarId(String calendarId) { this.calendarId = calendarId; } + + public boolean isManaged() { + return managed; + } + + public void setManaged(boolean managed) { + this.managed = managed; + } + + public String getExternalId() { + return externalId; + } + + public void setExternalId(String externalId) { + this.externalId = externalId; + } } diff --git a/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java b/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java index 040b4aec506fc79b1352b8db49fc7f76870cfa4b..221ae2433e77992722929022c606af53bb709565 100644 --- a/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java +++ b/src/main/java/org/olat/commons/calendar/ui/CalendarDetailsController.java @@ -28,6 +28,7 @@ import java.util.Locale; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.time.DateUtils; import org.olat.commons.calendar.CalendarManager; +import org.olat.commons.calendar.CalendarModule; import org.olat.commons.calendar.CalendarUtils; import org.olat.commons.calendar.model.KalendarEvent; import org.olat.commons.calendar.model.KalendarEventLink; @@ -45,6 +46,7 @@ import org.olat.core.gui.util.CSSHelper; import org.olat.core.helpers.Settings; import org.olat.core.util.StringHelper; import org.olat.core.util.Util; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -58,19 +60,22 @@ public class CalendarDetailsController extends BasicController { private final KalendarRenderWrapper calWrapper; private Link editButton; - private final VelocityContainer mainVC; private final boolean isGuestOnly; + @Autowired + private CalendarModule calendarModule; + public CalendarDetailsController(UserRequest ureq, WindowControl wControl, KalendarEvent event, KalendarRenderWrapper calWrapper) { super(ureq, wControl, Util.createPackageTranslator(CalendarManager.class, ureq.getLocale())); this.calEvent = event; this.calWrapper = calWrapper; isGuestOnly = ureq.getUserSession().getRoles().isGuestOnly(); - mainVC = createVelocityContainer("event_details"); + VelocityContainer mainVC = createVelocityContainer("event_details"); - if(!isGuestOnly) { + if(!isGuestOnly && + !(calendarModule.isManagedCalendars() && event.isManaged())) { editButton = LinkFactory.createButton("edit", mainVC, this); mainVC.put("edit", editButton); } diff --git a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java index c1928865222b2dfe6a9c9b41b642a9a3fef232b3..bd0e77fdedca8d6267a8ca2baaab390544b9bdb8 100644 --- a/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java +++ b/src/main/java/org/olat/commons/calendar/ui/WeeklyCalendarController.java @@ -342,6 +342,7 @@ public class WeeklyCalendarController extends FormBasicController implements Act super.formInnerEvent(ureq, source, event); } + @Override public void event(UserRequest ureq, Component source, Event event) { if (event == ComponentUtil.VALIDATE_EVENT && dirty) { dirty = false; @@ -353,6 +354,7 @@ public class WeeklyCalendarController extends FormBasicController implements Act super.event(ureq, source, event); } + @Override public void event(UserRequest ureq, Controller source, Event event) { Kalendar affectedCal = null; if (dirty) { diff --git a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java index fad92b10423ad01b544e4a1360534eb3bd5a1a54..27c969387546468153d0eef6eeed709da23f0584 100644 --- a/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java +++ b/src/main/java/org/olat/commons/calendar/ui/components/FullCalendarComponentRenderer.java @@ -25,12 +25,11 @@ import java.text.DateFormat; import java.util.Calendar; import org.olat.core.gui.components.Component; -import org.olat.core.gui.components.ComponentRenderer; +import org.olat.core.gui.components.DefaultComponentRenderer; import org.olat.core.gui.components.form.flexible.impl.Form; import org.olat.core.gui.components.form.flexible.impl.FormJSHelper; import org.olat.core.gui.render.RenderResult; import org.olat.core.gui.render.Renderer; -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; @@ -42,7 +41,7 @@ import org.olat.core.util.StringHelper; * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ -public class FullCalendarComponentRenderer implements ComponentRenderer { +public class FullCalendarComponentRenderer extends DefaultComponentRenderer { @Override public void render(Renderer renderer, StringOutput sb, Component source, URLBuilder ubu, Translator translator, @@ -224,15 +223,4 @@ public class FullCalendarComponentRenderer implements ComponentRenderer { .append(escapeJavaScript(translator.translate("month.short.dec"))).append("']"); return sb.toString(); } - - @Override - public void renderHeaderIncludes(Renderer renderer, StringOutput sb, Component source, URLBuilder ubu, Translator translator, - RenderingState rstate) { - // - } - - @Override - public void renderBodyOnLoadJSFunctionCall(Renderer renderer, StringOutput sb, Component source, RenderingState rstate) { - // - } } \ No newline at end of file diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties index 3827de71edddf1568e3bea78a3e2db68fe752163..4edf019c67bcf2315656cfda0d82d7cf5d4ac0ba 100644 --- a/src/main/resources/serviceconfig/olat.properties +++ b/src/main/resources/serviceconfig/olat.properties @@ -606,6 +606,9 @@ calendar.course.tool.enabled.values=true,false # Enable the calendar course element in course (if calendar is enabled) calendar.course.element.enabled=true calendar.course.element.enabled.values=true,false +# Enable managed calendars +calendar.managed=false +calendar.managed.values=true,false ######################################################################## # Social sharing options