From fa6156385b5c8fa50abb78369183365ce4aeabeb Mon Sep 17 00:00:00 2001
From: srosse <none@none>
Date: Thu, 19 Jul 2012 10:41:22 +0200
Subject: [PATCH] OO-291: fix some import/export  issues (remap hibernate
 classes, update names of groups and areas)

---
 .../bps/course/nodes/ChecklistCourseNode.java |  5 +-
 .../olat/core/util/xml/EnhancedMapper.java    | 60 +++++++++++++++++++
 .../org/olat/core/util/xml/XStreamHelper.java | 10 +++-
 .../export/CourseEnvironmentMapper.java       |  4 +-
 .../org/olat/course/nodes/COCourseNode.java   |  4 +-
 .../org/olat/course/nodes/ENCourseNode.java   |  4 +-
 .../olat/course/nodes/GenericCourseNode.java  | 12 ++--
 .../org/olat/upgrade/OLATUpgrade_8_2_0.java   | 11 +++-
 8 files changed, 93 insertions(+), 17 deletions(-)
 create mode 100644 src/main/java/org/olat/core/util/xml/EnhancedMapper.java

diff --git a/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java b/src/main/java/de/bps/course/nodes/ChecklistCourseNode.java
index 0c0b88a7998..e1c3c1832e1 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 00000000000..c381870bb7c
--- /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 eaaf51684f1..9cc6dd8fd31 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 d3578f36342..a5edd8e576a 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 8e8a4f1d73f..4bab1a17242 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 8a5d448cb57..c7bd05c71c0 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 22d38ce028e..51d9e7044f9 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 3ca3320248e..73319b1381b 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());
-- 
GitLab