There are 2 methods in ToolContentManager to support tool export and import tool content. One is void exportToolContent(Long, String). Another is void importToolContent(Long , Integer , String ). Following description is how to implement them with helper methods from LAMS ExportToolContentService.
Export tool content
In exportToolContent method, the work need to are
- Sort out what content is need to be exported, what is not necessary to exported
- Serialize content to XML file. The default name conversion is tool.xml which is under a subfolder which named by given toolContentId.
- Download all relevant attachment files from LAMS repository and save them into same folder with tool.xml, and their file name will be fileUuid rather than the original file name to avoid conflict.
Hibernate is data access API in LAMS tools. So we can easily reuse hibernate model class as content object and serialize it. To achieve this, ExportToolContentService in LAMS common package provides helper methods to make things easier. Usually, it needs 2 helper methods from this service bean: One is registerFileClassForExport(). Another is exportToolContent(). The former can tell service bean how to find out the attachment files information. The latter one can serialize content object to XML. Furthermore, it could retrieve content object and download all attachment files to target folder according to the register information in last step.
Below is two examples for export tool content. Notes:
- To detach useless object for content, e.g., Tool Session, ToolContentHandler etc. their value need to be set to null.
- If any subobjects (e.g. attachments) contain a link back to the main object, then clear the link to the main object. For example, the ScribeHeading has a back link to Scribe and this must be cleared.
Import tool content.
It is a reverse process with export content.
- Deserialize tool.xml to content object
- Upload attachment files to LAMS repository and refresh file uuid, version, type (ONLINE/OFFLINE) etc.
- Refresh any user information to new user. The new user usually be the person who handle importing.
- Refresh toolContentId.
There are helper methods from ExportToolContentService bean. They registers imported attachment files information and deserializes tool XML file to content object. The helper method, importToolContent(), also upload attachment files and refresh relevant fields in content object.
Except that, tool need refresh the user to the given user ( newUserUid ). The toolContentId need refresh as well. Below is example code:
Why use helper methods?
Except serialize or deserialize content object, helper methods also handle upload/download stuff. The reasons are:
- This make program simple.
- Upload/Download file/package is common operation for export/import and it is possible to abstract them to helper methods.
- The attachment files may be contained in content object directly, maybe not. For instance, in share resources tool, it has offline/online instruction files in content object. It also has attached files in resource item. Helper methods can retrieve content object in and out and pick them up wherever they are.
Import tool content from different version
Tool could have different version. A subclass of ToolContentVersionFilter could help tool to import old version content package to lams server which running latest tools (or in reverse). The methods in subclass must follow below name convension.
- upXXXToYYY() : this method will help tool to import old version to new version. In this case, XXX < YYY.
- downXXXToYYY() : this method will help tool to import new version to old version. In this case, XXX > YYY.
The XXX and YYY is tool's version number. It should be integer format digit. Our recommend tool version format is YYYYMMDD. The new version number MUST greater than older version.
In the up/down method, it simply calls 2 methods from its parent class, ToolContentVersionFilter:
- public void removeField(Class ownerClass, String fieldname)
- public void addField(Class ownerClass, String fieldname, Object defaultValue)
Any removed fields must be declared by removeField() method. addField() is optional, except when the added fields need some special default value.
Further, register this Version Filter class to exportContentService. In ToolContentManager.importToolContent(), add following sentence:
Check Your XML for Hibernate Objects
When you have written your logic, check the tool.xml produced by the export. It should not include any Hibernate class references. If you find reference to Hibernate object, you probably have either not set an unneeded value to null, or one of the subobjects contains a link back to an initial object. See the example code under Export tool content
In the example below, Scribe contains a set of ScribeHeadings. The ScribeHeading contains a reference to its Scribe, so if it is converted to XML as is, we end up with a Scribe, containing ScribeHeadings, which in turn contain the Hibernate version of Scribe. When the file is imported then the ScribeHeadings try to point to the wrong Scribe. This was fixed by first creating a new instance of Scribe and then going through the ScribeHeadings and setting their reference to Scribe to null.