cancel
Showing results for 
Search instead for 
Did you mean: 

Path conversion and node export [SOLVED]

jimcornmell
Champ in-the-making
Champ in-the-making
Hi All,

Simple question.  I'm trying to export some files from Alfresco 2.1 (in a tar etc) using Java.  To do this I have created an action which fires when files are placed into a folder (by an advanced workflow).  All is working fine so far.  The files are in a known folder, the action is fired, the java runs and knows the full path to the file which caused the action to fire.  Within the tar I need to include other files (which I know the path of).  Here is my problem:

I know the full paths to a bunch of files:

Company Home/SomeFolder/SomeOtherFolderEtc/SomeFileName.txt
Company Home/SomeFolder/SomeOtherFolderEtc/SomeFileName.xml
Company Home/SomeFolder/SomeOtherFolderEtc/SomeFileName.eps
Company Home/SomeFolder/SomeOtherFolderEtc/SomeFileName.ai
Company Home/SomeFolder/SomeOtherFolderEtc/SomeFileName.log
Company Home/SomeFolder/SomeOtherFolderEtc/SomeFileName.etc

but now I need to A) convert these paths into node refs and B) get a file handle (from the node ref in A) on each file so I can save locally (and then run tar etc….).

Does anyone know how I can do A and B?

Jim
1 REPLY 1

jimcornmell
Champ in-the-making
Champ in-the-making
Hi All,

Its amazing how after posting to this group I stumble on the answer.  Anyway here is my solution.  Essentially the workflow places a trigger file into a space, this space has a rule which runs the action below (based on the tagging sample in the SDK):

Two further requests though:  1) is there a better/shorter way to get the Company Home node rather than my messy method getCompanyHomeNode in the Java below.  2) any other review comments welcomed, I still think I'm making a bit of a meal of the code, the getCompanyHomeNode being a fine example.

Here is the workflow task node, the java action is activiated by a rule which spots the *_done.txt file being written:
<task-node name="Create">
   <task name="myCompanywf:createTask" swimlane="artist" />
   <transition name="Complete Job" to="Approved">
      <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript">
         <script>
            <expression>
               var completedHome = companyhome.childByNamePath("Completed");
               var completeDate = new Date();
               var jobSpace = myCompanywf_orderNum + "_" + completeDate.getFullYear() + utils.pad(completeDate.getMonth()+1,2) + utils.pad(completeDate.getDate(),2);
               jobSpace += "_" + utils.pad(completeDate.getHours(),2) + utils.pad(completeDate.getMinutes(),2) + utils.pad(completeDate.getSeconds(),2);
               var completedSpace = completedHome.createFolder(jobSpace);
               var doneFileContents = jobSpace + "\r\n";
               doneFileContents += myCompanywf_orderNum + ".log\r\n";
               doneFileContents += myCompanywf_orderNum + "_job.txt\r\n";

               for (var i = 0; i &lt; bpm_package.children.length; i++) {
                  bpm_package.children[i].move(completedSpace);
                  doneFileContents += bpm_package.children[i].name + "\r\n";
               }

               var jobFile = companyhome.childByNamePath(myCompanywf_studio + "/" + myCompanywf_team + "/" + myCompanywf_orderNum + "_job.txt");
               jobFile.move(completedSpace);

               var completeLine = completeDate.getFullYear() + "-" + utils.pad(completeDate.getMonth()+1,2) + "-" + utils.pad(completeDate.getDate(),2);
               completeLine += " " + utils.pad(completeDate.getHours(),2) + ":" + utils.pad(completeDate.getMinutes(),2) + ":" + utils.pad(completeDate.getSeconds(),2);
               completeLine += " : Artist Completed Advert ";
               completeLine += "(" + myCompanywf_orderNum;
               completeLine += ", " + person.properties.userName;
               completeLine += ", " + myCompanywf_studio;
               completeLine += ", " + myCompanywf_team + ")\r\n";
               var completeFileName = myCompanywf_orderNum + ".log";

               var completeFile = completedHome.childByNamePath(completeFileName);
               if (completeFile == null) {
                  completeFile = completedHome.createFile(completeFileName);
               }
               if (completeFile != null) {
                  completeFile.content += completeLine;
               }

               completeFile.move(completedSpace);

               var triggerFileName = myCompanywf_orderNum + "_done.txt";
               var triggerFile = completedSpace.childByNamePath(triggerFileName);
               if (triggerFile == null) {
                  triggerFile = completedHome.createFile(triggerFileName);
               }
               if (triggerFile != null) {
                  triggerFile.content += doneFileContents;
               }
               triggerFile.move(completedSpace);

               pinlog.info(person.properties.userName + " completed " + myCompanywf_orderNum + " : Into folder Completed/" + jobSpace);
            </expression>
         </script>
      </action>
   </transition>
