Importing folders with nested folders and files

Consider the case, when you need to add a directory with its subfolders and files from your operating system to the ELMA document storage. This function can be implemented with a business process.

When starting the process, you need to specify input parameters:

The easiest way to implement the algorithm when adding folders is by using recursion and implement everything in one script. But this option is not suitable, since a restriction may occur - the 10-minute timeout of the script execution. Therefore, divide the logic into three separate scripts: initialization, adding a folder, adding the files from the current folder.

During the initialization, you get the list of all the folders in the Source Folder and create a root folder and File-type documents, and save the files in the versions of the documents. Next, create folders and files, while tracking possible errors with a special task.

The number of folders is limited only by the free space on the ELMA file server.

You can improve the process and add the following features:

1)      possibility to specify a mask for filtering files or

2)      possibility to specify and add nested directories.

You can improve any logic for adding folders to ELMA: sort into different folders, document types, etc.

The process itself can be imported from the attached file.

Script text:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using EleWise.ELMA.API;
using EleWise.ELMA.Documents.Models;
using EleWise.ELMA.Files;
using EleWise.ELMA.Logging;
using EleWise.ELMA.Model.Common;
using EleWise.ELMA.Model.Entities;
using EleWise.ELMA.Model.Entities.ProcessContext;
using EleWise.ELMA.Model.Managers;
using EleWise.ELMA.Model.Services;
using EleWise.ELMA.Model.Types.Settings;
using EleWise.ELMA.Runtime.Managers;
using EleWise.ELMA.Services;
using Context = EleWise.ELMA.Model.Entities.ProcessContext.P_ImportPapok;


namespace EleWise.ELMA.Model.Scripts
    /// <summary>
    /// Scripts module of the Import Folders process
    /// </summary>
    public partial class P_ImportPapok_Scripts : EleWise.ELMA.Workflow.Scripts.ProcessScriptBase<Context>
        // class for storing the correspondence between the full paths to the folder and to the ELMA folder
        private class FolderMap
            public string FullName;
            public Folder ElmaFolder;
        static String[] allfiles = null; // array of paths to catalogues
        static List<FolderMap> folderMap = new List<FolderMap>(); // list of correspondences
        public void Init(Context context)
            // get the list of folders
            allfiles =  System.IO.Directory.GetDirectories(context.SourceFolder, "*",System.IO.SearchOption.AllDirectories);
            context.Kol = allfiles.Count();
             context.Current = 0;
            context.CurrentElmaFolder = context.TargetFolder;
            CreateFolderAtom(context, context.CurrentElmaFolder, context.SourceFolder); // move the root catalogue
            CreateFilesAtom(context, context.SourceFolder); // move the files from the root catalogue
        // the method creates a folder in ELMA
        public void CreateFolder(Context context)
            // search the parent folder
            Folder folder = GetCurrentFolderElma(context, allfiles[(int)context.Current]);
            // create a catalogue in ELMA
            CreateFolderAtom(context, folder, allfiles[(int)context.Current]);
        // move the files from the current catalogue to ELMA
        public void CreateFiles(Context context)
            CreateFilesAtom(context, allfiles[(int)context.Current]);
        // create files in ELMA from the current catalogue
        public void CreateFilesAtom(Context context, string pathToFiles)
            DirectoryInfo di = new DirectoryInfo(pathToFiles+"\\");            
            foreach (var element in di.GetFiles("*",SearchOption.TopDirectoryOnly)) {
                CreateFileAtom(context, context.CurrentElmaFolder, element.FullName);
        // returns the parent folder in ELMA for the specified FullFolderName
        public Folder GetCurrentFolderElma(Context context, string FullFolderName)
            Folder folder = context.TargetFolder;
            string path = Path.GetDirectoryName(FullFolderName);
            foreach (var element in folderMap) {
                if (element.FullName == path)
                    return PublicAPI.Docflow.Folder.Load(element.ElmaFolder.Id);
            return folder;
        // create a folder in ELMA
        public void CreateFolderAtom(Context context, Folder folderParent, string folderSystem)
            string lastFolderName = Path.GetFileName( folderSystem );
               Folder folder =  PublicAPI.Docflow.Folder.CreateFolder(folderParent,lastFolderName,true,false);
             context.CurrentElmaFolder = PublicAPI.Docflow.Folder.Load(folder.Id);
            FolderMap fm = new FolderMap();
            fm.FullName = folderSystem;
            fm.ElmaFolder = context.CurrentElmaFolder;
            Logger.Log.Error(context.Current.ToString()+":"+fm.FullName + "+++" + fm.ElmaFolder.Name);
        public void CreateFileAtom(Context context, Folder folderParent, string filename)
            // creating a system file in ELMA
            context.File = InterfaceActivator.Create<BinaryFile>();
            context.File.Name = Path.GetFileName(filename);
            context.File.CreateDate = DateTime.Now;
            System.IO.File.Copy(filename, context.File.ContentFilePath); // copy the file from the operating system
            Locator.GetServiceNotNull<IFileManager>().SaveFile(context.File); // save the file in ELMA
            // create a document of the File type in ELMA
            var doc = PublicAPI.Docflow.Types.File.Create(context.File, folderParent, context.File.Name );