Fisheye: Tag fc76a4bb4e5abc614e15b642e4015295b2912c0a refers to a dead (removed) revision in file `lams_common/src/java/org/lamsfoundation/lams/util/FlashMessage.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag fc76a4bb4e5abc614e15b642e4015295b2912c0a refers to a dead (removed) revision in file `lams_common/src/java/org/lamsfoundation/lams/util/HashtableUtils.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag fc76a4bb4e5abc614e15b642e4015295b2912c0a refers to a dead (removed) revision in file `lams_common/src/java/org/lamsfoundation/lams/util/LDWDDXValueObjectFactory.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag fc76a4bb4e5abc614e15b642e4015295b2912c0a refers to a dead (removed) revision in file `lams_common/src/java/org/lamsfoundation/lams/util/LDWDDXValueObjectStorer.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag fc76a4bb4e5abc614e15b642e4015295b2912c0a refers to a dead (removed) revision in file `lams_common/src/java/org/lamsfoundation/lams/util/WDDXProcessor.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag fc76a4bb4e5abc614e15b642e4015295b2912c0a refers to a dead (removed) revision in file `lams_common/src/java/org/lamsfoundation/lams/util/WDDXProcessorConversionException.java'. Fisheye: No comparison available. Pass `N' to diff? Fisheye: Tag fc76a4bb4e5abc614e15b642e4015295b2912c0a refers to a dead (removed) revision in file `lams_common/src/java/org/lamsfoundation/lams/util/WDDXTAGS.java'. Fisheye: No comparison available. Pass `N' to diff? Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/FlashMessage.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/FlashMessage.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/FlashMessage.java (revision fc76a4bb4e5abc614e15b642e4015295b2912c0a) @@ -0,0 +1,107 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ +package org.lamsfoundation.lams.util.wddx; + +import java.io.Serializable; + +/** + * @author Manpreet Minhas + * This class represents the message sent by the server to the + * Flash client. + * + */ +public class FlashMessage implements Serializable { + + /** Message type indicating that operation was + * unsuccessful due to some error on FLASH side. + * For example the WDDX packet contains a null value + */ + public static final int ERROR = 1; + + /** + * Message type indicating that operation failed + * due to some system eror. For example, the client + * was unable to serilaize the WDDX packet + */ + public static final int CRITICAL_ERROR = 2; + + /** + * Message type indicating that operation + * was executed successfully + */ + public static final int OBJECT_MESSAGE = 3; + + /** Usually the name of the method that was called by the flash */ + private String messageKey; + + /** + * The response to the flash's request. Normally a string either + * stating the error message or the WDDX packet + */ + private Object messageValue; + + /** + * Represents the type of message being sent to Flash. Can be one of + * the following values + * + */ + private int messageType; + + /** Minimal Constructor */ + public FlashMessage(String messageKey, Object messageValue) { + this.messageKey = messageKey; + this.messageValue = messageValue; + this.messageType = OBJECT_MESSAGE; + } + /** Full Constructor*/ + public FlashMessage(String messageKey, Object messageValue, int messageType) { + this.messageKey = messageKey; + this.messageValue = messageValue; + this.messageType = messageType; + } + public String getMessageKey() { + return messageKey; + } + public int getMessageType() { + return messageType; + } + public Object getMessageValue() { + return messageValue; + } + /** + * Return String representation of the message that will be sent to flash. + * @see java.lang.Object#toString() + */ + public String toString() + { + StringBuffer sb = new StringBuffer(getClass().getName() + ": "); + sb.append("messageKey='" + getMessageKey() + "'; "); + sb.append("messageType='" + getMessageType()+"';"); + sb.append("messageValue='" + getMessageValue() + "'; "); + return sb.toString(); + } +} Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/HashtableUtils.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/HashtableUtils.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/HashtableUtils.java (revision fc76a4bb4e5abc614e15b642e4015295b2912c0a) @@ -0,0 +1,95 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ +package org.lamsfoundation.lams.util.wddx; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.Hashtable; +import java.util.Vector; + +/** + * @author Manpreet Minhas + */ +public class HashtableUtils { + + /* + * Takes a string (possibly null) and returns a not null string + */ + public static String getValue( String possValue ) + { + return ( possValue==null ? "" : possValue ); + } + + /* + * Takes a Long (possibly null) and returns a not null Long + */ + public static Long getIdLong ( Long possValue ) + { + return ( possValue==null ? WDDXTAGS.NUMERIC_NULL_VALUE_LONG : possValue ); + } + + /* + * Takes a Integer (possibly null) and returns a not null Integer + */ + public static Integer getIdInteger ( Integer possValue ) + { + return ( possValue==null ? WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER : possValue ); + } + + public static Date getIdDate(Date possValue){ + return (possValue==null? WDDXTAGS.DATE_NULL_VALUE : possValue); + } + + public static Boolean getBoolean(Boolean possValue){ + return (possValue==null?WDDXTAGS.BOOLEAN_NULL_VALUE : possValue); + } + + /** + * Helper function to retrieve dataset from Hashtable. As it is possible to + * receive object array inside a hashtable. Simply cast it to Collection + * will generate ClassCasting Exception. Therefore, we need to create this + * helper function. + * + * @param clientObj + * @param questionSet + * @return return vector of data + * @author Jacky Fang + */ + public static Vector getCollectionDataFromHashTable(String identifier,Hashtable clientObj) + { + Vector dataSet = new Vector(); + if(clientObj.get(identifier)instanceof Collection) + dataSet = (Vector)clientObj.get(identifier); + else if( clientObj.get(identifier)!=null) + dataSet.addAll(Arrays.asList((Object []) clientObj.get(identifier))); + return dataSet; + } + + + + + + + +} Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/LDWDDXValueObjectFactory.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/LDWDDXValueObjectFactory.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/LDWDDXValueObjectFactory.java (revision fc76a4bb4e5abc614e15b642e4015295b2912c0a) @@ -0,0 +1,645 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ +package org.lamsfoundation.lams.util.wddx; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; + +import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.ChosenGrouping; +import org.lamsfoundation.lams.learningdesign.ComplexActivity; +import org.lamsfoundation.lams.learningdesign.GateActivity; +import org.lamsfoundation.lams.learningdesign.Grouping; +import org.lamsfoundation.lams.learningdesign.GroupingActivity; +import org.lamsfoundation.lams.learningdesign.LearningDesign; +import org.lamsfoundation.lams.learningdesign.LearningLibrary; +import org.lamsfoundation.lams.learningdesign.OptionsActivity; +import org.lamsfoundation.lams.learningdesign.ParallelActivity; +import org.lamsfoundation.lams.learningdesign.PermissionGateActivity; +import org.lamsfoundation.lams.learningdesign.RandomGrouping; +import org.lamsfoundation.lams.learningdesign.ScheduleGateActivity; +import org.lamsfoundation.lams.learningdesign.SequenceActivity; +import org.lamsfoundation.lams.learningdesign.SynchGateActivity; +import org.lamsfoundation.lams.learningdesign.ToolActivity; +import org.lamsfoundation.lams.learningdesign.Transition; +import org.lamsfoundation.lams.learningdesign.dao.hibernate.ActivityDAO; +import org.lamsfoundation.lams.tool.Tool; +import org.lamsfoundation.lams.tool.dao.hibernate.ToolDAO; + + + + +/** + * @author Manpreet Minhas + * + * When sending a number as a value within a hashtable, we have to either put a proper + * value in the hashtable (ie not null) or leave out that tag all together. On the + * flash end, if we leave out the tag, it will return nothing when that tag is checked, + * but it won't cause an error. Therefore when sending ids, if the id doesn't exist + * (value is null), don't add that tag to the hashtable, and that tag will be left out + * of the packet. + */ +public class LDWDDXValueObjectFactory { + + static LDWDDXValueObjectFactory factory = null; + + protected ActivityDAO activityDAO; + protected ToolDAO toolDAO; + + public LDWDDXValueObjectFactory(){ + + } + /** + * Constructor + * + * @param activityDAO The activityDAO to set + * @param toolDAO The toolDAO to set + */ + public LDWDDXValueObjectFactory(ActivityDAO activityDAO,ToolDAO toolDAO){ + this.activityDAO = activityDAO; + this.toolDAO = toolDAO; + } + /** + * @return LDWDDXValueObjectFactory Returns an instance of LDWDDXValueObjectFactory + */ + public static LDWDDXValueObjectFactory getInstance() + { + return (factory==null? new LDWDDXValueObjectFactory():factory); + } + + /** + * Returns the list of all Learning Libraries + * @param learningLibraries List of Learning Libraries + * @return Hashtable + */ + public Hashtable requestLearningLibraryList(Collection learningLibraries){ + Hashtable libraryList = new Hashtable(); + + libraryList.put(WDDXTAGS.OBJECT_TYPE,LearningLibrary.LIBRARY_LIST_OBJECT); + libraryList.put(WDDXTAGS.TITLE,"Learning Libraries"); + libraryList.put(WDDXTAGS.DESCRIPTION,"All available system libraries"); + + Vector libraries = new Vector(); + if(learningLibraries!=null){ + Iterator iter = learningLibraries.iterator(); + while(iter.hasNext()){ + LearningLibrary library = (LearningLibrary)iter.next(); + Hashtable output = buildLearningLibraryObject(library); + libraries.add(output); + } + } + libraryList.put(WDDXTAGS.LIB_PACKAGE,libraries); + return libraryList; + } + + /** + * Converts the LearningLibrary object into Hashtable + * with Key as the attribute_name and value as value as + * the attribute_value from the underlying database + * + * @param library The LearningLibrary to be converted + * @return Hashtable + */ + private Hashtable buildLearningLibraryObject(LearningLibrary library){ + Hashtable libraries = new Hashtable(); + + Long libraryID = library.getLearningLibraryId(); + + libraries.put(WDDXTAGS.LEARNING_LIBRARY_ID,libraryID); + + libraries.put(WDDXTAGS.DESCRIPTION, + (library.getDescription()!=null?library.getDescription():WDDXTAGS.STRING_NULL_VALUE)); + + libraries.put(WDDXTAGS.TITLE, + (library.getTitle()!=null?library.getTitle():WDDXTAGS.STRING_NULL_VALUE)); + + libraries.put(WDDXTAGS.CREATION_DATE, + (library.getCreateDateTime()!=null?library.getCreateDateTime():WDDXTAGS.DATE_NULL_VALUE)); + + Collection coll = activityDAO.getActivitiesByLibraryID(libraryID); + Vector templateActivities = new Vector(); + if(coll!=null){ + Iterator iter = coll.iterator(); + while (iter.hasNext()){ + Object object = iter.next(); + Hashtable output = buildActivityObject(object); + addAuthoringURLS(object,output); + templateActivities.add(output); + } + } + libraries.put(WDDXTAGS.LIB_ACTIVITIES,templateActivities); + return libraries; + } + + /** + * In case the activity object is of type ToolActivity, + * this function adds tool specific information required by the + * authoring enviornment such as Tool's Authoring Url's. + * + * @param activity The activity object to be parsed + * @param output The hashtable to be updated + */ + private void addAuthoringURLS(Object activity,Hashtable output){ + if (activity.getClass().getName().equals("org.lamsfoundation.lams.learningdesign.ToolActivity")){ + ToolActivity toolActivity = (ToolActivity)activity; + Tool tool =toolActivity.getTool(); + Hashtable toolOutput = buildToolObject(tool); + output.put(WDDXTAGS.AUTH_URL,toolOutput); + } + + } + /** + * Converts the Tool object into Hashtable + * with Key as the attribute_name and value as value as + * the attribute_value from the underlying database + * + * @param tool The Tool to be converted + * @return Hashtable + */ + private Hashtable buildToolObject(Tool tool){ + Hashtable table = new Hashtable(); + table.put(WDDXTAGS.OBJECT_TYPE,"Tool"); + table.put(WDDXTAGS.TOOL_ID,tool.getToolId()); + table.put(WDDXTAGS.TOOL_DISPLAY_NAME,tool.getToolDisplayName()); + table.put(WDDXTAGS.TOOl_AUTH_URL,tool.getAuthorUrl()); + return table; + } + /** + * Determines the type of activity and adds + * activity specific attributes + * + * @param activities + * @param activity + */ + private void processActivityType(Hashtable activities, Object activity){ + String className = activity.getClass().getName(); + if(activity instanceof GroupingActivity) + buildGroupingActivityObject(activities,activity); + else if(activity instanceof ToolActivity) + buildToolActivity(activities,(ToolActivity)activity); + else if(activity instanceof GateActivity) + buildGateActivityObject(activities,activity); + else + buildComplexActivityObject(activities,activity); + } + + /** + * Converts the Activity object into Hashtable + * with Key as the attribute_name and value as value as + * the attribute_value from the underlying database + * + * @param objActivity The object to be converted + * @return Hashtable + */ + private Hashtable buildActivityObject(Object objActivity){ + Hashtable activities = new Hashtable(); + + activities.put(WDDXTAGS.OBJECT_TYPE,"Activity"); + + processActivityType(activities,objActivity); + + Activity activity =(Activity)objActivity; + + activities.put(WDDXTAGS.ACTIVITY_ID,activity.getActivityId()); + + activities.put(WDDXTAGS.ACTIVITY_UIID, + (activity.getActivityUIID()!=null?activity.getActivityUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + activities.put(WDDXTAGS.DESCRIPTION, + (activity.getDescription()!=null?activity.getDescription():WDDXTAGS.STRING_NULL_VALUE)); + + activities.put(WDDXTAGS.TITLE, + (activity.getTitle()!=null?activity.getTitle():WDDXTAGS.STRING_NULL_VALUE)); + + activities.put(WDDXTAGS.HELP_TEXT, + (activity.getHelpText()!=null?activity.getHelpText():WDDXTAGS.STRING_NULL_VALUE)); + + activities.put(WDDXTAGS.XCOORD, + (activity.getXcoord()!=null?activity.getXcoord():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + activities.put(WDDXTAGS.YCOORD, + (activity.getYcoord()!=null?activity.getYcoord():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + activities.put(WDDXTAGS.PARENT_ACTIVITY_ID, + (activity.getParentActivity()!=null?activity.getParentActivity().getActivityId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + activities.put(WDDXTAGS.PARENT_UIID, + (activity.getParentActivity()!=null?activity.getParentActivity().getActivityUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + activities.put(WDDXTAGS.ACTIVITY_TYPE_ID, + (activity.getActivityTypeId()!=null?activity.getActivityTypeId():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + activities.put(WDDXTAGS.GROUPING_ID, + (activity.getGrouping()!=null?activity.getGrouping().getGroupingId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + activities.put(WDDXTAGS.GROUPING_UIID, + (activity.getGrouping()!=null?activity.getGrouping().getGroupingUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + activities.put(WDDXTAGS.DEFINE_LATER,activity.getDefineLater()); + + activities.put(WDDXTAGS.RUN_OFFLINE,activity.getRunOffline()); + + activities.put(WDDXTAGS.LEARNING_DESIGN_ID, + (activity.getLearningDesign()!=null?activity.getLearningDesign().getLearningDesignId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + activities.put(WDDXTAGS.LEARNING_LIBRARY_ID, + (activity.getLearningLibrary()!=null?activity.getLearningLibrary().getLearningLibraryId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + if(activity.getCreateDateTime()!=null) + activities.put(WDDXTAGS.CREATION_DATE,activity.getCreateDateTime()); + + activities.put(WDDXTAGS.OFFLINE_INSTRUCTIONS, + (activity.getOfflineInstructions()!=null?activity.getOfflineInstructions():WDDXTAGS.STRING_NULL_VALUE)); + + if(activity.getLibraryActivityUiImage()!=null) + activities.put(WDDXTAGS.LIBRARY_IMAGE,activity.getLibraryActivityUiImage()); + + activities.put(WDDXTAGS.LIBRARY_ACTIVITY, + (activity.getLibraryActivity()!=null?activity.getLibraryActivity().getActivityId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + return activities; + } + /** + * This function populates the hashtable to be sent to FLASH + * with all the information realted to the GroupingActivity. + * A GroupingActivity is always associated with Grouping + * (Chosen or Random)so it includes that information as well. + * + * @param activities + * @param activity + */ + private void buildGroupingActivityObject(Hashtable activities, Object activity){ + + GroupingActivity groupingActivity = (GroupingActivity)activity; + Grouping grouping = groupingActivity.getCreateGrouping(); + Integer groupingType = grouping.getGroupingTypeId(); + + Hashtable groupingTable = null; + if(groupingType==Grouping.CHOSEN_GROUPING_TYPE) + groupingTable = addChosenGroupingAttributes((ChosenGrouping)grouping); + else + groupingTable = addRandomGroupingAttributes((RandomGrouping)grouping); + + groupingTable.put(WDDXTAGS.MAX_NUMBER_OF_GROUPS,grouping.getMaxNumberOfGroups()); + groupingTable.put(WDDXTAGS.GROUPING_UIID,grouping.getGroupingUIID()); + + activities.put(WDDXTAGS.CREATE_GROUPING_ID,grouping.getGroupingId()); + activities.put(WDDXTAGS.CREATE_GROUPING_UIID,grouping.getGroupingUIID()); + activities.put(WDDXTAGS.GROUPING,groupingTable); + + + } + /** + * As of now there are no additional attributes defined for + * ChosenGrouping, so leaving this function blank. More attributes + * would be added later on + * + * @param chosenGrouping The Grouping object whose values have to be + * populated into the hashtable + * @return Hashtable The populated hashtable to be passed on to FLASH + */ + private Hashtable addChosenGroupingAttributes(ChosenGrouping chosenGrouping){ + return new Hashtable(); + } + /** + * This function adds RandomGrouping specific attributes to the + * hashtable to be passed on to FLASH + * + * @param randomGrouping The Grouping object whose values have to be + * populated into the hashtable + * @return Hashtable The populated hashtable to be passed on to FLASH + */ + private Hashtable addRandomGroupingAttributes(RandomGrouping randomGrouping){ + Hashtable groupingTable = new Hashtable(); + groupingTable.put(WDDXTAGS.NUMBER_OF_GROUPS,randomGrouping.getNumberOfGroups()); + groupingTable.put(WDDXTAGS.LEARNERS_PER_GROUP,randomGrouping.getLearnersPerGroup()); + return groupingTable; + } + + + /** + * Adds ToolActivity specific attributes + * @param activities + * @param toolActivity + */ + private void buildToolActivity(Hashtable activities, ToolActivity toolActivity){ + + activities.put(WDDXTAGS.ORDER_ID, + (toolActivity.getOrderId()!=null?toolActivity.getOrderId():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + if(toolActivity.getTool()!=null) + activities.put(WDDXTAGS.TOOL_ID,toolActivity.getTool().getToolId()); + if(toolActivity.getToolContentId()!=null) + activities.put(WDDXTAGS.TOOL_CONTENT_ID,toolActivity.getToolContentId()); + } + /** + * Adds OptionsActivity specific attributes + * @param activities + * @param optActivity + */ + private void buildOptionsActivityObject(Hashtable activities, OptionsActivity optActivity){ + + if(optActivity.getMaxNumberOfOptions()!=null) + activities.put(WDDXTAGS.MAX_OPTIONS,optActivity.getMaxNumberOfOptions()); + + if(optActivity.getMinNumberOfOptions()!=null) + activities.put(WDDXTAGS.MIN_OPTIONS,optActivity.getMinNumberOfOptions()); + + activities.put(WDDXTAGS.OPTIONS_INSTRUCTIONS, + (optActivity.getOptionsInstructions()!=null?optActivity.getOptionsInstructions():WDDXTAGS.STRING_NULL_VALUE)); + + Iterator iter = optActivity.getActivities().iterator(); + addChildActivities(activities,iter); + } + /** + * TODO As of now SequenceActivity has no additional attributes of its own. + * So leaving this function empty for now. In case it is decided that + * this activity will have no additional attributes, we have to get rid + * of this function + * + * @param activities + * @param sequenceActivity + */ + private void buildSequenceActivityObject(Hashtable activities,SequenceActivity sequenceActivity){ + + } + + /** + * TODO As of now ParallelActivity has no additional attributes of its own. + * So leaving this function empty for now. In case it is decided that + * this activity will have no additional attributes, we have to get rid + * of this function + * + * @param activities + * @param parallelActivity + */ + private void buildParallelActivityObject(Hashtable activities,ParallelActivity parallelActivity){ + + } + /** + * Adds ScheduleGateActivity specific attributes + * @param activities + * @param schActivity + */ + private void buildScheduleGateActivityObject(Hashtable activities, ScheduleGateActivity schActivity){ + + if(schActivity.getGateEndTimeOffset()!=null) + activities.put(WDDXTAGS.GATE_END_OFFSET,schActivity.getGateEndTimeOffset()); + + if(schActivity.getGateStartTimeOffset()!=null) + activities.put(WDDXTAGS.GATE_START_OFFSET,schActivity.getGateStartTimeOffset()); + + activities.put(WDDXTAGS.GATE_END_DATE, + (schActivity.getGateEndDateTime()!=null?schActivity.getGateEndDateTime():WDDXTAGS.DATE_NULL_VALUE)); + + activities.put(WDDXTAGS.GATE_START_DATE, + (schActivity.getGateStartDateTime()!=null?schActivity.getGateStartDateTime():WDDXTAGS.DATE_NULL_VALUE)); + } + /** + * Adds GateActivity specific attributes + * @param activities + * @param activity + */ + private void buildGateActivityObject(Hashtable activities, Object activity){ + + if(activity instanceof PermissionGateActivity) + buildPermissionGateActivityObject(activities,(PermissionGateActivity)activity); + else if(activity instanceof SynchGateActivity) + buildSynchGateActivityObject(activities,(SynchGateActivity)activity); + else + buildScheduleGateActivityObject(activities,(ScheduleGateActivity)activity); + + GateActivity gateActivity = (GateActivity)activity; + + activities.put(WDDXTAGS.GATE_ACTIVITY_LEVEL_ID, + (gateActivity.getGateActivityLevelId()!=null?gateActivity.getGateActivityLevelId():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + activities.put(WDDXTAGS.GATE_OPEN, + (gateActivity.getGateOpen()!=null?gateActivity.getGateOpen():WDDXTAGS.BOOLEAN_NULL_VALUE)); + } + private void buildPermissionGateActivityObject(Hashtable activities,PermissionGateActivity permissionGateActivity){ + + } + private void buildSynchGateActivityObject(Hashtable activities,SynchGateActivity synchGateActivity){ + + } + + /** + * Adds ComplexActivity specific attributes + * @param activities + * @param activity + */ + private void buildComplexActivityObject(Hashtable activities, Object activity){ + + if(activity instanceof OptionsActivity) + buildOptionsActivityObject(activities,(OptionsActivity)activity); + else if(activity instanceof SequenceActivity) + buildSequenceActivityObject(activities,(SequenceActivity)activity); + else + buildParallelActivityObject(activities,(ParallelActivity)activity); + + ComplexActivity complexActivity = (ComplexActivity)activity; + Iterator iter = complexActivity.getActivities().iterator(); + addChildActivities(activities,iter); + } + /** + * @param activities + * @param iter + */ + private void addChildActivities(Hashtable activities,Iterator iter){ + Vector childActivities = new Vector(); + while(iter.hasNext()){ + Object object = iter.next(); + childActivities.add(buildActivityObject(object)); + } + activities.put(WDDXTAGS.CHILD_ACTIVITIES,childActivities); + } + /** + * Converts the Transition object into Hashtable + * with Key as the attribute_name and value as value as + * the attribute_value from the underlying database + * + * @param trans + * @return Hashtable + */ + private Hashtable buildTransitionObject(Transition trans){ + Hashtable transitions = new Hashtable(); + + transitions.put(WDDXTAGS.TRANSITION_ID,trans.getTransitionId()); + + transitions.put(WDDXTAGS.TRANSITION_UIID, + (trans.getTransitionUIID()!=null?trans.getTransitionUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + if(trans.getDescription()!=null) + transitions.put(WDDXTAGS.DESCRIPTION,trans.getDescription()); + + if(trans.getTitle()!=null) + transitions.put(WDDXTAGS.TITLE,trans.getTitle()); + + transitions.put(WDDXTAGS.TRANSITION_TO, + (trans.getToActivity()!=null?trans.getToActivity().getActivityId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + transitions.put(WDDXTAGS.TRANSITION_FROM, + (trans.getFromActivity()!=null?trans.getFromActivity().getActivityId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + transitions.put(WDDXTAGS.LEARNING_DESIGN_ID, + (trans.getLearningDesign()!=null?trans.getLearningDesign().getLearningDesignId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + if(trans.getCreateDateTime()!=null) + transitions.put(WDDXTAGS.CREATION_DATE,trans.getCreateDateTime()); + + transitions.put(WDDXTAGS.TO_ACTIVITY_UIID, + (trans.getToUIID()!=null?trans.getToUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + transitions.put(WDDXTAGS.FROM_ACTIVITY_UIID, + (trans.getFromUIID()!=null?trans.getFromUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + return transitions; + } + + /** + * Returns the list of all availabe Learning Designs + * @param learningDesigns + * @return Hashtable + */ + public Hashtable requestLearningDesignList(Collection learningDesigns){ + Hashtable designList = new Hashtable(); + + designList.put(WDDXTAGS.OBJECT_TYPE,"LearningDesignList"); + designList.put(WDDXTAGS.TITLE,"Learning Designs"); + designList.put(WDDXTAGS.DESCRIPTION,"All available Learning Designs"); + + Vector designs = new Vector(); + if(learningDesigns!=null){ + Iterator iter = learningDesigns.iterator(); + while(iter.hasNext()){ + LearningDesign design = (LearningDesign)iter.next(); + Hashtable output = buildLearningDesignObject(design); + designs.add(output); + } + } + designList.put(WDDXTAGS.DESIGN_PACKAGE,designs); + return designList; + } + /** + * Converts the LearningDesign object into Hashtable + * with Key as the attribute_name and value as value as + * the attribute_value from the underlying database + * + * @param design The LearningDesign to be converted + * @return Hashtable + */ + public Hashtable buildLearningDesignObject(LearningDesign design){ + Hashtable designs = new Hashtable(); + + designs.put(WDDXTAGS.OBJECT_TYPE,LearningDesign.DESIGN_OBJECT); + + designs.put(WDDXTAGS.LEARNING_DESIGN_ID, + (design.getLearningDesignId()!=null?design.getLearningDesignId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + designs.put(WDDXTAGS.LEARNING_DESIGN_UIID, + (design.getLearningDesignUIID()!=null?design.getLearningDesignUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + designs.put(WDDXTAGS.DESCRIPTION, + (design.getDescription()!=null?design.getDescription():WDDXTAGS.STRING_NULL_VALUE)); + + designs.put(WDDXTAGS.TITLE, + (design.getTitle()!=null?design.getTitle():WDDXTAGS.STRING_NULL_VALUE)); + + designs.put(WDDXTAGS.FIRST_ACTIVITY_ID, + (design.getFirstActivity()!=null?design.getFirstActivity().getActivityId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + designs.put(WDDXTAGS.FIRST_ACTIVITY_UIID, + (design.getFirstActivity()!=null?design.getFirstActivity().getActivityUIID():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + designs.put(WDDXTAGS.MAX_ID, + (design.getMaxId()!=null?design.getMaxId():WDDXTAGS.NUMERIC_NULL_VALUE_INTEGER)); + + designs.put(WDDXTAGS.VALID_DESIGN,design.getValidDesign()); + + designs.put(WDDXTAGS.READ_ONLY,design.getReadOnly()); + + if(design.getDateReadOnly()!=null) + designs.put(WDDXTAGS.DATE_READ_ONLY,design.getDateReadOnly()); + + designs.put(WDDXTAGS.USER_ID,design.getUser().getUserId()); + + + designs.put(WDDXTAGS.HELP_TEXT, + (design.getHelpText()!=null?design.getHelpText():WDDXTAGS.STRING_NULL_VALUE)); + + designs.put(WDDXTAGS.VERSION, + (design.getVersion()!=null?design.getVersion():WDDXTAGS.STRING_NULL_VALUE)); + + designs.put(WDDXTAGS.PARENT_DESIGN_ID, + (design.getParentLearningDesign()!=null?design.getParentLearningDesign().getLearningDesignId():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + designs.put(WDDXTAGS.WORKSPACE_FOLDER_ID,design.getWorkspaceFolder().getWorkspaceFolderId()); + + designs.put(WDDXTAGS.DURATION, + (design.getDuration()!=null?design.getDuration():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + designs.put(WDDXTAGS.LICENCE_ID, + (design.getLicense()!=null?design.getLicense().getLicenseID():WDDXTAGS.NUMERIC_NULL_VALUE_LONG)); + + designs.put(WDDXTAGS.LICENSE_TEXT, + (design.getLicenseText()!=null?design.getLicenseText():WDDXTAGS.STRING_NULL_VALUE)); + + Collection coll = design.getActivities(); + HashSet parentActivities = new HashSet(); + Iterator iter =null; + if(coll!=null){ + iter = coll.iterator(); + while (iter.hasNext()){ + Activity activity = (Activity)iter.next(); + if(activity.getParentActivity()==null){ + parentActivities.add(activity); + } + } + } + iter = parentActivities.iterator(); + Vector activities = new Vector(); + while(iter.hasNext()){ + Object object = iter.next(); + Hashtable output = buildActivityObject(object); + activities.add(output); + } + designs.put(WDDXTAGS.ACTIVITIES,activities); + + coll = design.getTransitions(); + Vector transitions = new Vector(); + if(coll!=null){ + iter = coll.iterator(); + while (iter.hasNext()){ + Transition trans =(Transition) iter.next(); + Hashtable output = buildTransitionObject(trans); + transitions.add(output); + } + } + designs.put(WDDXTAGS.TRANSITIONS,transitions); + + return designs; + } +} Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/LDWDDXValueObjectStorer.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/LDWDDXValueObjectStorer.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/LDWDDXValueObjectStorer.java (revision fc76a4bb4e5abc614e15b642e4015295b2912c0a) @@ -0,0 +1,832 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ +package org.lamsfoundation.lams.util.wddx; + + +import java.util.Date; +import java.util.HashSet; +import java.util.Hashtable; +import java.util.Iterator; +import java.util.Vector; + +import org.lamsfoundation.lams.learningdesign.Activity; +import org.lamsfoundation.lams.learningdesign.ChosenGrouping; +import org.lamsfoundation.lams.learningdesign.ComplexActivity; +import org.lamsfoundation.lams.learningdesign.GateActivity; +import org.lamsfoundation.lams.learningdesign.Grouping; +import org.lamsfoundation.lams.learningdesign.GroupingActivity; +import org.lamsfoundation.lams.learningdesign.LearningDesign; +import org.lamsfoundation.lams.learningdesign.LearningLibrary; +import org.lamsfoundation.lams.learningdesign.License; +import org.lamsfoundation.lams.learningdesign.OptionsActivity; +import org.lamsfoundation.lams.learningdesign.ParallelActivity; +import org.lamsfoundation.lams.learningdesign.PermissionGateActivity; +import org.lamsfoundation.lams.learningdesign.RandomGrouping; +import org.lamsfoundation.lams.learningdesign.ScheduleGateActivity; +import org.lamsfoundation.lams.learningdesign.SequenceActivity; +import org.lamsfoundation.lams.learningdesign.SynchGateActivity; +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.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.tool.Tool; +import org.lamsfoundation.lams.tool.dao.hibernate.ToolDAO; +import org.lamsfoundation.lams.usermanagement.User; +import org.lamsfoundation.lams.usermanagement.WorkspaceFolder; +import org.lamsfoundation.lams.usermanagement.dao.hibernate.UserDAO; +import org.lamsfoundation.lams.usermanagement.dao.hibernate.WorkspaceFolderDAO; +/** + * @author Manpreet Minhas + * + * This class is used to save the WDDX information into the Database. + * The WDDX packet sent by FLASH mainly consists of information stored + * in key-value pairs in a Hashtable. We check the existence of a + * particular key and if present we populate the corresponding object + * with its value and then finally persist into the database. + * + */ +public class LDWDDXValueObjectStorer { + + static LDWDDXValueObjectStorer storer = null; + protected UserDAO userDAO = null; + protected LearningDesignDAO learningDesignDAO = null; + protected ActivityDAO activityDAO =null; + protected WorkspaceFolderDAO workspaceFolderDAO = null; + protected LearningLibraryDAO learningLibraryDAO = null; + protected LicenseDAO licenseDAO; + protected GroupingDAO groupingDAO; + protected ToolDAO toolDAO; + + public LDWDDXValueObjectStorer(){ + + } + + public LDWDDXValueObjectStorer(LearningDesignDAO learningDesignDAO,LearningLibraryDAO learningLibraryDAO, UserDAO userDAO, ActivityDAO activityDAO,WorkspaceFolderDAO workspaceFolderDAO,LicenseDAO licenseDAO,GroupingDAO groupingDAO){ + this.learningDesignDAO = learningDesignDAO; + this.learningLibraryDAO = learningLibraryDAO; + this.userDAO = userDAO; + this.activityDAO = activityDAO; + this.workspaceFolderDAO = workspaceFolderDAO; + this.licenseDAO = licenseDAO; + this.groupingDAO = groupingDAO; + } + /** + * @return LDWDDXValueObjectStorer Instance of LDWDDXValueObjectStorer + */ + public static LDWDDXValueObjectStorer getInstance() + { + return (storer==null? new LDWDDXValueObjectStorer():storer); + } + + /** + * This function creates a new LearningDesign object or updates + * and existing design depending upon the information provided by FLASH + * and persists it in the database. + * + * @param table Hashtable populated with data from the WDDX packet + * @return Long learning_design_id of the design updated/saved + */ + public Long processLearningDesign(Hashtable table)throws Exception{ + Long learning_design_id = null; + Long oldDesignID=null; + LearningDesign learningDesign = null; + boolean update = false; + /* + * If the hastable already contains the key LEARNING_DESIGN_ID + * this means its a request to update an existing design otherwise + * it is a request to store a new LearningDesign + * */ + if(table.containsKey(WDDXTAGS.LEARNING_DESIGN_ID)){ + update = true; + learning_design_id = WDDXProcessor.convertToLong("learning_design_id",table.get(WDDXTAGS.LEARNING_DESIGN_ID)); + learningDesign = learningDesignDAO.getLearningDesignById(learning_design_id); + if(learningDesign==null) + throw new Exception("Learning Design with the given learning_design_id " + + learning_design_id + " doesn't exists. Update Failed!!"); + + }else + learningDesign = new LearningDesign(); + + boolean readOnly = (WDDXProcessor.convertToBoolean("readOnly",table.get(WDDXTAGS.READ_ONLY))).booleanValue(); + if(readOnly){ + throw new Exception("This design is locked, you cannot save or update it.\n" + + "Please click on File | Save as... and rename it to save it"); + } + if(!table.containsKey(WDDXTAGS.FIRST_ACTIVITY_UIID)) + throw new Exception("Mandatory Field first_id is missing"); + + Integer firstID = WDDXProcessor.convertToInteger("first_activity_ui_id",table.get(WDDXTAGS.FIRST_ACTIVITY_UIID)); + + updateLearningDesign(table,learningDesign); + if(update){ + learningDesignDAO.update(learningDesign); + } + else{ + learningDesignDAO.insert(learningDesign); + updateDesignActivities(table,learningDesign); + } + /** The first activity of the design would be calculated only if + * it is a valid design */ + if(learningDesign.getValidDesign().booleanValue()) + calculateFirstActivity(firstID,learningDesign); + return learningDesign.getLearningDesignId(); + } + /** + * This function updates the LearningDesign object with activity information + * from the FLASH. + * + * @param table The Hashtable containing the information populated by FLASH + * @param learningDesign The LearningDesign object to be updated + * @throws Exception + */ + private void updateDesignActivities(Hashtable table,LearningDesign learningDesign)throws Exception{ + Vector activities =(Vector)table.get(WDDXTAGS.ACTIVITIES); + Iterator iter = activities.iterator(); + HashSet designActivities = new HashSet(); + while(iter.hasNext()){ + Hashtable activity =(Hashtable)iter.next(); + activity.put(WDDXTAGS.LEARNING_DESIGN_ID,learningDesign.getLearningDesignId()); + designActivities.add(processActivity(activity,learningDesign)); + } + learningDesign.setActivities(designActivities); + learningDesignDAO.update(learningDesign); + } + /** + * This method compares the first_id sent by the Flash to the + * one calculated manually by the server. If everything goes well + * both these should be the same but if there is a conflict an + * exception is thrown. + * + * @param firstID The activity_ui_id of the first activity sent by flash + * @param design The design for whome the first activity is being calculated + * @throws Exception + */ + private void calculateFirstActivity(Integer firstID, LearningDesign design)throws Exception{ + Activity flashFirstActivity = activityDAO.getActivityByUIID(firstID,design); + Activity designFirstActivity = design.calculateFirstActivity(); + if(flashFirstActivity.getActivityId()!=designFirstActivity.getActivityId()) + throw new Exception ("First Activity Conflict. We have two first activities here"); + design.setFirstActivity(flashFirstActivity); + } + private void updateDesignTransitions(Hashtable table,LearningDesign learningDesign)throws Exception{ + if(table.containsKey(WDDXTAGS.TRANSITIONS)){ + Vector transitions = (Vector)table.get(WDDXTAGS.TRANSITIONS); + Iterator iter = transitions.iterator(); + HashSet designTransitions = new HashSet(); + while(iter.hasNext()){ + Hashtable transition = (Hashtable)iter.next(); + transition.put(WDDXTAGS.LEARNING_DESIGN_ID,learningDesign.getLearningDesignId()); + designTransitions.add((transition)); + } + learningDesign.setTransitions(designTransitions); + learningDesignDAO.update(learningDesign); + } + + } + /** + * This method uses the Hashtable passed as an argument to build + * and populate a new Transition object. This hashtable is populated + * at the Flash side and all we have to do is iterate through it and + * set the values for the Transition object. If any of the values being + * passed by the Flash side are inconsistent with the database or + * any of the mandatory fields is missing an Exception is thrown + * + * @param table The Hashtable containing the information populated by FLASH + * @return Transition The populated Transition object + * @throws Exception + */ + private Transition processTransitionObject(Hashtable table)throws Exception{ + Transition transition = new Transition(); + + if(table.containsKey(WDDXTAGS.TRANSITION_UIID)) + transition.setTransitionUIID(WDDXProcessor.convertToInteger("transition_ui_id",table.get(WDDXTAGS.TRANSITION_UIID))); + + if(table.containsKey(WDDXTAGS.DESCRIPTION)) + transition.setDescription((String)table.get(WDDXTAGS.DESCRIPTION)); + + if(table.containsKey(WDDXTAGS.TITLE)) + transition.setTitle((String)WDDXTAGS.TITLE); + + if(table.containsKey(WDDXTAGS.TRANSITION_TO)){ + Long activityID = WDDXProcessor.convertToLong("to_activity_id",table.get(WDDXTAGS.TRANSITION_TO)); + Activity activity = activityDAO.getActivityByActivityId(activityID); + if(activity!=null) + transition.setToActivity(activity); + else + throw new Exception("Error setting to_activity_id. No activity with an activity_id of " + activityID + " exists"); + } + if(table.containsKey(WDDXTAGS.TRANSITION_FROM)){ + Long activityID = WDDXProcessor.convertToLong("from_activity_id",table.get(WDDXTAGS.TRANSITION_FROM)); + Activity activity = activityDAO.getActivityByActivityId(activityID); + if(activity!=null) + transition.setFromActivity(activity); + else + throw new Exception("Error setting from_activity_id. No activity with an activity_id of " + activityID + " exists"); + } + if(table.containsKey(WDDXTAGS.CREATION_DATE)) + transition.setCreateDateTime((Date)table.get(WDDXTAGS.CREATION_DATE)); + + if(table.containsKey(WDDXTAGS.TO_ACTIVITY_UIID)) + transition.setToUIID(WDDXProcessor.convertToInteger("to_activity_ui_id",table.get(WDDXTAGS.TO_ACTIVITY_UIID))); + + if(table.containsKey(WDDXTAGS.FROM_ACTIVITY_UIID)) + transition.setFromUIID(WDDXProcessor.convertToInteger("from_activity_ui_id",table.get(WDDXTAGS.FROM_ACTIVITY_UIID))); + + return transition; + + } + /** + * This method uses the Hashtable passed as an argument to update + * the learningDesign object. This hashtable is populated + * at the Flash side and all we have to do is iterate through it and + * set the values for the LearningDesign object. If any of the values being + * passed by the Flash side are inconsistent with the database or any of the + * mandatory fields is missing an Exception is thrown. + * + * @param table The Hashtable parsed from the WDDX string + * @param design The LearningDesign object to be updated/populated + * @throws Exception + */ + public void updateLearningDesign(Hashtable table, LearningDesign design) throws Exception{ + try{ + + if(table.containsKey(WDDXTAGS.LEARNING_DESIGN_UIID)) + design.setLearningDesignUIID(WDDXProcessor.convertToInteger("learning_design_ui_id",table.get(WDDXTAGS.LEARNING_DESIGN_UIID))); + + if(table.containsKey(WDDXTAGS.TITLE)) + design.setTitle((String)table.get(WDDXTAGS.TITLE)); + + if(table.containsKey(WDDXTAGS.DESCRIPTION)) + design.setDescription((String)table.get(WDDXTAGS.DESCRIPTION)); + + if(table.containsKey(WDDXTAGS.FIRST_ACTIVITY_ID)){ + Long firstActivityID = WDDXProcessor.convertToLong("first_activity_id",table.get(WDDXTAGS.FIRST_ACTIVITY_ID)); + Activity activity = activityDAO.getActivityByActivityId(firstActivityID); + if(activity==null) + throw new Exception("No activity with an activity_id: " + WDDXTAGS.FIRST_ACTIVITY_ID + " exists."); + design.setFirstActivity(activity); + } + + if(table.containsKey(WDDXTAGS.VERSION)) + design.setVersion((String)table.get(WDDXTAGS.VERSION)); + else + throw new Exception("Mandatory field version is missing for LearningDesign in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.MAX_ID)) + design.setMaxId(WDDXProcessor.convertToInteger("max_id",table.get(WDDXTAGS.MAX_ID))); + + if(table.containsKey(WDDXTAGS.VALID_DESIGN)) + design.setValidDesign(WDDXProcessor.convertToBoolean("valid_design_flag",table.get(WDDXTAGS.VALID_DESIGN))); + else + throw new Exception("Mandatory field valid_design_flag is missing for LearningDesign in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.READ_ONLY)) + design.setReadOnly(WDDXProcessor.convertToBoolean("read_only_flag",table.get(WDDXTAGS.READ_ONLY))); + else + throw new Exception("Mandatory field read_only_flag is missing for LearningDesign in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.DATE_READ_ONLY)) + design.setDateReadOnly((Date)table.get(WDDXTAGS.DATE_READ_ONLY)); + + if(table.containsKey(WDDXTAGS.HELP_TEXT)) + design.setHelpText((String)table.get(WDDXTAGS.HELP_TEXT)); + + if(table.containsKey(WDDXTAGS.COPY_TYPE)) + design.setCopyTypeID(WDDXProcessor.convertToInteger("copy_type",table.get(WDDXTAGS.COPY_TYPE))); + else + throw new Exception("Mandatory field copy_type is missing for LearningDesign in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.CREATION_DATE)) + design.setCreateDateTime((Date)table.get(WDDXTAGS.CREATION_DATE)); + else + throw new Exception("Mandatory field create_date_time is missing for LearningDesign in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.USER_ID)){ + Integer userId = WDDXProcessor.convertToInteger("user_id",table.get(WDDXTAGS.USER_ID)); + User user = userDAO.getUserById(userId); + if(user==null) + throw new Exception("No user with a user_id: " + WDDXTAGS.USER_ID + " exists."); + design.setUser(user); + }else + throw new Exception("Mandatory Field user_id is missing for LearningDesign in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.WORKSPACE_FOLDER_ID)){ + Integer workspaceFolderID = WDDXProcessor.convertToInteger("workspace_folder_id",table.get(WDDXTAGS.WORKSPACE_FOLDER_ID)); + WorkspaceFolder workspaceFolder = workspaceFolderDAO.getWorkspaceFolderByID(workspaceFolderID); + if(workspaceFolder==null) + throw new Exception("No workspaceFolder with a with workspace_folder_id: " + WDDXTAGS.WORKSPACE_FOLDER_ID + " exists."); + design.setWorkspaceFolder(workspaceFolder); + + }else + throw new Exception("Mandatory Field workspace_folder_id is missing for LearningDesign in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.PARENT_DESIGN_ID)){ + Long parentDesignID = WDDXProcessor.convertToLong("parent_learning_design_id",table.get(WDDXTAGS.PARENT_DESIGN_ID)); + LearningDesign parent = learningDesignDAO.getLearningDesignById(parentDesignID); + if(parent==null) + throw new Exception("No parent design with with learning_design_id of : " + WDDXTAGS.PARENT_DESIGN_ID + " exists."); + design.setParentLearningDesign(parent); + } + + if(table.containsKey(WDDXTAGS.DURATION)) + design.setDuration(WDDXProcessor.convertToLong("duration",table.get(WDDXTAGS.DURATION))); + + if(table.containsKey(WDDXTAGS.LICENCE_ID)){ + Long licenseID = WDDXProcessor.convertToLong("license_id",table.get(WDDXTAGS.LICENCE_ID)); + License license = licenseDAO.getLicenseByID(licenseID); + if(license!=null) + design.setLicense(license); + else + throw new Exception("No License with a license_id of : " + licenseID + " exists" ); + } + + if(table.containsKey(WDDXTAGS.LICENSE_TEXT)) + design.setLicenseText((String)table.get(WDDXTAGS.LICENSE_TEXT)); + + + }catch(WDDXProcessorConversionException wpce){ + String str = wpce.getMessage(); + throw new Exception(wpce.getMessage()); + } + + } + + /** + * This method uses the Hashtable passed as an argument to build and + * populate a new Activity object. This hashtable is populated + * at the Flash side and all we have to do is iterate through it and + * set the values for the Activity object. If any of the values being + * passed by the Flash side are inconsistent with the database or any of the + * mandatory fields is missing an Exception is thrown. + * + * @param table The hashtable passed by Flash + * @return Activity The populated Activity object + * @throws Exception + */ + private Activity processActivity(Hashtable table,LearningDesign design) throws Exception { + Long activityID =null; + Activity activity = null; + boolean update = false; + if(table.containsKey(WDDXTAGS.ACTIVITY_ID)){ + activityID = WDDXProcessor.convertToLong("activity_id",table.get(WDDXTAGS.ACTIVITY_ID)); + activity = activityDAO.getActivityByActivityId(activityID); + update=true; + }else{ + /* If the hastable doesn't contains the key ACTIVITY_ID + * this mean its a request to store a new Activity + */ + Integer activityTypeID = WDDXProcessor.convertToInteger("activity_type_id",table.get(WDDXTAGS.ACTIVITY_TYPE_ID)); + activity = createActivityInstance(activityTypeID,table); + } + + try{ + if(table.containsKey(WDDXTAGS.ACTIVITY_UIID)) + activity.setActivityUIID(WDDXProcessor.convertToInteger("activity_ui_id",table.get(WDDXTAGS.ACTIVITY_UIID))); + + if(table.containsKey(WDDXTAGS.DESCRIPTION)) + activity.setDescription((String)table.get(WDDXTAGS.DESCRIPTION)); + + if(table.containsKey(WDDXTAGS.TITLE)) + activity.setTitle((String)table.get(WDDXTAGS.TITLE)); + + if(table.containsKey(WDDXTAGS.HELP_TEXT)) + activity.setHelpText((String)table.get(WDDXTAGS.HELP_TEXT)); + + if(table.containsKey(WDDXTAGS.XCOORD)) + activity.setXcoord(WDDXProcessor.convertToInteger("xcoord",table.get(WDDXTAGS.XCOORD))); + + if(table.containsKey(WDDXTAGS.YCOORD)) + activity.setYcoord(WDDXProcessor.convertToInteger("ycoord",table.get(WDDXTAGS.YCOORD))); + + if(table.containsKey(WDDXTAGS.PARENT_UIID)){ + Integer parentUIID = WDDXProcessor.convertToInteger("parent_ui_id",table.get(WDDXTAGS.PARENT_UIID)); + Activity objActivity = activityDAO.getActivityByUIID(parentUIID,design); + if(objActivity!=null){ + activity.setParentActivity(objActivity); + activity.setParentUIID(parentUIID); + }else + throw new Exception ("Error setting parent_ui_id. No such activity with activity_ui_id : "+ parentUIID + "exists."); + } + + if(table.containsKey(WDDXTAGS.PARENT_ACTIVITY_ID)){ + Long parentActivityID = WDDXProcessor.convertToLong("parent_activity_id",table.get(WDDXTAGS.PARENT_ACTIVITY_ID)); + Activity parent = activityDAO.getActivityByActivityId(parentActivityID); + if(parent!=null){ + activity.setParentActivity(parent); + activity.setParentUIID(parent.getActivityUIID()); + } + else + throw new Exception("Error setting the parent_activity_id. No such activity with activity_id of: " + parentActivityID + " exists"); + + } + + if(table.containsKey(WDDXTAGS.ACTIVITY_TYPE_ID)) + activity.setActivityTypeId(WDDXProcessor.convertToInteger("learning_activity_type_id",table.get(WDDXTAGS.ACTIVITY_TYPE_ID))); + + if(table.containsKey(WDDXTAGS.GROUPING_UIID)){ + Integer groupingUIID = WDDXProcessor.convertToInteger("grouping_ui_id", + table.get(WDDXTAGS.GROUPING_UIID)); + activity.setGroupingUIID(groupingUIID); + + Grouping grouping = groupingDAO.getGroupingByUIID(groupingUIID); + activity.setGrouping(grouping); + } + + if(table.containsKey(WDDXTAGS.DEFINE_LATER)) + activity.setDefineLater((Boolean)table.get(WDDXTAGS.DEFINE_LATER)); + else + throw new Exception("Mandatory Field define_later is missing for Activity in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.RUN_OFFLINE)) + activity.setRunOffline(WDDXProcessor.convertToBoolean("run_offline",table.get(WDDXTAGS.RUN_OFFLINE))); + else + throw new Exception("Mandatory Field run_offline is missing for Activity in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.LEARNING_DESIGN_ID)){ + Long learningDesignID = WDDXProcessor.convertToLong("learning_design_id", table.get(WDDXTAGS.LEARNING_DESIGN_ID)); + LearningDesign learningDesign = learningDesignDAO.getLearningDesignById(learningDesignID); + if(learningDesign!=null) + activity.setLearningDesign(learningDesign); + else + throw new Exception("Error setting learning_design_Id." + + "No such design with learning_design_id : " + learningDesignID + " exists"); + } + + if(table.containsKey(WDDXTAGS.LEARNING_LIBRARY_ID)){ + Long learningLibraryID = WDDXProcessor.convertToLong("learning_library_id", table.get(WDDXTAGS.LEARNING_LIBRARY_ID)); + LearningLibrary learningLibrary = learningLibraryDAO.getLearningLibraryById(learningLibraryID); + if(learningLibrary!=null) + activity.setLearningLibrary(learningLibrary); + else + throw new Exception("Error setting learning_library_Id." + + "No such design with learning_library_id : " + learningLibraryID + " exists"); + + } + + if(table.containsKey(WDDXTAGS.CREATION_DATE)) + activity.setCreateDateTime((Date)table.get(WDDXTAGS.CREATION_DATE)); + else + throw new Exception("Mandatory Field create_date_time is missing for Activity in the WDDX packet"); + + if(table.containsKey(WDDXTAGS.OFFLINE_INSTRUCTIONS)) + activity.setOfflineInstructions((String)table.get(WDDXTAGS.OFFLINE_INSTRUCTIONS)); + + if(table.containsKey(WDDXTAGS.LIBRARY_IMAGE)) + activity.setLibraryActivityUiImage((String)table.get(WDDXTAGS.LIBRARY_IMAGE)); + + if(table.containsKey(WDDXTAGS.LIBRARY_ACTIVITY)){ + Long libraryActivityID = WDDXProcessor.convertToLong("library_activity_id",table.get(WDDXTAGS.LIBRARY_ACTIVITY)); + Activity libActivity = activityDAO.getActivityByActivityId(libraryActivityID); + if(libActivity!=null) + activity.setLibraryActivity(libActivity); + else + throw new Exception("Error setting library_activity_id" + + "No Such activity with activity_id of: " + libraryActivityID + " exists"); + } + }catch(WDDXProcessorConversionException wpce){ + throw new Exception(wpce.getMessage()); + } + if(update) + activityDAO.update(activity); + else + activityDAO.insert(activity); + return activity; + } + + /** + * Depending upon the activity's type this function instantiates + * a new object and calls the corresponding function to populate + * its attributes from the hashtable passed on by FLASH + * + * @param activityTypeID The type of Activity object to be instantiated + * @param table The Hashtable containing the information populated by FLASH + * @return Activity The requires populated activity object + * @throws Exception + */ + private Activity createActivityInstance(Integer activityTypeID,Hashtable table)throws Exception{ + Activity activity = null; + int type = activityTypeID.intValue(); + switch(type){ + case Activity.TOOL_ACTIVITY_TYPE: + activity = storeToolActivity(table); + break; + case Activity.OPTIONS_ACTIVITY_TYPE: + activity = storeOptionsActivity(table); + break; + case Activity.GROUPING_ACTIVITY_TYPE: + activity = storeGroupingActivity(table); + break; + case Activity.PERMISSION_GATE_ACTIVITY_TYPE: + activity = storePermissionGateActivity(table); + break; + case Activity.SCHEDULE_GATE_ACTIVITY_TYPE: + activity = storeScheduleGateActivity(table); + break; + case Activity.SYNCH_GATE_ACTIVITY_TYPE: + activity = storeSynchGateActivity(table); + break; + case Activity.PARALLEL_ACTIVITY_TYPE: + activity = storeParallelActivity(table); + break; + case Activity.SEQUENCE_ACTIVITY_TYPE: + activity = storeSequenceActivity(table); + } + + return activity; + } + + /** A GroupingActivity creates Grouping. So when we receive a request + * to store a GroupingActivity the grouping_id would be missing in + * that case. Instead we will have a unique flash generated value for + * grouping_ui_id, based upon which a new record will be generated in + * the database for the lams_grouping table.

Follwing steps are involved + * in saving a GroupingActivity to the database

+ *
    + *
  1. Determine the type of Grouping being created by the GroupingActivity
  2. + *
  3. Create the Grouping (Chosen/Random)
  4. + *
  5. Set the Grouping details for the GroupingActivity
  6. + *
+ * + * @param table The Hashtable containing the information populated by FLASH + * @return GroupingActivity The populated activity object + * @throws Exception + * */ + private GroupingActivity storeGroupingActivity(Hashtable table)throws Exception{ + + GroupingActivity groupingActivity = new GroupingActivity(); + + Hashtable groupingTable = (Hashtable)table.get(WDDXTAGS.GROUPING); + + Integer groupingType =null; + Grouping grouping = null; + + if(groupingTable.containsKey(WDDXTAGS.GROUPING_TYPE_ID)) + groupingType = WDDXProcessor.convertToInteger("grouping_type_id",groupingTable.get(WDDXTAGS.GROUPING_TYPE_ID)); + else + throw new Exception ("grouping_type_id missing for GroupingActivity.Cannot create Grouping without that"); + + if(groupingType==Grouping.RANDOM_GROUPING_TYPE) + grouping = createRandomGrouping(groupingTable); + else + grouping = createChosenGrouping(groupingTable); + + groupingActivity.setCreateGrouping(grouping); + groupingActivity.setCreateGroupingUIID(grouping.getGroupingUIID()); + return groupingActivity; + + } + + /** + * This function creates and populates the RandomGrouping object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return RandomGrouping The populated activity object + * @throws Exception + */ + private RandomGrouping createRandomGrouping(Hashtable table)throws Exception{ + + RandomGrouping randomGrouping = new RandomGrouping(); + + if(table.containsKey(WDDXTAGS.MAX_NUMBER_OF_GROUPS)) + randomGrouping.setMaxNumberOfGroups(WDDXProcessor.convertToInteger("max_number_of_groups",table.get(WDDXTAGS.MAX_NUMBER_OF_GROUPS))); + + if(table.containsKey(WDDXTAGS.GROUPING_UIID)) + randomGrouping.setGroupingUIID(WDDXProcessor.convertToInteger("grouping_ui_id",table.get(WDDXTAGS.GROUPING_UIID))); + + if(table.containsKey(WDDXTAGS.NUMBER_OF_GROUPS)) + randomGrouping.setNumberOfGroups(WDDXProcessor.convertToInteger("number_of_groups",table.get(WDDXTAGS.NUMBER_OF_GROUPS))); + + if(table.containsKey(WDDXTAGS.LEARNERS_PER_GROUP)) + randomGrouping.setLearnersPerGroup(WDDXProcessor.convertToInteger("learners_per_group",table.get(WDDXTAGS.LEARNERS_PER_GROUP))); + + groupingDAO.insert(randomGrouping); + return randomGrouping; + + } + /** + * This function creates and populates the ChosenGrouping object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return ChosenGrouping The populated activity object + * @throws Exception + */ + private ChosenGrouping createChosenGrouping(Hashtable table)throws Exception{ + ChosenGrouping chosenGrouping = new ChosenGrouping(); + + if(table.containsKey(WDDXTAGS.MAX_NUMBER_OF_GROUPS)) + chosenGrouping.setMaxNumberOfGroups(WDDXProcessor.convertToInteger("max_number_of_groups",table.get(WDDXTAGS.MAX_NUMBER_OF_GROUPS))); + + if(table.containsKey(WDDXTAGS.GROUPING_UIID)) + chosenGrouping.setGroupingUIID(WDDXProcessor.convertToInteger("grouping_ui_id",table.get(WDDXTAGS.GROUPING_UIID))); + + groupingDAO.insert(chosenGrouping); + return chosenGrouping; + } + + /** + * This function creates and populates the OptionsActivity object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return OptionsActivity The populated activity object + * @throws Exception + */ + private OptionsActivity storeOptionsActivity(Hashtable table)throws Exception{ + + OptionsActivity optActivity = new OptionsActivity(); + + if(table.containsKey(WDDXTAGS.MAX_OPTIONS)) + optActivity.setMaxNumberOfOptions(WDDXProcessor.convertToInteger("max_number_of_options",table.get(WDDXTAGS.MAX_OPTIONS))); + + if(table.containsKey(WDDXTAGS.MIN_OPTIONS)) + optActivity.setMinNumberOfOptions(WDDXProcessor.convertToInteger("min_number_of_options",table.get(WDDXTAGS.MIN_OPTIONS))); + + if(table.containsKey(WDDXTAGS.OPTIONS_INSTRUCTIONS)) + optActivity.setOptionsInstructions((String)table.get(WDDXTAGS.OPTIONS_INSTRUCTIONS)); + addChildActivities(optActivity,table); + return optActivity; + } + + /** + * This function creates and populates the ToolActivity object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return ToolActivity The populated activity object + * @throws Exception + */ + private ToolActivity storeToolActivity(Hashtable table)throws Exception{ + + ToolActivity toolActivity = new ToolActivity(); + + if(table.containsKey(WDDXTAGS.TOOL_ID)){ + Long toolID = WDDXProcessor.convertToLong("tool_id",table.get(WDDXTAGS.TOOL_ID)); + Tool tool = toolDAO.getToolByID(toolID); + if(tool!=null) + toolActivity.setTool(tool); + else + throw new Exception("Error setting tool_id. " + + "No such tool with tool_id of: " + toolID + "exists"); + + } + if(table.containsKey(WDDXTAGS.ORDER_ID)) + toolActivity.setOrderId(WDDXProcessor.convertToInteger("order_id",table.get(WDDXTAGS.ORDER_ID))); + + if(table.containsKey(WDDXTAGS.TOOL_CONTENT_ID)) + toolActivity.setToolContentId(WDDXProcessor.convertToLong("tool_content_id",table.get(WDDXTAGS.TOOL_CONTENT_ID))); + + return toolActivity; + + } + /** + * This functions adds the attributes that are common for all kind of + * gate activities (SYNCH/SCHEDULE/PERMISSION). Main purpose of this function + * is avoid any unnecessary duplicacy of code. + * + * @param gateActivity The GateActivity whose attributes are being set + * @param table The Hashtable containing the information populated by FLASH + * @throws Exception + */ + private void addGateActivityAttributes(GateActivity gateActivity, Hashtable table)throws Exception{ + + if(table.containsKey(WDDXTAGS.GATE_ACTIVITY_LEVEL_ID)) + gateActivity.setGateActivityLevelId(WDDXProcessor.convertToInteger("gate_activity_level_id", + table.get(WDDXTAGS.GATE_ACTIVITY_LEVEL_ID))); + if(table.containsKey(WDDXTAGS.GATE_OPEN)) + gateActivity.setGateOpen(WDDXProcessor.convertToBoolean("gate_open", + table.get(WDDXTAGS.GATE_OPEN))); + } + /** + * This function creates and populates the PermissionGateActivity object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return PermissionGateActivity The populated activity object + * @throws Exception + */ + private PermissionGateActivity storePermissionGateActivity(Hashtable table)throws Exception{ + PermissionGateActivity permissionGateActivity = new PermissionGateActivity(); + addGateActivityAttributes(permissionGateActivity,table); + return permissionGateActivity; + } + + /** + * This function creates and populates the ScheduleGateActivity object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return ScheduleGateActivity The populated activity object + * @throws Exception + */ + private ScheduleGateActivity storeScheduleGateActivity(Hashtable table)throws Exception{ + ScheduleGateActivity scheduleGateActivity = new ScheduleGateActivity(); + addGateActivityAttributes(scheduleGateActivity,table); + + if(table.containsKey(WDDXTAGS.GATE_START_DATE)) + scheduleGateActivity.setGateStartDateTime((Date)table.get(WDDXTAGS.GATE_START_DATE)); + + if(table.containsKey(WDDXTAGS.GATE_END_DATE)) + scheduleGateActivity.setGateEndDateTime((Date)table.get(WDDXTAGS.GATE_END_DATE)); + + if(table.containsKey(WDDXTAGS.GATE_START_OFFSET)) + scheduleGateActivity.setGateStartTimeOffset(WDDXProcessor.convertToLong("gate_start_time_offset", + table.get(WDDXTAGS.GATE_START_OFFSET))); + if(table.containsKey(WDDXTAGS.GATE_END_OFFSET)) + scheduleGateActivity.setGateEndTimeOffset(WDDXProcessor.convertToLong("gate_end_time_offset", + table.get(WDDXTAGS.GATE_END_OFFSET))); + + return scheduleGateActivity; + } + + /** + * This function creates and populates the SynchGateActivity object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return SynchGateActivity The populated activity object + * @throws Exception + */ + private SynchGateActivity storeSynchGateActivity(Hashtable table)throws Exception{ + SynchGateActivity synchGateActivity = new SynchGateActivity(); + addGateActivityAttributes(synchGateActivity,table); + return synchGateActivity; + } + + /** + * This function creates and populates the ParallelActivity object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return ParallelActivity The populated activity object + * @throws Exception + */ + private ParallelActivity storeParallelActivity(Hashtable table)throws Exception{ + ParallelActivity parallelActivity = new ParallelActivity(); + addChildActivities(parallelActivity,table); + return parallelActivity; + } + /** + * This function creates and populates the SequenceActivity object from + * the information passed on by FLASH in the Hashtable + * + * @param table The Hashtable containing the information populated by FLASH + * @return SequenceActivity The populated activity object + * @throws Exception + */ + private SequenceActivity storeSequenceActivity(Hashtable table) throws Exception{ + SequenceActivity sequenceActivity = new SequenceActivity(); + addChildActivities(sequenceActivity,table); + return sequenceActivity; + } + /** + * This function parses the FLASH populated hashtable for any child activities + * for a given ComplexActivity. If found it sets them otherwise it throws an + * Exception saying an attempt was made to save a ComplexActivity without + * any child activities coz that is not possible. We cannot have an + * OptionsActivity without any optional activities (child activities) inside it. + * + * @param complexActivity The ComplexActivity whose children are being set + * @param table The Hashtable containing the information populated by FLASH + * @throws Exception + */ + private void addChildActivities(ComplexActivity complexActivity, Hashtable table)throws Exception{ + + if(table.containsKey(WDDXTAGS.CHILD_ACTIVITIES)){ + Vector vector = (Vector)table.get(WDDXTAGS.CHILD_ACTIVITIES); + HashSet childActivities = new HashSet(); + Iterator iter = vector.iterator(); + while(iter.hasNext()){ + Activity activity = (Activity)iter.next(); + childActivities.add(activity); + } + complexActivity.setActivities(childActivities); + }else + throw new Exception("An attempt to save a complex activity with no child activities"); + } + +} Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXProcessor.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXProcessor.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXProcessor.java (revision fc76a4bb4e5abc614e15b642e4015295b2912c0a) @@ -0,0 +1,287 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ +package org.lamsfoundation.lams.util.wddx; + +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.xml.sax.InputSource; + +import com.allaire.wddx.WddxDeserializationException; +import com.allaire.wddx.WddxDeserializer; +import com.allaire.wddx.WddxSerializer; + + +/** + * @author Manpreet Minhas + */ +public class WDDXProcessor { + private static Logger logger = Logger.getLogger(WDDXProcessor.class.getName()); + + WDDXProcessor m_theRealMe = null; + + /** + * Constructor for Serialiser. Private to ensure singleton behaviour + */ + private WDDXProcessor() + { + super(); + } + + + WDDXProcessor getInstance() + { + if ( m_theRealMe == null ) + m_theRealMe = new WDDXProcessor(); + return m_theRealMe; + } + + /** Replace any "%0D0A" in the wddx packet with true java characters + * Flash clients will put in "%0D0A" to get around the Flash code + * removing newlines before creating the packet. + *

+ * Made public as some parts of the system use the same format when + * sending from Flash clients, but not via a wddx packet (just a normal post). + */ + public static String replaceNewline(String inputPacket) + { + String ret = null; + if ( inputPacket != null ) + { + ret = StringUtils.replace(inputPacket,"%0D%0A","\r\n"); + } + return ret; + } + + /** + * Deserialize an arbitrary packet. + */ + public static Object deserialize(String wddxPacket) + throws WddxDeserializationException + { + String replacedString = replaceNewline(wddxPacket); + + // Create an input source (org.xml.sax.InputSource) bound to the packet + InputSource tempSource = new InputSource(new StringReader(replacedString)); + + // Create a WDDX deserializer (com.allaire.wddx.WddxDeserializer) + WddxDeserializer tempDeserializer = new WddxDeserializer("org.apache.xerces.parsers.SAXParser"); + + // Deserialize the WDDX packet + Object result; + try + { + result = tempDeserializer.deserialize(tempSource); + } + catch (IOException e) + { + throw new WddxDeserializationException( e ); + } + + return result; + } + + /** + * Serialize an arbitrary packet. + */ + public static String serialize(Object data) throws IOException + { + // Create a WDDX serializer + WddxSerializer tempws = new WddxSerializer(); + + // Create a writer to store the generated WDDX + StringWriter tempsw = new StringWriter(); + // Serialize the data + tempws.serialize(data, tempsw); + // Return the WDDX packet + return tempsw.toString(); + } + + /** Convert a string to an int, based on how WDDX usually passes numbers. + * @param identifier - name of value being converted - using in the exception thrown + * if the number cannot be converted. + * @param value - the value to be converted + * @return int value + * @throws Exception - will contain a message "Unable to convert value (identifier): (value) to an int" + */ + public static int convertToInt( String identifier, Object value) + throws WDDXProcessorConversionException + { + int result=-255; + if ( value == null ) + { + throw new WDDXProcessorConversionException(identifier+" is null, cannot convert to an int"); + } + + try { + // WDDX should give us a double + result = ((Number)value).intValue(); + return(result); + } catch (Exception e) {} + + try { + String textValue = (String) value; + if ( textValue.length() == 0 ) + return -1; + + double dTemp = Double.parseDouble(textValue); + result = (int) dTemp; + } catch ( Exception e2) { + throw new WDDXProcessorConversionException("Unable to convert value "+identifier+":"+value+" to an int"); + } + return(result); + } + + /** + * Some conversion doesn't allow null value. Doing so will result in hidden + * nullpointer exception. We do need this helper function. + * + * @param identifier + * @param value + * @return converted integer. + * @throws WDDXProcessorConversionException + * @author Jacky Fang + */ + public static Integer nullSafeCovertToInteger(String identifier,Object value) throws WDDXProcessorConversionException + { + if(value == null) + throw new IllegalArgumentException("["+identifier+"] is null. We can't convert null value to integer"); + //delegate to convertToInteger + return convertToInteger(identifier,value); + } + /** Convert a string to an integer, based on how WDDX usually passes numbers. + * As it is an integer, if the field is blank (or not there), then return null + * @param identifier - name of value being converted - using in the exception thrown + * if the number cannot be converted. + * @param value - the value to be converted + * @return integer value or null + * @throws Exception - will contain a message "Unable to convert value (identifier): (value) to an int" + */ + public static Integer convertToInteger( String identifier, Object value) + throws WDDXProcessorConversionException + { + Integer result = null; + if ( value == null ) + return null; + + try { + // WDDX should give us a double + result = new Integer (((Number)value).intValue() ); + return(result); + } catch (Exception e) {} + + try { + String textValue = (String) value; + if ( textValue.length() == 0 ) + return null; + + int posPeriod = textValue.indexOf('.'); + if ( posPeriod > 0 ) + { + textValue = textValue.substring(0,posPeriod); + } + result = new Integer (textValue); + } catch ( Exception e2) { + throw new WDDXProcessorConversionException("Unable to convert value "+identifier+":"+value+" to an int"); + } + return(result); + } + + /** Convert a String to an Long, based on how WDDX usually passes numbers. + * As it is a Long, if the field is blank (or not there), then return null + * @param identifier - name of value being converted - using in the exception thrown + * if the number cannot be converted. + * @param value - the value to be converted + * @return Long value or null + * @throws Exception - will contain a message "Unable to convert value (identifier): (value) to an int" + */ + public static Long convertToLong( String identifier, Object value) + throws WDDXProcessorConversionException + { + Long result = null; + if ( value == null ) + { + return null; + } + + try { + // WDDX should give us a double + result = new Long(((Number)value).intValue() ); + return(result); + } catch (Exception e) {} + + try { + String textValue = (String) value; + if ( textValue.length() == 0 ) + return null; + + int posPeriod = textValue.indexOf('.'); + if ( posPeriod > 0 ) + { + textValue = textValue.substring(0,posPeriod); + } + result = new Long (textValue); + } catch ( Exception e2) { + throw new WDDXProcessorConversionException("Unable to convert value "+identifier+":"+value+" to an int"); + } + return(result); + } + + /** Convert a String/Boolean to an Boolean + * @param identifier - name of value being converted - using in the exception thrown + * if the value cannot be converted. + * @param value - the value to be converted + * @return Boolean value or null + * @throws Exception - will contain a message "Unable to convert value (identifier): (value) to an int" + */ + public static Boolean convertToBoolean( String identifier, Object value) + throws WDDXProcessorConversionException + { + Boolean result = null; + if ( value == null ) + { + return null; + } + + try { + result = (Boolean) value; + logger.debug("identifier "+identifier+" was Boolean value "+value+" becomes "+result); + return(result); + } catch (Exception e) {} + + try { + String textValue = (String) value; + if ( textValue.length() == 0 ) + return null; + + result = new Boolean (textValue); + logger.debug("identifier "+identifier+" was String value "+value+" becomes "+result); + return(result); + } catch ( Exception e2) { + throw new WDDXProcessorConversionException("Unable to convert value "+identifier+":"+value+" to a Boolean"); + } + } +} Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXProcessorConversionException.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXProcessorConversionException.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXProcessorConversionException.java (revision fc76a4bb4e5abc614e15b642e4015295b2912c0a) @@ -0,0 +1,66 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ + +package org.lamsfoundation.lams.util.wddx; + +/** + * @author Manpreet Minhas + * + * Thrown if an error occurs trying to get the numeric data from the wddx generated objects. + * + */ +public class WDDXProcessorConversionException extends Exception { + + /** + * Constructor for WDDXProcessorConversionException. + */ + public WDDXProcessorConversionException() { + super(); + } + + /** + * Constructor for WDDXProcessorConversionException. + * @param message + */ + public WDDXProcessorConversionException(String message) { + super(message); + } + + /** + * Constructor for WDDXProcessorConversionException. + * @param message + * @param cause + */ + public WDDXProcessorConversionException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructor for WDDXProcessorConversionException. + * @param cause + */ + public WDDXProcessorConversionException(Throwable cause) { + super(cause); + } + +} Index: lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java =================================================================== diff -u --- lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java (revision 0) +++ lams_common/src/java/org/lamsfoundation/lams/util/wddx/WDDXTAGS.java (revision fc76a4bb4e5abc614e15b642e4015295b2912c0a) @@ -0,0 +1,147 @@ +/*************************************************************************** + * Copyright (C) 2005 LAMS Foundation (http://lamsfoundation.org) + * ============================================================= + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + * USA + * + * http://www.gnu.org/licenses/gpl.txt + * ************************************************************************ + */ +package org.lamsfoundation.lams.util.wddx; + +import java.util.Date; + + + +/** + * @author Manpreet Minhas + * The tags used in WDDX Packet + */ +public interface WDDXTAGS { + + /* General Tags */ + public static final String OBJECT_TYPE = "objectType"; + + public static final String DESCRIPTION = "description"; + public static final String TITLE = "title"; + public static final String HELP_TEXT ="help_text"; + public static final String XCOORD="xcoord"; + public static final String YCOORD="ycoord"; + public static final String GROUPING ="grouping"; + public static final String TRANSITIONS ="transitions"; + public static final String ACTIVITIES ="activities"; + + /*Learning Library specific tags */ + public static final String LEARNING_LIBRARY_ID ="learning_library_id"; + public static final String LIB_ACTIVITIES="templateActivities"; + public static final String LIB_PACKAGE = "libraries"; + public static final String DESIGN_PACKAGE ="designs"; + + + public static final Long NUMERIC_NULL_VALUE_LONG = new Long(-111111); + public static final String STRING_NULL_VALUE = "string_null_value"; + public static final Integer NUMERIC_NULL_VALUE_INTEGER = new Integer(-111111); + public static final Date DATE_NULL_VALUE = new Date(0); + public static final Boolean BOOLEAN_NULL_VALUE = new Boolean("false"); + + /*Activity specific tags*/ + public static final String ACTIVITY_ID ="activity_id"; + public static final String ACTIVITY_UIID ="activity_ui_id"; + + public static final String PARENT_ACTIVITY_ID ="parent_activity_id"; + public static final String PARENT_UIID ="parent_activity_ui_id"; + + public static final String ACTIVITY_TYPE_ID ="learning_activity_type_id"; + public static final String ORDER_ID ="order_id"; + + public static final String DEFINE_LATER ="define_later_flag"; + public static final String RUN_OFFLINE ="run_offline"; + public static final String OFFLINE_INSTRUCTIONS ="offline_instructions"; + public static final String LIBRARY_IMAGE ="library_activity_ui_image"; + public static final String LIBRARY_ACTIVITY ="library_activity_id"; + + /** OptionsActivity specific tags*/ + public static final String MAX_OPTIONS="max_number_of_options"; + public static final String MIN_OPTIONS="min_number_of_options"; + public static final String OPTIONS_INSTRUCTIONS ="options_instructions"; + + /** ToolActivity specific tags*/ + public static final String TOOL_ID="tool_id"; + public static final String TOOL_CONTENT_ID="tool_content_id"; + + /** GateActivity specific tags*/ + public static final String GATE_ACTIVITY_LEVEL_ID ="gate_activity_level_id"; + public static final String GATE_START_DATE ="gate_start_date_time"; + public static final String GATE_END_DATE ="gate_end_date_time"; + public static final String GATE_START_OFFSET="gate_start_time_offset"; + public static final String GATE_END_OFFSET="gate_end_time_offset"; + public static final String GATE_OPEN ="gate_open"; + + /** Grouping Activity specific tags */ + public static final String CREATE_GROUPING_ID ="create_grouping_id"; + public static final String CREATE_GROUPING_UIID ="create_grouping_ui_id"; + + /** Grouping specific tags */ + public static final String GROUPING_ID ="grouping_id"; + public static final String GROUPING_UIID ="grouping_ui_id"; + public static final String GROUPING_TYPE_ID ="grouping_type_id"; + public static final String LEARNERS_PER_GROUP ="learners_per_group"; + public static final String MAX_NUMBER_OF_GROUPS ="max_number_of_groups"; + public static final String NUMBER_OF_GROUPS ="number_of_groups"; + + /** Transition specific tags */ + public static final String TRANSITION_ID ="transition_id"; + public static final String TRANSITION_UIID ="transition_ui_id"; + public static final String TRANSITION_TO="to_activity_id"; + public static final String TRANSITION_FROM="from_activity_id"; + public static final String TO_ACTIVITY_UIID ="to_activity_ui_id"; + public static final String FROM_ACTIVITY_UIID ="from_activity_ui_id"; + + + /** Tool Specific tags */ + public static final String TOOL_DISPLAY_NAME ="displayName"; + public static final String TOOl_AUTH_URL ="toolAuthoringURL"; + public static final String AUTH_URL ="authoringURLS"; + + + + /** LearningDesign specific tags*/ + public static final String LEARNING_DESIGN_ID="learning_design_id"; + public static final String LEARNING_DESIGN_UIID="learning_design_ui_id"; + public static final String FIRST_ACTIVITY_ID ="first_activity_id"; + public static final String FIRST_ACTIVITY_UIID ="first_activity_ui_id"; + + public static final String MAX_ID ="max_id"; + public static final String VALID_DESIGN ="valid_design_flag"; + public static final String READ_ONLY ="read_only_flag"; + public static final String DATE_READ_ONLY ="date_read_only"; + public static final String USER_ID="user_id"; + + public static final String COPY_TYPE="copy_type_id"; + public static final String CREATION_DATE ="create_date_time"; + public static final String VERSION="version"; + public static final String PARENT_DESIGN_ID ="parent_learning_design_id"; + public static final String WORKSPACE_FOLDER_ID= "workspace_folder_id"; + public static final String DURATION ="duration"; + public static final String LICENCE_ID ="license_id"; + public static final String LICENSE_TEXT ="license_text"; + + /**ComplexActivity specific tags */ + public static final String CHILD_ACTIVITIES ="childActivities"; + + + +}