diff --git a/src/main/java/org/olat/collaboration/CollaborationManager.java b/src/main/java/org/olat/collaboration/CollaborationManager.java index 3a41b69d59cf3b27042ec5ecf2d4911aaf2a02b1..8702403350bf4d370bd13b97cf7d5d31f48f9003 100644 --- a/src/main/java/org/olat/collaboration/CollaborationManager.java +++ b/src/main/java/org/olat/collaboration/CollaborationManager.java @@ -19,6 +19,9 @@ */ package org.olat.collaboration; +import java.util.List; +import java.util.Map; + import org.olat.commons.calendar.ui.components.KalendarRenderWrapper; import org.olat.core.gui.UserRequest; import org.olat.core.id.OLATResourceable; @@ -34,6 +37,8 @@ public interface CollaborationManager { public Long lookupFolderAccess(OLATResourceable ores); + public Map<Long,Long> lookupCalendarAccess(List<BusinessGroup> groups); + public KalendarRenderWrapper getCalendar(BusinessGroup group, UserRequest ureq, boolean isAdmin); } diff --git a/src/main/java/org/olat/collaboration/CollaborationManagerImpl.java b/src/main/java/org/olat/collaboration/CollaborationManagerImpl.java index 28ca29d6bf62bc4532dfe4768b0b5dea784e70ee..6ec567167f296141b9cf465915a6bf189015f858 100644 --- a/src/main/java/org/olat/collaboration/CollaborationManagerImpl.java +++ b/src/main/java/org/olat/collaboration/CollaborationManagerImpl.java @@ -19,23 +19,31 @@ */ package org.olat.collaboration; +import static org.olat.collaboration.CollaborationTools.KEY_CALENDAR_ACCESS; import static org.olat.collaboration.CollaborationTools.KEY_FOLDER_ACCESS; import static org.olat.collaboration.CollaborationTools.PROP_CAT_BG_COLLABTOOLS; +import java.util.HashMap; import java.util.List; +import java.util.Map; + +import javax.persistence.TypedQuery; import org.olat.basesecurity.BaseSecurityManager; import org.olat.commons.calendar.CalendarManager; import org.olat.commons.calendar.CalendarManagerFactory; import org.olat.commons.calendar.model.KalendarConfig; import org.olat.commons.calendar.ui.components.KalendarRenderWrapper; +import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.DBFactory; import org.olat.core.commons.persistence.DBQuery; +import org.olat.core.commons.persistence.PersistenceHelper; import org.olat.core.gui.UserRequest; import org.olat.core.id.OLATResourceable; import org.olat.core.manager.BasicManager; import org.olat.group.BusinessGroup; import org.olat.properties.Property; +import org.springframework.beans.factory.annotation.Autowired; /** * @@ -43,6 +51,8 @@ import org.olat.properties.Property; */ public class CollaborationManagerImpl extends BasicManager implements CollaborationManager { + @Autowired + private DB dbInstance; public String getFolderRelPath(OLATResourceable ores) { return "/cts/folders/" + ores.getResourceableTypeName() + "/" + ores.getResourceableId(); @@ -69,6 +79,42 @@ public class CollaborationManagerImpl extends BasicManager implements Collaborat return props.get(0); } } + + @Override + public Map<Long,Long> lookupCalendarAccess(List<BusinessGroup> groups) { + if(groups == null || groups.isEmpty()) { + return new HashMap<Long,Long>(); + } + + StringBuilder query = new StringBuilder(); + query.append("select prop from ").append(Property.class.getName()).append(" as prop where ") + .append(" prop.category='").append(PROP_CAT_BG_COLLABTOOLS).append("'") + .append(" and prop.resourceTypeName='BusinessGroup'") + .append(" and prop.resourceTypeId in (:groupKeys)") + .append(" and prop.name='").append(KEY_CALENDAR_ACCESS).append("'") + .append(" and prop.identity is null and prop.grp is null"); + + TypedQuery<Property> dbquery = dbInstance.getCurrentEntityManager().createQuery(query.toString(), Property.class); + Map<Long,Long> groupKeyToAccess = new HashMap<Long,Long>(); + + int count = 0; + int batch = 200; + do { + int toIndex = Math.min(count + batch, groups.size()); + List<BusinessGroup> toLoad = groups.subList(count, toIndex); + List<Long> groupKeys = PersistenceHelper.toKeys(toLoad); + + List<Property> props = dbquery.setFirstResult(count) + .setMaxResults(batch) + .setParameter("groupKeys", groupKeys) + .getResultList(); + for(Property prop:props) { + groupKeyToAccess.put(prop.getResourceTypeId(), prop.getLongValue()); + } + count += batch; + } while(count < groups.size()); + return groupKeyToAccess; + } @Override public KalendarRenderWrapper getCalendar(BusinessGroup businessGroup, UserRequest ureq, boolean isAdmin) { diff --git a/src/main/java/org/olat/collaboration/CollaborationTools.java b/src/main/java/org/olat/collaboration/CollaborationTools.java index 20e772bc6cc5214085e5dcfbc8e50fbd1a3c53bb..069ed53bb323311d76b937f91e30645b07602890 100644 --- a/src/main/java/org/olat/collaboration/CollaborationTools.java +++ b/src/main/java/org/olat/collaboration/CollaborationTools.java @@ -218,7 +218,7 @@ public class CollaborationTools implements Serializable { * cache for Boolean Objects representing the State */ private final static String KEY_NEWS = "news"; - private final static String KEY_CALENDAR_ACCESS = "cal"; + public final static String KEY_CALENDAR_ACCESS = "cal"; //fxdiff VCRP-8: collaboration tools folder access control public final static String KEY_FOLDER_ACCESS = "folder"; diff --git a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java index e445656577391aaf179a7b1a67efcaae37a19ed7..4f967f2cf2bcb02a0ec276a50aebcc3fb9cd911e 100644 --- a/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java +++ b/src/main/java/org/olat/commons/calendar/ICalFileCalendarManager.java @@ -63,7 +63,6 @@ import net.fortuna.ical4j.model.property.CalScale; import net.fortuna.ical4j.model.property.Clazz; import net.fortuna.ical4j.model.property.Contact; import net.fortuna.ical4j.model.property.Created; -import net.fortuna.ical4j.model.property.DtEnd; import net.fortuna.ical4j.model.property.Duration; import net.fortuna.ical4j.model.property.ExDate; import net.fortuna.ical4j.model.property.LastModified; @@ -108,7 +107,7 @@ public class ICalFileCalendarManager extends BasicManager implements CalendarMan private File fStorageBase; // o_clusterOK by:cg - private CacheWrapper calendarCache; + private CacheWrapper<String, Kalendar> calendarCache; private static final Clazz ICAL_CLASS_PRIVATE = new Clazz("PRIVATE"); private static final Clazz ICAL_CLASS_PUBLIC = new Clazz("PUBLIC"); @@ -162,27 +161,30 @@ public class ICalFileCalendarManager extends BasicManager implements CalendarMan return new Kalendar(calendarID, type); } - public Kalendar getCalendar(String type, String calendarID) { - //o_clusterOK by:cg - OLATResourceable calOres = OresHelper.createOLATResourceableType(getKeyFor(type,calendarID)); - final String callType = type; - final String callCalendarID = calendarID; - Kalendar cal = CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync( calOres, new SyncerCallback<Kalendar>() { - public Kalendar execute() { - return getCalendarFromCache(callType, callCalendarID); - } - }); + @Override + public Kalendar getCalendar(final String type, final String calendarID) { + String key = getKeyFor(type, calendarID); + Kalendar cal = calendarCache.get(key); + if(cal == null) { + //o_clusterOK by:cg + OLATResourceable calOres = OresHelper.createOLATResourceableType(getKeyFor(type,calendarID)); + cal = CoordinatorManager.getInstance().getCoordinator().getSyncer().doInSync( calOres, new SyncerCallback<Kalendar>() { + public Kalendar execute() { + return getCalendarFromCache(type, calendarID); + } + }); + } return cal; } - protected Kalendar getCalendarFromCache(final String callType, final String callCalendarID) { - OLATResourceable calOres = OresHelper.createOLATResourceableType(getKeyFor(callType,callCalendarID)); + private Kalendar getCalendarFromCache(final String callType, final String callCalendarID) { + String calKey = getKeyFor(callType,callCalendarID); + OLATResourceable calOres = OresHelper.createOLATResourceableType(calKey); CoordinatorManager.getInstance().getCoordinator().getSyncer().assertAlreadyDoInSyncFor(calOres); - String key = getKeyFor(callType,callCalendarID); - Kalendar cal = (Kalendar)calendarCache.get(key); + Kalendar cal = calendarCache.get(calKey); if (cal == null) { cal = loadOrCreateCalendar(callType, callCalendarID); - calendarCache.put(key, cal); + calendarCache.put(calKey, cal); } return cal; } @@ -400,10 +402,10 @@ public class ICalFileCalendarManager extends BasicManager implements CalendarMan } // event links - List kalendarEventLinks = kEvent.getKalendarEventLinks(); + List<KalendarEventLink> kalendarEventLinks = kEvent.getKalendarEventLinks(); if ((kalendarEventLinks != null) && !kalendarEventLinks.isEmpty()) { - for (Iterator iter = kalendarEventLinks.iterator(); iter.hasNext();) { - KalendarEventLink link = (KalendarEventLink) iter.next(); + for (Iterator<KalendarEventLink> iter = kalendarEventLinks.iterator(); iter.hasNext();) { + KalendarEventLink link = iter.next(); StringBuilder linkEncoded = new StringBuilder(200); linkEncoded.append(link.getProvider()); linkEncoded.append("§"); @@ -547,7 +549,7 @@ public class ICalFileCalendarManager extends BasicManager implements CalendarMan // links if any List linkProperties = event.getProperties(ICAL_X_OLAT_LINK); - List kalendarEventLinks = new ArrayList(); + List<KalendarEventLink> kalendarEventLinks = new ArrayList<KalendarEventLink>(); for (Iterator iter = linkProperties.iterator(); iter.hasNext();) { XProperty linkProperty = (XProperty) iter.next(); if (linkProperty != null) { diff --git a/src/main/java/org/olat/commons/calendar/model/Kalendar.java b/src/main/java/org/olat/commons/calendar/model/Kalendar.java index 003e65a024b56411accdc2878610af39a214ca07..e96d85fe927ca5d303d61568e321e6bce30a3c3a 100644 --- a/src/main/java/org/olat/commons/calendar/model/Kalendar.java +++ b/src/main/java/org/olat/commons/calendar/model/Kalendar.java @@ -32,6 +32,8 @@ import java.util.Map; public class Kalendar implements Serializable { + private static final long serialVersionUID = -2179014489859413340L; + private String calendarID; private String type; private Map<String, KalendarEvent> events; diff --git a/src/main/java/org/olat/home/HomeCalendarController.java b/src/main/java/org/olat/home/HomeCalendarController.java index c6ef0dd6685e899249710754cc8abfedae3e4e84..15b2532a675abdec2f1673fd5f902ade6fbcf3d6 100644 --- a/src/main/java/org/olat/home/HomeCalendarController.java +++ b/src/main/java/org/olat/home/HomeCalendarController.java @@ -29,9 +29,10 @@ import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; +import java.util.Map; +import org.olat.collaboration.CollaborationManager; import org.olat.collaboration.CollaborationTools; -import org.olat.collaboration.CollaborationToolsFactory; import org.olat.commons.calendar.CalendarManager; import org.olat.commons.calendar.CalendarManagerFactory; import org.olat.commons.calendar.ImportCalendarManager; @@ -197,18 +198,25 @@ public class HomeCalendarController extends BasicController implements Activatea return ImportCalendarManager.getImportedCalendarsForIdentity(ureq); } + /** + * Append the calendars of a list of groups. The groups must have their calendar tool + * enabled, this routine doesn't check it. + * @param ureq + * @param groups + * @param isOwner + * @param calendars + */ private static void addCalendars(UserRequest ureq, List<BusinessGroup> groups, boolean isOwner, List<KalendarRenderWrapper> calendars) { - CollaborationToolsFactory collabFactory = CollaborationToolsFactory.getInstance(); CalendarManager calendarManager = CalendarManagerFactory.getInstance().getCalendarManager(); - for (Iterator<BusinessGroup> iter = groups.iterator(); iter.hasNext();) { - BusinessGroup bGroup = iter.next(); - CollaborationTools collabTools = collabFactory.getOrCreateCollaborationTools(bGroup); - if (!collabTools.isToolEnabled(CollaborationTools.TOOL_CALENDAR)) continue; + Map<Long,Long> groupKeyToAccess = CoreSpringFactory.getImpl(CollaborationManager.class).lookupCalendarAccess(groups); + for (BusinessGroup bGroup:groups) { KalendarRenderWrapper groupCalendarWrapper = calendarManager.getGroupCalendar(bGroup); // set calendar access int iCalAccess = CollaborationTools.CALENDAR_ACCESS_OWNERS; - Long lCalAccess = collabTools.lookupCalendarAccess(); - if (lCalAccess != null) iCalAccess = lCalAccess.intValue(); + Long lCalAccess = groupKeyToAccess.get(bGroup.getKey()); + if (lCalAccess != null) { + iCalAccess = lCalAccess.intValue(); + } if (iCalAccess == CollaborationTools.CALENDAR_ACCESS_OWNERS && !isOwner) { groupCalendarWrapper.setAccess(KalendarRenderWrapper.ACCESS_READ_ONLY); } else { diff --git a/src/main/resources/infinispan-config.xml b/src/main/resources/infinispan-config.xml index 9df5dcb7a95ff169981c3600dab717cba5758636..37a50c8a2c995d373c3cc159978f4dbebf9821bd 100644 --- a/src/main/resources/infinispan-config.xml +++ b/src/main/resources/infinispan-config.xml @@ -29,6 +29,12 @@ <transaction transactionMode="TRANSACTIONAL" /> </namedCache> + <namedCache name="CalendarManager@calendar"> + <eviction maxEntries="500" strategy="LRU"/> + <expiration maxIdle="900000" wakeUpInterval="5000"/> + <transaction transactionMode="NON_TRANSACTIONAL" /> + </namedCache> + <!-- Hibernate cache -->