diff --git a/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java b/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java index 0c0b88a7998e23f51ad7f9e37cfa238757bfb2b1..e1c3c1832e1541b499f58b9d6634306f1a523693 100644 --- a/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java +++ b/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java @@ -32,6 +32,7 @@ import org.olat.core.util.FileUtils; import org.olat.core.util.Util; import org.olat.core.util.ValidationStatus; import org.olat.core.util.WebappHelper; +import org.olat.core.util.xml.XStreamHelper; import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.condition.Condition; @@ -265,7 +266,7 @@ public class ChecklistCourseNode extends AbstractAccessableCourseNode { @Override public void exportNode(File exportDirectory, ICourse course) { - XStream xstream = new XStream(); + XStream xstream = XStreamHelper.createXStreamInstance(); ChecklistManager cm = ChecklistManager.getInstance(); Checklist checklist = loadOrCreateChecklist(course.getCourseEnvironment().getCoursePropertyManager()); Checklist copy = cm.copyChecklistInRAM(checklist); @@ -284,7 +285,7 @@ public class ChecklistCourseNode extends AbstractAccessableCourseNode { return null; } - XStream xstream = new XStream(); + XStream xstream = XStreamHelper.createXStreamInstance(); Checklist checklist = (Checklist) xstream.fromXML(importContent); if(checklist != null) { checklist = ChecklistManager.getInstance().copyChecklist(checklist); diff --git a/src/main/java/org/olat/core/util/xml/EnhancedMapper.java b/src/main/java/org/olat/core/util/xml/EnhancedMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..c381870bb7c96e06a17427de84d92bae0a81a768 --- /dev/null +++ b/src/main/java/org/olat/core/util/xml/EnhancedMapper.java @@ -0,0 +1,60 @@ +/** + * <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.util.xml; + +import org.hibernate.collection.internal.PersistentBag; +import org.hibernate.collection.internal.PersistentList; + +import com.thoughtworks.xstream.mapper.MapperWrapper; + +/** + * Remap some specific class as hibernate class to maintain compatibility + * with other olat system and/or old versions + * + * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com + */ +public class EnhancedMapper extends MapperWrapper { + + public EnhancedMapper(MapperWrapper mapper) { + super(mapper); + } + + @Override + public Class<?> realClass(String elementName) { + if("org.hibernate.collection.PersistentBag".equals(elementName)) { + return PersistentBag.class; + } else if("org.hibernate.collection.PersistentList".equals(elementName)) { + return PersistentList.class; + } else { + return super.realClass(elementName); + } + } + + @SuppressWarnings("rawtypes") + public String serializedClass(final Class type) { + if(type.equals(PersistentBag.class)) { + return "org.hibernate.collection.PersistentBag"; + } else if(type.equals(PersistentList.class)) { + return "org.hibernate.collection.PersistentList"; + } else { + return super.serializedClass(type); + } + } +} diff --git a/src/main/java/org/olat/core/util/xml/XStreamHelper.java b/src/main/java/org/olat/core/util/xml/XStreamHelper.java index eaaf51684f172b345c8df3917787d0b8202b9051..9cc6dd8fd31217183645b0ae5cdc62c6e4fe98a9 100644 --- a/src/main/java/org/olat/core/util/xml/XStreamHelper.java +++ b/src/main/java/org/olat/core/util/xml/XStreamHelper.java @@ -40,6 +40,7 @@ import org.olat.core.util.FileUtils; import org.olat.core.util.vfs.VFSLeaf; import com.thoughtworks.xstream.XStream; +import com.thoughtworks.xstream.mapper.MapperWrapper; /** * Description:<br> @@ -224,7 +225,7 @@ public class XStreamHelper { * writing to a configured XML mapping */ public static XStream createXStreamInstance() { - return new XStream(); + return new EnhancedXStream(); } /** @@ -378,5 +379,12 @@ public class XStreamHelper { FileUtils.closeSafely(os); } } + + private static class EnhancedXStream extends XStream { + @Override + protected MapperWrapper wrapMapper(MapperWrapper next) { + return new EnhancedMapper(next); + } + } } diff --git a/src/main/java/org/olat/course/export/CourseEnvironmentMapper.java b/src/main/java/org/olat/course/export/CourseEnvironmentMapper.java index d3578f3634217c789d73a39a0d91a4816dc8b986..a5edd8e576a555c410dbd2b1522ef90a81b10c0f 100644 --- a/src/main/java/org/olat/course/export/CourseEnvironmentMapper.java +++ b/src/main/java/org/olat/course/export/CourseEnvironmentMapper.java @@ -110,7 +110,7 @@ public class CourseEnvironmentMapper { return areaKeyList; } - public String toOriginalGroupNames(List<Long> groupKeys) { + public String toGroupNames(List<Long> groupKeys) { if(groupKeys == null || groupKeys.isEmpty()) return ""; StringBuilder sb = new StringBuilder(); for(Long groupKey:groupKeys) { @@ -125,7 +125,7 @@ public class CourseEnvironmentMapper { return sb.toString(); } - public String toOriginalAreaNames(List<Long> areaKeys) { + public String toAreaNames(List<Long> areaKeys) { if(areaKeys == null || areaKeys.isEmpty()) return ""; StringBuilder sb = new StringBuilder(); for(Long areaKey:areaKeys) { diff --git a/src/main/java/org/olat/course/nodes/COCourseNode.java b/src/main/java/org/olat/course/nodes/COCourseNode.java index 8e8a4f1d73ff2e21f2903f3f9ece6c4aec749906..4bab1a172428777c818ac0e96eb088d594ca866f 100644 --- a/src/main/java/org/olat/course/nodes/COCourseNode.java +++ b/src/main/java/org/olat/course/nodes/COCourseNode.java @@ -143,14 +143,14 @@ public class COCourseNode extends AbstractAccessableCourseNode { @SuppressWarnings("unchecked") List<Long> groupKeys = (List<Long>) mc.get(COEditController.CONFIG_KEY_EMAILTOGROUP_IDS); if(groupKeys != null) { - String groupNames = envMapper.toOriginalGroupNames(groupKeys); + String groupNames = envMapper.toGroupNames(groupKeys); mc.set(COEditController.CONFIG_KEY_EMAILTOGROUPS, groupNames); } @SuppressWarnings("unchecked") List<Long> areaKeys = (List<Long>) mc.get(COEditController.CONFIG_KEY_EMAILTOAREA_IDS); if(areaKeys != null) { - String areaNames = envMapper.toOriginalAreaNames(areaKeys); + String areaNames = envMapper.toAreaNames(areaKeys); mc.set(COEditController.CONFIG_KEY_EMAILTOAREAS, areaNames); } diff --git a/src/main/java/org/olat/course/nodes/ENCourseNode.java b/src/main/java/org/olat/course/nodes/ENCourseNode.java index 8a5d448cb573f18856e5fba0487852662aeb1af3..c7bd05c71c0ddaf4b871dd15b6fb7cea507ffc73 100644 --- a/src/main/java/org/olat/course/nodes/ENCourseNode.java +++ b/src/main/java/org/olat/course/nodes/ENCourseNode.java @@ -294,14 +294,14 @@ public class ENCourseNode extends AbstractAccessableCourseNode { @SuppressWarnings("unchecked") List<Long> groupKeys = (List<Long>) mc.get(ENCourseNode.CONFIG_GROUP_IDS); if(groupKeys != null) { - String groupNames = envMapper.toOriginalGroupNames(groupKeys); + String groupNames = envMapper.toGroupNames(groupKeys); mc.set(ENCourseNode.CONFIG_GROUPNAME, groupNames); } @SuppressWarnings("unchecked") List<Long> areaKeys = (List<Long>) mc.get(ENCourseNode.CONFIG_AREA_IDS); if(areaKeys != null ) { - String areaNames = envMapper.toOriginalAreaNames(areaKeys); + String areaNames = envMapper.toAreaNames(areaKeys); mc.set(ENCourseNode.CONFIG_AREANAME, areaNames); } diff --git a/src/main/java/org/olat/course/nodes/GenericCourseNode.java b/src/main/java/org/olat/course/nodes/GenericCourseNode.java index 22d38ce028ea91b71639fb1c3d14b776dee605d3..51d9e7044f9902b0ad7e9714746ebf3c84cbdd8e 100644 --- a/src/main/java/org/olat/course/nodes/GenericCourseNode.java +++ b/src/main/java/org/olat/course/nodes/GenericCourseNode.java @@ -398,22 +398,24 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod boolean easy = StringHelper.containsNonWhitespace(condition.getConditionFromEasyModeConfiguration()); if(easy) { List<Long> groupKeys = condition.getEasyModeGroupAccessIdList(); - if(groupKeys == null) { + if(groupKeys == null || groupKeys.isEmpty()) { //this is an old course -> get group keys from original names groupKeys = envMapper.toGroupKeyFromOriginalNames(condition.getEasyModeGroupAccess()); } else { //map the original exported group key to the newly created one groupKeys = envMapper.toGroupKeyFromOriginalKeys(groupKeys); } - condition.setEasyModeGroupAccessIdList(groupKeys); + condition.setEasyModeGroupAccessIdList(groupKeys);//update keys + condition.setEasyModeGroupAccess(envMapper.toGroupNames(groupKeys));//update names with the current values List<Long> areaKeys = condition.getEasyModeGroupAreaAccessIdList(); - if(areaKeys == null) { + if(areaKeys == null || areaKeys.isEmpty()) { areaKeys = envMapper.toAreaKeyFromOriginalNames(condition.getEasyModeGroupAreaAccess()); } else { areaKeys = envMapper.toAreaKeyFromOriginalKeys(areaKeys); } condition.setEasyModeGroupAreaAccessIdList(areaKeys); + condition.setEasyModeGroupAreaAccess(envMapper.toAreaNames(areaKeys)); String condString = condition.getConditionFromEasyModeConfiguration(); condition.setConditionExpression(condString); @@ -444,9 +446,9 @@ public abstract class GenericCourseNode extends GenericNode implements CourseNod if(condition.getEasyModeGroupAccessIdList() != null || condition.getEasyModeGroupAreaAccessIdList() != null) { - String groupNames = envMapper.toOriginalGroupNames(condition.getEasyModeGroupAccessIdList()); + String groupNames = envMapper.toGroupNames(condition.getEasyModeGroupAccessIdList()); condition.setEasyModeGroupAccess(groupNames); - String areaNames = envMapper.toOriginalAreaNames(condition.getEasyModeGroupAreaAccessIdList()); + String areaNames = envMapper.toAreaNames(condition.getEasyModeGroupAreaAccessIdList()); condition.setEasyModeGroupAreaAccess(areaNames); String condString = condition.getConditionFromEasyModeConfiguration(); if(backwardsCompatible) { diff --git a/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java b/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java index 3ca3320248e2b188b670ea564bbb0cd745b2f005..73319b1381becc942722dbd862e996470bebd20b 100644 --- a/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java +++ b/src/main/java/org/olat/upgrade/OLATUpgrade_8_2_0.java @@ -26,6 +26,7 @@ import java.util.List; import org.olat.basesecurity.BaseSecurity; import org.olat.core.commons.persistence.DB; import org.olat.core.id.Roles; +import org.olat.course.CorruptedCourseException; import org.olat.course.CourseFactory; import org.olat.course.ICourse; import org.olat.course.export.CourseEnvironmentMapper; @@ -167,9 +168,13 @@ public class OLATUpgrade_8_2_0 extends OLATUpgrade { do { entries = repositoryManager.genericANDQueryWithRolesRestriction(params, counter, REPO_ENTRIES_BATCH_SIZE, true); for(RepositoryEntry entry:entries) { - ICourse course = CourseFactory.loadCourse(entry.getOlatResource()); - CourseEnvironmentMapper envMapper = getCourseEnvironmentMapper(entry.getOlatResource()); - course.postImport(envMapper); + try { + ICourse course = CourseFactory.loadCourse(entry.getOlatResource()); + CourseEnvironmentMapper envMapper = getCourseEnvironmentMapper(entry.getOlatResource()); + course.postImport(envMapper); + } catch (CorruptedCourseException e) { + log.error("Course seems corrupt: " + entry.getOlatResource().getResourceableId()); + } } counter += entries.size(); log.audit("Processed repository entries: " + entries.size());