Index: lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java =================================================================== RCS file: /usr/local/cvsroot/lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java,v diff -u -r1.36.2.3 -r1.36.2.4 --- lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java 22 Feb 2007 04:15:24 -0000 1.36.2.3 +++ lams_central/src/java/org/lamsfoundation/lams/authoring/ObjectExtractor.java 1 Mar 2007 23:57:41 -0000 1.36.2.4 @@ -34,7 +34,7 @@ import javax.servlet.http.HttpSession; import org.apache.log4j.Logger; -import org.lamsfoundation.lams.dao.hibernate.BaseDAO; +import org.lamsfoundation.lams.dao.IBaseDAO; import org.lamsfoundation.lams.learningdesign.Activity; import org.lamsfoundation.lams.learningdesign.ChosenGrouping; import org.lamsfoundation.lams.learningdesign.ComplexActivity; @@ -55,18 +55,20 @@ import org.lamsfoundation.lams.learningdesign.SystemGateActivity; import org.lamsfoundation.lams.learningdesign.ToolActivity; import org.lamsfoundation.lams.learningdesign.Transition; -import org.lamsfoundation.lams.learningdesign.dao.hibernate.ActivityDAO; -import org.lamsfoundation.lams.learningdesign.dao.hibernate.GroupDAO; -import org.lamsfoundation.lams.learningdesign.dao.hibernate.GroupingDAO; -import org.lamsfoundation.lams.learningdesign.dao.hibernate.LearningDesignDAO; -import org.lamsfoundation.lams.learningdesign.dao.hibernate.LearningLibraryDAO; -import org.lamsfoundation.lams.learningdesign.dao.hibernate.LicenseDAO; -import org.lamsfoundation.lams.learningdesign.dao.hibernate.TransitionDAO; +import org.lamsfoundation.lams.learningdesign.dao.IActivityDAO; +import org.lamsfoundation.lams.learningdesign.dao.IGroupDAO; +import org.lamsfoundation.lams.learningdesign.dao.IGroupingDAO; +import org.lamsfoundation.lams.learningdesign.dao.ILearningDesignDAO; +import org.lamsfoundation.lams.learningdesign.dao.ILearningLibraryDAO; +import org.lamsfoundation.lams.learningdesign.dao.ILicenseDAO; +import org.lamsfoundation.lams.learningdesign.dao.ITransitionDAO; import org.lamsfoundation.lams.lesson.LessonClass; import org.lamsfoundation.lams.tool.SystemTool; import org.lamsfoundation.lams.tool.Tool; -import org.lamsfoundation.lams.tool.dao.hibernate.SystemToolDAO; -import org.lamsfoundation.lams.tool.dao.hibernate.ToolDAO; +import org.lamsfoundation.lams.tool.ToolSession; +import org.lamsfoundation.lams.tool.dao.ISystemToolDAO; +import org.lamsfoundation.lams.tool.dao.IToolDAO; +import org.lamsfoundation.lams.tool.dao.IToolSessionDAO; import org.lamsfoundation.lams.usermanagement.User; import org.lamsfoundation.lams.usermanagement.WorkspaceFolder; import org.lamsfoundation.lams.usermanagement.dto.UserDTO; @@ -99,29 +101,38 @@ */ public class ObjectExtractor implements IObjectExtractor { - protected BaseDAO baseDAO = null; - protected LearningDesignDAO learningDesignDAO = null; - protected ActivityDAO activityDAO =null; - protected TransitionDAO transitionDAO =null; - protected LearningLibraryDAO learningLibraryDAO = null; - protected LicenseDAO licenseDAO = null; - protected GroupingDAO groupingDAO = null; - protected ToolDAO toolDAO = null; - protected SystemToolDAO systemToolDAO = null; - protected GroupDAO groupDAO = null; + protected IBaseDAO baseDAO = null; + protected ILearningDesignDAO learningDesignDAO = null; + protected IActivityDAO activityDAO =null; + protected ITransitionDAO transitionDAO =null; + protected ILearningLibraryDAO learningLibraryDAO = null; + protected ILicenseDAO licenseDAO = null; + protected IGroupingDAO groupingDAO = null; + protected IToolDAO toolDAO = null; + protected ISystemToolDAO systemToolDAO = null; + protected IGroupDAO groupDAO = null; + protected IToolSessionDAO toolSessionDAO = null; private Integer mode = null; - /** The newActivityMap is a local copy of all the current activities. This will include + /* The newActivityMap is a local copy of all the current activities. This will include * the "top level" activities and subactivities. It is used to "crossreference" activities * as we go, without having to repull them from the database. The keys are the UIIDs * of the activities, not the IDs. It is important that the values in this map are the Activity * objects related to the Hibernate session as they are updated by the parseTransitions code. */ protected HashMap newActivityMap = new HashMap(); - // cache of groupings - too hard to get them from the db + /* + * Record the tool sessions and activities as we go for edit on fly. This is needed in case we delete any. + * Cannot get them at the end as Hibernate tries to store the activities before getting the + * tool sessions, and this fails due to a foriegn key error. Its the foriegn key error + * that we are trying to avoid! + */ + protected HashMap> toolSessionMap = new HashMap>(); // Activity UIID -> ToolSession + protected HashMap oldActivityMap = new HashMap(); // Activity UIID -> Activity + /* cache of groupings - too hard to get them from the db */ protected HashMap groupings = new HashMap(); - // can't delete as we go as they are linked to other items - keep a list and delete at the end. + /* can't delete as we go as they are linked to other items - keep a list and delete at the end. */ protected Set groupingsToDelete = new HashSet(); protected LearningDesign learningDesign = null; @@ -132,11 +143,11 @@ } /** Constructor to be used if Spring method injection is not used */ - public ObjectExtractor(BaseDAO baseDAO, - LearningDesignDAO learningDesignDAO, ActivityDAO activityDAO, - LearningLibraryDAO learningLibraryDAO, LicenseDAO licenseDAO, - GroupingDAO groupingDAO, ToolDAO toolDAO, SystemToolDAO systemToolDAO, - GroupDAO groupDAO,TransitionDAO transitionDAO) { + public ObjectExtractor(IBaseDAO baseDAO, + ILearningDesignDAO learningDesignDAO, IActivityDAO activityDAO, + ILearningLibraryDAO learningLibraryDAO, ILicenseDAO licenseDAO, + IGroupingDAO groupingDAO, IToolDAO toolDAO, ISystemToolDAO systemToolDAO, + IGroupDAO groupDAO, ITransitionDAO transitionDAO, IToolSessionDAO toolSessionDAO) { this.baseDAO = baseDAO; this.learningDesignDAO = learningDesignDAO; this.activityDAO = activityDAO; @@ -147,57 +158,66 @@ this.systemToolDAO = systemToolDAO; this.groupDAO = groupDAO; this.transitionDAO = transitionDAO; + this.toolSessionDAO = toolSessionDAO; } /** Spring injection methods */ - public ActivityDAO getActivityDAO() { + public IActivityDAO getActivityDAO() { return activityDAO; } - public void setActivityDAO(ActivityDAO activityDAO) { + public void setActivityDAO(IActivityDAO activityDAO) { this.activityDAO = activityDAO; } - public GroupDAO getGroupDAO() { + public IGroupDAO getGroupDAO() { return groupDAO; } - public void setGroupDAO(GroupDAO groupDAO) { + public void setGroupDAO(IGroupDAO groupDAO) { this.groupDAO = groupDAO; } - public GroupingDAO getGroupingDAO() { + public IGroupingDAO getGroupingDAO() { return groupingDAO; } - public void setGroupingDAO(GroupingDAO groupingDAO) { + public void setGroupingDAO(IGroupingDAO groupingDAO) { this.groupingDAO = groupingDAO; } - public LearningDesignDAO getLearningDesignDAO() { + public ILearningDesignDAO getLearningDesignDAO() { return learningDesignDAO; } - public void setLearningDesignDAO(LearningDesignDAO learningDesignDAO) { + public void setLearningDesignDAO(ILearningDesignDAO learningDesignDAO) { this.learningDesignDAO = learningDesignDAO; } - public LearningLibraryDAO getLearningLibraryDAO() { + public ILearningLibraryDAO getLearningLibraryDAO() { return learningLibraryDAO; } - public void setLearningLibraryDAO(LearningLibraryDAO learningLibraryDAO) { + public void setLearningLibraryDAO(ILearningLibraryDAO learningLibraryDAO) { this.learningLibraryDAO = learningLibraryDAO; } - public LicenseDAO getLicenseDAO() { + public ILicenseDAO getLicenseDAO() { return licenseDAO; } - public void setLicenseDAO(LicenseDAO licenseDAO) { + public void setLicenseDAO(ILicenseDAO licenseDAO) { this.licenseDAO = licenseDAO; } + public IToolSessionDAO getToolSessionDAODAO() { + return toolSessionDAO; + } + + public void setToolSessionDAO(IToolSessionDAO toolSessionDAO) { + this.toolSessionDAO = toolSessionDAO; + } + public HashMap getNewActivityMap() { return newActivityMap; } @@ -206,36 +226,36 @@ this.newActivityMap = newActivityMap; } - public ToolDAO getToolDAO() { + public IToolDAO getToolDAO() { return toolDAO; } - public void setToolDAO(ToolDAO toolDAO) { + public void setToolDAO(IToolDAO toolDAO) { this.toolDAO = toolDAO; } - public SystemToolDAO getSystemToolDAO() { + public ISystemToolDAO getSystemToolDAO() { return systemToolDAO; } - public void setSystemToolDAO(SystemToolDAO systemToolDAO) { + public void setSystemToolDAO(ISystemToolDAO systemToolDAO) { this.systemToolDAO = systemToolDAO; } - public TransitionDAO getTransitionDAO() { + public ITransitionDAO getTransitionDAO() { return transitionDAO; } - public void setTransitionDAO(TransitionDAO transitionDAO) { + public void setTransitionDAO(ITransitionDAO transitionDAO) { this.transitionDAO = transitionDAO; } - public BaseDAO getBaseDAO() { + public IBaseDAO getBaseDAO() { return baseDAO; } - public void setBaseDAO(BaseDAO baseDAO) { + public void setBaseDAO(IBaseDAO baseDAO) { this.baseDAO = baseDAO; } @@ -269,6 +289,9 @@ // here for reference later. initialiseGroupings(); + // get a mapping of all the existing activities and their tool sessions, in case we need to delete some tool sessions later. + initialiseToolSessionMap(learningDesign); + //get the core learning design stuff - default to invalid learningDesign.setValidDesign(Boolean.FALSE); if (keyExists(table, WDDXTAGS.LEARNING_DESIGN_UIID)) @@ -375,6 +398,7 @@ learningDesign.setFirstActivity(learningDesign.calculateFirstActivity()); learningDesignDAO.insertOrUpdate(learningDesign); deleteUnwantedGroupings(); + deleteUnwantedToolSessions(); return learningDesign; } @@ -392,12 +416,64 @@ } } + /** Initialise the map of tool sessions already in the database. Used to work out what will be deleted + * by Hibernate later - useful to clean up any unwanted tool sessions for edit on the fly. + */ + private void initialiseToolSessionMap(LearningDesign learningDesign) { + // if ( edit on fly) { + Iterator iter = learningDesign.getActivities().iterator(); + while ( iter.hasNext() ) { + Activity activity = (Activity) iter.next(); + oldActivityMap.put(activity.getActivityUIID(), activity); + List toolSessions = toolSessionDAO.getToolSessionByActivity(activity); + if ( toolSessions != null && toolSessions.size() > 0 ) + toolSessionMap.put(activity.getActivityUIID(),toolSessions); + } + // } + } + /** Delete the old unneeded groupings. Won't be done via a cascase */ private void deleteUnwantedGroupings() { for ( Grouping grouping: groupingsToDelete) { groupingDAO.delete(grouping); } } + + /** Delete the old tool session. Won't be done via Hibernate cascades as we only want to do it + * for edit on fly. The progress engine pre-generates the tool sessions for class level activities, + * so if we edit the design, we need to delete the tool sessions. If we encounter evidence that this + * is a grouped activity - either more than one tool session exists or the activity is grouped, then abort. */ + private void deleteUnwantedToolSessions() throws ObjectExtractorException { +// TODO if ( editOnFly ) { + + for ( Integer uiid : toolSessionMap.keySet() ) { + if ( ! newActivityMap.containsKey(uiid) ) { + List toolSessions = toolSessionMap.get(uiid); + if ( toolSessions != null ) { + + Activity activity = oldActivityMap.get(uiid); + if ( toolSessions.size() > 1 ) { + throw new ObjectExtractorException("More than one tool session exists for activity "+activity.getTitle()+" ("+uiid+") but this shouldn't be possible. Cannot delete this tool session so editing is not allowed!"); + } else if (toolSessions.size() == 1) { + + ToolSession toolSession = (ToolSession) toolSessions.get(0); + if ( activity.isGroupingActivity() ) { + throw new ObjectExtractorException("Activity "+activity.getTitle()+" ("+activity.getActivityUIID()+") has a tool session but it is grouped. Cannot delete this tool session so editing is not allowed!"); + } + + // all okay, do ahead and delete the tool session + if ( log.isDebugEnabled()) + log.debug("Removing tool session for activity "+activity.getTitle()+" ("+activity.getActivityUIID()+")"); + + toolSessionDAO.removeToolSession(toolSession); + } + } + } + } + +// } + } + /** * Parses the groupings array sent from the WDDX packet. It will create * the groupings object (ChosenGrouping, RandomGrouping) so that when the @@ -510,7 +586,7 @@ // this means we don't have to manually remove the transition object. // Note: This will leave orphan content in the tool tables. It can be removed by the tool content cleaning job, // which may be run from the admin screen or via a cron job. - + learningDesign.getActivities().clear(); learningDesign.getActivities().addAll(newActivityMap.values()); @@ -1030,4 +1106,4 @@ return learner != null ? learner.getUserID() : null; } } - \ No newline at end of file + Index: lams_central/src/java/org/lamsfoundation/lams/authoring/authoringApplicationContext.xml =================================================================== RCS file: /usr/local/cvsroot/lams_central/src/java/org/lamsfoundation/lams/authoring/authoringApplicationContext.xml,v diff -u -r1.13.6.2 -r1.13.6.3 --- lams_central/src/java/org/lamsfoundation/lams/authoring/authoringApplicationContext.xml 21 Feb 2007 06:38:04 -0000 1.13.6.2 +++ lams_central/src/java/org/lamsfoundation/lams/authoring/authoringApplicationContext.xml 1 Mar 2007 23:57:42 -0000 1.13.6.3 @@ -32,6 +32,7 @@ + Index: lams_common/src/java/org/lamsfoundation/lams/tool/dao/IToolSessionDAO.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/tool/dao/IToolSessionDAO.java,v diff -u -r1.12 -r1.12.6.1 --- lams_common/src/java/org/lamsfoundation/lams/tool/dao/IToolSessionDAO.java 17 Sep 2006 06:14:17 -0000 1.12 +++ lams_common/src/java/org/lamsfoundation/lams/tool/dao/IToolSessionDAO.java 1 Mar 2007 23:57:20 -0000 1.12.6.1 @@ -66,6 +66,14 @@ */ public List getToolSessionsByLesson(final Lesson lesson); + /** + * Get the tool session by activity. A class-grouped activity should have only one tool session, + * per activity but a proper grouped activity or an individial activity may have more + * than one tool sesssion. + * @see org.lamsfoundation.lams.tool.dao.IToolSessionDAO#getToolSessionByActivity(org.lamsfoundation.lams.learningdesign.Activity) + * @returns List of toolSessions, may be of subclass NonGroupedToolSession or GroupedToolSession + */ + public List getToolSessionByActivity(final Activity activity); public void updateToolSession(ToolSession toolSession); } Index: lams_common/src/java/org/lamsfoundation/lams/tool/dao/hibernate/ToolSessionDAO.java =================================================================== RCS file: /usr/local/cvsroot/lams_common/src/java/org/lamsfoundation/lams/tool/dao/hibernate/ToolSessionDAO.java,v diff -u -r1.15 -r1.15.6.1 --- lams_common/src/java/org/lamsfoundation/lams/tool/dao/hibernate/ToolSessionDAO.java 17 Sep 2006 06:14:22 -0000 1.15 +++ lams_common/src/java/org/lamsfoundation/lams/tool/dao/hibernate/ToolSessionDAO.java 1 Mar 2007 23:57:20 -0000 1.15.6.1 @@ -49,6 +49,8 @@ protected static final String LOAD_GROUPED_TOOL_SESSION_BY_GROUP2 = "select s from GroupedToolSession as s inner join s.sessionGroup as sg inner join sg.users as u " +" where :learner = u and s.toolActivity = :activity"; + protected static final String LOAD_TOOL_SESSION_BY_ACTIVITY = + "from ToolSession s where s.toolActivity = :activity"; protected static final String LOAD_TOOL_SESSION_BY_LESSON = "from ToolSession s where s.lesson = :lesson"; @@ -88,6 +90,21 @@ } + /** + * Get the tool session by activity. A class-grouped activity should have only one tool session, + * per activity but a proper grouped activity or an individial activity may have more + * than one tool sesssion. + * @see org.lamsfoundation.lams.tool.dao.IToolSessionDAO#getToolSessionByActivity(org.lamsfoundation.lams.learningdesign.Activity) + * @returns List of toolSessions, may be of subclass NonGroupedToolSession or GroupedToolSession + */ + public List getToolSessionByActivity(final Activity activity) + { + Query query = this.getSession().createQuery(LOAD_TOOL_SESSION_BY_ACTIVITY); + query.setParameter("activity",activity); + return (List) query.list(); + } + + public void saveToolSession(ToolSession toolSession) { getHibernateTemplate().save(toolSession);