@Override
  public List<KalendarRenderWrapper> getListOfCalendarWrappers(
      UserRequest ureq, WindowControl wControl) {
    if (!calendarModule.isEnabled()) {
      return new ArrayList<KalendarRenderWrapper>();
    }

    Identity identity = ureq.getIdentity();

    List<KalendarRenderWrapper> calendars = new ArrayList<KalendarRenderWrapper>();
    Map<CalendarKey, CalendarUserConfiguration> configMap =
        calendarManager.getCalendarUserConfigurationsMap(ureq.getIdentity());
    appendPersonalCalendar(identity, calendars, configMap);
    appendGroupCalendars(identity, calendars, configMap);
    appendCourseCalendars(ureq, wControl, calendars, configMap);

    // reload every hour
    List<KalendarRenderWrapper> importedCalendars =
        importCalendarManager.getImportedCalendarsForIdentity(identity, true);
    for (KalendarRenderWrapper importedCalendar : importedCalendars) {
      importedCalendar.setPrivateEventsVisible(true);
    }

    calendars.addAll(importedCalendars);
    return calendars;
  }
  @Override
  protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) {
    setFormTitle("rest.title");
    setFormContextHelp("REST API");

    if (formLayout instanceof FormLayoutContainer) {
      FormLayoutContainer layoutContainer = (FormLayoutContainer) formLayout;

      boolean restEnabled = restModule.isEnabled();
      docLinkFlc =
          FormLayoutContainer.createCustomFormLayout(
              "doc_link", getTranslator(), velocity_root + "/docLink.html");
      layoutContainer.add(docLinkFlc);
      docLinkFlc.setVisible(restEnabled);

      String link =
          Settings.getServerContextPathURI() + RestSecurityHelper.SUB_CONTEXT + "/api/doc";
      docLinkFlc.contextPut("docLink", link);

      FormLayoutContainer accessDataFlc =
          FormLayoutContainer.createDefaultFormLayout("flc_access_data", getTranslator());
      layoutContainer.add(accessDataFlc);

      String[] values = new String[] {getTranslator().translate("rest.on")};
      enabled = uifactory.addCheckboxesHorizontal("rest.enabled", accessDataFlc, keys, values);
      enabled.select(keys[0], restEnabled);
      enabled.addActionListener(FormEvent.ONCHANGE);

      accessDataFlc.setVisible(true);
      formLayout.add(accessDataFlc);

      FormLayoutContainer managedFlc =
          FormLayoutContainer.createDefaultFormLayout("flc_managed", getTranslator());
      layoutContainer.add(managedFlc);

      String[] valueGrps = new String[] {getTranslator().translate("rest.on")};
      managedGroupsEl =
          uifactory.addCheckboxesHorizontal("managed.group", managedFlc, keys, valueGrps);
      managedGroupsEl.addActionListener(FormEvent.ONCHANGE);
      managedGroupsEl.select(keys[0], groupModule.isManagedBusinessGroups());

      String[] valueRes = new String[] {getTranslator().translate("rest.on")};
      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());
    }
  }
 private void appendPersonalCalendar(
     Identity identity,
     List<KalendarRenderWrapper> calendars,
     Map<CalendarKey, CalendarUserConfiguration> configMap) {
   // get the personal calendar
   if (calendarModule.isEnablePersonalCalendar()) {
     KalendarRenderWrapper calendarWrapper = calendarManager.getPersonalCalendar(identity);
     calendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_WRITE);
     calendarWrapper.setPrivateEventsVisible(true);
     CalendarUserConfiguration config = configMap.get(calendarWrapper.getCalendarKey());
     if (config != null) {
       calendarWrapper.setConfiguration(config);
     }
     calendars.add(calendarWrapper);
   }
 }
 @Override
 protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) {
   if (source == enabled) {
     boolean on = enabled.isAtLeastSelected(1);
     restModule.setEnabled(on);
     docLinkFlc.setVisible(on);
     getWindowControl().setInfo("saved");
   } else if (source == managedGroupsEl) {
     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);
 }
  private void appendGroupCalendars(
      Identity identity,
      List<KalendarRenderWrapper> calendars,
      Map<CalendarKey, CalendarUserConfiguration> configMap) {
    // get group calendars
    if (calendarModule.isEnableGroupCalendar()) {
      SearchBusinessGroupParams groupParams = new SearchBusinessGroupParams(identity, true, false);
      groupParams.addTools(CollaborationTools.TOOL_CALENDAR);
      List<BusinessGroup> ownerGroups =
          businessGroupService.findBusinessGroups(groupParams, null, 0, -1);
      addCalendars(ownerGroups, true, false, calendars, configMap);

      SearchBusinessGroupParams groupParams2 = new SearchBusinessGroupParams(identity, false, true);
      groupParams2.addTools(CollaborationTools.TOOL_CALENDAR);
      List<BusinessGroup> attendedGroups =
          businessGroupService.findBusinessGroups(groupParams2, null, 0, -1);
      attendedGroups.removeAll(ownerGroups);
      addCalendars(attendedGroups, false, true, calendars, configMap);
    }
  }
  @Override
  public List<CalendarFileInfos> getListOfCalendarsFiles(Identity identity) {
    List<CalendarFileInfos> aggregatedFiles = new ArrayList<>();

    Map<CalendarKey, CalendarUserConfiguration> configMap =
        calendarManager.getCalendarUserConfigurationsMap(identity);

    // personal calendar
    CalendarKey personalCalendarKey =
        new CalendarKey(identity.getName(), CalendarManager.TYPE_USER);
    CalendarUserConfiguration personalCalendarConfig = configMap.get(personalCalendarKey);
    if (calendarModule.isEnablePersonalCalendar()
        && (personalCalendarConfig == null || personalCalendarConfig.isInAggregatedFeed())) {
      File iCalFile =
          calendarManager.getCalendarICalFile(CalendarManager.TYPE_USER, identity.getName());
      if (iCalFile != null) {
        aggregatedFiles.add(
            new CalendarFileInfos(identity.getName(), CalendarManager.TYPE_USER, iCalFile));
      }

      // reload every hour
      List<CalendarFileInfos> importedCalendars =
          importCalendarManager.getImportedCalendarInfosForIdentity(identity, true);
      aggregatedFiles.addAll(importedCalendars);
    }

    // group calendars
    if (calendarModule.isEnableGroupCalendar()) {
      SearchBusinessGroupParams groupParams = new SearchBusinessGroupParams(identity, true, true);
      groupParams.addTools(CollaborationTools.TOOL_CALENDAR);
      List<BusinessGroup> groups =
          businessGroupService.findBusinessGroups(groupParams, null, 0, -1);
      for (BusinessGroup group : groups) {
        String calendarId = group.getKey().toString();
        CalendarKey key = new CalendarKey(calendarId, CalendarManager.TYPE_GROUP);
        CalendarUserConfiguration calendarConfig = configMap.get(key);
        if (calendarConfig == null || calendarConfig.isInAggregatedFeed()) {
          File iCalFile =
              calendarManager.getCalendarICalFile(CalendarManager.TYPE_GROUP, calendarId);
          if (iCalFile != null) {
            aggregatedFiles.add(
                new CalendarFileInfos(calendarId, CalendarManager.TYPE_GROUP, iCalFile));
          }
        }
      }
    }

    if (calendarModule.isEnableCourseElementCalendar()
        || calendarModule.isEnableCourseToolCalendar()) {
      List<Object[]> resources = getCourses(identity);
      for (Object[] resource : resources) {
        RepositoryEntry courseEntry = (RepositoryEntry) resource[0];
        String calendarId = courseEntry.getOlatResource().getResourceableId().toString();
        CalendarKey key = new CalendarKey(calendarId, CalendarManager.TYPE_COURSE);
        CalendarUserConfiguration calendarConfig = configMap.get(key);
        if (calendarConfig == null || calendarConfig.isInAggregatedFeed()) {
          File iCalFile =
              calendarManager.getCalendarICalFile(CalendarManager.TYPE_COURSE, calendarId);
          if (iCalFile != null) {
            aggregatedFiles.add(
                new CalendarFileInfos(calendarId, CalendarManager.TYPE_COURSE, iCalFile));
          }
        }
      }
    }

    return aggregatedFiles;
  }
  private void appendCourseCalendars(
      UserRequest ureq,
      WindowControl wControl,
      List<KalendarRenderWrapper> calendars,
      Map<CalendarKey, CalendarUserConfiguration> configMap) {
    if (calendarModule.isEnableCourseElementCalendar()
        || calendarModule.isEnableCourseToolCalendar()) {

      // add course calendars
      List<Object[]> resources = getCourses(ureq.getIdentity());
      Set<OLATResource> editoredResources = getEditorGrants(ureq.getIdentity());

      Set<Long> duplicates = new HashSet<>();

      for (Object[] resource : resources) {
        RepositoryEntry courseEntry = (RepositoryEntry) resource[0];
        if (duplicates.contains(courseEntry.getKey())) {
          continue;
        }
        duplicates.add(courseEntry.getKey());

        String role = (String) resource[1];
        Long courseResourceableID = courseEntry.getOlatResource().getResourceableId();
        try {
          ICourse course = CourseFactory.loadCourse(courseEntry);
          if (isCourseCalendarEnabled(course)) {
            // calendar course aren't enabled per default but course node of type calendar are
            // always possible
            // REVIEW if (!course.getCourseEnvironment().getCourseConfig().isCalendarEnabled())
            // continue;
            // add course calendar
            KalendarRenderWrapper courseCalendarWrapper = calendarManager.getCourseCalendar(course);
            boolean isPrivileged =
                GroupRoles.owner.name().equals(role)
                    || editoredResources.contains(courseEntry.getOlatResource());
            if (isPrivileged) {
              courseCalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_WRITE);
            } else {
              courseCalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_ONLY);
            }

            if (role != null
                && (GroupRoles.owner.name().equals(role)
                    || GroupRoles.coach.name().equals(role)
                    || GroupRoles.participant.name().equals(role))) {
              courseCalendarWrapper.setPrivateEventsVisible(true);
            }

            CalendarUserConfiguration config =
                configMap.get(courseCalendarWrapper.getCalendarKey());
            if (config != null) {
              courseCalendarWrapper.setConfiguration(config);
            }
            courseCalendarWrapper.setLinkProvider(
                new CourseLinkProviderController(
                    course, Collections.singletonList(course), ureq, wControl));
            calendars.add(courseCalendarWrapper);
          }
        } catch (CorruptedCourseException e) {
          OLATResource olatResource = courseEntry.getOlatResource();
          log.error(
              "Corrupted course: "
                  + olatResource.getResourceableTypeName()
                  + " :: "
                  + courseResourceableID,
              null);
        }
      }
    }
  }