https://community.alfresco.com/thread/178902-acp-import-with-uuid-binding-specified
http://ecmarchitect.com/archives/2008/10/27/859
To preserve UUID binding during existing ACP import:
- Followed the steps from the first article above, creating a custom class that extended the ImporterActionExecuter. cherryshoe-alfresco-amp\src\main\java\com\cherryshoe\action\executer\CustomAcpImporterActionExecuter.java
package com.cherryshoe.action.executer; import java.io.File; import org.alfresco.model.ContentModel; import org.alfresco.repo.action.executer.ImporterActionExecuter; import org.alfresco.repo.content.MimetypeMap; import org.alfresco.repo.importer.ACPImportPackageHandler; import org.alfresco.service.cmr.action.Action; import org.alfresco.service.cmr.repository.ContentReader; import org.alfresco.service.cmr.repository.ContentService; import org.alfresco.service.cmr.repository.NodeRef; import org.alfresco.service.cmr.repository.NodeService; import org.alfresco.service.cmr.view.ImporterBinding; import org.alfresco.service.cmr.view.ImporterService; import org.alfresco.service.cmr.view.Location; import org.alfresco.service.namespace.QName; import org.alfresco.util.TempFileProvider; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class CustomAcpImporterActionExecuter extends ImporterActionExecuter { private static final Log log = LogFactory.getLog(CustomAcpImporterActionExecuter.class); public static final String NAME = "custom-import"; public static final String PARAM_ENCODING = "encoding"; public static final String PARAM_DESTINATION_FOLDER = "destination"; private static final String TEMP_FILE_PREFIX = "alf"; private static final String TEMP_FILE_SUFFIX_ACP = ".acp"; private ImporterBinding.UUID_BINDING uuidBinding; private ImporterService importerService; private NodeService nodeService; private ContentService contentService; public void setImporterService(ImporterService importerService) { this.importerService = importerService; } public void setNodeService(NodeService nodeService) { this.nodeService = nodeService; } public void setContentService(ContentService contentService) { this.contentService = contentService; } public CustomAcpImporterActionExecuter() { super(); log.info( "*****************************CustomAcpImporterActionExecuter constructor*************************************"); } /** * @see org.alfresco.repo.action.executer.ActionExecuter#execute(org.alfresco.repo.ref.NodeRef, * org.alfresco.repo.ref.NodeRef) */ @Override public void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) { log.info( "************************actionedUponNodeRef:**********************************" + actionedUponNodeRef); if (this.nodeService.exists(actionedUponNodeRef) == true) { // The node being passed in should be an Alfresco content package ContentReader reader = this.contentService.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT); if (reader != null) { NodeRef importDest = (NodeRef) ruleAction.getParameterValue(PARAM_DESTINATION_FOLDER); log.info("*******************************importDest:" + importDest + " actionedUponNodeRef:" + actionedUponNodeRef); if (MimetypeMap.MIMETYPE_ACP.equals(reader.getMimetype())) { // perform an import of an Alfresco ACP file (special format // ZIP structure) File zipFile = null; try { // unfortunately a ZIP file can not be read directly // from an input stream so we have to create // a temporary file first zipFile = TempFileProvider.createTempFile(TEMP_FILE_PREFIX, TEMP_FILE_SUFFIX_ACP); reader.getContent(zipFile); ACPImportPackageHandler importHandler = new ACPImportPackageHandler(zipFile, (String) ruleAction.getParameterValue(PARAM_ENCODING)); log.debug( "************************************Starting import*****************************************"); this.importerService.importView(importHandler, new Location(importDest), getBinding(), null); log.debug( "************************************Stopping import*****************************************"); } finally { // now the import is done, delete the temporary file if (zipFile != null) { zipFile.delete(); } } } } } } private ImporterBinding getBinding() { ImporterBinding binding = new ImporterBinding() { public boolean allowReferenceWithinTransaction() { return false; } public QName[] getExcludedClasses() { return null; } public UUID_BINDING getUUIDBinding() { return uuidBinding; } public String getValue(String key) { return null; } }; // Uses UPDATE_EXISTING as usage of REPLACE_EXISTING removes child nodes // if these are not sent over in the export. uuidBinding = ImporterBinding.UUID_BINDING.UPDATE_EXISTING; return binding; } }
- Copied the existing alfresco\WEB-INF\classes\alfresco\action-services-context.xml file to my maven alfresco sdk folder cherryshoe-alfresco-amp\src\main\amp\config\alfresco\extension folder and named it action-services-cherryshoe-override-context.xml. I removed everything in the file except the spring bean with id "import", and updated the class attribute with the package location of my custom class com.cherryshoe.action.executer.CustomAcpImporterActionExecuter. The extension folder gets loaded after the out-of-the-box alfresco folders, so this should be overriding the WEB-INF\classes\alfresco\action-services-context.xml with just this one bean to use our custom one (If you know the classloading order of resources, Spring does allow overriding beans of the same id).
cherryshoe-alfresco-amp\src\main\amp\config\alfresco\extension\action-services-cherryshoe-override-context.xml
<?xml version='1.0' encoding='UTF-8'?> <!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'> <beans> <!-- The extension folder gets loaded after the OOB alfresco folders, so this should be overriding the WEB-INF\classes\alfresco\action-services-context.xml with just this one bean to use our custom one --> <bean id="import" class="com.cherryshoe.action.executer.CustomAcpImporterActionExecuter" parent="action-executer"> <property name="importerService"> <ref bean="ImporterService"/> </property> <property name="nodeService"> <ref bean="NodeService"></ref> </property> <property name="contentService"> <ref bean="ContentService" /> </property> <property name="fileFolderService"> <ref bean="FileFolderService"/> </property> </bean> </beans>
- Updated cherryshoe-alfresco-amp\src\test\resources\alfresco\extension\custom-log4j.properties with:
# custom import action executer log4j.logger.com.cherryshoe.action.executor=info
- After navigating to <servername>:<port>/alfresco -> Folder to import ACP -> Import ACP -> then searching no a known node reference UUID using the Node Browser, I can see that the node was binded with the original UUID!
- NOTE: Since ACP files can be very large, using this default behavior could hang/fail, since the ACP first has to be uploaded, then imported. Instead you can write a javascript script, implement a rule on a folder to call that script, and import an ACP that already exists on the repository (this article was helpful and worked great for me).
No comments:
Post a Comment
I appreciate your time in leaving a comment!