A common problem that comes up is the need to change how documents are stored in the Document Library.
For example, you may start out storing documents using Jackrabbit hooked to a database. However, as time goes on and you find yourself using more Liferay deployments, the number of database connections reserved for Jackrabbit alone gets dangerously close to the maximum number of database connections supported by your database vender.
So, you want to switch from using JCRHook over to using the FileSystemHook to store documents on a SAN.
If your migration uses two different hooks and you have access to the portal class loader (for example, you're running in the EXT environment, or you have the ability to update the context class loader for your web application like in Tomcat 5.5), the solution is straightforward.
InputStream exportStream = sourceHook.getFileAsStream( companyId, folderId, fileName, versionNumber); targetHook.updateFile( companyId, portletId, groupId, folderId, fileName, versionNumber, fileName, fileEntryId, properties, modifiedDate, tagsCategories, tagsEntries, exportStream);
In summary, you instantiate the hook objects, pull data from your source hook and push it to your target hook. Then, update your configurations and restart your server to use the new document library hook. (In case you're not sure how to change document library hooks, see the comments for the dl.hook.impl property in portal.properties.)
If you'd like to see how this is accomplished via code samples rather than via textual explanations, these document links might help (just to note, the sample plugins SDK portlets leverage the portal class loader in order to access the classes found in portal-impl.jar, and so you must use Tomcat 5.5 or another servlet container that supports a similar mechanism in order to use them):
- sample 5.2.x migration code
- sample 5.1.x migration portlet (requires Tomcat 5.5)
- sample 5.2.x migration portlet (requires Tomcat 5.5)
However, it's not always so easy. Another common problem is where you start out using Jackrabbit hooked up to a file system (perhaps in the earlier iterations of Liferay where JCRHook was the default), but you want to move to a clustered environment and you do not have access to a SAN.
Therefore, you want to migrate over to using Jackrabbit hooked to a database.
This is different from the previous problem in that you're using the same exact hook in both cases, and the way Liferay handles Jackrabbit inside of this hook makes it so that you can only have one active Jackrabbit workspace configuration (specified in your portal.properties file), and so simply instantiating two different hooks is not possible.
The solution here is to run the migration twice.
First, with the original JCRHook configuration, export the data to an intermediate hook (for example, the Liferay FileSystemHook) and shut down your Liferay instance. Then, you update portal.properties and/or repository.xml to reflect the desired JCRHook configuration, and import from your intermediate hook back to JCRHook.
If you do not have access to the portal class loader, the migration is less straightforward, because you won't have access to the hook classes themselves.
InputStream exportStream = DLLocalServiceUtil.getFileAsStream( companyId, folderId, fileName, versionNumber); FileUtil.write(intermediateFileLocation, exportStream); InputStream importStream = new FileInputStream(intermediateFileLocation); DLLocalServiceUtil.updateFile( companyId, portletId, groupId, folderId, fileName, versionNumber, fileName, fileEntryId, properties, modifiedDate, tagsCategories, tagsEntries, importStream);
In summary, you'll have to read the documents using DLLocalServiceUtil with the original configuration and save them to disk in a way where you can parse all the data needed to call updateFile (perhaps in the same way that mirrors the way FileSystemHook works). Then, you re-import those exported documents using DLLocalServiceUtil after updating your configuration and restarting the server.

