Synchronize with File-Libraries added

Nov 23, 2008 at 3:31 PM
Edited Nov 24, 2008 at 6:42 AM
Hi!

I implemented a new menu entry into your great Guidance Explorer to synchronize between file-libraries. It synchronizes the libraries and copies the changed or are missing items to the remote library or the local library.
We needed this, because we are working with laptops and want to synchronize the items with our company-knowledgebase without installing a server. But we also want to use the items if we are not connected to the company network.
Now we have a UNC-Path with a CompanyLibrary. Everyone can Insert or Edit the items.

I dont know a way to do this with your original Guidance Explorer.
Perhaps I misunderstand a function that does this.

Sorry for my english ;-)

Here is the source of the menu entry:
(Perhaps you can implement this in a better way in the next release)

CommandHandlers.cs

    [CommandHandler(GuidanceExplorer.Commands.SyncronizeLibrary)]
    public void SyncFileLibrary(object sender, EventArgs e)
    {
      //Prepare the dialog.
      OpenFileDialog openFile = new OpenFileDialog();
      openFile.CheckFileExists = true;
      openFile.CheckPathExists = true;
      openFile.DefaultExt = "*.xml";
      openFile.Filter = Messages.XML_FILES_FILTER;
      openFile.Multiselect = false;
      openFile.RestoreDirectory = true;
      openFile.Title = "Syncronize Library From File";

      //Ask the user to select the file.
      if (openFile.ShowDialog() == DialogResult.OK)
      {

        Library remoteLibrary = _modelService.ConvertFileInfoToLibrary(new FileInfo(openFile.FileName));

        Library localLibrary = null;
        if (!_modelService.Guidance.Libraries.ContainsKey(remoteLibrary.Name))
        {
          //MessageBox.Show("not Containing");
          //ImportLibrary(

          localLibrary = Library.New();
          localLibrary.ReadProtection = ReadProtection.ReadWrite;
          localLibrary.Caption = remoteLibrary.Caption;
          localLibrary.Name = remoteLibrary.Name;
          localLibrary.WebSubscribed = false;
          localLibrary.FileSubscribed = false;
          localLibrary.SourceFileInfo = new FileInfo(Path.GetFullPath(Path.Combine(ModelStorageService.LibraryFolder, localLibrary.Caption + ".xml")));

          //Add the library to the guidance.
          _modelService.Guidance.Libraries.Add(localLibrary.Name, localLibrary);
        }
        else
        {
          foreach (KeyValuePair<string, Library> SearchLib in _modelService.Guidance.Libraries)
          {
            if (SearchLib.Key == remoteLibrary.Name)
            {
              localLibrary = SearchLib.Value;
              break;
            }
          }
        }
        if (localLibrary == null)
        {
          MessageBox.Show("Sync Error - Local Library not found");
          return;
        }

        //Hier Synchonizieren
        //_modelService.SyncronizeLibraries(library,newLibrary);

        #region Copy Items from Local-Library to Remote-Library
        foreach (GuidanceItem GItem in localLibrary)
        {
          string sKeyName = remoteLibrary.Caption + "\\" + GItem.GuidanceType.DisplayName + "\\" + GItem.Id + ".xml";
          if ((!remoteLibrary.Items.ContainsKey(sKeyName)) && (!remoteLibrary.Items.ContainsKey(GItem.Id)))
          {

            GuidanceItemFileReference fileRef;
            fileRef = _modelService.Guidance.GetGuidanceItemFileReference(GItem);

            DirectoryInfo newLibraryPath = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, ModelStorageService.LibraryFolder));
            DirectoryInfo itemsBaseFolder = new DirectoryInfo(Path.Combine(newLibraryPath.FullName, remoteLibrary.Caption));

            _asyncLoad.ProcessGuidanceItemFile(fileRef);

            string newItemFileName = Path.Combine(remoteLibrary.SourceFileInfo.DirectoryName, remoteLibrary.Caption + "\\" + fileRef.GuidanceType.DisplayName + "\\" + Path.GetFileName(fileRef.FileName));
            string oldItemFileName = Path.Combine(ModelStorageService.LibraryFolder, remoteLibrary.Caption + "\\" + fileRef.GuidanceType.DisplayName + "\\" + Path.GetFileName(fileRef.FileName));

            //Validate file names.
            if (!File.Exists(oldItemFileName))
            {
              MessageBox.Show(string.Format("The item '{0}' in the library can't be found.", oldItemFileName));
              return;
            }

            //Create the required directories.
            if (!Directory.Exists(Path.GetDirectoryName(newItemFileName)))
            {
              Directory.CreateDirectory(Path.GetDirectoryName(newItemFileName));
            }

            //Copy the file.
            File.Copy(oldItemFileName, newItemFileName, true);
            GuidanceItemFileReference remotefileRef = fileRef.Clone();
            remotefileRef.Id = fileRef.Id;
            remotefileRef.FileName = remoteLibrary.Caption + "\\" + fileRef.GuidanceType.DisplayName + "\\" + Path.GetFileName(fileRef.FileName);
            remotefileRef.Library = remoteLibrary;
            _modelService.AddGuidanceItemToLibrary(remoteLibrary, remotefileRef);
            remoteLibrary.HasChanges = true;
          }
          else
          {
            //Item Exists
          }
        }
        #endregion

        #region Copy Items from Remote-Library to Local-Library
        foreach (GuidanceItem GItem in remoteLibrary)
        {
          if ((!localLibrary.Items.ContainsKey(GItem.Id)) && (!localLibrary.Items.ContainsKey(Path.GetFileNameWithoutExtension(GItem.Id))))
          {
            GuidanceItemFileReference fileRef = GuidanceItemFileReference.New();
            fileRef.FileName = Path.Combine(Path.GetDirectoryName(openFile.FileName), GItem.Id);
            fileRef.Library = remoteLibrary;

            DirectoryInfo newLibraryPath = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, ModelStorageService.LibraryFolder));
            DirectoryInfo itemsBaseFolder = new DirectoryInfo(Path.Combine(newLibraryPath.FullName, localLibrary.Caption));

            _asyncLoad.ProcessGuidanceItemFile(fileRef);

            string oldItemFileName = Path.Combine(remoteLibrary.SourceFileInfo.DirectoryName, fileRef.FileName);
            string newItemFileName = Path.Combine(ModelStorageService.LibraryFolder, localLibrary.Caption + "\\" + fileRef.GuidanceType.DisplayName + "\\" + Path.GetFileName(fileRef.FileName));

            //Validate file names.
            if (!File.Exists(oldItemFileName))
            {
              MessageBox.Show(string.Format("The item '{0}' in the library can't be found.", oldItemFileName));
              return;
            }

            //Create the required directories.
            if (!Directory.Exists(Path.GetDirectoryName(newItemFileName)))
            {
              Directory.CreateDirectory(Path.GetDirectoryName(newItemFileName));
            }

            //Copy the file.
            File.Copy(oldItemFileName, newItemFileName, true);
            fileRef.FileName = newItemFileName;
            _modelService.AddGuidanceItemToLibrary(localLibrary, fileRef);
            localLibrary.HasChanges = true;
          }
          else
          {
            //Item Exists
          }

        }
        #endregion

        #region Update Changed Items

        foreach (GuidanceItem GItem in localLibrary)
        {
          GuidanceItemFileReference localGItemRef = _modelService.Guidance.GetGuidanceItemFileReference(GItem);
          _asyncLoad.ProcessGuidanceItemFile(localGItemRef);

          GuidanceItemFileReference remoteGItemRef = GuidanceItemFileReference.New();
          remoteGItemRef.Library = remoteLibrary;

          GuidanceItem remoteItem = null;
          if (remoteLibrary.Items.ContainsKey(GItem.Id))
          {
            remoteItem = remoteLibrary.Items[GItem.Id];
            remoteGItemRef.FileName = GItem.Id;
          }
          else
            if (remoteLibrary.Items.ContainsKey(Path.GetFileNameWithoutExtension(GItem.Id)))
            {
              remoteItem = remoteLibrary.Items[Path.GetFileNameWithoutExtension(GItem.Id)];
              remoteGItemRef.FileName = Path.GetFileNameWithoutExtension(GItem.Id);
            }
            else
              if (remoteLibrary.Items.ContainsKey(localLibrary.Caption + "\\" + localGItemRef.GuidanceType.DisplayName + "\\" + GItem.Id + ".xml"))
              {
                remoteItem = remoteLibrary.Items[localLibrary.Caption + "\\" + localGItemRef.GuidanceType.DisplayName + "\\" + GItem.Id + ".xml"];
                remoteGItemRef.FileName = localLibrary.Caption + "\\" + localGItemRef.GuidanceType.DisplayName + "\\" + GItem.Id + ".xml";
              }
              else
              {
                MessageBox.Show("Items not found");
              }
          string remoteItemFileName = Path.Combine(remoteLibrary.SourceFileInfo.DirectoryName, localLibrary.Caption + "\\" + localGItemRef.GuidanceType.DisplayName + "\\" + Path.GetFileName(remoteGItemRef.FileName));
          if (remoteItemFileName.IndexOf(".xml") < 0)
          {
            remoteItemFileName += ".xml";
          }
          string localItemFileName = Path.Combine(ModelStorageService.LibraryFolder, localLibrary.Caption + "\\" + localGItemRef.GuidanceType.DisplayName + "\\" + Path.GetFileName(localGItemRef.FileName));
          if (!File.Exists(remoteItemFileName))
          {
            MessageBox.Show(string.Format("The item '{0}' in the library can't be found.", remoteItemFileName));
            return;
          }
          remoteGItemRef.FileName = remoteItemFileName;
          _asyncLoad.ProcessGuidanceItemFile(remoteGItemRef);

          if (!(remoteItem == null))
          {
            if (remoteGItemRef.DateTime < GItem.DateTime)
            {
              //Local DT changed
              File.Copy(localItemFileName, remoteItemFileName, true);
              remoteLibrary.HasChanges = true;
            }
            else
              if (remoteGItemRef.DateTime > GItem.DateTime)
              {
                //remote DT changed
                File.Copy(remoteItemFileName, localItemFileName, true);
                localLibrary.HasChanges = true;
              }
          }
        }

        #endregion

        if (remoteLibrary.HasChanges)
        {
          FileInfo fi = new FileInfo(openFile.FileName);
          File.Delete(remoteLibrary.IndexFileName);
          _modelService.RenderLibraryToFileInfo(remoteLibrary, fi);
        }
        if (localLibrary.HasChanges)
        {
          File.Delete(localLibrary.IndexFileName);
          _asyncLoad.ProcessLibrary(localLibrary, null, null);
        }
        Synchronize(sender, e);

        return;
      }

    }
Coordinator
Jan 6, 2009 at 9:16 PM
I'm glad you were able to get this working for you. Did you first try to use the UNC library subscribe feature in GE?  You can click File->Subscribe to library->From File... and point to a UNC location.  If this is not working for you, please let me know.
Jan 13, 2009 at 3:17 PM
Edited Jan 13, 2009 at 3:17 PM
Hi,
the UNC-Path is not working for me. Because i can't view the items, if the UNC-Path is not available. If i'am working with my notebook and don't have a connection to my company-server, i can not view or modify the items.
Perhaps there is a something i didn't see ?