/** * <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.group.manager; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Set; import org.olat.collaboration.CollaborationTools; import org.olat.collaboration.CollaborationToolsFactory; import org.olat.core.commons.persistence.DB; import org.olat.core.logging.AssertException; import org.olat.core.logging.OLATRuntimeException; import org.olat.core.logging.OLog; import org.olat.core.logging.Tracing; import org.olat.core.util.FileUtils; import org.olat.core.util.StringHelper; import org.olat.group.BusinessGroup; import org.olat.group.BusinessGroupModule; import org.olat.group.BusinessGroupService; import org.olat.group.area.BGArea; import org.olat.group.area.BGAreaManager; import org.olat.group.model.BGAreaReference; import org.olat.group.model.BusinessGroupEnvironment; import org.olat.group.model.BusinessGroupReference; import org.olat.repository.RepositoryEntry; /** * * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com */ public class BusinessGroupImportExport { private static final OLog log = Tracing.createLoggerFor(BusinessGroupImportExport.class); private final GroupXStream xstream = new GroupXStream(); private final DB dbInstance; private final BGAreaManager areaManager; private final BusinessGroupService businessGroupService; private final BusinessGroupModule groupModule; protected BusinessGroupImportExport(DB dbInstance, BGAreaManager areaManager, BusinessGroupService businessGroupService, BusinessGroupModule groupModule) { this.dbInstance = dbInstance; this.areaManager = areaManager; this.businessGroupService = businessGroupService; this.groupModule = groupModule; } public void exportGroups(List<BusinessGroup> groups, List<BGArea> areas, File fExportFile, BusinessGroupEnvironment env, boolean runtimeDatas, boolean backwardsCompatible) { if (groups == null || groups.isEmpty()) { return; // nothing to do... says Florian. } OLATGroupExport root = new OLATGroupExport(); // export areas root.setAreas(new AreaCollection()); root.getAreas().setGroups(new ArrayList<Area>()); for (BGArea area : areas) { Area newArea = new Area(); newArea.key = backwardsCompatible ? null : area.getKey(); newArea.name = area.getName(); if(backwardsCompatible && env != null) { String newName = env.getAreaName(area.getKey()); if(StringHelper.containsNonWhitespace(newName)) { newArea.name = newName; } } newArea.description = Collections.singletonList(area.getDescription()); root.getAreas().getGroups().add(newArea); } // export groups root.setGroups(new GroupCollection()); root.getGroups().setGroups(new ArrayList<Group>()); for (BusinessGroup group : groups) { String groupName = null; if(backwardsCompatible && env != null) { groupName = env.getGroupName(group.getKey()); } Group newGroup = exportGroup(fExportFile, group, groupName, runtimeDatas, backwardsCompatible); root.getGroups().getGroups().add(newGroup); } saveGroupConfiguration(fExportFile, root); } private Group exportGroup(File fExportFile, BusinessGroup group, String groupName, boolean runtimeDatas, boolean backwardsCompatible) { Group newGroup = new Group(); newGroup.key = backwardsCompatible ? null : group.getKey(); newGroup.name = StringHelper.containsNonWhitespace(groupName) ? groupName : group.getName(); if (group.getMinParticipants() != null) { newGroup.minParticipants = group.getMinParticipants(); } if (group.getMaxParticipants() != null) { newGroup.maxParticipants = group.getMaxParticipants(); } if (group.getWaitingListEnabled() != null) { newGroup.waitingList = group.getWaitingListEnabled(); } if (group.getAutoCloseRanksEnabled() != null) { newGroup.autoCloseRanks = group.getAutoCloseRanksEnabled(); } if(StringHelper.containsNonWhitespace(group.getDescription())) { newGroup.description = Collections.singletonList(group.getDescription()); } // collab tools String[] availableTools = CollaborationToolsFactory.getInstance().getAvailableTools().clone(); CollabTools toolsConfig = new CollabTools(); CollaborationTools ct = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(group); for (int i = 0; i < availableTools.length; i++) { try { Field field = toolsConfig.getClass().getField(availableTools[i]); field.setBoolean(toolsConfig, ct.isToolEnabled(availableTools[i])); } catch(NoSuchFieldException e) { //no field to fill (hasOpenMeetings is not set for backwards compatibility) } catch (Exception e) { log.error("", e); } } newGroup.tools = toolsConfig; Long calendarAccess = ct.lookupCalendarAccess(); if (calendarAccess != null) { newGroup.calendarAccess = calendarAccess; } //fxdiff VCRP-8: collaboration tools folder access control Long folderAccess = ct.lookupFolderAccess(); if(folderAccess != null) { newGroup.folderAccess = folderAccess; } String info = ct.lookupNews(); if (info != null && !info.trim().equals("")) { newGroup.info = info.trim(); } log.debug("fExportFile.getParent()=" + fExportFile.getParent()); if(runtimeDatas) { ct.archive(fExportFile.getParent()); } // export membership List<BGArea> bgAreas = areaManager.findBGAreasOfBusinessGroup(group); newGroup.areaRelations = new ArrayList<String>(); for (BGArea areaRelation : bgAreas) { newGroup.areaRelations.add(areaRelation.getName()); } // export properties boolean showOwners = group.isOwnersVisibleIntern(); boolean showParticipants = group.isParticipantsVisibleIntern(); boolean showWaitingList = group.isWaitingListVisibleIntern(); newGroup.showOwners = showOwners; newGroup.showParticipants = showParticipants; newGroup.showWaitingList = showWaitingList; return newGroup; } private void saveGroupConfiguration(File fExportFile, OLATGroupExport root) { FileOutputStream fOut = null; try { fOut = new FileOutputStream(fExportFile); xstream.toXML(root, fOut); } catch (IOException ioe) { throw new OLATRuntimeException( "Error writing group configuration during group export.", ioe); } catch (Exception cfe) { throw new OLATRuntimeException( "Error writing group configuration during group export.", cfe); } finally { FileUtils.closeSafely(fOut); } } public BusinessGroupEnvironment importGroups(RepositoryEntry re, File fGroupExportXML) { if (!fGroupExportXML.exists()) return new BusinessGroupEnvironment(); //start with a new connection dbInstance.commitAndCloseSession(); OLATGroupExport groupConfig = null; try { groupConfig = xstream.fromXML(fGroupExportXML); } catch (Exception ce) { throw new OLATRuntimeException("Error importing group config.", ce); } if (groupConfig == null) { throw new AssertException( "Invalid group export file. Root does not match."); } BusinessGroupEnvironment env = new BusinessGroupEnvironment(); Set<BGArea> areaSet = new HashSet<BGArea>(); // get areas int dbCount = 0; if (groupConfig.getAreas() != null && groupConfig.getAreas().getGroups() != null) { for (Area area : groupConfig.getAreas().getGroups()) { String areaName = area.name; String areaDesc = (area.description != null && !area.description.isEmpty()) ? area.description.get(0) : ""; BGArea newArea = areaManager.createAndPersistBGArea(areaName, areaDesc, re.getOlatResource()); if(areaSet.add(newArea)) { env.getAreas().add(new BGAreaReference(newArea, area.key, area.name)); } if(dbCount++ % 25 == 0) { dbInstance.commitAndCloseSession(); } } } // get groups if (groupConfig.getGroups() != null && groupConfig.getGroups().getGroups() != null) { for (Group group : groupConfig.getGroups().getGroups()) { // create group String groupName = group.name; String groupDesc = (group.description != null && !group.description.isEmpty()) ? group.description.get(0) : ""; // get min/max participants int groupMinParticipants = group.minParticipants == null ? -1 : group.minParticipants.intValue(); int groupMaxParticipants = group.maxParticipants == null ? -1 : group.maxParticipants.intValue(); // waiting list configuration boolean waitingList = false; if (group.waitingList != null) { waitingList = group.waitingList.booleanValue(); } boolean enableAutoCloseRanks = false; if (group.autoCloseRanks != null) { enableAutoCloseRanks = group.autoCloseRanks.booleanValue(); } // get properties boolean showOwners = true; boolean showParticipants = true; boolean showWaitingList = true; if (group.showOwners != null) { showOwners = group.showOwners; } if (group.showParticipants != null) { showParticipants = group.showParticipants; } if (group.showWaitingList != null) { showWaitingList = group.showWaitingList; } BusinessGroup newGroup = businessGroupService.createBusinessGroup(null, groupName, groupDesc, groupMinParticipants, groupMaxParticipants, waitingList, enableAutoCloseRanks, re); //map the group env.getGroups().add(new BusinessGroupReference(newGroup, group.key, group.name)); // get tools config String[] availableTools = CollaborationToolsFactory.getInstance().getAvailableTools().clone(); CollabTools toolsConfig = group.tools; CollaborationTools ct = CollaborationToolsFactory.getInstance().getOrCreateCollaborationTools(newGroup); for (int i = 0; i < availableTools.length; i++) { try { Field field = toolsConfig.getClass().getField(availableTools[i]); Boolean val = field.getBoolean(toolsConfig); if (val != null) { ct.setToolEnabled(availableTools[i], val); } } catch(NoSuchFieldException e) { // hasOpenMeetings compatibility } catch (Exception e) { log.error("", e); } } if (group.calendarAccess != null) { Long calendarAccess = group.calendarAccess; ct.saveCalendarAccess(calendarAccess); } if(group.folderAccess != null) { ct.saveFolderAccess(group.folderAccess); } if (group.info != null) { ct.saveNews(group.info); } // get memberships List<String> memberships = group.areaRelations; if(memberships != null && memberships.size() > 0) { Set<String> uniqueMemberships = new HashSet<>(memberships); for (String membership : uniqueMemberships) { BGArea area = areaManager.findBGArea(membership, re.getOlatResource()); if (area != null) { areaManager.addBGToBGArea(newGroup, area); } else { log.error("Area not found", null); } } } boolean download = groupModule.isUserListDownloadDefaultAllowed(); newGroup = businessGroupService.updateDisplayMembers(newGroup, showOwners, showParticipants, showWaitingList, false, false, false, download); if(dbCount++ % 3 == 0) { dbInstance.commitAndCloseSession(); } } } dbInstance.commitAndCloseSession(); return env; } }