</task-node>

Here is the Java:
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.alfresco.model.ContentModel;
import org.alfresco.repo.action.ParameterDefinitionImpl;
import org.alfresco.repo.action.executer.ActionExecuterAbstractBase;
import org.alfresco.service.cmr.action.Action;
import org.alfresco.service.cmr.action.ParameterDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
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.repository.StoreRef;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class MyCompanyImportExportExecuter extends ActionExecuterAbstractBase {
   /** CVS tagging information. */
   @SuppressWarnings("unused")
   private final String __version = "@(#) $Id: MyCompanyImportExportExecuter.java,v 1.1 2008/02/20 10:16:27 jimc Exp $";

   /** log4j logger handle. */
    private static final Log logger = LogFactory.getLog(MyCompanyImportExportExecuter.class);

   public static final String PARAM_TAGS = "tags";
   public static final String PARAM_WORKFLOW_NAME = "workflowName";
   public static final String PARAM_END_START_TASK = "endStartTask";
   public static final String PARAM_START_TASK_TRANSITION = "startTaskTransition";
   public static final String HOME_MIGRATION = "Migration";

   /** The node service */
   private NodeService nodeService;
   /** The content service */
   private ContentService contentService;

   /**
    * On startup creates a NodeService handle.
    *
    * @param nodeService
    */
   public void setNodeService(NodeService nodeService) {
      logger.debug("setNodeService");
      this.nodeService = nodeService;
   }

   /**
    * On startup creates a ContentService handle.
    *
    * @param contentService
    */
   public void setContentService(ContentService contentService) {
      logger.debug("setContentService");
      this.contentService = contentService;
   }

   @Override
   protected void addParameterDefinitions(List<ParameterDefinition> paramList) {
      // Specify the parameters
      paramList.add(new ParameterDefinitionImpl(PARAM_TAGS, DataTypeDefinition.TEXT, true,
            getParamDisplayLabel(PARAM_TAGS)));
      paramList.add(new ParameterDefinitionImpl(PARAM_WORKFLOW_NAME, DataTypeDefinition.TEXT, false,
            getParamDisplayLabel(PARAM_WORKFLOW_NAME)));
      paramList.add(new ParameterDefinitionImpl(PARAM_END_START_TASK, DataTypeDefinition.BOOLEAN, false,
            getParamDisplayLabel(PARAM_END_START_TASK)));
      paramList.add(new ParameterDefinitionImpl(PARAM_START_TASK_TRANSITION, DataTypeDefinition.TEXT, false,
            getParamDisplayLabel(PARAM_START_TASK_TRANSITION)));

      // Comfort boot message.
      logger.info("*** Initialising MyCompany Import and Export action. ***");
      System.out.println("*** Initialising MyCompany Import and Export action. ***");
   }

   /**
    * Find company home location.
    * @param storeRef
    * @return
    */
   private NodeRef getCompanyHomeNode(StoreRef storeRef) {
      NodeRef rootNodeRef = nodeService.getRootNode(storeRef);
      List<ChildAssociationRef> rootChildren = nodeService.getChildAssocs(rootNodeRef);
      int nbRootChildren = rootChildren.size();
      int iRootChild;
      NodeRef rootChild = null;
      NodeRef companyHomeNode = null;
      String nodeId;

      for (iRootChild = 0; iRootChild < nbRootChildren; iRootChild++) {
         rootChild = rootChildren.get(iRootChild).getChildRef();
         nodeId = rootChild.getId();
         Serializable prop = nodeService.getProperty(rootChild, ContentModel.PROP_NAME);
         logger.debug(prop.toString() + " = " + nodeId);

         if ("Company Home".equals(prop.toString()) || HOME_MIGRATION.equals(prop.toString())) {
            companyHomeNode = rootChild;
            break;
         }
      }

      if (companyHomeNode == null) {
         logger.error("Company home is null");
      } else {
         logger.debug("Company home = " + rootChild.toString());
      }

      return companyHomeNode;
   }

   /**
    * Export a single file to the file system.
    * @param folder the files will be in this folder on Alfresco.
    * @param epsFileName the file name of the eps file to export.
    * @param xmlFileName the file name of the xml data (this may be changed for export).
    */
   private void exportSingleTarFile(StoreRef storeRef, String folder, String epsFileName, String xmlFileName) {
      logger.info("Exporting file: " + folder + "/" + epsFileName + " using xml data in " + folder + "/" + xmlFileName);

      // Walk down folder tree to the files.
      NodeRef companyHomeNode = getCompanyHomeNode(storeRef);
      NodeRef completedRef = nodeService.getChildByName(companyHomeNode, ContentModel.ASSOC_CONTAINS, "Completed");
      NodeRef folderRef = nodeService.getChildByName(completedRef, ContentModel.ASSOC_CONTAINS, folder);
      NodeRef epsFileRef = nodeService.getChildByName(folderRef, ContentModel.ASSOC_CONTAINS, epsFileName);
      NodeRef xmlFileRef = nodeService.getChildByName(folderRef, ContentModel.ASSOC_CONTAINS, xmlFileName);

      // Try and get their content?
      ContentReader xmlContentsNode = this.contentService.getReader(xmlFileRef, ContentModel.PROP_CONTENT);
      ContentReader epsContentsNode = this.contentService.getReader(epsFileRef, ContentModel.PROP_CONTENT);

      if (xmlContentsNode != null && epsContentsNode != null) {
         // Write the XML file.
         try {
            FileOutputStream out = new FileOutputStream("C:\\foo.xml");
            xmlContentsNode.getContent(out);
            out.close();
         } catch (IOException e) {
            logger.error("Unable to write XML file: " + e.getMessage());
            return;
         }

         // Write the EPS file.
         try {
            FileOutputStream out = new FileOutputStream("C:\\foo.eps");
            epsContentsNode.getContent(out);
            out.close();
         } catch (IOException e) {
            logger.error("Unable to write EPS file: " + e.getMessage());
            return;
         }

         // Tar the file.
      }
   }

   /**
    * Called by Alfresco to perform the action.
    * @param ruleAction details of the action.
    * @param actionedUponNodeRef The associated file.
    */
   @Override
   protected void executeImpl(Action ruleAction, NodeRef actionedUponNodeRef) {
      logger.info("—– Starting EXPORT Action.");
      ContentReader readerCurNode = this.contentService.getReader(actionedUponNodeRef, ContentModel.PROP_CONTENT);

      if (readerCurNode != null) {
         // Get the file list from the current node.
         String contentString = readerCurNode.getContentString();
         String[] fileList = contentString.split("\\n");
         ArrayList<String> filesToExport = new ArrayList<String>();
         String xmlFile = null;
         String folder = null;

         // Parse actioned file for list of files to export.
         for (int x = 0; x < fileList.length; x++) {
            fileList[x] = fileList[x].trim();

            if (x == 0) {
               logger.debug("Folder to export is : " + fileList[x]);
               folder = fileList[x];
            } else {
               if (fileList[x].endsWith(".eps")) {
                  filesToExport.add(fileList[x]);
               } else if (fileList[x].endsWith(".xml")) {
                  xmlFile = fileList[x];
               } else {
                  logger.debug("Not exporting this file : " + fileList[x]);
               }
            }
         }

         StoreRef storeRef = actionedUponNodeRef.getStoreRef();

         // Export each eps file using the data within the XML file.
         for (int x = 0; x < filesToExport.size(); x++) {
            exportSingleTarFile(storeRef, folder, filesToExport.get(x), xmlFile);
         }
      }

      logger.info("—– Action complete.");
   }
}